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.
50 * Mark strings for auto dump
52 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
53 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
56 * Variables for auto dump
58 static FILE *auto_dump_stream;
59 static cptr auto_dump_mark;
60 static int auto_dump_line_num;
64 * @brief prf出力内容を消去する /
65 * Remove old lines automatically generated before.
66 * @param orig_file 消去を行うファイル名
68 static void remove_auto_dump(cptr orig_file)
70 FILE *tmp_fff, *orig_fff;
74 bool between_mark = FALSE;
77 long header_location = 0;
78 char header_mark_str[80];
79 char footer_mark_str[80];
82 /* Prepare a header/footer mark string */
83 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
84 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
86 mark_len = strlen(footer_mark_str);
88 /* Open an old dump file in read-only mode */
89 orig_fff = my_fopen(orig_file, "r");
91 /* If original file does not exist, nothing to do */
92 if (!orig_fff) return;
94 /* Open a new (temporary) file */
95 tmp_fff = my_fopen_temp(tmp_file, 1024);
99 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
104 /* Loop for every line */
108 if (my_fgets(orig_fff, buf, sizeof(buf)))
110 /* Read error: Assume End of File */
113 * Was looking for the footer, but not found.
115 * Since automatic dump might be edited by hand,
116 * it's dangerous to kill these lines.
117 * Seek back to the next line of the (pseudo) header,
122 fseek(orig_fff, header_location, SEEK_SET);
123 between_mark = FALSE;
127 /* Success -- End the loop */
134 /* We are looking for the header mark of automatic dump */
137 /* Is this line a header? */
138 if (!strcmp(buf, header_mark_str))
140 /* Memorise seek point of this line */
141 header_location = ftell(orig_fff);
143 /* Initialize counter for number of lines */
146 /* Look for the footer from now */
149 /* There are some changes */
156 /* Copy orginally lines */
157 fprintf(tmp_fff, "%s\n", buf);
161 /* We are looking for the footer mark of automatic dump */
164 /* Is this line a footer? */
165 if (!strncmp(buf, footer_mark_str, mark_len))
170 * Compare the number of lines
172 * If there is an inconsistency between
173 * actual number of lines and the
174 * number here, the automatic dump
175 * might be edited by hand. So it's
176 * dangerous to kill these lines.
177 * Seek back to the next line of the
178 * (pseudo) header, and read again.
180 if (!sscanf(buf + mark_len, " (%d)", &tmp)
183 fseek(orig_fff, header_location, SEEK_SET);
186 /* Look for another header */
187 between_mark = FALSE;
193 /* Ignore old line, and count number of lines */
203 /* If there are some changes, overwrite the original file with new one */
206 /* Copy contents of temporary file */
208 tmp_fff = my_fopen(tmp_file, "r");
209 orig_fff = my_fopen(orig_file, "w");
211 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
212 fprintf(orig_fff, "%s\n", buf);
218 /* Kill the temporary file */
226 * @brief prfファイルのフォーマットに従った内容を出力する /
227 * Dump a formatted line, using "vstrnfmt()".
230 static void auto_dump_printf(cptr fmt, ...)
237 /* Begin the Varargs Stuff */
240 /* Format the args, save the length */
241 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
243 /* End the Varargs Stuff */
246 /* Count number of lines */
247 for (p = buf; *p; p++)
249 if (*p == '\n') auto_dump_line_num++;
253 fprintf(auto_dump_stream, "%s", buf);
258 * @brief prfファイルをファイルオープンする /
259 * Open file to append auto dump.
261 * @param mark 出力するヘッダマーク
262 * @return ファイルポインタを取得できたらTRUEを返す
264 static bool open_auto_dump(cptr buf, cptr mark)
267 char header_mark_str[80];
269 /* Save the mark string */
270 auto_dump_mark = mark;
272 /* Prepare a header mark string */
273 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
275 /* Remove old macro dumps */
276 remove_auto_dump(buf);
278 /* Append to the file */
279 auto_dump_stream = my_fopen(buf, "a");
282 if (!auto_dump_stream) {
283 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
291 fprintf(auto_dump_stream, "%s\n", header_mark_str);
293 /* Initialize counter */
294 auto_dump_line_num = 0;
296 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
297 "# *Warning!* The lines below are an automatic dump.\n"));
298 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
299 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
305 * @brief prfファイルをファイルクローズする /
306 * Append foot part and close auto dump.
309 static void close_auto_dump(void)
311 char footer_mark_str[80];
313 /* Prepare a footer mark string */
314 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
316 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
317 "# *Warning!* The lines below are an automatic dump.\n"));
318 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
319 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
321 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
324 my_fclose(auto_dump_stream);
333 * @brief Return suffix of ordinal number
335 * @return pointer of suffix string.
337 cptr get_ordinal_number_suffix(int num)
339 num = ABS(num) % 100;
343 return (num == 11) ? "th" : "st";
345 return (num == 12) ? "th" : "nd";
347 return (num == 13) ? "th" : "rd";
356 * @brief 日記にメッセージを追加する /
357 * Take note to the diary.
358 * @param type 日記内容のID
359 * @param num 日記内容のIDに応じた数値
360 * @param note 日記内容のIDに応じた文字列参照ポインタ
363 errr do_cmd_write_nikki(int type, int num, cptr note)
367 GAME_TEXT file_name[80];
369 cptr note_level = "";
370 bool do_level = TRUE;
371 char note_level_buf[40];
374 static bool disable_nikki = FALSE;
376 extract_day_hour_min(&day, &hour, &min);
378 if (disable_nikki) return(-1);
380 if (type == NIKKI_FIX_QUEST_C ||
381 type == NIKKI_FIX_QUEST_F ||
382 type == NIKKI_RAND_QUEST_C ||
383 type == NIKKI_RAND_QUEST_F ||
384 type == NIKKI_TO_QUEST)
388 old_quest = p_ptr->inside_quest;
389 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
391 /* Get the quest text */
392 init_flags = INIT_NAME_ONLY;
394 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
396 /* Reset the old quest number */
397 p_ptr->inside_quest = old_quest;
400 /* different filne name to avoid mixing */
401 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
403 /* Build the filename */
404 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
406 /* File type is "TEXT" */
407 FILE_TYPE(FILE_TYPE_TEXT);
409 fff = my_fopen(buf, "a");
414 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
420 q_idx = quest_number(dun_level);
424 if (p_ptr->inside_arena)
425 note_level = _("アリーナ:", "Arane:");
427 note_level = _("地上:", "Surface:");
428 else if (q_idx && (is_fixed_quest_idx(q_idx)
429 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
430 note_level = _("クエスト:", "Quest:");
434 sprintf(note_level_buf, "%d階(%s):", (int)dun_level, d_name+d_info[dungeon_type].name);
436 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
438 note_level = note_level_buf;
446 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
447 else fputs(_("*****日目\n", "Day *****\n"), fff);
455 fprintf(fff, "%s\n",note);
459 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
464 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
467 case NIKKI_ART_SCROLL:
469 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
474 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
477 case NIKKI_FIX_QUEST_C:
479 if (quest[num].flags & QUEST_FLAG_SILENT) break;
480 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
481 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
484 case NIKKI_FIX_QUEST_F:
486 if (quest[num].flags & QUEST_FLAG_SILENT) break;
487 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
488 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
491 case NIKKI_RAND_QUEST_C:
494 strcpy(name, r_name+r_info[quest[num].r_idx].name);
495 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
496 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
499 case NIKKI_RAND_QUEST_F:
502 strcpy(name, r_name+r_info[quest[num].r_idx].name);
503 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
504 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
507 case NIKKI_MAXDEAPTH:
509 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
510 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
511 _(d_name+d_info[dungeon_type].name, num),
512 _(num, d_name+d_info[dungeon_type].name));
517 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
518 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
519 _(d_name + d_info[num].name, (int)max_dlv[num]),
520 _((int)max_dlv[num], d_name + d_info[num].name));
526 if (q_idx && (is_fixed_quest_idx(q_idx)
527 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
529 to = _("地上", "the surface");
533 if (!(dun_level+num)) to = _("地上", "the surface");
534 else to = format(_("%d階", "level %d"), dun_level+num);
536 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
542 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
543 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]),
544 _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
546 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
551 if (quest[num].flags & QUEST_FLAG_SILENT) break;
552 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
553 hour, min, note_level, quest[num].name);
558 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
559 hour, min, note_level);
564 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
569 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
577 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
578 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
581 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
582 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
584 if (num == MAX_ARENA_MONS)
586 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
587 " won all fight to become a Chanpion.\n"));
594 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
601 to = _("地上", "the surface");
603 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
605 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
606 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
613 to = _("地上", "the surface");
615 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
617 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
618 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
623 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
626 case NIKKI_GAMESTART:
628 time_t ct = time((time_t*)0);
632 fprintf(fff, "%s %s",note, ctime(&ct));
635 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
638 case NIKKI_NAMED_PET:
640 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
643 case RECORD_NAMED_PET_NAME:
644 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
646 case RECORD_NAMED_PET_UNNAME:
647 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
649 case RECORD_NAMED_PET_DISMISS:
650 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
652 case RECORD_NAMED_PET_DEATH:
653 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
655 case RECORD_NAMED_PET_MOVED:
656 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
658 case RECORD_NAMED_PET_LOST_SIGHT:
659 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
661 case RECORD_NAMED_PET_DESTROY:
662 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
664 case RECORD_NAMED_PET_EARTHQUAKE:
665 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
667 case RECORD_NAMED_PET_GENOCIDE:
668 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
670 case RECORD_NAMED_PET_WIZ_ZAP:
671 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
673 case RECORD_NAMED_PET_TELE_LEVEL:
674 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
676 case RECORD_NAMED_PET_BLAST:
677 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
679 case RECORD_NAMED_PET_HEAL_LEPER:
680 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
682 case RECORD_NAMED_PET_COMPACT:
683 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
685 case RECORD_NAMED_PET_LOSE_PARENT:
686 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
697 case NIKKI_WIZARD_LOG:
698 fprintf(fff, "%s\n", note);
707 if (do_level) write_level = FALSE;
713 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
716 * @brief 日記のタイトル表記と内容出力 /
719 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
721 static void do_cmd_disp_nikki(void)
723 char nikki_title[256];
724 GAME_TEXT file_name[80];
729 static const char subtitle[][30] = {"最強の肉体を求めて",
760 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
761 "Attack is the best form of defence.",
763 "An unexpected windfall",
764 "A drowning man will catch at a straw",
765 "Don't count your chickens before they are hatched.",
766 "It is no use crying over spilt milk.",
767 "Seeing is believing.",
768 "Strike the iron while it is hot.",
769 "I don't care what follows.",
770 "To dig a well to put out a house on fire.",
771 "Tomorrow is another day.",
772 "Easy come, easy go.",
773 "The more haste, the less speed.",
774 "Where there is life, there is hope.",
775 "There is no royal road to *WINNER*.",
776 "Danger past, God forgotten.",
777 "The best thing to do now is to run away.",
778 "Life is but an empty dream.",
779 "Dead men tell no tales.",
780 "A book that remains shut is but a block.",
781 "Misfortunes never come singly.",
782 "A little knowledge is a dangerous thing.",
783 "History repeats itself.",
784 "*WINNER* was not built in a day.",
785 "Ignorance is bliss.",
786 "To lose is to win?",
787 "No medicine can cure folly.",
788 "All good things come to an end.",
789 "M$ Empire strikes back.",
790 "To see is to believe",
792 "Quest of The World's Greatest Brain"};
794 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
796 /* Build the filename */
797 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
799 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
800 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
801 else if (IS_WIZARD_CLASS())
802 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
803 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
806 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」",
807 ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
809 sprintf(nikki_title, "Legend of %s %s '%s'",
810 ap_ptr->title, p_ptr->name, tmp);
813 /* Display the file contents */
814 show_file(FALSE, buf, nikki_title, -1, 0);
818 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
821 static void do_cmd_bunshou(void)
824 char bunshou[80] = "\0";
826 if (get_string(_("内容: ", "diary note: "), tmp, 79))
828 strcpy(bunshou, tmp);
830 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
835 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
838 static void do_cmd_last_get(void)
843 if (record_o_name[0] == '\0') return;
845 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
846 if (!get_check(buf)) return;
850 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
851 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
856 * @brief ファイル中の全日記記録を消去する /
859 static void do_cmd_erase_nikki(void)
861 GAME_TEXT file_name[80];
865 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
866 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
868 /* Build the filename */
869 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
871 /* Remove the file */
874 fff = my_fopen(buf, "w");
877 msg_format(_("記録を消去しました。", "deleted record."));
879 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
888 void do_cmd_nikki(void)
892 /* File type is "TEXT" */
893 FILE_TYPE(FILE_TYPE_TEXT);
896 /* Interact until done */
901 /* Ask for a choice */
902 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
904 /* Give some choices */
905 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
906 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
907 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
908 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
910 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
913 prt(_("コマンド:", "Command: "), 18, 0);
918 if (i == ESCAPE) break;
932 do_cmd_erase_nikki();
936 prepare_movie_hooks();
938 default: /* Unknown option */
948 * @brief 画面を再描画するコマンドのメインルーチン
949 * Hack -- redraw the screen
953 * This command performs various low level updates, clears all the "extra"
954 * windows, does a total redraw of the main window, and requests all of the
955 * interesting updates and redraws that I can think of.
957 * This command is also used to "instantiate" the results of the user
958 * selecting various things, such as graphics mode, so it must call
959 * the "TERM_XTRA_REACT" hook before redrawing the windows.
962 void do_cmd_redraw(void)
969 /* Hack -- react to changes */
970 Term_xtra(TERM_XTRA_REACT, 0);
973 /* Combine and Reorder the pack (later) */
974 p_ptr->notice |= (PN_COMBINE | PN_REORDER);
977 p_ptr->update |= (PU_TORCH);
978 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
979 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
980 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
981 p_ptr->update |= (PU_MONSTERS);
983 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
985 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
986 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
992 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
995 /* Redraw every window */
996 for (j = 0; j < 8; j++)
999 if (!angband_term[j]) continue;
1002 Term_activate(angband_term[j]);
1011 * @brief 名前を変更するコマンドのメインルーチン
1012 * Hack -- change name
1015 void do_cmd_change_name(void)
1030 /* Display the player */
1031 display_player(mode);
1036 display_player(mode);
1041 Term_putstr(2, 23, -1, TERM_WHITE,
1042 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1044 Term_putstr(2, 23, -1, TERM_WHITE,
1045 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1053 if (c == ESCAPE) break;
1060 /* Process the player name */
1061 process_player_name(FALSE);
1067 sprintf(tmp, "%s.txt", player_base);
1068 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1070 if (tmp[0] && (tmp[0] != ' '))
1072 file_character(tmp);
1090 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1097 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1098 * Recall the most recent message
1101 void do_cmd_message_one(void)
1103 /* Recall one message */
1104 prt(format("> %s", message_str(0)), 0, 0);
1109 * @brief メッセージのログを表示するコマンドのメインルーチン
1110 * Recall the most recent message
1114 * Show previous messages to the user -BEN-
1116 * The screen format uses line 0 and 23 for headers and prompts,
1117 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1119 * This command shows you which commands you are viewing, and allows
1120 * you to "search" for strings in the recall.
1122 * Note that messages may be longer than 80 characters, but they are
1123 * displayed using "infinite" length, with a special sub-command to
1124 * "slide" the virtual display to the left or right.
1126 * Attempt to only hilite the matching portions of the string.
1129 void do_cmd_messages(int num_now)
1133 char shower_str[81];
1134 char finder_str[81];
1140 Term_get_size(&wid, &hgt);
1142 /* Number of message lines in a screen */
1143 num_lines = hgt - 4;
1146 strcpy(finder_str, "");
1149 strcpy(shower_str, "");
1151 /* Total messages */
1154 /* Start on first message */
1159 /* Process requests until done */
1165 /* Dump up to 20 lines of messages */
1166 for (j = 0; (j < num_lines) && (i + j < n); j++)
1168 cptr msg = message_str(i+j);
1170 /* Dump the messages, bottom to top */
1171 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1173 /* Hilite "shower" */
1174 if (shower && shower[0])
1178 /* Display matches */
1179 while ((str = my_strstr(str, shower)) != NULL)
1181 int len = strlen(shower);
1183 /* Display the match */
1184 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1192 /* Erase remaining lines */
1193 for (; j < num_lines; j++)
1195 Term_erase(0, num_lines + 1 - j, 255);
1198 /* Display header */
1200 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1201 i, i + j - 1, n), 0, 0);
1203 /* Display prompt (not very informative) */
1204 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1205 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1208 skey = inkey_special(TRUE);
1210 /* Exit on Escape */
1211 if (skey == ESCAPE) break;
1213 /* Hack -- Save the old index */
1218 /* Hack -- handle show */
1221 prt(_("強調: ", "Show: "), hgt - 1, 0);
1223 /* Get a "shower" string, or continue */
1224 strcpy(back_str, shower_str);
1225 if (askfor(shower_str, 80))
1228 shower = shower_str[0] ? shower_str : NULL;
1230 else strcpy(shower_str, back_str);
1234 /* Hack -- handle find */
1241 prt(_("検索: ", "Find: "), hgt - 1, 0);
1243 /* Get a "finder" string, or continue */
1244 strcpy(back_str, finder_str);
1245 if (!askfor(finder_str, 80))
1247 strcpy(finder_str, back_str);
1250 else if (!finder_str[0])
1252 shower = NULL; /* Stop showing */
1257 shower = finder_str;
1260 for (z = i + 1; z < n; z++)
1262 cptr msg = message_str(z);
1265 if (my_strstr(msg, finder_str))
1276 /* Recall 1 older message */
1278 /* Go to the oldest line */
1282 /* Recall 1 newer message */
1284 /* Go to the newest line */
1288 /* Recall 1 older message */
1293 /* Go older if legal */
1294 i = MIN(i + 1, n - num_lines);
1297 /* Recall 10 older messages */
1299 /* Go older if legal */
1300 i = MIN(i + 10, n - num_lines);
1303 /* Recall 20 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + num_lines, n - num_lines);
1312 /* Recall 20 newer messages */
1316 /* Go newer (if able) */
1317 i = MAX(0, i - num_lines);
1320 /* Recall 10 newer messages */
1322 /* Go newer (if able) */
1326 /* Recall 1 newer messages */
1329 /* Go newer (if able) */
1334 /* Hack -- Error of some kind */
1342 * @brief チートオプションを変更するコマンドのメインルーチン
1343 * Interact with some options for cheating
1344 * @param info 表示メッセージ
1347 static void do_cmd_options_cheat(cptr info)
1350 int i, k = 0, n = CHEAT_MAX;
1354 /* Interact with the player */
1360 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1365 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1366 prt(" << 注意 >>", 11, 0);
1367 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1368 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1369 prt(" じらないようにして下さい。", 14, 0);
1371 /* Display the options */
1372 for (i = 0; i < n; i++)
1374 byte a = TERM_WHITE;
1376 /* Color current option */
1377 if (i == k) a = TERM_L_BLUE;
1379 /* Display the option text */
1380 sprintf(buf, "%-48s: %s (%s)",
1381 cheat_info[i].o_desc,
1382 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1383 cheat_info[i].o_text);
1384 c_prt(a, buf, i + 2, 0);
1387 /* Hilite current option */
1388 move_cursor(k + 2, 50);
1394 * HACK - Try to translate the key into a direction
1395 * to allow using the roguelike keys for navigation.
1397 dir = get_keymap_dir(ch);
1398 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1412 k = (n + k - 1) % n;
1430 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1431 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1432 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1433 (*cheat_info[k].o_var) = TRUE;
1442 (*cheat_info[k].o_var) = FALSE;
1449 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1450 /* Peruse the help file */
1451 (void)show_file(TRUE, buf, NULL, 0, 0);
1468 * @brief セーブ頻度ターンの次の値を返す
1469 * @param current 現在のセーブ頻度ターン値
1470 * @return 次のセーブ頻度ターン値
1472 static s16b toggle_frequency(s16b current)
1477 case 50: return 100;
1478 case 100: return 250;
1479 case 250: return 500;
1480 case 500: return 1000;
1481 case 1000: return 2500;
1482 case 2500: return 5000;
1483 case 5000: return 10000;
1484 case 10000: return 25000;
1491 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1492 * @param info 表示メッセージ
1495 static void do_cmd_options_autosave(cptr info)
1498 int i, k = 0, n = 2;
1503 /* Interact with the player */
1507 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1508 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1512 /* Display the options */
1513 for (i = 0; i < n; i++)
1515 byte a = TERM_WHITE;
1517 /* Color current option */
1518 if (i == k) a = TERM_L_BLUE;
1520 /* Display the option text */
1521 sprintf(buf, "%-48s: %s (%s)",
1522 autosave_info[i].o_desc,
1523 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1524 autosave_info[i].o_text);
1525 c_prt(a, buf, i + 2, 0);
1527 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1529 /* Hilite current option */
1530 move_cursor(k + 2, 50);
1546 k = (n + k - 1) % n;
1564 (*autosave_info[k].o_var) = TRUE;
1573 (*autosave_info[k].o_var) = FALSE;
1581 autosave_freq = toggle_frequency(autosave_freq);
1582 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1588 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1604 * @brief 標準オプションを変更するコマンドのサブルーチン /
1605 * Interact with some options
1606 * @param page オプションページ番号
1607 * @param info 表示メッセージ
1610 void do_cmd_options_aux(int page, cptr info)
1613 int i, k = 0, n = 0, l;
1616 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1617 (!p_ptr->wizard || !allow_debug_opts);
1620 /* Lookup the options */
1621 for (i = 0; i < 24; i++) opt[i] = 0;
1623 /* Scan the options */
1624 for (i = 0; option_info[i].o_desc; i++)
1626 /* Notice options on this "page" */
1627 if (option_info[i].o_page == page) opt[n++] = i;
1631 /* Interact with the player */
1637 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1638 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1641 /* HACK -- description for easy-auto-destroy options */
1642 if (page == OPT_PAGE_AUTODESTROY)
1643 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1644 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1646 /* Display the options */
1647 for (i = 0; i < n; i++)
1649 byte a = TERM_WHITE;
1651 /* Color current option */
1652 if (i == k) a = TERM_L_BLUE;
1654 /* Display the option text */
1655 sprintf(buf, "%-48s: %s (%.19s)",
1656 option_info[opt[i]].o_desc,
1657 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1658 option_info[opt[i]].o_text);
1659 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1660 else c_prt(a, buf, i + 2, 0);
1663 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1666 /* Hilite current option */
1667 move_cursor(k + 2 + l, 50);
1673 * HACK - Try to translate the key into a direction
1674 * to allow using the roguelike keys for navigation.
1676 dir = get_keymap_dir(ch);
1677 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1691 k = (n + k - 1) % n;
1708 if (browse_only) break;
1709 (*option_info[opt[k]].o_var) = TRUE;
1718 if (browse_only) break;
1719 (*option_info[opt[k]].o_var) = FALSE;
1727 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1733 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1734 /* Peruse the help file */
1735 (void)show_file(TRUE, buf, NULL, 0, 0);
1752 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1753 * Modify the "window" options
1756 static void do_cmd_options_win(void)
1766 /* Memorize old flags */
1767 for (j = 0; j < 8; j++)
1769 /* Acquire current flags */
1770 old_flag[j] = window_flag[j];
1779 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1781 /* Display the windows */
1782 for (j = 0; j < 8; j++)
1784 byte a = TERM_WHITE;
1786 cptr s = angband_term_name[j];
1789 if (j == x) a = TERM_L_BLUE;
1791 /* Window name, staggered, centered */
1792 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1795 /* Display the options */
1796 for (i = 0; i < 16; i++)
1798 byte a = TERM_WHITE;
1800 cptr str = window_flag_desc[i];
1803 if (i == y) a = TERM_L_BLUE;
1806 if (!str) str = _("(未使用)", "(Unused option)");
1809 Term_putstr(0, i + 5, -1, a, str);
1811 /* Display the windows */
1812 for (j = 0; j < 8; j++)
1818 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1821 if (window_flag[j] & (1L << i)) c = 'X';
1824 Term_putch(35 + j * 5, i + 5, a, c);
1829 Term_gotoxy(35 + x * 5, y + 5);
1847 for (j = 0; j < 8; j++)
1849 window_flag[j] &= ~(1L << y);
1853 for (i = 0; i < 16; i++)
1855 window_flag[x] &= ~(1L << i);
1868 window_flag[x] |= (1L << y);
1876 window_flag[x] &= ~(1L << y);
1882 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1890 d = get_keymap_dir(ch);
1892 x = (x + ddx[d] + 8) % 8;
1893 y = (y + ddy[d] + 16) % 16;
1900 /* Notice changes */
1901 for (j = 0; j < 8; j++)
1906 if (!angband_term[j]) continue;
1908 /* Ignore non-changes */
1909 if (window_flag[j] == old_flag[j]) continue;
1912 Term_activate(angband_term[j]);
1929 option_fields[OPT_NUM] =
1932 { '1', " キー入力 オプション", 3 },
1933 { '2', " マップ画面 オプション", 4 },
1934 { '3', " テキスト表示 オプション", 5 },
1935 { '4', " ゲームプレイ オプション", 6 },
1936 { '5', " 行動中止関係 オプション", 7 },
1937 { '6', " 簡易自動破壊 オプション", 8 },
1938 { 'r', " プレイ記録 オプション", 9 },
1940 { 'p', "自動拾いエディタ", 11 },
1941 { 'd', " 基本ウェイト量 ", 12 },
1942 { 'h', "低ヒットポイント", 13 },
1943 { 'm', " 低魔力色閾値 ", 14 },
1944 { 'a', " 自動セーブ オプション", 15 },
1945 { 'w', "ウインドウフラグ", 16 },
1947 { 'b', " 初期 オプション (参照のみ)", 18 },
1948 { 'c', " 詐欺 オプション", 19 },
1950 { '1', "Input Options", 3 },
1951 { '2', "Map Screen Options", 4 },
1952 { '3', "Text Display Options", 5 },
1953 { '4', "Game-Play Options", 6 },
1954 { '5', "Disturbance Options", 7 },
1955 { '6', "Easy Auto-Destroyer Options", 8 },
1956 { 'r', "Play record Options", 9 },
1958 { 'p', "Auto-picker/destroyer editor", 11 },
1959 { 'd', "Base Delay Factor", 12 },
1960 { 'h', "Hitpoint Warning", 13 },
1961 { 'm', "Mana Color Threshold", 14 },
1962 { 'a', "Autosave Options", 15 },
1963 { 'w', "Window Flags", 16 },
1965 { 'b', "Birth Options (Browse Only)", 18 },
1966 { 'c', "Cheat Options", 19 },
1972 * @brief 標準オプションを変更するコマンドのメインルーチン /
1973 * Set or unset various options.
1977 * The user must use the "Ctrl-R" command to "adapt" to changes
1978 * in any options which control "visual" aspects of the game.
1981 void do_cmd_options(void)
1993 /* Does not list cheat option when cheat option is off */
1994 if (!p_ptr->noscore && !allow_debug_opts) n--;
1997 /* Why are we here */
1998 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2002 /* Give some choices */
2003 for (i = 0; i < n; i++)
2005 byte a = TERM_WHITE;
2006 if (i == y) a = TERM_L_BLUE;
2007 Term_putstr(5, option_fields[i].row, -1, a,
2008 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2011 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2014 skey = inkey_special(TRUE);
2015 if (!(skey & SKEY_MASK)) k = (char)skey;
2019 if (k == ESCAPE) break;
2021 if (my_strchr("\n\r ", k))
2023 k = option_fields[y].key;
2027 for (i = 0; i < n; i++)
2029 if (tolower(k) == option_fields[i].key) break;
2032 /* Command is found */
2035 /* Hack -- browse help */
2036 if (k == '?') break;
2040 if (skey == SKEY_UP) d = 8;
2041 if (skey == SKEY_DOWN) d = 2;
2042 y = (y + ddy[d] + n) % n;
2047 if (k == ESCAPE) break;
2054 /* Process the general options */
2055 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2061 /* Process the general options */
2062 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2069 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2076 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2083 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2090 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2094 /* Play-record Options */
2099 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2108 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2109 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2110 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2114 /* Cheating Options */
2117 if (!p_ptr->noscore && !allow_debug_opts)
2119 /* Cheat options are not permitted */
2125 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2132 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2141 do_cmd_options_win();
2142 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2143 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2144 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2145 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2150 /* Auto-picker/destroyer editor */
2154 do_cmd_edit_autopick();
2158 /* Hack -- Delay Speed */
2164 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2166 /* Get a new value */
2169 int msec = delay_factor * delay_factor * delay_factor;
2170 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2171 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2173 if (k == ESCAPE) break;
2176 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2179 else if (isdigit(k)) delay_factor = D2I(k);
2186 /* Hack -- hitpoint warning factor */
2192 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2194 /* Get a new value */
2197 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2198 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2200 if (k == ESCAPE) break;
2203 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2206 else if (isdigit(k)) hitpoint_warn = D2I(k);
2213 /* Hack -- mana color factor */
2219 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2221 /* Get a new value */
2224 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2225 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2227 if (k == ESCAPE) break;
2230 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2233 else if (isdigit(k)) mana_warn = D2I(k);
2241 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2245 /* Unknown option */
2258 /* Hack - Redraw equippy chars */
2259 p_ptr->redraw |= (PR_EQUIPPY);
2265 * @brief prefファイルを選択して処理する /
2266 * Ask for a "user pref line" and process it
2269 * Allow absolute file names?
2271 void do_cmd_pref(void)
2278 /* Ask for a "user pref command" */
2279 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2281 /* Process that pref command */
2282 (void)process_pref_file_command(buf);
2286 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2289 void do_cmd_reload_autopick(void)
2291 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2292 /* Load the file with messages */
2293 autopick_load_pref(TRUE);
2299 * @brief マクロ情報をprefファイルに保存する /
2300 * @param fname ファイル名
2303 static errr macro_dump(cptr fname)
2305 static cptr mark = "Macro Dump";
2311 /* Build the filename */
2312 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2314 /* File type is "TEXT" */
2315 FILE_TYPE(FILE_TYPE_TEXT);
2317 /* Append to the file */
2318 if (!open_auto_dump(buf, mark)) return (-1);
2321 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2324 for (i = 0; i < macro__num; i++)
2326 /* Extract the action */
2327 ascii_to_text(buf, macro__act[i]);
2329 /* Dump the macro */
2330 auto_dump_printf("A:%s\n", buf);
2332 /* Extract the action */
2333 ascii_to_text(buf, macro__pat[i]);
2335 /* Dump normal macros */
2336 auto_dump_printf("P:%s\n", buf);
2339 auto_dump_printf("\n");
2351 * @brief マクロのトリガーキーを取得する /
2352 * Hack -- ask for a "trigger" (see below)
2353 * @param buf キー表記を保管するバッファ
2357 * Note the complex use of the "inkey()" function from "util.c".
2359 * Note that both "flush()" calls are extremely important.
2362 static void do_cmd_macro_aux(char *buf)
2370 /* Do not process macros */
2376 /* Read the pattern */
2382 /* Do not process macros */
2385 /* Do not wait for keys */
2388 /* Attempt to read a key */
2397 /* Convert the trigger */
2398 ascii_to_text(tmp, buf);
2400 /* Hack -- display the trigger */
2401 Term_addstr(-1, TERM_WHITE, tmp);
2407 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2408 * Hack -- ask for a keymap "trigger" (see below)
2409 * @param buf キー表記を取得するバッファ
2413 * Note that both "flush()" calls are extremely important. This may
2414 * no longer be true, since "util.c" is much simpler now.
2417 static void do_cmd_macro_aux_keymap(char *buf)
2427 /* Convert to ascii */
2428 ascii_to_text(tmp, buf);
2430 /* Hack -- display the trigger */
2431 Term_addstr(-1, TERM_WHITE, tmp);
2438 * @brief キーマップをprefファイルにダンプする /
2439 * Hack -- append all keymaps to the given file
2440 * @param fname ファイルネーム
2444 static errr keymap_dump(cptr fname)
2446 static cptr mark = "Keymap Dump";
2455 if (rogue_like_commands)
2457 mode = KEYMAP_MODE_ROGUE;
2463 mode = KEYMAP_MODE_ORIG;
2467 /* Build the filename */
2468 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2470 /* File type is "TEXT" */
2471 FILE_TYPE(FILE_TYPE_TEXT);
2473 /* Append to the file */
2474 if (!open_auto_dump(buf, mark)) return -1;
2477 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2480 for (i = 0; i < 256; i++)
2484 /* Loop up the keymap */
2485 act = keymap_act[mode][i];
2487 /* Skip empty keymaps */
2490 /* Encode the key */
2493 ascii_to_text(key, buf);
2495 /* Encode the action */
2496 ascii_to_text(buf, act);
2498 /* Dump the macro */
2499 auto_dump_printf("A:%s\n", buf);
2500 auto_dump_printf("C:%d:%s\n", mode, key);
2512 * @brief マクロを設定するコマンドのメインルーチン /
2513 * Interact with "macros"
2517 * Note that the macro "action" must be defined before the trigger.
2519 * Could use some helpful instructions on this page.
2522 void do_cmd_macros(void)
2534 if (rogue_like_commands)
2536 mode = KEYMAP_MODE_ROGUE;
2542 mode = KEYMAP_MODE_ORIG;
2545 /* File type is "TEXT" */
2546 FILE_TYPE(FILE_TYPE_TEXT);
2551 /* Process requests until done */
2555 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2557 /* Describe that action */
2558 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2560 /* Analyze the current action */
2561 ascii_to_text(buf, macro__buf);
2563 /* Display the current action */
2568 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2570 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2571 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2572 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2573 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2574 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2575 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2576 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2577 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2578 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2579 #endif /* ALLOW_MACROS */
2582 prt(_("コマンド: ", "Command: "), 16, 0);
2588 if (i == ESCAPE) break;
2590 /* Load a 'macro' file */
2596 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2599 prt(_("ファイル: ", "File: "), 18, 0);
2601 /* Default filename */
2602 sprintf(tmp, "%s.prf", player_base);
2604 /* Ask for a file */
2605 if (!askfor(tmp, 80)) continue;
2607 /* Process the given filename */
2608 err = process_pref_file(tmp);
2611 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2616 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2620 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2630 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2633 prt(_("ファイル: ", "File: "), 18, 0);
2635 /* Default filename */
2636 sprintf(tmp, "%s.prf", player_base);
2638 /* Ask for a file */
2639 if (!askfor(tmp, 80)) continue;
2641 /* Dump the macros */
2642 (void)macro_dump(tmp);
2645 msg_print(_("マクロを追加しました。", "Appended macros."));
2654 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2658 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2660 /* Get a macro trigger */
2661 do_cmd_macro_aux(buf);
2663 /* Acquire action */
2664 k = macro_find_exact(buf);
2670 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2676 /* Obtain the action */
2677 strcpy(macro__buf, macro__act[k]);
2679 /* Analyze the current action */
2680 ascii_to_text(buf, macro__buf);
2682 /* Display the current action */
2686 msg_print(_("マクロを確認しました。", "Found a macro."));
2690 /* Create a macro */
2694 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2697 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2699 /* Get a macro trigger */
2700 do_cmd_macro_aux(buf);
2706 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2707 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2710 prt(_("マクロ行動: ", "Action: "), 20, 0);
2712 /* Convert to text */
2713 ascii_to_text(tmp, macro__buf);
2715 /* Get an encoded action */
2716 if (askfor(tmp, 80))
2718 /* Convert to ascii */
2719 text_to_ascii(macro__buf, tmp);
2721 /* Link the macro */
2722 macro_add(buf, macro__buf);
2725 msg_print(_("マクロを追加しました。", "Added a macro."));
2729 /* Remove a macro */
2733 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2736 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2738 /* Get a macro trigger */
2739 do_cmd_macro_aux(buf);
2741 /* Link the macro */
2742 macro_add(buf, buf);
2745 msg_print(_("マクロを削除しました。", "Removed a macro."));
2752 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2755 prt(_("ファイル: ", "File: "), 18, 0);
2757 /* Default filename */
2758 sprintf(tmp, "%s.prf", player_base);
2760 /* Ask for a file */
2761 if (!askfor(tmp, 80)) continue;
2763 /* Dump the macros */
2764 (void)keymap_dump(tmp);
2767 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2770 /* Query a keymap */
2776 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2779 prt(_("押すキー: ", "Keypress: "), 18, 0);
2781 /* Get a keymap trigger */
2782 do_cmd_macro_aux_keymap(buf);
2784 /* Look up the keymap */
2785 act = keymap_act[mode][(byte)(buf[0])];
2791 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2797 /* Obtain the action */
2798 strcpy(macro__buf, act);
2800 /* Analyze the current action */
2801 ascii_to_text(buf, macro__buf);
2803 /* Display the current action */
2807 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2811 /* Create a keymap */
2815 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2818 prt(_("押すキー: ", "Keypress: "), 18, 0);
2820 /* Get a keymap trigger */
2821 do_cmd_macro_aux_keymap(buf);
2827 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2828 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2831 prt(_("行動: ", "Action: "), 20, 0);
2833 /* Convert to text */
2834 ascii_to_text(tmp, macro__buf);
2836 /* Get an encoded action */
2837 if (askfor(tmp, 80))
2839 /* Convert to ascii */
2840 text_to_ascii(macro__buf, tmp);
2842 /* Free old keymap */
2843 string_free(keymap_act[mode][(byte)(buf[0])]);
2845 /* Make new keymap */
2846 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2849 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2853 /* Remove a keymap */
2857 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2860 prt(_("押すキー: ", "Keypress: "), 18, 0);
2862 /* Get a keymap trigger */
2863 do_cmd_macro_aux_keymap(buf);
2865 /* Free old keymap */
2866 string_free(keymap_act[mode][(byte)(buf[0])]);
2868 /* Make new keymap */
2869 keymap_act[mode][(byte)(buf[0])] = NULL;
2872 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2875 /* Enter a new action */
2879 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2885 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2886 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2889 prt(_("マクロ行動: ", "Action: "), 20, 0);
2891 /* Hack -- limit the value */
2894 /* Get an encoded action */
2895 if (!askfor(buf, 80)) continue;
2897 /* Extract an action */
2898 text_to_ascii(macro__buf, buf);
2901 #endif /* ALLOW_MACROS */
2914 * @brief キャラクタ色の明暗表現
2916 static cptr lighting_level_str[F_LIT_MAX] =
2931 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2932 * @param i 指定対象となるキャラクタコード
2933 * @param num 指定されたビジュアルIDを返す参照ポインタ
2934 * @param max ビジュアルIDの最大数
2935 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2937 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2944 sprintf(str, "%d", *num);
2946 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2949 tmp = (IDX)strtol(str, NULL, 0);
2950 if (tmp >= 0 && tmp < max)
2953 else if (isupper(i))
2954 *num = (*num + max - 1) % max;
2956 *num = (*num + 1) % max;
2962 * @brief キャラクタの変更メニュー表示
2963 * @param choice_msg 選択メッセージ
2966 static void print_visuals_menu(cptr choice_msg)
2968 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2970 /* Give some choices */
2971 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2973 #ifdef ALLOW_VISUALS
2974 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2975 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2976 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2977 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2978 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2979 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2980 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2981 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2982 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2983 #endif /* ALLOW_VISUALS */
2985 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2988 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2991 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2992 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2993 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2996 * Interact with "visuals"
2998 void do_cmd_visuals(void)
3003 bool need_redraw = FALSE;
3004 const char *empty_symbol = "<< ? >>";
3006 if (use_bigtile) empty_symbol = "<< ?? >>";
3008 /* File type is "TEXT" */
3009 FILE_TYPE(FILE_TYPE_TEXT);
3012 /* Interact until done */
3017 /* Ask for a choice */
3018 print_visuals_menu(NULL);
3023 if (i == ESCAPE) break;
3027 /* Load a 'pref' file */
3030 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3033 prt(_("ファイル: ", "File: "), 17, 0);
3035 /* Default filename */
3036 sprintf(tmp, "%s.prf", player_base);
3039 if (!askfor(tmp, 70)) continue;
3041 /* Process the given filename */
3042 (void)process_pref_file(tmp);
3047 #ifdef ALLOW_VISUALS
3049 /* Dump monster attr/chars */
3052 static cptr mark = "Monster attr/chars";
3055 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3058 prt(_("ファイル: ", "File: "), 17, 0);
3060 /* Default filename */
3061 sprintf(tmp, "%s.prf", player_base);
3063 /* Get a filename */
3064 if (!askfor(tmp, 70)) continue;
3066 /* Build the filename */
3067 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3069 /* Append to the file */
3070 if (!open_auto_dump(buf, mark)) continue;
3073 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3076 for (i = 0; i < max_r_idx; i++)
3078 monster_race *r_ptr = &r_info[i];
3080 /* Skip non-entries */
3081 if (!r_ptr->name) continue;
3083 /* Dump a comment */
3084 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3086 /* Dump the monster attr/char info */
3087 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3088 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3094 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3099 /* Dump object attr/chars */
3102 static cptr mark = "Object attr/chars";
3103 KIND_OBJECT_IDX k_idx;
3106 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3109 prt(_("ファイル: ", "File: "), 17, 0);
3111 /* Default filename */
3112 sprintf(tmp, "%s.prf", player_base);
3114 /* Get a filename */
3115 if (!askfor(tmp, 70)) continue;
3117 /* Build the filename */
3118 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3120 /* Append to the file */
3121 if (!open_auto_dump(buf, mark)) continue;
3124 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3127 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3129 GAME_TEXT o_name[80];
3130 object_kind *k_ptr = &k_info[k_idx];
3132 /* Skip non-entries */
3133 if (!k_ptr->name) continue;
3138 strip_name(o_name, k_idx);
3144 /* Prepare dummy object */
3145 object_prep(&forge, k_idx);
3147 /* Get un-shuffled flavor name */
3148 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3151 /* Dump a comment */
3152 auto_dump_printf("# %s\n", o_name);
3154 /* Dump the object attr/char info */
3155 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3156 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3162 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3167 /* Dump feature attr/chars */
3170 static cptr mark = "Feature attr/chars";
3173 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3176 prt(_("ファイル: ", "File: "), 17, 0);
3178 /* Default filename */
3179 sprintf(tmp, "%s.prf", player_base);
3181 /* Get a filename */
3182 if (!askfor(tmp, 70)) continue;
3184 /* Build the filename */
3185 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3187 /* Append to the file */
3188 if (!open_auto_dump(buf, mark)) continue;
3191 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3194 for (i = 0; i < max_f_idx; i++)
3196 feature_type *f_ptr = &f_info[i];
3198 /* Skip non-entries */
3199 if (!f_ptr->name) continue;
3201 /* Skip mimiccing features */
3202 if (f_ptr->mimic != i) continue;
3204 /* Dump a comment */
3205 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3207 /* Dump the feature attr/char info */
3208 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3209 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3210 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3211 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3217 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3222 /* Modify monster attr/chars (numeric operation) */
3225 static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3228 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3230 /* Hack -- query until done */
3233 monster_race *r_ptr = &r_info[r];
3237 TERM_COLOR da = r_ptr->d_attr;
3238 byte dc = r_ptr->d_char;
3239 TERM_COLOR ca = r_ptr->x_attr;
3240 byte cc = r_ptr->x_char;
3242 /* Label the object */
3243 Term_putstr(5, 17, -1, TERM_WHITE,
3244 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3246 /* Label the Default values */
3247 Term_putstr(10, 19, -1, TERM_WHITE,
3248 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3250 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3251 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3253 /* Label the Current values */
3254 Term_putstr(10, 20, -1, TERM_WHITE,
3255 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3257 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3258 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3261 Term_putstr(0, 22, -1, TERM_WHITE,
3262 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3268 if (i == ESCAPE) break;
3270 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3271 else if (isupper(i)) c = 'a' + i - 'A';
3281 if (!cmd_visuals_aux(i, &r, max_r_idx))
3287 while (!r_info[r].name);
3291 t = (int)r_ptr->x_attr;
3292 (void)cmd_visuals_aux(i, &t, 256);
3293 r_ptr->x_attr = (byte)t;
3297 t = (int)r_ptr->x_char;
3298 (void)cmd_visuals_aux(i, &t, 256);
3299 r_ptr->x_char = (byte)t;
3303 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3305 print_visuals_menu(choice_msg);
3313 /* Modify object attr/chars (numeric operation) */
3316 static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3318 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3320 /* Hack -- query until done */
3323 object_kind *k_ptr = &k_info[k];
3327 TERM_COLOR da = k_ptr->d_attr;
3328 SYMBOL_CODE dc = k_ptr->d_char;
3329 TERM_COLOR ca = k_ptr->x_attr;
3330 SYMBOL_CODE cc = k_ptr->x_char;
3332 /* Label the object */
3333 Term_putstr(5, 17, -1, TERM_WHITE,
3334 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3335 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3337 /* Label the Default values */
3338 Term_putstr(10, 19, -1, TERM_WHITE,
3339 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3341 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3342 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3344 /* Label the Current values */
3345 Term_putstr(10, 20, -1, TERM_WHITE,
3346 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3348 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3349 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3352 Term_putstr(0, 22, -1, TERM_WHITE,
3353 _("コマンド (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): "));
3359 if (i == ESCAPE) break;
3361 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3362 else if (isupper(i)) c = 'a' + i - 'A';
3372 if (!cmd_visuals_aux(i, &k, max_k_idx))
3378 while (!k_info[k].name);
3382 t = (int)k_ptr->x_attr;
3383 (void)cmd_visuals_aux(i, &t, 256);
3384 k_ptr->x_attr = (byte)t;
3388 t = (int)k_ptr->x_char;
3389 (void)cmd_visuals_aux(i, &t, 256);
3390 k_ptr->x_char = (byte)t;
3394 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3396 print_visuals_menu(choice_msg);
3404 /* Modify feature attr/chars (numeric operation) */
3407 static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3409 static IDX lighting_level = F_LIT_STANDARD;
3410 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3412 /* Hack -- query until done */
3415 feature_type *f_ptr = &f_info[f];
3419 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3420 byte dc = f_ptr->d_char[lighting_level];
3421 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3422 byte cc = f_ptr->x_char[lighting_level];
3424 /* Label the object */
3426 Term_putstr(5, 17, -1, TERM_WHITE,
3427 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3428 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3430 /* Label the Default values */
3431 Term_putstr(10, 19, -1, TERM_WHITE,
3432 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3434 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3435 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3437 /* Label the Current values */
3439 Term_putstr(10, 20, -1, TERM_WHITE,
3440 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3442 Term_putstr(10, 20, -1, TERM_WHITE,
3443 format("Current attr/char = %3d / %3d", ca, cc));
3446 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3447 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3451 Term_putstr(0, 22, -1, TERM_WHITE,
3452 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3454 Term_putstr(0, 22, -1, TERM_WHITE,
3455 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3462 if (i == ESCAPE) break;
3464 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3465 else if (isupper(i)) c = 'a' + i - 'A';
3475 if (!cmd_visuals_aux(i, &f, max_f_idx))
3481 while (!f_info[f].name || (f_info[f].mimic != f));
3485 t = (int)f_ptr->x_attr[lighting_level];
3486 (void)cmd_visuals_aux(i, &t, 256);
3487 f_ptr->x_attr[lighting_level] = (byte)t;
3491 t = (int)f_ptr->x_char[lighting_level];
3492 (void)cmd_visuals_aux(i, &t, 256);
3493 f_ptr->x_char[lighting_level] = (byte)t;
3497 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3500 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3504 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3506 print_visuals_menu(choice_msg);
3514 /* Modify monster attr/chars (visual mode) */
3516 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3519 /* Modify object attr/chars (visual mode) */
3521 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3524 /* Modify feature attr/chars (visual mode) */
3527 IDX lighting_level = F_LIT_STANDARD;
3528 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3532 #endif /* ALLOW_VISUALS */
3540 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3544 /* Unknown option */
3554 if (need_redraw) do_cmd_redraw();
3559 * Interact with "colors"
3561 void do_cmd_colors(void)
3570 /* File type is "TEXT" */
3571 FILE_TYPE(FILE_TYPE_TEXT);
3576 /* Interact until done */
3581 /* Ask for a choice */
3582 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3584 /* Give some choices */
3585 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3588 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3589 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3593 prt(_("コマンド: ", "Command: "), 8, 0);
3597 if (i == ESCAPE) break;
3599 /* Load a 'pref' file */
3603 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3606 prt(_("ファイル: ", "File: "), 10, 0);
3609 sprintf(tmp, "%s.prf", player_base);
3612 if (!askfor(tmp, 70)) continue;
3614 /* Process the given filename */
3615 (void)process_pref_file(tmp);
3617 /* Mega-Hack -- react to changes */
3618 Term_xtra(TERM_XTRA_REACT, 0);
3620 /* Mega-Hack -- redraw */
3629 static cptr mark = "Colors";
3632 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3635 prt(_("ファイル: ", "File: "), 10, 0);
3637 /* Default filename */
3638 sprintf(tmp, "%s.prf", player_base);
3640 /* Get a filename */
3641 if (!askfor(tmp, 70)) continue;
3643 /* Build the filename */
3644 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3646 /* Append to the file */
3647 if (!open_auto_dump(buf, mark)) continue;
3650 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3653 for (i = 0; i < 256; i++)
3655 int kv = angband_color_table[i][0];
3656 int rv = angband_color_table[i][1];
3657 int gv = angband_color_table[i][2];
3658 int bv = angband_color_table[i][3];
3660 cptr name = _("未知", "unknown");
3662 /* Skip non-entries */
3663 if (!kv && !rv && !gv && !bv) continue;
3665 /* Extract the color name */
3666 if (i < 16) name = color_names[i];
3668 /* Dump a comment */
3669 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3671 /* Dump the monster attr/char info */
3672 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3679 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3688 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3690 /* Hack -- query until done */
3699 /* Exhibit the normal colors */
3700 for (j = 0; j < 16; j++)
3702 /* Exhibit this color */
3703 Term_putstr(j*4, 20, -1, a, "###");
3705 /* Exhibit all colors */
3706 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3709 /* Describe the color */
3710 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3712 /* Describe the color */
3713 Term_putstr(5, 10, -1, TERM_WHITE,
3714 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3716 /* Label the Current values */
3717 Term_putstr(5, 12, -1, TERM_WHITE,
3718 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3719 angband_color_table[a][0],
3720 angband_color_table[a][1],
3721 angband_color_table[a][2],
3722 angband_color_table[a][3]));
3725 Term_putstr(0, 14, -1, TERM_WHITE,
3726 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3733 if (i == ESCAPE) break;
3736 if (i == 'n') a = (byte)(a + 1);
3737 if (i == 'N') a = (byte)(a - 1);
3738 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3739 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3740 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3741 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3742 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3743 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3744 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3745 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3747 /* Hack -- react to changes */
3748 Term_xtra(TERM_XTRA_REACT, 0);
3750 /* Hack -- redraw */
3757 /* Unknown option */
3771 * Note something in the message recall
3773 void do_cmd_note(void)
3781 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3783 /* Ignore empty notes */
3784 if (!buf[0] || (buf[0] == ' ')) return;
3786 /* Add the note to the message recall */
3787 msg_format(_("メモ: %s", "Note: %s"), buf);
3792 * Mention the current version
3794 void do_cmd_version(void)
3798 #if FAKE_VER_EXTRA > 0
3799 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3800 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3802 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3803 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3810 * Array of feeling strings
3812 static cptr do_cmd_feeling_text[11] =
3814 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3815 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3816 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3817 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3818 _("とても悪い予感がする...", "You have a very bad feeling..."),
3819 _("悪い予感がする...", "You have a bad feeling..."),
3820 _("何か緊張する。", "You feel nervous."),
3821 _("少し不運な気がする...", "You feel your luck is turning..."),
3822 _("この場所は好きになれない。", "You don't like the look of this place."),
3823 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3824 _("なんて退屈なところだ...", "What a boring place...")
3827 static cptr do_cmd_feeling_text_combat[11] =
3829 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3830 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3831 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3832 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3833 _("とても悪い予感がする...", "You have a very bad feeling..."),
3834 _("悪い予感がする...", "You have a bad feeling..."),
3835 _("何か緊張する。", "You feel nervous."),
3836 _("少し不運な気がする...", "You feel your luck is turning..."),
3837 _("この場所は好きになれない。", "You don't like the look of this place."),
3838 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3839 _("なんて退屈なところだ...", "What a boring place...")
3842 static cptr do_cmd_feeling_text_lucky[11] =
3844 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3845 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3846 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3847 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3848 _("とても良い感じがする...", "You have a very good feeling..."),
3849 _("良い感じがする...", "You have a good feeling..."),
3850 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3851 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3852 _("見た感じ悪くはない...", "You like the look of this place..."),
3853 _("全然駄目ということはないが...", "This level can't be all bad..."),
3854 _("なんて退屈なところだ...", "What a boring place...")
3859 * Note that "feeling" is set to zero unless some time has passed.
3860 * Note that this is done when the level is GENERATED, not entered.
3862 void do_cmd_feeling(void)
3864 /* No useful feeling in quests */
3865 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3867 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3871 /* No useful feeling in town */
3872 else if (p_ptr->town_num && !dun_level)
3874 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3876 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3881 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3886 /* No useful feeling in the wilderness */
3887 else if (!dun_level)
3889 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3893 /* Display the feeling */
3894 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3895 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3896 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3897 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3898 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3900 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3906 * Description of each monster group.
3908 static cptr monster_group_text[] =
3911 "ユニーク", /* "Uniques" */
3912 "乗馬可能なモンスター", /* "Riding" */
3913 "賞金首", /* "Wanted */
3914 "アンバーの王族", /* "Ambertite" */
3943 /* "古代ドラゴン/ワイアーム", */
4004 /* "Ancient Dragon/Wyrm", */
4013 "Multi-Headed Reptile",
4018 "Reptile/Amphibian",
4019 "Spider/Scorpion/Tick",
4021 /* "Major Demon", */
4038 * Symbols of monsters in each group. Note the "Uniques" group
4039 * is handled differently.
4041 static cptr monster_group_char[] =
4098 "!$&()+./=>?[\\]`{|~",
4108 * hook function to sort monsters by level
4110 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4112 u16b *who = (u16b*)(u);
4117 monster_race *r_ptr1 = &r_info[w1];
4118 monster_race *r_ptr2 = &r_info[w2];
4123 if (r_ptr2->level > r_ptr1->level) return TRUE;
4124 if (r_ptr1->level > r_ptr2->level) return FALSE;
4126 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4127 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4132 * Build a list of monster indexes in the given group. Return the number
4133 * of monsters in the group.
4135 * mode & 0x01 : check for non-empty group
4136 * mode & 0x02 : visual operation only
4138 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4144 /* Get a list of x_char in this group */
4145 cptr group_char = monster_group_char[grp_cur];
4147 /* XXX Hack -- Check if this is the "Uniques" group */
4148 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4150 /* XXX Hack -- Check if this is the "Riding" group */
4151 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4153 /* XXX Hack -- Check if this is the "Wanted" group */
4154 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4156 /* XXX Hack -- Check if this is the "Amberite" group */
4157 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4160 /* Check every race */
4161 for (i = 0; i < max_r_idx; i++)
4163 /* Access the race */
4164 monster_race *r_ptr = &r_info[i];
4166 /* Skip empty race */
4167 if (!r_ptr->name) continue ;
4169 /* Require known monsters */
4170 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4174 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4177 else if (grp_riding)
4179 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4182 else if (grp_wanted)
4184 bool wanted = FALSE;
4186 for (j = 0; j < MAX_KUBI; j++)
4188 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4189 (p_ptr->today_mon && p_ptr->today_mon == i))
4195 if (!wanted) continue;
4198 else if (grp_amberite)
4200 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4205 /* Check for race in the group */
4206 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4210 mon_idx[mon_cnt++] = i;
4212 /* XXX Hack -- Just checking for non-empty group */
4213 if (mode & 0x01) break;
4216 /* Terminate the list */
4217 mon_idx[mon_cnt] = -1;
4219 /* Select the sort method */
4220 ang_sort_comp = ang_sort_comp_monster_level;
4221 ang_sort_swap = ang_sort_swap_hook;
4223 /* Sort by monster level */
4224 ang_sort(mon_idx, &dummy_why, mon_cnt);
4226 /* Return the number of races */
4232 * Description of each monster group.
4234 static cptr object_group_text[] =
4237 "キノコ", /* "Mushrooms" */
4238 "薬", /* "Potions" */
4239 "油つぼ", /* "Flasks" */
4240 "巻物", /* "Scrolls" */
4242 "アミュレット", /* "Amulets" */
4243 "笛", /* "Whistle" */
4244 "光源", /* "Lanterns" */
4245 "魔法棒", /* "Wands" */
4248 "カード", /* "Cards" */
4259 "刀剣類", /* "Swords" */
4260 "鈍器", /* "Blunt Weapons" */
4261 "長柄武器", /* "Polearms" */
4262 "採掘道具", /* "Diggers" */
4263 "飛び道具", /* "Bows" */
4267 "軽装鎧", /* "Soft Armor" */
4268 "重装鎧", /* "Hard Armor" */
4269 "ドラゴン鎧", /* "Dragon Armor" */
4270 "盾", /* "Shields" */
4271 "クローク", /* "Cloaks" */
4272 "籠手", /* "Gloves" */
4273 "ヘルメット", /* "Helms" */
4275 "ブーツ", /* "Boots" */
4328 * TVALs of items in each group
4330 static byte object_group_tval[] =
4371 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4379 * Build a list of object indexes in the given group. Return the number
4380 * of objects in the group.
4382 * mode & 0x01 : check for non-empty group
4383 * mode & 0x02 : visual operation only
4385 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4388 int j, k, object_cnt = 0;
4390 /* Get a list of x_char in this group */
4391 byte group_tval = object_group_tval[grp_cur];
4393 /* Check every object */
4394 for (i = 0; i < max_k_idx; i++)
4396 /* Access the object */
4397 object_kind *k_ptr = &k_info[i];
4399 /* Skip empty objects */
4400 if (!k_ptr->name) continue;
4404 /* Any objects will be displayed */
4410 /* Skip non-flavoured objects */
4411 if (!k_ptr->flavor) continue;
4413 /* Require objects ever seen */
4414 if (!k_ptr->aware) continue;
4417 /* Skip items with no distribution (special artifacts) */
4418 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4422 /* Check for objects in the group */
4423 if (TV_LIFE_BOOK == group_tval)
4425 /* Hack -- All spell books */
4426 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4428 /* Add the object */
4429 object_idx[object_cnt++] = i;
4433 else if (k_ptr->tval == group_tval)
4435 /* Add the object */
4436 object_idx[object_cnt++] = i;
4440 /* XXX Hack -- Just checking for non-empty group */
4441 if (mode & 0x01) break;
4444 /* Terminate the list */
4445 object_idx[object_cnt] = -1;
4447 /* Return the number of objects */
4453 * Description of each feature group.
4455 static cptr feature_group_text[] =
4463 * Build a list of feature indexes in the given group. Return the number
4464 * of features in the group.
4466 * mode & 0x01 : check for non-empty group
4468 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4473 /* Unused; There is a single group. */
4476 /* Check every feature */
4477 for (i = 0; i < max_f_idx; i++)
4479 /* Access the index */
4480 feature_type *f_ptr = &f_info[i];
4482 /* Skip empty index */
4483 if (!f_ptr->name) continue;
4485 /* Skip mimiccing features */
4486 if (f_ptr->mimic != i) continue;
4489 feat_idx[feat_cnt++] = i;
4491 /* XXX Hack -- Just checking for non-empty group */
4492 if (mode & 0x01) break;
4495 /* Terminate the list */
4496 feat_idx[feat_cnt] = -1;
4498 /* Return the number of races */
4505 * Build a list of monster indexes in the given group. Return the number
4506 * of monsters in the group.
4508 static int collect_artifacts(int grp_cur, int object_idx[])
4510 int i, object_cnt = 0;
4512 /* Get a list of x_char in this group */
4513 byte group_tval = object_group_tval[grp_cur];
4515 /* Check every object */
4516 for (i = 0; i < max_a_idx; i++)
4518 /* Access the artifact */
4519 artifact_type *a_ptr = &a_info[i];
4521 /* Skip empty artifacts */
4522 if (!a_ptr->name) continue;
4524 /* Skip "uncreated" artifacts */
4525 if (!a_ptr->cur_num) continue;
4527 /* Check for race in the group */
4528 if (a_ptr->tval == group_tval)
4531 object_idx[object_cnt++] = i;
4535 /* Terminate the list */
4536 object_idx[object_cnt] = 0;
4538 /* Return the number of races */
4545 * Encode the screen colors
4547 static char hack[17] = "dwsorgbuDWvyRGBU";
4551 * Hack -- load a screen dump from a file
4553 void do_cmd_load_screen(void)
4568 Term_get_size(&wid, &hgt);
4570 /* Build the filename */
4571 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4573 /* Append to the file */
4574 fff = my_fopen(buf, "r");
4577 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4585 /* Load the screen */
4586 for (y = 0; okay; y++)
4588 /* Get a line of data including control code */
4589 if (!fgets(buf, 1024, fff)) okay = FALSE;
4591 /* Get the blank line */
4592 if (buf[0] == '\n' || buf[0] == '\0') break;
4594 /* Ignore too large screen image */
4595 if (y >= hgt) continue;
4598 for (x = 0; x < wid - 1; x++)
4601 if (buf[x] == '\n' || buf[x] == '\0') break;
4603 /* Put the attr/char */
4604 Term_draw(x, y, TERM_WHITE, buf[x]);
4608 /* Dump the screen */
4609 for (y = 0; okay; y++)
4611 /* Get a line of data including control code */
4612 if (!fgets(buf, 1024, fff)) okay = FALSE;
4614 /* Get the blank line */
4615 if (buf[0] == '\n' || buf[0] == '\0') break;
4617 /* Ignore too large screen image */
4618 if (y >= hgt) continue;
4621 for (x = 0; x < wid - 1; x++)
4624 if (buf[x] == '\n' || buf[x] == '\0') break;
4626 /* Get the attr/char */
4627 (void)(Term_what(x, y, &a, &c));
4629 /* Look up the attr */
4630 for (i = 0; i < 16; i++)
4632 /* Use attr matches */
4633 if (hack[i] == buf[x]) a = (byte_hack)i;
4636 /* Put the attr/char */
4637 Term_draw(x, y, a, c);
4646 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4657 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4658 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4661 #define IM_FLAG_STR _("*", "* ")
4662 #define HAS_FLAG_STR _("+", "+ ")
4663 #define NO_FLAG_STR _("・", ". ")
4665 #define print_im_or_res_flag(IM, RES) \
4667 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4668 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4671 #define print_flag(TR) \
4673 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4677 /* XTRA HACK RESLIST */
4678 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4680 GAME_TEXT o_name[MAX_NLEN];
4681 BIT_FLAGS flgs[TR_FLAG_SIZE];
4683 if (!o_ptr->k_idx) return;
4684 if (o_ptr->tval != tval) return;
4686 /* Identified items only */
4687 if (!object_is_known(o_ptr)) return;
4690 * HACK:Ring of Lordly protection and Dragon equipment
4691 * have random resistances.
4693 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4694 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4695 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4696 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4697 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4698 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4699 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4700 || object_is_artifact(o_ptr))
4703 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4705 while (o_name[i] && (i < 26))
4708 if (iskanji(o_name[i])) i++;
4717 o_name[i] = ' '; i++;
4722 fprintf(fff, "%s %s", where, o_name);
4724 if (!(o_ptr->ident & (IDENT_MENTAL)))
4726 fputs(_("-------不明--------------- -------不明---------\n",
4727 "-------unknown------------ -------unknown------\n"), fff);
4731 object_flags_known(o_ptr, flgs);
4733 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4734 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4735 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4736 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4737 print_flag(TR_RES_POIS);
4738 print_flag(TR_RES_LITE);
4739 print_flag(TR_RES_DARK);
4740 print_flag(TR_RES_SHARDS);
4741 print_flag(TR_RES_SOUND);
4742 print_flag(TR_RES_NETHER);
4743 print_flag(TR_RES_NEXUS);
4744 print_flag(TR_RES_CHAOS);
4745 print_flag(TR_RES_DISEN);
4749 print_flag(TR_RES_BLIND);
4750 print_flag(TR_RES_FEAR);
4751 print_flag(TR_RES_CONF);
4752 print_flag(TR_FREE_ACT);
4753 print_flag(TR_SEE_INVIS);
4754 print_flag(TR_HOLD_EXP);
4755 print_flag(TR_TELEPATHY);
4756 print_flag(TR_SLOW_DIGEST);
4757 print_flag(TR_REGEN);
4758 print_flag(TR_LEVITATION);
4766 fprintf(fff, "%s\n", inven_res_label);
4772 * Display *ID* ed weapons/armors's resistances
4774 static void do_cmd_knowledge_inven(void)
4778 GAME_TEXT file_name[1024];
4782 OBJECT_TYPE_VALUE tval;
4788 /* Open a new file */
4789 fff = my_fopen_temp(file_name, 1024);
4792 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4796 fprintf(fff, "%s\n", inven_res_label);
4798 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4802 for (; j < 9; j++) fputc('\n', fff);
4804 fprintf(fff, "%s\n", inven_res_label);
4806 strcpy(where, _("装", "E "));
4807 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4809 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4811 strcpy(where, _("持", "I "));
4812 for (i = 0; i < INVEN_PACK; i++)
4814 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4817 st_ptr = &town[1].store[STORE_HOME];
4818 strcpy(where, _("家", "H "));
4819 for (i = 0; i < st_ptr->stock_num; i++)
4821 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4826 /* Display the file contents */
4827 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4829 /* Remove the file */
4834 void do_cmd_save_screen_html_aux(char *filename, int message)
4838 TERM_COLOR a = 0, old_a = 0;
4852 cptr html_head[] = {
4853 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4857 cptr html_foot[] = {
4859 "</body>\n</html>\n",
4865 Term_get_size(&wid, &hgt);
4867 /* File type is "TEXT" */
4868 FILE_TYPE(FILE_TYPE_TEXT);
4870 /* Append to the file */
4871 fff = my_fopen(filename, "w");
4875 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4881 if (message) screen_save();
4883 /* Build the filename */
4884 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4885 tmpfff = my_fopen(buf, "r");
4887 for (i = 0; html_head[i]; i++)
4888 fputs(html_head[i], fff);
4892 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4894 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4898 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4900 fprintf(fff, "%s\n", buf);
4905 /* Dump the screen */
4906 for (y = 0; y < hgt; y++)
4913 for (x = 0; x < wid - 1; x++)
4917 /* Get the attr/char */
4918 (void)(Term_what(x, y, &a, &c));
4922 case '&': cc = "&"; break;
4923 case '<': cc = "<"; break;
4924 case '>': cc = ">"; break;
4926 case 0x1f: c = '.'; break;
4927 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4932 if ((y == 0 && x == 0) || a != old_a) {
4933 rv = angband_color_table[a][1];
4934 gv = angband_color_table[a][2];
4935 bv = angband_color_table[a][3];
4936 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4937 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4941 fprintf(fff, "%s", cc);
4943 fprintf(fff, "%c", c);
4946 fprintf(fff, "</font>");
4949 for (i = 0; html_foot[i]; i++)
4950 fputs(html_foot[i], fff);
4955 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4957 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4961 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4963 fprintf(fff, "%s\n", buf);
4976 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4984 * Hack -- save a screen dump to a file
4986 static void do_cmd_save_screen_html(void)
4988 char buf[1024], tmp[256] = "screen.html";
4990 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4993 /* Build the filename */
4994 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4998 do_cmd_save_screen_html_aux(buf, 1);
5003 * Redefinable "save_screen" action
5005 void (*screendump_aux)(void) = NULL;
5009 * Hack -- save a screen dump to a file
5011 void do_cmd_save_screen(void)
5013 bool old_use_graphics = use_graphics;
5014 bool html_dump = FALSE;
5018 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5022 if (c == 'Y' || c == 'y')
5024 else if (c == 'H' || c == 'h')
5036 Term_get_size(&wid, &hgt);
5038 if (old_use_graphics)
5040 use_graphics = FALSE;
5042 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5048 do_cmd_save_screen_html();
5052 /* Do we use a special screendump function ? */
5053 else if (screendump_aux)
5055 /* Dump the screen to a graphics file */
5056 (*screendump_aux)();
5058 else /* Dump the screen as text */
5069 /* Build the filename */
5070 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5072 /* File type is "TEXT" */
5073 FILE_TYPE(FILE_TYPE_TEXT);
5075 /* Append to the file */
5076 fff = my_fopen(buf, "w");
5080 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5088 /* Dump the screen */
5089 for (y = 0; y < hgt; y++)
5092 for (x = 0; x < wid - 1; x++)
5094 /* Get the attr/char */
5095 (void)(Term_what(x, y, &a, &c));
5105 fprintf(fff, "%s\n", buf);
5112 /* Dump the screen */
5113 for (y = 0; y < hgt; y++)
5116 for (x = 0; x < wid - 1; x++)
5118 /* Get the attr/char */
5119 (void)(Term_what(x, y, &a, &c));
5122 buf[x] = hack[a&0x0F];
5129 fprintf(fff, "%s\n", buf);
5138 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5143 if (old_use_graphics)
5145 use_graphics = TRUE;
5147 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5154 * Sorting hook -- Comp function -- see below
5156 * We use "u" to point to array of monster indexes,
5157 * and "v" to select the type of sorting to perform on "u".
5159 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5161 u16b *who = (u16b*)(u);
5163 u16b *why = (u16b*)(v);
5170 /* Sort by total kills */
5173 /* Extract total kills */
5174 z1 = a_info[w1].tval;
5175 z2 = a_info[w2].tval;
5177 /* Compare total kills */
5178 if (z1 < z2) return (TRUE);
5179 if (z1 > z2) return (FALSE);
5183 /* Sort by monster level */
5186 /* Extract levels */
5187 z1 = a_info[w1].sval;
5188 z2 = a_info[w2].sval;
5190 /* Compare levels */
5191 if (z1 < z2) return (TRUE);
5192 if (z1 > z2) return (FALSE);
5196 /* Sort by monster experience */
5199 /* Extract experience */
5200 z1 = a_info[w1].level;
5201 z2 = a_info[w2].level;
5203 /* Compare experience */
5204 if (z1 < z2) return (TRUE);
5205 if (z1 > z2) return (FALSE);
5209 /* Compare indexes */
5215 * Sorting hook -- Swap function -- see below
5217 * We use "u" to point to array of monster indexes,
5218 * and "v" to select the type of sorting to perform.
5220 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5222 u16b *who = (u16b*)(u);
5237 * Check the status of "artifacts"
5239 static void do_cmd_knowledge_artifacts(void)
5251 GAME_TEXT file_name[1024];
5253 GAME_TEXT base_name[MAX_NLEN];
5257 /* Open a new file */
5258 fff = my_fopen_temp(file_name, 1024);
5261 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5266 /* Allocate the "who" array */
5267 C_MAKE(who, max_a_idx, s16b);
5269 /* Allocate the "okay" array */
5270 C_MAKE(okay, max_a_idx, bool);
5272 /* Scan the artifacts */
5273 for (k = 0; k < max_a_idx; k++)
5275 artifact_type *a_ptr = &a_info[k];
5280 /* Skip "empty" artifacts */
5281 if (!a_ptr->name) continue;
5283 /* Skip "uncreated" artifacts */
5284 if (!a_ptr->cur_num) continue;
5290 /* Check the dungeon */
5291 for (y = 0; y < cur_hgt; y++)
5293 for (x = 0; x < cur_wid; x++)
5295 cave_type *c_ptr = &cave[y][x];
5297 OBJECT_IDX this_o_idx, next_o_idx = 0;
5299 /* Scan all objects in the grid */
5300 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5303 o_ptr = &o_list[this_o_idx];
5305 /* Acquire next object */
5306 next_o_idx = o_ptr->next_o_idx;
5308 /* Ignore non-artifacts */
5309 if (!object_is_fixed_artifact(o_ptr)) continue;
5311 /* Ignore known items */
5312 if (object_is_known(o_ptr)) continue;
5314 /* Note the artifact */
5315 okay[o_ptr->name1] = FALSE;
5320 /* Check the inventory and equipment */
5321 for (i = 0; i < INVEN_TOTAL; i++)
5323 object_type *o_ptr = &inventory[i];
5325 /* Ignore non-objects */
5326 if (!o_ptr->k_idx) continue;
5328 /* Ignore non-artifacts */
5329 if (!object_is_fixed_artifact(o_ptr)) continue;
5331 /* Ignore known items */
5332 if (object_is_known(o_ptr)) continue;
5334 /* Note the artifact */
5335 okay[o_ptr->name1] = FALSE;
5338 for (k = 0; k < max_a_idx; k++)
5340 if (okay[k]) who[n++] = k;
5343 /* Select the sort method */
5344 ang_sort_comp = ang_sort_art_comp;
5345 ang_sort_swap = ang_sort_art_swap;
5347 /* Sort the array by dungeon depth of monsters */
5348 ang_sort(who, &why, n);
5350 /* Scan the artifacts */
5351 for (k = 0; k < n; k++)
5353 artifact_type *a_ptr = &a_info[who[k]];
5356 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5358 /* Obtain the base object type */
5359 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5368 /* Create fake object */
5369 object_prep(q_ptr, z);
5371 /* Make it an artifact */
5372 q_ptr->name1 = (byte)who[k];
5374 /* Display as if known */
5375 q_ptr->ident |= IDENT_STORE;
5377 /* Describe the artifact */
5378 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5381 /* Hack -- Build the artifact name */
5382 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5385 /* Free the "who" array */
5386 C_KILL(who, max_a_idx, s16b);
5388 /* Free the "okay" array */
5389 C_KILL(okay, max_a_idx, bool);
5392 /* Display the file contents */
5393 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5395 /* Remove the file */
5401 * Display known uniques
5402 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5404 static void do_cmd_knowledge_uniques(void)
5413 GAME_TEXT file_name[1024];
5416 int n_alive_surface = 0;
5417 int n_alive_over100 = 0;
5418 int n_alive_total = 0;
5421 for (i = 0; i < 10; i++) n_alive[i] = 0;
5423 /* Open a new file */
5424 fff = my_fopen_temp(file_name, 1024);
5428 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5433 /* Allocate the "who" array */
5434 C_MAKE(who, max_r_idx, s16b);
5436 /* Scan the monsters */
5437 for (i = 1; i < max_r_idx; i++)
5439 monster_race *r_ptr = &r_info[i];
5442 if (!r_ptr->name) continue;
5444 /* Require unique monsters */
5445 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5447 /* Only display "known" uniques */
5448 if (!cheat_know && !r_ptr->r_sights) continue;
5450 /* Only print rarity <= 100 uniques */
5451 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5453 /* Only "alive" uniques */
5454 if (r_ptr->max_num == 0) continue;
5458 lev = (r_ptr->level - 1) / 10;
5462 if (max_lev < lev) max_lev = lev;
5464 else n_alive_over100++;
5466 else n_alive_surface++;
5468 /* Collect "appropriate" monsters */
5472 /* Select the sort method */
5473 ang_sort_comp = ang_sort_comp_hook;
5474 ang_sort_swap = ang_sort_swap_hook;
5476 /* Sort the array by dungeon depth of monsters */
5477 ang_sort(who, &why, n);
5479 if (n_alive_surface)
5481 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5482 n_alive_total += n_alive_surface;
5484 for (i = 0; i <= max_lev; i++)
5486 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5487 n_alive_total += n_alive[i];
5489 if (n_alive_over100)
5491 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5492 n_alive_total += n_alive_over100;
5497 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5498 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5502 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5505 /* Scan the monster races */
5506 for (k = 0; k < n; k++)
5508 monster_race *r_ptr = &r_info[who[k]];
5510 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5513 /* Free the "who" array */
5514 C_KILL(who, max_r_idx, s16b);
5517 /* Display the file contents */
5518 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5520 /* Remove the file */
5526 * Display weapon-exp
5528 static void do_cmd_knowledge_weapon_exp(void)
5530 int i, num, weapon_exp;
5535 GAME_TEXT file_name[1024];
5538 /* Open a new file */
5539 fff = my_fopen_temp(file_name, 1024);
5541 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5546 for (i = 0; i < 5; i++)
5548 for (num = 0; num < 64; num++)
5550 for (j = 0; j < max_k_idx; j++)
5552 object_kind *k_ptr = &k_info[j];
5554 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5556 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5558 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5560 fprintf(fff, "%-25s ", tmp);
5561 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5562 else fprintf(fff, " ");
5563 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5564 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5573 /* Display the file contents */
5574 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5576 /* Remove the file */
5582 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5586 static void do_cmd_knowledge_spell_exp(void)
5589 int spell_exp, exp_level;
5592 const magic_type *s_ptr;
5594 GAME_TEXT file_name[1024];
5596 /* Open a new file */
5597 fff = my_fopen_temp(file_name, 1024);
5599 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5604 if (p_ptr->realm1 != REALM_NONE)
5606 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5607 for (i = 0; i < 32; i++)
5609 if (!is_magic(p_ptr->realm1))
5611 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5615 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5617 if (s_ptr->slevel >= 99) continue;
5618 spell_exp = p_ptr->spell_exp[i];
5619 exp_level = spell_exp_level(spell_exp);
5620 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5621 if (p_ptr->realm1 == REALM_HISSATSU)
5622 fprintf(fff, "[--]");
5625 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5626 else fprintf(fff, " ");
5627 fprintf(fff, "%s", exp_level_str[exp_level]);
5629 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5634 if (p_ptr->realm2 != REALM_NONE)
5636 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5637 for (i = 0; i < 32; i++)
5639 if (!is_magic(p_ptr->realm1))
5641 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5645 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5647 if (s_ptr->slevel >= 99) continue;
5649 spell_exp = p_ptr->spell_exp[i + 32];
5650 exp_level = spell_exp_level(spell_exp);
5651 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5652 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5653 else fprintf(fff, " ");
5654 fprintf(fff, "%s", exp_level_str[exp_level]);
5655 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5661 /* Display the file contents */
5662 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5664 /* Remove the file */
5670 * @brief スキル情報を表示するコマンドのメインルーチン /
5674 static void do_cmd_knowledge_skill_exp(void)
5676 int i = 0, skill_exp;
5680 GAME_TEXT file_name[1024];
5681 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5682 _("二刀流 ", "Dual Wielding "),
5683 _("乗馬 ", "Riding ")};
5685 /* Open a new file */
5686 fff = my_fopen_temp(file_name, 1024);
5688 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5693 for (i = 0; i < 3; i++)
5695 skill_exp = p_ptr->skill_exp[i];
5696 fprintf(fff, "%-20s ", skill_name[i]);
5697 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5698 else fprintf(fff, " ");
5699 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5700 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5705 /* Display the file contents */
5706 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5708 /* Remove the file */
5714 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5715 * @param Name 変換したい文字列の参照ポインタ
5718 void plural_aux(char *Name)
5720 int NameLen = strlen(Name);
5722 if (my_strstr(Name, "Disembodied hand"))
5724 strcpy(Name, "Disembodied hands that strangled people");
5726 else if (my_strstr(Name, "Colour out of space"))
5728 strcpy(Name, "Colours out of space");
5730 else if (my_strstr(Name, "stairway to hell"))
5732 strcpy(Name, "stairways to hell");
5734 else if (my_strstr(Name, "Dweller on the threshold"))
5736 strcpy(Name, "Dwellers on the threshold");
5738 else if (my_strstr(Name, " of "))
5740 cptr aider = my_strstr(Name, " of ");
5751 if (dummy[i-1] == 's')
5753 strcpy(&(dummy[i]), "es");
5758 strcpy(&(dummy[i]), "s");
5761 strcpy(&(dummy[i+1]), aider);
5762 strcpy(Name, dummy);
5764 else if (my_strstr(Name, "coins"))
5767 strcpy(dummy, "piles of ");
5768 strcat(dummy, Name);
5769 strcpy(Name, dummy);
5772 else if (my_strstr(Name, "Manes"))
5776 else if (streq(&(Name[NameLen - 2]), "ey"))
5778 strcpy(&(Name[NameLen - 2]), "eys");
5780 else if (Name[NameLen - 1] == 'y')
5782 strcpy(&(Name[NameLen - 1]), "ies");
5784 else if (streq(&(Name[NameLen - 4]), "ouse"))
5786 strcpy(&(Name[NameLen - 4]), "ice");
5788 else if (streq(&(Name[NameLen - 2]), "us"))
5790 strcpy(&(Name[NameLen - 2]), "i");
5792 else if (streq(&(Name[NameLen - 6]), "kelman"))
5794 strcpy(&(Name[NameLen - 6]), "kelmen");
5796 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5798 strcpy(&(Name[NameLen - 8]), "wordsmen");
5800 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5802 strcpy(&(Name[NameLen - 7]), "oodsmen");
5804 else if (streq(&(Name[NameLen - 7]), "eastman"))
5806 strcpy(&(Name[NameLen - 7]), "eastmen");
5808 else if (streq(&(Name[NameLen - 8]), "izardman"))
5810 strcpy(&(Name[NameLen - 8]), "izardmen");
5812 else if (streq(&(Name[NameLen - 5]), "geist"))
5814 strcpy(&(Name[NameLen - 5]), "geister");
5816 else if (streq(&(Name[NameLen - 2]), "ex"))
5818 strcpy(&(Name[NameLen - 2]), "ices");
5820 else if (streq(&(Name[NameLen - 2]), "lf"))
5822 strcpy(&(Name[NameLen - 2]), "lves");
5824 else if (suffix(Name, "ch") ||
5825 suffix(Name, "sh") ||
5826 suffix(Name, "nx") ||
5827 suffix(Name, "s") ||
5830 strcpy(&(Name[NameLen]), "es");
5834 strcpy(&(Name[NameLen]), "s");
5839 * @brief 現在のペットを表示するコマンドのメインルーチン /
5840 * Display current pets
5843 static void do_cmd_knowledge_pets(void)
5847 monster_type *m_ptr;
5848 GAME_TEXT pet_name[80];
5850 int show_upkeep = 0;
5851 GAME_TEXT file_name[1024];
5854 /* Open a new file */
5855 fff = my_fopen_temp(file_name, 1024);
5857 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5862 /* Process the monsters (backwards) */
5863 for (i = m_max - 1; i >= 1; i--)
5865 /* Access the monster */
5868 /* Ignore "dead" monsters */
5869 if (!m_ptr->r_idx) continue;
5871 /* Calculate "upkeep" for pets */
5875 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5876 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5880 show_upkeep = calculate_upkeep();
5882 fprintf(fff, "----------------------------------------------\n");
5884 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5885 fprintf(fff, " 維持コスト: %d%% MP\n", show_upkeep);
5887 fprintf(fff, " Total: %d pet%s.\n",
5888 t_friends, (t_friends == 1 ? "" : "s"));
5889 fprintf(fff, " Upkeep: %d%% mana.\n", show_upkeep);
5895 /* Display the file contents */
5896 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5898 /* Remove the file */
5904 * @brief 現在のペットを表示するコマンドのメインルーチン /
5907 * @note the player ghosts are ignored.
5909 static void do_cmd_knowledge_kill_count(void)
5918 GAME_TEXT file_name[1024];
5923 /* Open a new file */
5924 fff = my_fopen_temp(file_name, 1024);
5927 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5932 /* Allocate the "who" array */
5933 C_MAKE(who, max_r_idx, s16b);
5936 /* Monsters slain */
5939 for (kk = 1; kk < max_r_idx; kk++)
5941 monster_race *r_ptr = &r_info[kk];
5943 if (r_ptr->flags1 & (RF1_UNIQUE))
5945 bool dead = (r_ptr->max_num == 0);
5954 MONSTER_NUMBER This = r_ptr->r_pkills;
5964 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5967 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5969 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5975 /* Scan the monsters */
5976 for (i = 1; i < max_r_idx; i++)
5978 monster_race *r_ptr = &r_info[i];
5980 /* Use that monster */
5981 if (r_ptr->name) who[n++] = i;
5984 /* Select the sort method */
5985 ang_sort_comp = ang_sort_comp_hook;
5986 ang_sort_swap = ang_sort_swap_hook;
5988 /* Sort the array by dungeon depth of monsters */
5989 ang_sort(who, &why, n);
5991 /* Scan the monster races */
5992 for (k = 0; k < n; k++)
5994 monster_race *r_ptr = &r_info[who[k]];
5996 if (r_ptr->flags1 & (RF1_UNIQUE))
5998 bool dead = (r_ptr->max_num == 0);
6002 fprintf(fff, " %s\n", (r_name + r_ptr->name));
6008 MONSTER_NUMBER This = r_ptr->r_pkills;
6013 /* p,tは人と数える by ita */
6014 if (my_strchr("pt", r_ptr->d_char))
6015 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
6017 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6021 if (my_strstr(r_name + r_ptr->name, "coins"))
6023 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6027 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6033 strcpy(ToPlural, (r_name + r_ptr->name));
6034 plural_aux(ToPlural);
6035 fprintf(fff, " %d %s\n", This, ToPlural);
6045 fprintf(fff,"----------------------------------------------\n");
6047 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6049 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6053 /* Free the "who" array */
6054 C_KILL(who, max_r_idx, s16b);
6057 /* Display the file contents */
6058 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6060 /* Remove the file */
6066 * @brief モンスター情報リスト中のグループを表示する /
6067 * Display the object groups.
6071 * @param per_page リストの表示行
6072 * @param grp_idx グループのID配列
6073 * @param group_text グループ名の文字列配列
6074 * @param grp_cur 現在の選択ID
6075 * @param grp_top 現在の選択リスト最上部ID
6078 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)
6082 /* Display lines until done */
6083 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6085 /* Get the group index */
6086 int grp = grp_idx[grp_top + i];
6088 /* Choose a color */
6089 byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6091 /* Erase the entire line */
6092 Term_erase(col, row + i, wid);
6094 /* Display the group label */
6095 c_put_str(attr, group_text[grp], row + i, col);
6101 * Move the cursor in a browser window
6103 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6104 IDX *list_cur, int list_cnt)
6109 IDX list = *list_cur;
6111 /* Extract direction */
6114 /* Hack -- scroll up full screen */
6119 /* Hack -- scroll down full screen */
6124 d = get_keymap_dir(ch);
6129 /* Diagonals - hack */
6130 if ((ddx[d] > 0) && ddy[d])
6135 Term_get_size(&wid, &hgt);
6137 browser_rows = hgt - 8;
6139 /* Browse group list */
6144 /* Move up or down */
6145 grp += ddy[d] * (browser_rows - 1);
6148 if (grp >= grp_cnt) grp = grp_cnt - 1;
6149 if (grp < 0) grp = 0;
6150 if (grp != old_grp) list = 0;
6153 /* Browse sub-list list */
6156 /* Move up or down */
6157 list += ddy[d] * browser_rows;
6160 if (list >= list_cnt) list = list_cnt - 1;
6161 if (list < 0) list = 0;
6173 if (col < 0) col = 0;
6174 if (col > 1) col = 1;
6181 /* Browse group list */
6186 /* Move up or down */
6190 if (grp >= grp_cnt) grp = grp_cnt - 1;
6191 if (grp < 0) grp = 0;
6192 if (grp != old_grp) list = 0;
6195 /* Browse sub-list list */
6198 /* Move up or down */
6202 if (list >= list_cnt) list = list_cnt - 1;
6203 if (list < 0) list = 0;
6214 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6218 /* Clear the display lines */
6219 for (i = 0; i < height; i++)
6221 Term_erase(col, row + i, width);
6224 /* Bigtile mode uses double width */
6225 if (use_bigtile) width /= 2;
6227 /* Display lines until done */
6228 for (i = 0; i < height; i++)
6230 /* Display columns until done */
6231 for (j = 0; j < width; j++)
6235 TERM_LEN x = col + j;
6236 TERM_LEN y = row + i;
6239 /* Bigtile mode uses double width */
6240 if (use_bigtile) x += j;
6245 /* Ignore illegal characters */
6246 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6247 (!use_graphics && ic > 0x7f))
6253 /* Force correct code for both ASCII character and tile */
6254 if (c & 0x80) a |= 0x80;
6256 /* Display symbol */
6257 Term_queue_bigchar(x, y, a, c, 0, 0);
6264 * Place the cursor at the collect position for visual mode
6266 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6268 int i = (a & 0x7f) - attr_top;
6269 int j = c - char_left;
6271 TERM_LEN x = col + j;
6272 TERM_LEN y = row + i;
6274 /* Bigtile mode uses double width */
6275 if (use_bigtile) x += j;
6277 /* Place the cursor */
6283 * Clipboard variables for copy&paste in visual mode
6285 static TERM_COLOR attr_idx = 0;
6286 static byte char_idx = 0;
6288 /* Hack -- for feature lighting */
6289 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6290 static byte char_idx_feat[F_LIT_MAX];
6293 * Do visual mode command -- Change symbols
6295 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6296 int height, int width,
6297 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6298 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6300 static TERM_COLOR attr_old = 0;
6301 static SYMBOL_CODE char_old = 0;
6306 if (*visual_list_ptr)
6309 *cur_attr_ptr = attr_old;
6310 *cur_char_ptr = char_old;
6311 *visual_list_ptr = FALSE;
6319 if (*visual_list_ptr)
6322 *visual_list_ptr = FALSE;
6323 *need_redraw = TRUE;
6331 if (!*visual_list_ptr)
6333 *visual_list_ptr = TRUE;
6335 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6336 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6338 attr_old = *cur_attr_ptr;
6339 char_old = *cur_char_ptr;
6350 /* Set the visual */
6351 attr_idx = *cur_attr_ptr;
6352 char_idx = *cur_char_ptr;
6354 /* Hack -- for feature lighting */
6355 for (i = 0; i < F_LIT_MAX; i++)
6357 attr_idx_feat[i] = 0;
6358 char_idx_feat[i] = 0;
6365 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6368 *cur_attr_ptr = attr_idx;
6369 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6370 if (!*visual_list_ptr) *need_redraw = TRUE;
6376 *cur_char_ptr = char_idx;
6377 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6378 if (!*visual_list_ptr) *need_redraw = TRUE;
6384 if (*visual_list_ptr)
6387 int d = get_keymap_dir(ch);
6388 byte a = (*cur_attr_ptr & 0x7f);
6389 byte c = *cur_char_ptr;
6391 if (use_bigtile) eff_width = width / 2;
6392 else eff_width = width;
6394 /* Restrict direction */
6395 if ((a == 0) && (ddy[d] < 0)) d = 0;
6396 if ((c == 0) && (ddx[d] < 0)) d = 0;
6397 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6398 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6403 /* Force correct code for both ASCII character and tile */
6404 if (c & 0x80) a |= 0x80;
6406 /* Set the visual */
6411 /* Move the frame */
6412 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6413 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6414 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6415 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6421 /* Visual mode command is not used */
6427 * Display the monsters in a group.
6429 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6430 int mon_cur, int mon_top, bool visual_only)
6434 /* Display lines until done */
6435 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6439 /* Get the race index */
6440 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6442 /* Access the race */
6443 monster_race *r_ptr = &r_info[r_idx];
6445 /* Choose a color */
6446 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6448 /* Display the name */
6449 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6451 /* Hack -- visual_list mode */
6454 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6456 if (p_ptr->wizard || visual_only)
6458 c_prt(attr, format("%d", r_idx), row + i, 62);
6461 /* Erase chars before overwritten by the race letter */
6462 Term_erase(69, row + i, 255);
6464 /* Display symbol */
6465 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6470 if (!(r_ptr->flags1 & RF1_UNIQUE))
6471 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6473 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6474 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6478 /* Clear remaining lines */
6479 for (; i < per_page; i++)
6481 Term_erase(col, row + i, 255);
6487 * Display known monsters.
6489 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6493 IDX grp_cur, grp_top, old_grp_cur;
6494 IDX mon_cur, mon_top;
6495 IDX grp_cnt, grp_idx[100];
6503 bool visual_list = FALSE;
6504 TERM_COLOR attr_top = 0;
6512 Term_get_size(&wid, &hgt);
6514 browser_rows = hgt - 8;
6516 /* Allocate the "mon_idx" array */
6517 C_MAKE(mon_idx, max_r_idx, s16b);
6522 if (direct_r_idx < 0)
6524 mode = visual_only ? 0x03 : 0x01;
6526 /* Check every group */
6527 for (i = 0; monster_group_text[i] != NULL; i++)
6529 /* Measure the label */
6530 len = strlen(monster_group_text[i]);
6532 /* Save the maximum length */
6533 if (len > max) max = len;
6535 /* See if any monsters are known */
6536 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6538 /* Build a list of groups with known monsters */
6539 grp_idx[grp_cnt++] = i;
6547 mon_idx[0] = direct_r_idx;
6550 /* Terminate the list */
6553 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6554 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6557 /* Terminate the list */
6558 grp_idx[grp_cnt] = -1;
6561 grp_cur = grp_top = 0;
6562 mon_cur = mon_top = 0;
6567 mode = visual_only ? 0x02 : 0x00;
6572 monster_race *r_ptr;
6579 prt(format("%s - モンスター", !visual_only ? "知識" : "表示"), 2, 0);
6580 if (direct_r_idx < 0) prt("グループ", 4, 0);
6581 prt("名前", 4, max + 3);
6582 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6584 if (!visual_only) prt("殺害数", 4, 72);
6586 prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6587 if (direct_r_idx < 0) prt("Group", 4, 0);
6588 prt("Name", 4, max + 3);
6589 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6591 if (!visual_only) prt("Kills", 4, 73);
6594 for (i = 0; i < 78; i++)
6596 Term_putch(i, 5, TERM_WHITE, '=');
6599 if (direct_r_idx < 0)
6601 for (i = 0; i < browser_rows; i++)
6603 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6610 if (direct_r_idx < 0)
6612 /* Scroll group list */
6613 if (grp_cur < grp_top) grp_top = grp_cur;
6614 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6616 /* Display a list of monster groups */
6617 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6619 if (old_grp_cur != grp_cur)
6621 old_grp_cur = grp_cur;
6623 /* Get a list of monsters in the current group */
6624 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6627 /* Scroll monster list */
6628 while (mon_cur < mon_top)
6629 mon_top = MAX(0, mon_top - browser_rows/2);
6630 while (mon_cur >= mon_top + browser_rows)
6631 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6636 /* Display a list of monsters in the current group */
6637 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6643 /* Display a monster name */
6644 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6646 /* Display visual list below first monster */
6647 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6652 prt(format("<方向>%s%s%s, ESC",
6653 (!visual_list && !visual_only) ? ", 'r'で思い出を見る" : "",
6654 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6655 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6658 prt(format("<dir>%s%s%s, ESC",
6659 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6660 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6661 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6665 /* Get the current monster */
6666 r_ptr = &r_info[mon_idx[mon_cur]];
6670 /* Mega Hack -- track this monster race */
6671 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6677 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6681 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6685 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6690 /* Do visual mode command if needed */
6691 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))
6693 if (direct_r_idx >= 0)
6718 /* Recall on screen */
6719 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6721 screen_roff(mon_idx[mon_cur], 0);
6732 /* Move the cursor */
6733 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6740 /* Free the "mon_idx" array */
6741 C_KILL(mon_idx, max_r_idx, s16b);
6746 * Display the objects in a group.
6748 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6749 int object_cur, int object_top, bool visual_only)
6753 /* Display lines until done */
6754 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6756 GAME_TEXT o_name[80];
6759 object_kind *flavor_k_ptr;
6761 /* Get the object index */
6762 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6764 /* Access the object */
6765 object_kind *k_ptr = &k_info[k_idx];
6767 /* Choose a color */
6768 byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6769 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6772 if (!visual_only && k_ptr->flavor)
6774 /* Appearance of this object is shuffled */
6775 flavor_k_ptr = &k_info[k_ptr->flavor];
6779 /* Appearance of this object is very normal */
6780 flavor_k_ptr = k_ptr;
6785 attr = ((i + object_top == object_cur) ? cursor : attr);
6787 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6790 strip_name(o_name, k_idx);
6795 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6798 /* Display the name */
6799 c_prt(attr, o_name, row + i, col);
6801 /* Hack -- visual_list mode */
6804 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);
6806 if (p_ptr->wizard || visual_only)
6808 c_prt(attr, format("%d", k_idx), row + i, 70);
6811 a = flavor_k_ptr->x_attr;
6812 c = flavor_k_ptr->x_char;
6814 /* Display symbol */
6815 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6818 /* Clear remaining lines */
6819 for (; i < per_page; i++)
6821 Term_erase(col, row + i, 255);
6826 * Describe fake object
6828 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6831 object_type object_type_body;
6832 o_ptr = &object_type_body;
6835 /* Create the artifact */
6836 object_prep(o_ptr, k_idx);
6838 /* It's fully know */
6839 o_ptr->ident |= IDENT_KNOWN;
6841 /* Track the object */
6842 /* object_actual_track(o_ptr); */
6844 /* Hack - mark as fake */
6845 /* term_obj_real = FALSE; */
6848 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6850 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6858 * Display known objects
6860 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6864 IDX grp_cur, grp_top, old_grp_cur;
6865 IDX object_old, object_cur, object_top;
6875 bool visual_list = FALSE;
6876 TERM_COLOR attr_top = 0;
6884 Term_get_size(&wid, &hgt);
6886 browser_rows = hgt - 8;
6888 /* Allocate the "object_idx" array */
6889 C_MAKE(object_idx, max_k_idx, IDX);
6894 if (direct_k_idx < 0)
6896 mode = visual_only ? 0x03 : 0x01;
6898 /* Check every group */
6899 for (i = 0; object_group_text[i] != NULL; i++)
6901 /* Measure the label */
6902 len = strlen(object_group_text[i]);
6904 /* Save the maximum length */
6905 if (len > max) max = len;
6907 /* See if any monsters are known */
6908 if (collect_objects(i, object_idx, mode))
6910 /* Build a list of groups with known monsters */
6911 grp_idx[grp_cnt++] = i;
6920 object_kind *k_ptr = &k_info[direct_k_idx];
6921 object_kind *flavor_k_ptr;
6923 if (!visual_only && k_ptr->flavor)
6925 /* Appearance of this object is shuffled */
6926 flavor_k_ptr = &k_info[k_ptr->flavor];
6930 /* Appearance of this object is very normal */
6931 flavor_k_ptr = k_ptr;
6934 object_idx[0] = direct_k_idx;
6935 object_old = direct_k_idx;
6938 /* Terminate the list */
6941 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6942 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6945 /* Terminate the list */
6946 grp_idx[grp_cnt] = -1;
6949 grp_cur = grp_top = 0;
6950 object_cur = object_top = 0;
6955 mode = visual_only ? 0x02 : 0x00;
6960 object_kind *k_ptr, *flavor_k_ptr;
6967 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6968 if (direct_k_idx < 0) prt("グループ", 4, 0);
6969 prt("名前", 4, max + 3);
6970 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6973 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6974 if (direct_k_idx < 0) prt("Group", 4, 0);
6975 prt("Name", 4, max + 3);
6976 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6980 for (i = 0; i < 78; i++)
6982 Term_putch(i, 5, TERM_WHITE, '=');
6985 if (direct_k_idx < 0)
6987 for (i = 0; i < browser_rows; i++)
6989 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6996 if (direct_k_idx < 0)
6998 /* Scroll group list */
6999 if (grp_cur < grp_top) grp_top = grp_cur;
7000 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7002 /* Display a list of object groups */
7003 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
7005 if (old_grp_cur != grp_cur)
7007 old_grp_cur = grp_cur;
7009 /* Get a list of objects in the current group */
7010 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
7013 /* Scroll object list */
7014 while (object_cur < object_top)
7015 object_top = MAX(0, object_top - browser_rows/2);
7016 while (object_cur >= object_top + browser_rows)
7017 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
7022 /* Display a list of objects in the current group */
7023 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
7027 object_top = object_cur;
7029 /* Display a list of objects in the current group */
7030 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
7032 /* Display visual list below first object */
7033 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7036 /* Get the current object */
7037 k_ptr = &k_info[object_idx[object_cur]];
7039 if (!visual_only && k_ptr->flavor)
7041 /* Appearance of this object is shuffled */
7042 flavor_k_ptr = &k_info[k_ptr->flavor];
7046 /* Appearance of this object is very normal */
7047 flavor_k_ptr = k_ptr;
7052 prt(format("<方向>%s%s%s, ESC",
7053 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7054 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7055 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7058 prt(format("<dir>%s%s%s, ESC",
7059 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7060 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7061 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7067 /* Mega Hack -- track this object */
7068 if (object_cnt) object_kind_track(object_idx[object_cur]);
7070 /* The "current" object changed */
7071 if (object_old != object_idx[object_cur])
7075 /* Remember the "current" object */
7076 object_old = object_idx[object_cur];
7082 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7086 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7090 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7095 /* Do visual mode command if needed */
7096 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))
7098 if (direct_k_idx >= 0)
7123 /* Recall on screen */
7124 if (!visual_list && !visual_only && (grp_cnt > 0))
7126 desc_obj_fake(object_idx[object_cur]);
7134 /* Move the cursor */
7135 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7141 /* Free the "object_idx" array */
7142 C_KILL(object_idx, max_k_idx, IDX);
7147 * Display the features in a group.
7149 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7150 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7152 int lit_col[F_LIT_MAX], i, j;
7153 int f_idx_col = use_bigtile ? 62 : 64;
7155 /* Correct columns 1 and 4 */
7156 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7157 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7158 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7160 /* Display lines until done */
7161 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7166 FEAT_IDX f_idx = feat_idx[feat_top + i];
7168 /* Access the index */
7169 feature_type *f_ptr = &f_info[f_idx];
7171 int row_i = row + i;
7173 /* Choose a color */
7174 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7176 /* Display the name */
7177 c_prt(attr, f_name + f_ptr->name, row_i, col);
7179 /* Hack -- visual_list mode */
7182 /* Display lighting level */
7183 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7185 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));
7187 if (p_ptr->wizard || visual_only)
7189 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7192 /* Display symbol */
7193 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);
7195 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7196 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7198 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7200 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7202 /* Mega-hack -- Use non-standard colour */
7203 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7205 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7209 /* Clear remaining lines */
7210 for (; i < per_page; i++)
7212 Term_erase(col, row + i, 255);
7218 * Interact with feature visuals.
7220 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7224 IDX grp_cur, grp_top, old_grp_cur;
7225 IDX feat_cur, feat_top;
7235 bool visual_list = FALSE;
7236 TERM_COLOR attr_top = 0;
7242 TERM_COLOR attr_old[F_LIT_MAX];
7243 SYMBOL_CODE char_old[F_LIT_MAX];
7244 TERM_COLOR *cur_attr_ptr;
7245 SYMBOL_CODE *cur_char_ptr;
7247 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7248 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7250 Term_get_size(&wid, &hgt);
7252 browser_rows = hgt - 8;
7254 /* Allocate the "feat_idx" array */
7255 C_MAKE(feat_idx, max_f_idx, IDX);
7260 if (direct_f_idx < 0)
7262 /* Check every group */
7263 for (i = 0; feature_group_text[i] != NULL; i++)
7265 /* Measure the label */
7266 len = strlen(feature_group_text[i]);
7268 /* Save the maximum length */
7269 if (len > max) max = len;
7271 /* See if any features are known */
7272 if (collect_features(i, feat_idx, 0x01))
7274 /* Build a list of groups with known features */
7275 grp_idx[grp_cnt++] = i;
7283 feature_type *f_ptr = &f_info[direct_f_idx];
7285 feat_idx[0] = direct_f_idx;
7288 /* Terminate the list */
7291 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7292 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7294 for (i = 0; i < F_LIT_MAX; i++)
7296 attr_old[i] = f_ptr->x_attr[i];
7297 char_old[i] = f_ptr->x_char[i];
7301 /* Terminate the list */
7302 grp_idx[grp_cnt] = -1;
7305 grp_cur = grp_top = 0;
7306 feat_cur = feat_top = 0;
7314 feature_type *f_ptr;
7321 prt("表示 - 地形", 2, 0);
7322 if (direct_f_idx < 0) prt("グループ", 4, 0);
7323 prt("名前", 4, max + 3);
7326 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7327 prt("文字 ( l/ d)", 4, 66);
7331 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7332 prt("文字 (l/d)", 4, 68);
7335 prt("Visuals - features", 2, 0);
7336 if (direct_f_idx < 0) prt("Group", 4, 0);
7337 prt("Name", 4, max + 3);
7340 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7341 prt("Sym ( l/ d)", 4, 67);
7345 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7346 prt("Sym (l/d)", 4, 69);
7350 for (i = 0; i < 78; i++)
7352 Term_putch(i, 5, TERM_WHITE, '=');
7355 if (direct_f_idx < 0)
7357 for (i = 0; i < browser_rows; i++)
7359 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7366 if (direct_f_idx < 0)
7368 /* Scroll group list */
7369 if (grp_cur < grp_top) grp_top = grp_cur;
7370 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7372 /* Display a list of feature groups */
7373 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7375 if (old_grp_cur != grp_cur)
7377 old_grp_cur = grp_cur;
7379 /* Get a list of features in the current group */
7380 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7383 /* Scroll feature list */
7384 while (feat_cur < feat_top)
7385 feat_top = MAX(0, feat_top - browser_rows/2);
7386 while (feat_cur >= feat_top + browser_rows)
7387 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7392 /* Display a list of features in the current group */
7393 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7397 feat_top = feat_cur;
7399 /* Display a list of features in the current group */
7400 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7402 /* Display visual list below first object */
7403 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7408 prt(format("<方向>%s, 'd'で標準光源効果%s, ESC",
7409 visual_list ? ", ENTERで決定, 'a'で対象明度変更" : ", 'v'でシンボル変更",
7410 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7413 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
7414 visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
7415 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7419 /* Get the current feature */
7420 f_ptr = &f_info[feat_idx[feat_cur]];
7421 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7422 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7426 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7430 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7434 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7439 if (visual_list && ((ch == 'A') || (ch == 'a')))
7441 int prev_lighting_level = *lighting_level;
7445 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7446 else (*lighting_level)--;
7450 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7451 else (*lighting_level)++;
7454 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7455 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7457 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7458 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7463 else if ((ch == 'D') || (ch == 'd'))
7465 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7466 byte prev_x_char = f_ptr->x_char[*lighting_level];
7468 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7472 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7473 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7475 if (prev_x_char != f_ptr->x_char[*lighting_level])
7476 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7478 else *need_redraw = TRUE;
7483 /* Do visual mode command if needed */
7484 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))
7488 /* Restore previous visual settings */
7490 for (i = 0; i < F_LIT_MAX; i++)
7492 f_ptr->x_attr[i] = attr_old[i];
7493 f_ptr->x_char[i] = char_old[i];
7500 if (direct_f_idx >= 0) flag = TRUE;
7501 else *lighting_level = F_LIT_STANDARD;
7504 /* Preserve current visual settings */
7507 for (i = 0; i < F_LIT_MAX; i++)
7509 attr_old[i] = f_ptr->x_attr[i];
7510 char_old[i] = f_ptr->x_char[i];
7512 *lighting_level = F_LIT_STANDARD;
7519 for (i = 0; i < F_LIT_MAX; i++)
7521 attr_idx_feat[i] = f_ptr->x_attr[i];
7522 char_idx_feat[i] = f_ptr->x_char[i];
7531 /* Allow TERM_DARK text */
7532 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7534 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7535 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7553 /* Move the cursor */
7554 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7560 /* Free the "feat_idx" array */
7561 C_KILL(feat_idx, max_f_idx, IDX);
7566 * List wanted monsters
7568 static void do_cmd_knowledge_kubi(void)
7573 GAME_TEXT file_name[1024];
7576 /* Open a new file */
7577 fff = my_fopen_temp(file_name, 1024);
7579 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7586 bool listed = FALSE;
7589 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7591 fprintf(fff, "賞金首リスト\n");
7593 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7595 fprintf(fff, "List of wanted monsters\n");
7597 fprintf(fff, "----------------------------------------------\n");
7599 for (i = 0; i < MAX_KUBI; i++)
7601 if (kubi_r_idx[i] <= 10000)
7603 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7611 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7616 /* Display the file contents */
7617 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7619 /* Remove the file */
7624 * List virtues & status
7626 static void do_cmd_knowledge_virtues(void)
7629 GAME_TEXT file_name[1024];
7631 /* Open a new file */
7632 fff = my_fopen_temp(file_name, 1024);
7634 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7641 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7646 /* Display the file contents */
7647 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7649 /* Remove the file */
7657 static void do_cmd_knowledge_dungeon(void)
7661 GAME_TEXT file_name[1024];
7664 /* Open a new file */
7665 fff = my_fopen_temp(file_name, 1024);
7667 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7674 for (i = 1; i < max_d_idx; i++)
7678 if (!d_info[i].maxdepth) continue;
7679 if (!max_dlv[i]) continue;
7680 if (d_info[i].final_guardian)
7682 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7684 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7686 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7691 /* Display the file contents */
7692 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7694 /* Remove the file */
7699 * List virtues & status
7702 static void do_cmd_knowledge_stat(void)
7706 GAME_TEXT file_name[1024];
7709 /* Open a new file */
7710 fff = my_fopen_temp(file_name, 1024);
7712 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7719 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7720 (2 * p_ptr->hitdie +
7721 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7724 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7725 else fprintf(fff, "現在の体力ランク : ???\n\n");
7726 fprintf(fff, "能力の最大値\n\n");
7728 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7729 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7730 fprintf(fff, "Limits of maximum stats\n\n");
7732 for (v_nr = 0; v_nr < 6; v_nr++)
7734 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);
7735 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7742 /* Display the file contents */
7743 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7745 /* Remove the file */
7751 * Print all active quests
7753 static void do_cmd_knowledge_quests_current(FILE *fff)
7756 char rand_tmp_str[120] = "\0";
7758 monster_race *r_ptr;
7760 int rand_level = 100;
7763 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7765 for (i = 1; i < max_q_idx; i++)
7767 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7768 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7769 (quest[i].status == QUEST_STATUS_COMPLETED))
7771 /* Set the quest number temporary */
7772 IDX old_quest = p_ptr->inside_quest;
7775 /* Clear the text */
7776 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7777 quest_text_line = 0;
7779 p_ptr->inside_quest = i;
7781 /* Get the quest text */
7782 init_flags = INIT_SHOW_TEXT;
7784 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7786 /* Reset the old quest number */
7787 p_ptr->inside_quest = old_quest;
7789 /* No info from "silent" quests */
7790 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7794 if (quest[i].type != QUEST_TYPE_RANDOM)
7796 char note[80] = "\0";
7798 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7800 switch (quest[i].type)
7802 case QUEST_TYPE_KILL_LEVEL:
7803 case QUEST_TYPE_KILL_ANY_LEVEL:
7804 r_ptr = &r_info[quest[i].r_idx];
7805 strcpy(name, r_name + r_ptr->name);
7806 if (quest[i].max_num > 1)
7809 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7810 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7813 sprintf(note," - kill %d %s, have killed %d.",
7814 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7818 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7821 case QUEST_TYPE_FIND_ARTIFACT:
7824 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7826 object_type *q_ptr = &forge;
7827 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7828 object_prep(q_ptr, k_idx);
7829 q_ptr->name1 = quest[i].k_idx;
7830 q_ptr->ident = IDENT_STORE;
7831 object_desc(name, q_ptr, OD_NAME_ONLY);
7833 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7835 case QUEST_TYPE_FIND_EXIT:
7836 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7839 case QUEST_TYPE_KILL_NUMBER:
7841 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7842 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7844 sprintf(note," - Kill %d monsters, have killed %d.",
7845 (int)quest[i].max_num, (int)quest[i].cur_num);
7849 case QUEST_TYPE_KILL_ALL:
7850 case QUEST_TYPE_TOWER:
7851 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7856 /* Print the quest info */
7857 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7858 quest[i].name, (int)quest[i].level, note);
7860 fputs(tmp_str, fff);
7862 if (quest[i].status == QUEST_STATUS_COMPLETED)
7864 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7865 fputs(tmp_str, fff);
7871 while (quest_text[j][0] && j < 10)
7873 fprintf(fff, " %s\n", quest_text[j]);
7878 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7881 rand_level = quest[i].level;
7883 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7885 /* Print the quest info */
7886 r_ptr = &r_info[quest[i].r_idx];
7887 strcpy(name, r_name + r_ptr->name);
7889 if (quest[i].max_num > 1)
7892 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7893 quest[i].name, (int)quest[i].level,
7894 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7898 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7899 quest[i].name, (int)quest[i].level,
7900 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7905 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7906 quest[i].name, (int)quest[i].level, name);
7913 /* Print the current random quest */
7914 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7916 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7920 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7923 char playtime_str[16];
7924 quest_type* const q_ptr = &quest[q_idx];
7926 if (is_fixed_quest_idx(q_idx))
7928 /* Set the quest number temporary */
7929 IDX old_quest = p_ptr->inside_quest;
7931 p_ptr->inside_quest = q_idx;
7934 init_flags = INIT_NAME_ONLY;
7936 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7938 /* Reset the old quest number */
7939 p_ptr->inside_quest = old_quest;
7941 /* No info from "silent" quests */
7942 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7945 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7946 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7948 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7950 /* Print the quest info */
7951 if (q_ptr->complev == 0)
7954 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7955 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7956 r_name+r_info[q_ptr->r_idx].name,
7957 (int)q_ptr->level, playtime_str);
7962 _(" %-35s (%3d階) - レベル%2d - %s\n",
7963 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7964 r_name+r_info[q_ptr->r_idx].name,
7972 /* Print the quest info */
7974 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7975 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7976 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7979 fputs(tmp_str, fff);
7985 * Print all finished quests
7987 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7992 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7993 for (i = 1; i < max_q_idx; i++)
7995 IDX q_idx = quest_num[i];
7996 quest_type* const q_ptr = &quest[q_idx];
7998 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7999 do_cmd_knowledge_quests_aux(fff, q_idx))
8004 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8009 * Print all failed quests
8011 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
8016 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
8017 for (i = 1; i < max_q_idx; i++)
8019 IDX q_idx = quest_num[i];
8020 quest_type* const q_ptr = &quest[q_idx];
8022 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
8023 do_cmd_knowledge_quests_aux(fff, q_idx))
8028 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8033 * Print all random quests
8035 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
8041 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
8042 for (i = 1; i < max_q_idx; i++)
8044 /* No info from "silent" quests */
8045 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8047 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
8051 /* Print the quest info */
8052 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
8053 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
8054 fputs(tmp_str, fff);
8057 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8061 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8063 QUEST_IDX *q_num = (QUEST_IDX *)u;
8064 quest_type *qa = &quest[q_num[a]];
8065 quest_type *qb = &quest[q_num[b]];
8070 return (qa->comptime != qb->comptime) ?
8071 (qa->comptime < qb->comptime) :
8072 (qa->level <= qb->level);
8075 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8077 QUEST_IDX *q_num = (QUEST_IDX *)u;
8084 q_num[a] = q_num[b];
8090 * Print quest status of all active quests
8092 static void do_cmd_knowledge_quests(void)
8095 GAME_TEXT file_name[1024];
8100 /* Open a new file */
8101 fff = my_fopen_temp(file_name, 1024);
8104 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8109 /* Allocate Memory */
8110 C_MAKE(quest_num, max_q_idx, IDX);
8112 /* Sort by compete level */
8113 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8114 ang_sort_comp = ang_sort_comp_quest_num;
8115 ang_sort_swap = ang_sort_swap_quest_num;
8116 ang_sort(quest_num, &dummy, max_q_idx);
8118 /* Dump Quest Information */
8119 do_cmd_knowledge_quests_current(fff);
8121 do_cmd_knowledge_quests_completed(fff, quest_num);
8123 do_cmd_knowledge_quests_failed(fff, quest_num);
8127 do_cmd_knowledge_quests_wiz_random(fff);
8131 /* Display the file contents */
8132 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8134 /* Remove the file */
8138 C_KILL(quest_num, max_q_idx, IDX);
8145 static void do_cmd_knowledge_home(void)
8150 GAME_TEXT file_name[1024];
8152 GAME_TEXT o_name[MAX_NLEN];
8155 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8157 /* Open a new file */
8158 fff = my_fopen_temp(file_name, 1024);
8160 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8167 /* Print all homes in the different towns */
8168 st_ptr = &town[1].store[STORE_HOME];
8170 /* Home -- if anything there */
8171 if (st_ptr->stock_num)
8176 /* Header with name of the town */
8177 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8179 /* Dump all available items */
8180 for (i = 0; i < st_ptr->stock_num; i++)
8183 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8184 object_desc(o_name, &st_ptr->stock[i], 0);
8185 if (strlen(o_name) <= 80-3)
8187 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8193 for (n = 0, t = o_name; n < 80-3; n++, t++)
8194 if(iskanji(*t)) {t++; n++;}
8195 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8197 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8198 fprintf(fff, " %.77s\n", o_name+n);
8201 object_desc(o_name, &st_ptr->stock[i], 0);
8202 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8207 /* Add an empty line */
8208 fprintf(fff, "\n\n");
8213 /* Display the file contents */
8214 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8216 /* Remove the file */
8222 * Check the status of "autopick"
8224 static void do_cmd_knowledge_autopick(void)
8228 GAME_TEXT file_name[1024];
8230 /* Open a new file */
8231 fff = my_fopen_temp(file_name, 1024);
8235 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8242 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8246 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8247 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8250 for (k = 0; k < max_autopick; k++)
8253 byte act = autopick_list[k].action;
8254 if (act & DONT_AUTOPICK)
8256 tmp = _("放置", "Leave");
8258 else if (act & DO_AUTODESTROY)
8260 tmp = _("破壊", "Destroy");
8262 else if (act & DO_AUTOPICK)
8264 tmp = _("拾う", "Pickup");
8268 tmp = _("確認", "Query");
8271 if (act & DO_DISPLAY)
8272 fprintf(fff, "%11s", format("[%s]", tmp));
8274 fprintf(fff, "%11s", format("(%s)", tmp));
8276 tmp = autopick_line_from_entry(&autopick_list[k]);
8277 fprintf(fff, " %s", tmp);
8282 /* Display the file contents */
8283 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8285 /* Remove the file */
8291 * Interact with "knowledge"
8293 void do_cmd_knowledge(void)
8296 bool need_redraw = FALSE;
8298 /* File type is "TEXT" */
8299 FILE_TYPE(FILE_TYPE_TEXT);
8302 /* Interact until done */
8307 /* Ask for a choice */
8308 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8309 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8311 /* Give some choices */
8315 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8316 prt("(2) 既知のアイテム の一覧", 7, 5);
8317 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8318 prt("(4) 既知のモンスター の一覧", 9, 5);
8319 prt("(5) 倒した敵の数 の一覧", 10, 5);
8320 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8321 prt("(7) 現在のペット の一覧", 12, 5);
8322 prt("(8) 我が家のアイテム の一覧", 13, 5);
8323 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8324 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8328 prt("(a) 自分に関する情報 の一覧", 6, 5);
8329 prt("(b) 突然変異 の一覧", 7, 5);
8330 prt("(c) 武器の経験値 の一覧", 8, 5);
8331 prt("(d) 魔法の経験値 の一覧", 9, 5);
8332 prt("(e) 技能の経験値 の一覧", 10, 5);
8333 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8334 prt("(g) 入ったダンジョン の一覧", 12, 5);
8335 prt("(h) 実行中のクエスト の一覧", 13, 5);
8336 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8341 prt("(1) Display known artifacts", 6, 5);
8342 prt("(2) Display known objects", 7, 5);
8343 prt("(3) Display remaining uniques", 8, 5);
8344 prt("(4) Display known monster", 9, 5);
8345 prt("(5) Display kill count", 10, 5);
8346 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8347 prt("(7) Display current pets", 12, 5);
8348 prt("(8) Display home inventory", 13, 5);
8349 prt("(9) Display *identified* equip.", 14, 5);
8350 prt("(0) Display terrain symbols.", 15, 5);
8354 prt("(a) Display about yourself", 6, 5);
8355 prt("(b) Display mutations", 7, 5);
8356 prt("(c) Display weapon proficiency", 8, 5);
8357 prt("(d) Display spell proficiency", 9, 5);
8358 prt("(e) Display misc. proficiency", 10, 5);
8359 prt("(f) Display virtues", 11, 5);
8360 prt("(g) Display dungeons", 12, 5);
8361 prt("(h) Display current quests", 13, 5);
8362 prt("(i) Display auto pick/destroy", 14, 5);
8366 prt(_("-続く-", "-more-"), 17, 8);
8367 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8368 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8369 /*prt("-) 前ページ", 21, 60);*/
8370 prt(_("コマンド:", "Command: "), 20, 0);
8373 if (i == ESCAPE) break;
8376 case ' ': /* Page change */
8380 case '1': /* Artifacts */
8381 do_cmd_knowledge_artifacts();
8383 case '2': /* Objects */
8384 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8386 case '3': /* Uniques */
8387 do_cmd_knowledge_uniques();
8389 case '4': /* Monsters */
8390 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8392 case '5': /* Kill count */
8393 do_cmd_knowledge_kill_count();
8395 case '6': /* wanted */
8396 if (!vanilla_town) do_cmd_knowledge_kubi();
8398 case '7': /* Pets */
8399 do_cmd_knowledge_pets();
8401 case '8': /* Home */
8402 do_cmd_knowledge_home();
8404 case '9': /* Resist list */
8405 do_cmd_knowledge_inven();
8407 case '0': /* Feature list */
8409 IDX lighting_level = F_LIT_STANDARD;
8410 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8414 case 'a': /* Max stat */
8415 do_cmd_knowledge_stat();
8417 case 'b': /* Mutations */
8418 do_cmd_knowledge_mutations();
8420 case 'c': /* weapon-exp */
8421 do_cmd_knowledge_weapon_exp();
8423 case 'd': /* spell-exp */
8424 do_cmd_knowledge_spell_exp();
8426 case 'e': /* skill-exp */
8427 do_cmd_knowledge_skill_exp();
8429 case 'f': /* Virtues */
8430 do_cmd_knowledge_virtues();
8432 case 'g': /* Dungeon */
8433 do_cmd_knowledge_dungeon();
8435 case 'h': /* Quests */
8436 do_cmd_knowledge_quests();
8438 case 'i': /* Autopick */
8439 do_cmd_knowledge_autopick();
8441 default: /* Unknown option */
8449 if (need_redraw) do_cmd_redraw();
8454 * Check on the status of an active quest
8456 void do_cmd_checkquest(void)
8458 /* File type is "TEXT" */
8459 FILE_TYPE(FILE_TYPE_TEXT);
8463 do_cmd_knowledge_quests();
8469 * Display the time and date
8471 void do_cmd_time(void)
8473 int day, hour, min, full, start, end, num;
8481 extract_day_hour_min(&day, &hour, &min);
8483 full = hour * 100 + min;
8490 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8492 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8493 else strcpy(day_buf, "*****");
8496 msg_format("%s日目, 時刻は%d:%02d %sです。",
8497 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8498 min, (hour < 12) ? "AM" : "PM");
8500 msg_format("This is day %s. The time is %d:%02d %s.",
8501 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8502 min, (hour < 12) ? "AM" : "PM");
8507 if (!randint0(10) || p_ptr->image)
8509 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8513 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8516 /* Open this file */
8517 fff = my_fopen(buf, "rt");
8521 /* Find this time */
8522 while (!my_fgets(fff, buf, sizeof(buf)))
8524 /* Ignore comments */
8525 if (!buf[0] || (buf[0] == '#')) continue;
8527 /* Ignore invalid lines */
8528 if (buf[1] != ':') continue;
8530 /* Process 'Start' */
8533 /* Extract the starting time */
8534 start = atoi(buf + 2);
8536 /* Assume valid for an hour */
8546 /* Extract the ending time */
8547 end = atoi(buf + 2);
8553 /* Ignore incorrect range */
8554 if ((start > full) || (full > end)) continue;
8556 /* Process 'Description' */
8561 /* Apply the randomizer */
8562 if (!randint0(num)) strcpy(desc, buf + 2);