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[MAX_NLEN];
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[MAX_NLEN];
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[MAX_NLEN];
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);
1207 skey = inkey_special(TRUE);
1209 /* Exit on Escape */
1210 if (skey == ESCAPE) break;
1212 /* Hack -- Save the old index */
1217 /* Hack -- handle show */
1220 prt(_("強調: ", "Show: "), hgt - 1, 0);
1222 /* Get a "shower" string, or continue */
1223 strcpy(back_str, shower_str);
1224 if (askfor(shower_str, 80))
1227 shower = shower_str[0] ? shower_str : NULL;
1229 else strcpy(shower_str, back_str);
1233 /* Hack -- handle find */
1240 prt(_("検索: ", "Find: "), hgt - 1, 0);
1242 /* Get a "finder" string, or continue */
1243 strcpy(back_str, finder_str);
1244 if (!askfor(finder_str, 80))
1246 strcpy(finder_str, back_str);
1249 else if (!finder_str[0])
1251 shower = NULL; /* Stop showing */
1256 shower = finder_str;
1259 for (z = i + 1; z < n; z++)
1261 cptr msg = message_str(z);
1264 if (my_strstr(msg, finder_str))
1275 /* Recall 1 older message */
1277 /* Go to the oldest line */
1281 /* Recall 1 newer message */
1283 /* Go to the newest line */
1287 /* Recall 1 older message */
1292 /* Go older if legal */
1293 i = MIN(i + 1, n - num_lines);
1296 /* Recall 10 older messages */
1298 /* Go older if legal */
1299 i = MIN(i + 10, n - num_lines);
1302 /* Recall 20 older messages */
1307 /* Go older if legal */
1308 i = MIN(i + num_lines, n - num_lines);
1311 /* Recall 20 newer messages */
1315 /* Go newer (if able) */
1316 i = MAX(0, i - num_lines);
1319 /* Recall 10 newer messages */
1321 /* Go newer (if able) */
1325 /* Recall 1 newer messages */
1328 /* Go newer (if able) */
1333 /* Hack -- Error of some kind */
1341 * @brief チートオプションを変更するコマンドのメインルーチン
1342 * Interact with some options for cheating
1343 * @param info 表示メッセージ
1346 static void do_cmd_options_cheat(cptr info)
1349 int i, k = 0, n = CHEAT_MAX;
1353 /* Interact with the player */
1359 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1364 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1365 prt(" << 注意 >>", 11, 0);
1366 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1367 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1368 prt(" じらないようにして下さい。", 14, 0);
1370 /* Display the options */
1371 for (i = 0; i < n; i++)
1373 byte a = TERM_WHITE;
1375 /* Color current option */
1376 if (i == k) a = TERM_L_BLUE;
1378 /* Display the option text */
1379 sprintf(buf, "%-48s: %s (%s)",
1380 cheat_info[i].o_desc,
1381 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1382 cheat_info[i].o_text);
1383 c_prt(a, buf, i + 2, 0);
1386 /* Hilite current option */
1387 move_cursor(k + 2, 50);
1393 * HACK - Try to translate the key into a direction
1394 * to allow using the roguelike keys for navigation.
1396 dir = get_keymap_dir(ch);
1397 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1411 k = (n + k - 1) % n;
1429 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1430 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1431 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1432 (*cheat_info[k].o_var) = TRUE;
1441 (*cheat_info[k].o_var) = FALSE;
1448 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1449 /* Peruse the help file */
1450 (void)show_file(TRUE, buf, NULL, 0, 0);
1467 * @brief セーブ頻度ターンの次の値を返す
1468 * @param current 現在のセーブ頻度ターン値
1469 * @return 次のセーブ頻度ターン値
1471 static s16b toggle_frequency(s16b current)
1476 case 50: return 100;
1477 case 100: return 250;
1478 case 250: return 500;
1479 case 500: return 1000;
1480 case 1000: return 2500;
1481 case 2500: return 5000;
1482 case 5000: return 10000;
1483 case 10000: return 25000;
1490 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1491 * @param info 表示メッセージ
1494 static void do_cmd_options_autosave(cptr info)
1497 int i, k = 0, n = 2;
1502 /* Interact with the player */
1506 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1507 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1511 /* Display the options */
1512 for (i = 0; i < n; i++)
1514 byte a = TERM_WHITE;
1516 /* Color current option */
1517 if (i == k) a = TERM_L_BLUE;
1519 /* Display the option text */
1520 sprintf(buf, "%-48s: %s (%s)",
1521 autosave_info[i].o_desc,
1522 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1523 autosave_info[i].o_text);
1524 c_prt(a, buf, i + 2, 0);
1526 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1528 /* Hilite current option */
1529 move_cursor(k + 2, 50);
1545 k = (n + k - 1) % n;
1563 (*autosave_info[k].o_var) = TRUE;
1572 (*autosave_info[k].o_var) = FALSE;
1580 autosave_freq = toggle_frequency(autosave_freq);
1581 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1587 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1603 * @brief 標準オプションを変更するコマンドのサブルーチン /
1604 * Interact with some options
1605 * @param page オプションページ番号
1606 * @param info 表示メッセージ
1609 void do_cmd_options_aux(int page, cptr info)
1612 int i, k = 0, n = 0, l;
1615 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1616 (!p_ptr->wizard || !allow_debug_opts);
1619 /* Lookup the options */
1620 for (i = 0; i < 24; i++) opt[i] = 0;
1622 /* Scan the options */
1623 for (i = 0; option_info[i].o_desc; i++)
1625 /* Notice options on this "page" */
1626 if (option_info[i].o_page == page) opt[n++] = i;
1630 /* Interact with the player */
1636 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1637 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1640 /* HACK -- description for easy-auto-destroy options */
1641 if (page == OPT_PAGE_AUTODESTROY)
1642 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1643 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1645 /* Display the options */
1646 for (i = 0; i < n; i++)
1648 byte a = TERM_WHITE;
1650 /* Color current option */
1651 if (i == k) a = TERM_L_BLUE;
1653 /* Display the option text */
1654 sprintf(buf, "%-48s: %s (%.19s)",
1655 option_info[opt[i]].o_desc,
1656 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1657 option_info[opt[i]].o_text);
1658 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1659 else c_prt(a, buf, i + 2, 0);
1662 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1665 /* Hilite current option */
1666 move_cursor(k + 2 + l, 50);
1672 * HACK - Try to translate the key into a direction
1673 * to allow using the roguelike keys for navigation.
1675 dir = get_keymap_dir(ch);
1676 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1690 k = (n + k - 1) % n;
1707 if (browse_only) break;
1708 (*option_info[opt[k]].o_var) = TRUE;
1717 if (browse_only) break;
1718 (*option_info[opt[k]].o_var) = FALSE;
1726 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1732 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1733 /* Peruse the help file */
1734 (void)show_file(TRUE, buf, NULL, 0, 0);
1751 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1752 * Modify the "window" options
1755 static void do_cmd_options_win(void)
1765 /* Memorize old flags */
1766 for (j = 0; j < 8; j++)
1768 /* Acquire current flags */
1769 old_flag[j] = window_flag[j];
1778 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1780 /* Display the windows */
1781 for (j = 0; j < 8; j++)
1783 byte a = TERM_WHITE;
1785 cptr s = angband_term_name[j];
1788 if (j == x) a = TERM_L_BLUE;
1790 /* Window name, staggered, centered */
1791 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1794 /* Display the options */
1795 for (i = 0; i < 16; i++)
1797 byte a = TERM_WHITE;
1799 cptr str = window_flag_desc[i];
1802 if (i == y) a = TERM_L_BLUE;
1805 if (!str) str = _("(未使用)", "(Unused option)");
1808 Term_putstr(0, i + 5, -1, a, str);
1810 /* Display the windows */
1811 for (j = 0; j < 8; j++)
1817 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1820 if (window_flag[j] & (1L << i)) c = 'X';
1823 Term_putch(35 + j * 5, i + 5, a, c);
1828 Term_gotoxy(35 + x * 5, y + 5);
1846 for (j = 0; j < 8; j++)
1848 window_flag[j] &= ~(1L << y);
1852 for (i = 0; i < 16; i++)
1854 window_flag[x] &= ~(1L << i);
1867 window_flag[x] |= (1L << y);
1875 window_flag[x] &= ~(1L << y);
1881 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1889 d = get_keymap_dir(ch);
1891 x = (x + ddx[d] + 8) % 8;
1892 y = (y + ddy[d] + 16) % 16;
1899 /* Notice changes */
1900 for (j = 0; j < 8; j++)
1905 if (!angband_term[j]) continue;
1907 /* Ignore non-changes */
1908 if (window_flag[j] == old_flag[j]) continue;
1911 Term_activate(angband_term[j]);
1928 option_fields[OPT_NUM] =
1931 { '1', " キー入力 オプション", 3 },
1932 { '2', " マップ画面 オプション", 4 },
1933 { '3', " テキスト表示 オプション", 5 },
1934 { '4', " ゲームプレイ オプション", 6 },
1935 { '5', " 行動中止関係 オプション", 7 },
1936 { '6', " 簡易自動破壊 オプション", 8 },
1937 { 'r', " プレイ記録 オプション", 9 },
1939 { 'p', "自動拾いエディタ", 11 },
1940 { 'd', " 基本ウェイト量 ", 12 },
1941 { 'h', "低ヒットポイント", 13 },
1942 { 'm', " 低魔力色閾値 ", 14 },
1943 { 'a', " 自動セーブ オプション", 15 },
1944 { 'w', "ウインドウフラグ", 16 },
1946 { 'b', " 初期 オプション (参照のみ)", 18 },
1947 { 'c', " 詐欺 オプション", 19 },
1949 { '1', "Input Options", 3 },
1950 { '2', "Map Screen Options", 4 },
1951 { '3', "Text Display Options", 5 },
1952 { '4', "Game-Play Options", 6 },
1953 { '5', "Disturbance Options", 7 },
1954 { '6', "Easy Auto-Destroyer Options", 8 },
1955 { 'r', "Play record Options", 9 },
1957 { 'p', "Auto-picker/destroyer editor", 11 },
1958 { 'd', "Base Delay Factor", 12 },
1959 { 'h', "Hitpoint Warning", 13 },
1960 { 'm', "Mana Color Threshold", 14 },
1961 { 'a', "Autosave Options", 15 },
1962 { 'w', "Window Flags", 16 },
1964 { 'b', "Birth Options (Browse Only)", 18 },
1965 { 'c', "Cheat Options", 19 },
1971 * @brief 標準オプションを変更するコマンドのメインルーチン /
1972 * Set or unset various options.
1976 * The user must use the "Ctrl-R" command to "adapt" to changes
1977 * in any options which control "visual" aspects of the game.
1980 void do_cmd_options(void)
1992 /* Does not list cheat option when cheat option is off */
1993 if (!p_ptr->noscore && !allow_debug_opts) n--;
1996 /* Why are we here */
1997 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2001 /* Give some choices */
2002 for (i = 0; i < n; i++)
2004 byte a = TERM_WHITE;
2005 if (i == y) a = TERM_L_BLUE;
2006 Term_putstr(5, option_fields[i].row, -1, a,
2007 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2010 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2013 skey = inkey_special(TRUE);
2014 if (!(skey & SKEY_MASK)) k = (char)skey;
2018 if (k == ESCAPE) break;
2020 if (my_strchr("\n\r ", k))
2022 k = option_fields[y].key;
2026 for (i = 0; i < n; i++)
2028 if (tolower(k) == option_fields[i].key) break;
2031 /* Command is found */
2034 /* Hack -- browse help */
2035 if (k == '?') break;
2039 if (skey == SKEY_UP) d = 8;
2040 if (skey == SKEY_DOWN) d = 2;
2041 y = (y + ddy[d] + n) % n;
2046 if (k == ESCAPE) break;
2053 /* Process the general options */
2054 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2060 /* Process the general options */
2061 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2068 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2075 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2082 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2089 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2093 /* Play-record Options */
2098 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2107 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2108 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2109 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2113 /* Cheating Options */
2116 if (!p_ptr->noscore && !allow_debug_opts)
2118 /* Cheat options are not permitted */
2124 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2131 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2140 do_cmd_options_win();
2141 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2142 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2143 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2144 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2149 /* Auto-picker/destroyer editor */
2153 do_cmd_edit_autopick();
2157 /* Hack -- Delay Speed */
2163 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2165 /* Get a new value */
2168 int msec = delay_factor * delay_factor * delay_factor;
2169 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2170 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2172 if (k == ESCAPE) break;
2175 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2178 else if (isdigit(k)) delay_factor = D2I(k);
2185 /* Hack -- hitpoint warning factor */
2191 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2193 /* Get a new value */
2196 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2197 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2199 if (k == ESCAPE) break;
2202 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2205 else if (isdigit(k)) hitpoint_warn = D2I(k);
2212 /* Hack -- mana color factor */
2218 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2220 /* Get a new value */
2223 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2224 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2226 if (k == ESCAPE) break;
2229 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2232 else if (isdigit(k)) mana_warn = D2I(k);
2240 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2244 /* Unknown option */
2257 /* Hack - Redraw equippy chars */
2258 p_ptr->redraw |= (PR_EQUIPPY);
2264 * @brief prefファイルを選択して処理する /
2265 * Ask for a "user pref line" and process it
2268 * Allow absolute file names?
2270 void do_cmd_pref(void)
2277 /* Ask for a "user pref command" */
2278 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2280 /* Process that pref command */
2281 (void)process_pref_file_command(buf);
2285 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2288 void do_cmd_reload_autopick(void)
2290 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2291 /* Load the file with messages */
2292 autopick_load_pref(TRUE);
2298 * @brief マクロ情報をprefファイルに保存する /
2299 * @param fname ファイル名
2302 static errr macro_dump(cptr fname)
2304 static cptr mark = "Macro Dump";
2310 /* Build the filename */
2311 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2313 /* File type is "TEXT" */
2314 FILE_TYPE(FILE_TYPE_TEXT);
2316 /* Append to the file */
2317 if (!open_auto_dump(buf, mark)) return (-1);
2320 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2323 for (i = 0; i < macro__num; i++)
2325 /* Extract the action */
2326 ascii_to_text(buf, macro__act[i]);
2328 /* Dump the macro */
2329 auto_dump_printf("A:%s\n", buf);
2331 /* Extract the action */
2332 ascii_to_text(buf, macro__pat[i]);
2334 /* Dump normal macros */
2335 auto_dump_printf("P:%s\n", buf);
2338 auto_dump_printf("\n");
2350 * @brief マクロのトリガーキーを取得する /
2351 * Hack -- ask for a "trigger" (see below)
2352 * @param buf キー表記を保管するバッファ
2356 * Note the complex use of the "inkey()" function from "util.c".
2358 * Note that both "flush()" calls are extremely important.
2361 static void do_cmd_macro_aux(char *buf)
2369 /* Do not process macros */
2375 /* Read the pattern */
2381 /* Do not process macros */
2384 /* Do not wait for keys */
2387 /* Attempt to read a key */
2396 /* Convert the trigger */
2397 ascii_to_text(tmp, buf);
2399 /* Hack -- display the trigger */
2400 Term_addstr(-1, TERM_WHITE, tmp);
2406 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2407 * Hack -- ask for a keymap "trigger" (see below)
2408 * @param buf キー表記を取得するバッファ
2412 * Note that both "flush()" calls are extremely important. This may
2413 * no longer be true, since "util.c" is much simpler now.
2416 static void do_cmd_macro_aux_keymap(char *buf)
2426 /* Convert to ascii */
2427 ascii_to_text(tmp, buf);
2429 /* Hack -- display the trigger */
2430 Term_addstr(-1, TERM_WHITE, tmp);
2437 * @brief キーマップをprefファイルにダンプする /
2438 * Hack -- append all keymaps to the given file
2439 * @param fname ファイルネーム
2443 static errr keymap_dump(cptr fname)
2445 static cptr mark = "Keymap Dump";
2454 if (rogue_like_commands)
2456 mode = KEYMAP_MODE_ROGUE;
2462 mode = KEYMAP_MODE_ORIG;
2466 /* Build the filename */
2467 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2469 /* File type is "TEXT" */
2470 FILE_TYPE(FILE_TYPE_TEXT);
2472 /* Append to the file */
2473 if (!open_auto_dump(buf, mark)) return -1;
2476 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2479 for (i = 0; i < 256; i++)
2483 /* Loop up the keymap */
2484 act = keymap_act[mode][i];
2486 /* Skip empty keymaps */
2489 /* Encode the key */
2492 ascii_to_text(key, buf);
2494 /* Encode the action */
2495 ascii_to_text(buf, act);
2497 /* Dump the macro */
2498 auto_dump_printf("A:%s\n", buf);
2499 auto_dump_printf("C:%d:%s\n", mode, key);
2511 * @brief マクロを設定するコマンドのメインルーチン /
2512 * Interact with "macros"
2516 * Note that the macro "action" must be defined before the trigger.
2518 * Could use some helpful instructions on this page.
2521 void do_cmd_macros(void)
2533 if (rogue_like_commands)
2535 mode = KEYMAP_MODE_ROGUE;
2541 mode = KEYMAP_MODE_ORIG;
2544 /* File type is "TEXT" */
2545 FILE_TYPE(FILE_TYPE_TEXT);
2550 /* Process requests until done */
2554 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2556 /* Describe that action */
2557 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2559 /* Analyze the current action */
2560 ascii_to_text(buf, macro__buf);
2562 /* Display the current action */
2567 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2569 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2570 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2571 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2572 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2573 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2574 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2575 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2576 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2577 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2578 #endif /* ALLOW_MACROS */
2581 prt(_("コマンド: ", "Command: "), 16, 0);
2586 if (i == ESCAPE) break;
2588 /* Load a 'macro' file */
2594 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2597 prt(_("ファイル: ", "File: "), 18, 0);
2599 /* Default filename */
2600 sprintf(tmp, "%s.prf", player_base);
2602 /* Ask for a file */
2603 if (!askfor(tmp, 80)) continue;
2605 /* Process the given filename */
2606 err = process_pref_file(tmp);
2609 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2614 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2618 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2628 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2631 prt(_("ファイル: ", "File: "), 18, 0);
2633 /* Default filename */
2634 sprintf(tmp, "%s.prf", player_base);
2636 /* Ask for a file */
2637 if (!askfor(tmp, 80)) continue;
2639 /* Dump the macros */
2640 (void)macro_dump(tmp);
2643 msg_print(_("マクロを追加しました。", "Appended macros."));
2652 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2656 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2658 /* Get a macro trigger */
2659 do_cmd_macro_aux(buf);
2661 /* Acquire action */
2662 k = macro_find_exact(buf);
2668 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2674 /* Obtain the action */
2675 strcpy(macro__buf, macro__act[k]);
2677 /* Analyze the current action */
2678 ascii_to_text(buf, macro__buf);
2680 /* Display the current action */
2684 msg_print(_("マクロを確認しました。", "Found a macro."));
2688 /* Create a macro */
2692 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2695 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2697 /* Get a macro trigger */
2698 do_cmd_macro_aux(buf);
2704 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2705 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2708 prt(_("マクロ行動: ", "Action: "), 20, 0);
2710 /* Convert to text */
2711 ascii_to_text(tmp, macro__buf);
2713 /* Get an encoded action */
2714 if (askfor(tmp, 80))
2716 /* Convert to ascii */
2717 text_to_ascii(macro__buf, tmp);
2719 /* Link the macro */
2720 macro_add(buf, macro__buf);
2723 msg_print(_("マクロを追加しました。", "Added a macro."));
2727 /* Remove a macro */
2731 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2734 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2736 /* Get a macro trigger */
2737 do_cmd_macro_aux(buf);
2739 /* Link the macro */
2740 macro_add(buf, buf);
2743 msg_print(_("マクロを削除しました。", "Removed a macro."));
2750 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2753 prt(_("ファイル: ", "File: "), 18, 0);
2755 /* Default filename */
2756 sprintf(tmp, "%s.prf", player_base);
2758 /* Ask for a file */
2759 if (!askfor(tmp, 80)) continue;
2761 /* Dump the macros */
2762 (void)keymap_dump(tmp);
2765 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2768 /* Query a keymap */
2774 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2777 prt(_("押すキー: ", "Keypress: "), 18, 0);
2779 /* Get a keymap trigger */
2780 do_cmd_macro_aux_keymap(buf);
2782 /* Look up the keymap */
2783 act = keymap_act[mode][(byte)(buf[0])];
2789 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2795 /* Obtain the action */
2796 strcpy(macro__buf, act);
2798 /* Analyze the current action */
2799 ascii_to_text(buf, macro__buf);
2801 /* Display the current action */
2805 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2809 /* Create a keymap */
2813 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2816 prt(_("押すキー: ", "Keypress: "), 18, 0);
2818 /* Get a keymap trigger */
2819 do_cmd_macro_aux_keymap(buf);
2825 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2826 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2829 prt(_("行動: ", "Action: "), 20, 0);
2831 /* Convert to text */
2832 ascii_to_text(tmp, macro__buf);
2834 /* Get an encoded action */
2835 if (askfor(tmp, 80))
2837 /* Convert to ascii */
2838 text_to_ascii(macro__buf, tmp);
2840 /* Free old keymap */
2841 string_free(keymap_act[mode][(byte)(buf[0])]);
2843 /* Make new keymap */
2844 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2847 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2851 /* Remove a keymap */
2855 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2858 prt(_("押すキー: ", "Keypress: "), 18, 0);
2860 /* Get a keymap trigger */
2861 do_cmd_macro_aux_keymap(buf);
2863 /* Free old keymap */
2864 string_free(keymap_act[mode][(byte)(buf[0])]);
2866 /* Make new keymap */
2867 keymap_act[mode][(byte)(buf[0])] = NULL;
2870 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2873 /* Enter a new action */
2877 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2883 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2884 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2887 prt(_("マクロ行動: ", "Action: "), 20, 0);
2889 /* Hack -- limit the value */
2892 /* Get an encoded action */
2893 if (!askfor(buf, 80)) continue;
2895 /* Extract an action */
2896 text_to_ascii(macro__buf, buf);
2899 #endif /* ALLOW_MACROS */
2912 * @brief キャラクタ色の明暗表現
2914 static cptr lighting_level_str[F_LIT_MAX] =
2929 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2930 * @param i 指定対象となるキャラクタコード
2931 * @param num 指定されたビジュアルIDを返す参照ポインタ
2932 * @param max ビジュアルIDの最大数
2933 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2935 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2942 sprintf(str, "%d", *num);
2944 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2947 tmp = (IDX)strtol(str, NULL, 0);
2948 if (tmp >= 0 && tmp < max)
2951 else if (isupper(i))
2952 *num = (*num + max - 1) % max;
2954 *num = (*num + 1) % max;
2960 * @brief キャラクタの変更メニュー表示
2961 * @param choice_msg 選択メッセージ
2964 static void print_visuals_menu(cptr choice_msg)
2966 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2968 /* Give some choices */
2969 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2971 #ifdef ALLOW_VISUALS
2972 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2973 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2974 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2975 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2976 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2977 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2978 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2979 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2980 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2981 #endif /* ALLOW_VISUALS */
2983 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2986 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2989 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2990 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2991 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2994 * Interact with "visuals"
2996 void do_cmd_visuals(void)
3001 bool need_redraw = FALSE;
3002 const char *empty_symbol = "<< ? >>";
3004 if (use_bigtile) empty_symbol = "<< ?? >>";
3006 /* File type is "TEXT" */
3007 FILE_TYPE(FILE_TYPE_TEXT);
3010 /* Interact until done */
3015 /* Ask for a choice */
3016 print_visuals_menu(NULL);
3021 if (i == ESCAPE) break;
3025 /* Load a 'pref' file */
3028 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3031 prt(_("ファイル: ", "File: "), 17, 0);
3033 /* Default filename */
3034 sprintf(tmp, "%s.prf", player_base);
3037 if (!askfor(tmp, 70)) continue;
3039 /* Process the given filename */
3040 (void)process_pref_file(tmp);
3045 #ifdef ALLOW_VISUALS
3047 /* Dump monster attr/chars */
3050 static cptr mark = "Monster attr/chars";
3053 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3056 prt(_("ファイル: ", "File: "), 17, 0);
3058 /* Default filename */
3059 sprintf(tmp, "%s.prf", player_base);
3061 /* Get a filename */
3062 if (!askfor(tmp, 70)) continue;
3064 /* Build the filename */
3065 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3067 /* Append to the file */
3068 if (!open_auto_dump(buf, mark)) continue;
3071 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3074 for (i = 0; i < max_r_idx; i++)
3076 monster_race *r_ptr = &r_info[i];
3078 /* Skip non-entries */
3079 if (!r_ptr->name) continue;
3081 /* Dump a comment */
3082 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3084 /* Dump the monster attr/char info */
3085 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3086 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3092 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3097 /* Dump object attr/chars */
3100 static cptr mark = "Object attr/chars";
3101 KIND_OBJECT_IDX k_idx;
3104 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3107 prt(_("ファイル: ", "File: "), 17, 0);
3109 /* Default filename */
3110 sprintf(tmp, "%s.prf", player_base);
3112 /* Get a filename */
3113 if (!askfor(tmp, 70)) continue;
3115 /* Build the filename */
3116 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3118 /* Append to the file */
3119 if (!open_auto_dump(buf, mark)) continue;
3122 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3125 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3127 GAME_TEXT o_name[MAX_NLEN];
3128 object_kind *k_ptr = &k_info[k_idx];
3130 /* Skip non-entries */
3131 if (!k_ptr->name) continue;
3136 strip_name(o_name, k_idx);
3142 /* Prepare dummy object */
3143 object_prep(&forge, k_idx);
3145 /* Get un-shuffled flavor name */
3146 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3149 /* Dump a comment */
3150 auto_dump_printf("# %s\n", o_name);
3152 /* Dump the object attr/char info */
3153 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3154 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3160 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3165 /* Dump feature attr/chars */
3168 static cptr mark = "Feature attr/chars";
3171 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3174 prt(_("ファイル: ", "File: "), 17, 0);
3176 /* Default filename */
3177 sprintf(tmp, "%s.prf", player_base);
3179 /* Get a filename */
3180 if (!askfor(tmp, 70)) continue;
3182 /* Build the filename */
3183 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3185 /* Append to the file */
3186 if (!open_auto_dump(buf, mark)) continue;
3189 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3192 for (i = 0; i < max_f_idx; i++)
3194 feature_type *f_ptr = &f_info[i];
3196 /* Skip non-entries */
3197 if (!f_ptr->name) continue;
3199 /* Skip mimiccing features */
3200 if (f_ptr->mimic != i) continue;
3202 /* Dump a comment */
3203 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3205 /* Dump the feature attr/char info */
3206 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3207 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3208 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3209 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3215 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3220 /* Modify monster attr/chars (numeric operation) */
3223 static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3226 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3228 /* Hack -- query until done */
3231 monster_race *r_ptr = &r_info[r];
3235 TERM_COLOR da = r_ptr->d_attr;
3236 byte dc = r_ptr->d_char;
3237 TERM_COLOR ca = r_ptr->x_attr;
3238 byte cc = r_ptr->x_char;
3240 /* Label the object */
3241 Term_putstr(5, 17, -1, TERM_WHITE,
3242 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3244 /* Label the Default values */
3245 Term_putstr(10, 19, -1, TERM_WHITE,
3246 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3248 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3249 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3251 /* Label the Current values */
3252 Term_putstr(10, 20, -1, TERM_WHITE,
3253 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3255 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3256 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3259 Term_putstr(0, 22, -1, TERM_WHITE,
3260 _("コマンド (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): "));
3265 if (i == ESCAPE) break;
3267 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3268 else if (isupper(i)) c = 'a' + i - 'A';
3278 if (!cmd_visuals_aux(i, &r, max_r_idx))
3284 while (!r_info[r].name);
3288 t = (int)r_ptr->x_attr;
3289 (void)cmd_visuals_aux(i, &t, 256);
3290 r_ptr->x_attr = (byte)t;
3294 t = (int)r_ptr->x_char;
3295 (void)cmd_visuals_aux(i, &t, 256);
3296 r_ptr->x_char = (byte)t;
3300 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3302 print_visuals_menu(choice_msg);
3310 /* Modify object attr/chars (numeric operation) */
3313 static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3315 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3317 /* Hack -- query until done */
3320 object_kind *k_ptr = &k_info[k];
3324 TERM_COLOR da = k_ptr->d_attr;
3325 SYMBOL_CODE dc = k_ptr->d_char;
3326 TERM_COLOR ca = k_ptr->x_attr;
3327 SYMBOL_CODE cc = k_ptr->x_char;
3329 /* Label the object */
3330 Term_putstr(5, 17, -1, TERM_WHITE,
3331 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3332 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3334 /* Label the Default values */
3335 Term_putstr(10, 19, -1, TERM_WHITE,
3336 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3338 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3339 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3341 /* Label the Current values */
3342 Term_putstr(10, 20, -1, TERM_WHITE,
3343 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3345 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3346 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3349 Term_putstr(0, 22, -1, TERM_WHITE,
3350 _("コマンド (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): "));
3355 if (i == ESCAPE) break;
3357 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3358 else if (isupper(i)) c = 'a' + i - 'A';
3368 if (!cmd_visuals_aux(i, &k, max_k_idx))
3374 while (!k_info[k].name);
3378 t = (int)k_ptr->x_attr;
3379 (void)cmd_visuals_aux(i, &t, 256);
3380 k_ptr->x_attr = (byte)t;
3384 t = (int)k_ptr->x_char;
3385 (void)cmd_visuals_aux(i, &t, 256);
3386 k_ptr->x_char = (byte)t;
3390 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3392 print_visuals_menu(choice_msg);
3400 /* Modify feature attr/chars (numeric operation) */
3403 static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3405 static IDX lighting_level = F_LIT_STANDARD;
3406 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3408 /* Hack -- query until done */
3411 feature_type *f_ptr = &f_info[f];
3415 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3416 byte dc = f_ptr->d_char[lighting_level];
3417 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3418 byte cc = f_ptr->x_char[lighting_level];
3420 /* Label the object */
3422 Term_putstr(5, 17, -1, TERM_WHITE,
3423 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3424 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3426 /* Label the Default values */
3427 Term_putstr(10, 19, -1, TERM_WHITE,
3428 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3430 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3431 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3433 /* Label the Current values */
3435 Term_putstr(10, 20, -1, TERM_WHITE,
3436 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3438 Term_putstr(10, 20, -1, TERM_WHITE,
3439 format("Current attr/char = %3d / %3d", ca, cc));
3442 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3443 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3447 Term_putstr(0, 22, -1, TERM_WHITE,
3448 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3450 Term_putstr(0, 22, -1, TERM_WHITE,
3451 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3457 if (i == ESCAPE) break;
3459 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3460 else if (isupper(i)) c = 'a' + i - 'A';
3470 if (!cmd_visuals_aux(i, &f, max_f_idx))
3476 while (!f_info[f].name || (f_info[f].mimic != f));
3480 t = (int)f_ptr->x_attr[lighting_level];
3481 (void)cmd_visuals_aux(i, &t, 256);
3482 f_ptr->x_attr[lighting_level] = (byte)t;
3486 t = (int)f_ptr->x_char[lighting_level];
3487 (void)cmd_visuals_aux(i, &t, 256);
3488 f_ptr->x_char[lighting_level] = (byte)t;
3492 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3495 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3499 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3501 print_visuals_menu(choice_msg);
3509 /* Modify monster attr/chars (visual mode) */
3511 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3514 /* Modify object attr/chars (visual mode) */
3516 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3519 /* Modify feature attr/chars (visual mode) */
3522 IDX lighting_level = F_LIT_STANDARD;
3523 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3527 #endif /* ALLOW_VISUALS */
3535 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3539 /* Unknown option */
3549 if (need_redraw) do_cmd_redraw();
3554 * Interact with "colors"
3556 void do_cmd_colors(void)
3565 /* File type is "TEXT" */
3566 FILE_TYPE(FILE_TYPE_TEXT);
3571 /* Interact until done */
3576 /* Ask for a choice */
3577 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3579 /* Give some choices */
3580 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3583 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3584 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3588 prt(_("コマンド: ", "Command: "), 8, 0);
3592 if (i == ESCAPE) break;
3594 /* Load a 'pref' file */
3598 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3601 prt(_("ファイル: ", "File: "), 10, 0);
3604 sprintf(tmp, "%s.prf", player_base);
3607 if (!askfor(tmp, 70)) continue;
3609 /* Process the given filename */
3610 (void)process_pref_file(tmp);
3612 /* Mega-Hack -- react to changes */
3613 Term_xtra(TERM_XTRA_REACT, 0);
3615 /* Mega-Hack -- redraw */
3624 static cptr mark = "Colors";
3627 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3630 prt(_("ファイル: ", "File: "), 10, 0);
3632 /* Default filename */
3633 sprintf(tmp, "%s.prf", player_base);
3635 /* Get a filename */
3636 if (!askfor(tmp, 70)) continue;
3638 /* Build the filename */
3639 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3641 /* Append to the file */
3642 if (!open_auto_dump(buf, mark)) continue;
3645 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3648 for (i = 0; i < 256; i++)
3650 int kv = angband_color_table[i][0];
3651 int rv = angband_color_table[i][1];
3652 int gv = angband_color_table[i][2];
3653 int bv = angband_color_table[i][3];
3655 cptr name = _("未知", "unknown");
3657 /* Skip non-entries */
3658 if (!kv && !rv && !gv && !bv) continue;
3660 /* Extract the color name */
3661 if (i < 16) name = color_names[i];
3663 /* Dump a comment */
3664 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3666 /* Dump the monster attr/char info */
3667 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3674 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3683 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3685 /* Hack -- query until done */
3694 /* Exhibit the normal colors */
3695 for (j = 0; j < 16; j++)
3697 /* Exhibit this color */
3698 Term_putstr(j*4, 20, -1, a, "###");
3700 /* Exhibit all colors */
3701 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3704 /* Describe the color */
3705 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3707 /* Describe the color */
3708 Term_putstr(5, 10, -1, TERM_WHITE,
3709 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3711 /* Label the Current values */
3712 Term_putstr(5, 12, -1, TERM_WHITE,
3713 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3714 angband_color_table[a][0],
3715 angband_color_table[a][1],
3716 angband_color_table[a][2],
3717 angband_color_table[a][3]));
3720 Term_putstr(0, 14, -1, TERM_WHITE,
3721 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3726 if (i == ESCAPE) break;
3729 if (i == 'n') a = (byte)(a + 1);
3730 if (i == 'N') a = (byte)(a - 1);
3731 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3732 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3733 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3734 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3735 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3736 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3737 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3738 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3740 /* Hack -- react to changes */
3741 Term_xtra(TERM_XTRA_REACT, 0);
3743 /* Hack -- redraw */
3750 /* Unknown option */
3764 * Note something in the message recall
3766 void do_cmd_note(void)
3774 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3776 /* Ignore empty notes */
3777 if (!buf[0] || (buf[0] == ' ')) return;
3779 /* Add the note to the message recall */
3780 msg_format(_("メモ: %s", "Note: %s"), buf);
3785 * Mention the current version
3787 void do_cmd_version(void)
3791 #if FAKE_VER_EXTRA > 0
3792 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3793 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3795 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3796 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3803 * Array of feeling strings
3805 static cptr do_cmd_feeling_text[11] =
3807 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3808 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3809 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3810 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3811 _("とても悪い予感がする...", "You have a very bad feeling..."),
3812 _("悪い予感がする...", "You have a bad feeling..."),
3813 _("何か緊張する。", "You feel nervous."),
3814 _("少し不運な気がする...", "You feel your luck is turning..."),
3815 _("この場所は好きになれない。", "You don't like the look of this place."),
3816 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3817 _("なんて退屈なところだ...", "What a boring place...")
3820 static cptr do_cmd_feeling_text_combat[11] =
3822 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3823 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3824 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3825 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3826 _("とても悪い予感がする...", "You have a very bad feeling..."),
3827 _("悪い予感がする...", "You have a bad feeling..."),
3828 _("何か緊張する。", "You feel nervous."),
3829 _("少し不運な気がする...", "You feel your luck is turning..."),
3830 _("この場所は好きになれない。", "You don't like the look of this place."),
3831 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3832 _("なんて退屈なところだ...", "What a boring place...")
3835 static cptr do_cmd_feeling_text_lucky[11] =
3837 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3838 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3839 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3840 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3841 _("とても良い感じがする...", "You have a very good feeling..."),
3842 _("良い感じがする...", "You have a good feeling..."),
3843 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3844 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3845 _("見た感じ悪くはない...", "You like the look of this place..."),
3846 _("全然駄目ということはないが...", "This level can't be all bad..."),
3847 _("なんて退屈なところだ...", "What a boring place...")
3852 * Note that "feeling" is set to zero unless some time has passed.
3853 * Note that this is done when the level is GENERATED, not entered.
3855 void do_cmd_feeling(void)
3857 /* No useful feeling in quests */
3858 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3860 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3864 /* No useful feeling in town */
3865 else if (p_ptr->town_num && !dun_level)
3867 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3869 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3874 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3879 /* No useful feeling in the wilderness */
3880 else if (!dun_level)
3882 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3886 /* Display the feeling */
3887 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3888 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3889 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3890 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3891 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3893 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3899 * Description of each monster group.
3901 static cptr monster_group_text[] =
3904 "ユニーク", /* "Uniques" */
3905 "乗馬可能なモンスター", /* "Riding" */
3906 "賞金首", /* "Wanted */
3907 "アンバーの王族", /* "Ambertite" */
3936 /* "古代ドラゴン/ワイアーム", */
3997 /* "Ancient Dragon/Wyrm", */
4006 "Multi-Headed Reptile",
4011 "Reptile/Amphibian",
4012 "Spider/Scorpion/Tick",
4014 /* "Major Demon", */
4031 * Symbols of monsters in each group. Note the "Uniques" group
4032 * is handled differently.
4034 static cptr monster_group_char[] =
4091 "!$&()+./=>?[\\]`{|~",
4101 * hook function to sort monsters by level
4103 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4105 u16b *who = (u16b*)(u);
4110 monster_race *r_ptr1 = &r_info[w1];
4111 monster_race *r_ptr2 = &r_info[w2];
4116 if (r_ptr2->level > r_ptr1->level) return TRUE;
4117 if (r_ptr1->level > r_ptr2->level) return FALSE;
4119 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4120 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4125 * Build a list of monster indexes in the given group. Return the number
4126 * of monsters in the group.
4128 * mode & 0x01 : check for non-empty group
4129 * mode & 0x02 : visual operation only
4131 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4137 /* Get a list of x_char in this group */
4138 cptr group_char = monster_group_char[grp_cur];
4140 /* XXX Hack -- Check if this is the "Uniques" group */
4141 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4143 /* XXX Hack -- Check if this is the "Riding" group */
4144 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4146 /* XXX Hack -- Check if this is the "Wanted" group */
4147 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4149 /* XXX Hack -- Check if this is the "Amberite" group */
4150 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4153 /* Check every race */
4154 for (i = 0; i < max_r_idx; i++)
4156 /* Access the race */
4157 monster_race *r_ptr = &r_info[i];
4159 /* Skip empty race */
4160 if (!r_ptr->name) continue ;
4162 /* Require known monsters */
4163 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4167 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4170 else if (grp_riding)
4172 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4175 else if (grp_wanted)
4177 bool wanted = FALSE;
4179 for (j = 0; j < MAX_KUBI; j++)
4181 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4182 (p_ptr->today_mon && p_ptr->today_mon == i))
4188 if (!wanted) continue;
4191 else if (grp_amberite)
4193 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4198 /* Check for race in the group */
4199 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4203 mon_idx[mon_cnt++] = i;
4205 /* XXX Hack -- Just checking for non-empty group */
4206 if (mode & 0x01) break;
4209 /* Terminate the list */
4210 mon_idx[mon_cnt] = -1;
4212 /* Select the sort method */
4213 ang_sort_comp = ang_sort_comp_monster_level;
4214 ang_sort_swap = ang_sort_swap_hook;
4216 /* Sort by monster level */
4217 ang_sort(mon_idx, &dummy_why, mon_cnt);
4219 /* Return the number of races */
4225 * Description of each monster group.
4227 static cptr object_group_text[] =
4230 "キノコ", /* "Mushrooms" */
4231 "薬", /* "Potions" */
4232 "油つぼ", /* "Flasks" */
4233 "巻物", /* "Scrolls" */
4235 "アミュレット", /* "Amulets" */
4236 "笛", /* "Whistle" */
4237 "光源", /* "Lanterns" */
4238 "魔法棒", /* "Wands" */
4241 "カード", /* "Cards" */
4252 "刀剣類", /* "Swords" */
4253 "鈍器", /* "Blunt Weapons" */
4254 "長柄武器", /* "Polearms" */
4255 "採掘道具", /* "Diggers" */
4256 "飛び道具", /* "Bows" */
4260 "軽装鎧", /* "Soft Armor" */
4261 "重装鎧", /* "Hard Armor" */
4262 "ドラゴン鎧", /* "Dragon Armor" */
4263 "盾", /* "Shields" */
4264 "クローク", /* "Cloaks" */
4265 "籠手", /* "Gloves" */
4266 "ヘルメット", /* "Helms" */
4268 "ブーツ", /* "Boots" */
4321 * TVALs of items in each group
4323 static byte object_group_tval[] =
4364 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4372 * Build a list of object indexes in the given group. Return the number
4373 * of objects in the group.
4375 * mode & 0x01 : check for non-empty group
4376 * mode & 0x02 : visual operation only
4378 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4381 int j, k, object_cnt = 0;
4383 /* Get a list of x_char in this group */
4384 byte group_tval = object_group_tval[grp_cur];
4386 /* Check every object */
4387 for (i = 0; i < max_k_idx; i++)
4389 /* Access the object */
4390 object_kind *k_ptr = &k_info[i];
4392 /* Skip empty objects */
4393 if (!k_ptr->name) continue;
4397 /* Any objects will be displayed */
4403 /* Skip non-flavoured objects */
4404 if (!k_ptr->flavor) continue;
4406 /* Require objects ever seen */
4407 if (!k_ptr->aware) continue;
4410 /* Skip items with no distribution (special artifacts) */
4411 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4415 /* Check for objects in the group */
4416 if (TV_LIFE_BOOK == group_tval)
4418 /* Hack -- All spell books */
4419 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4421 /* Add the object */
4422 object_idx[object_cnt++] = i;
4426 else if (k_ptr->tval == group_tval)
4428 /* Add the object */
4429 object_idx[object_cnt++] = i;
4433 /* XXX Hack -- Just checking for non-empty group */
4434 if (mode & 0x01) break;
4437 /* Terminate the list */
4438 object_idx[object_cnt] = -1;
4440 /* Return the number of objects */
4446 * Description of each feature group.
4448 static cptr feature_group_text[] =
4456 * Build a list of feature indexes in the given group. Return the number
4457 * of features in the group.
4459 * mode & 0x01 : check for non-empty group
4461 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4466 /* Unused; There is a single group. */
4469 /* Check every feature */
4470 for (i = 0; i < max_f_idx; i++)
4472 /* Access the index */
4473 feature_type *f_ptr = &f_info[i];
4475 /* Skip empty index */
4476 if (!f_ptr->name) continue;
4478 /* Skip mimiccing features */
4479 if (f_ptr->mimic != i) continue;
4482 feat_idx[feat_cnt++] = i;
4484 /* XXX Hack -- Just checking for non-empty group */
4485 if (mode & 0x01) break;
4488 /* Terminate the list */
4489 feat_idx[feat_cnt] = -1;
4491 /* Return the number of races */
4498 * Build a list of monster indexes in the given group. Return the number
4499 * of monsters in the group.
4501 static int collect_artifacts(int grp_cur, int object_idx[])
4503 int i, object_cnt = 0;
4505 /* Get a list of x_char in this group */
4506 byte group_tval = object_group_tval[grp_cur];
4508 /* Check every object */
4509 for (i = 0; i < max_a_idx; i++)
4511 /* Access the artifact */
4512 artifact_type *a_ptr = &a_info[i];
4514 /* Skip empty artifacts */
4515 if (!a_ptr->name) continue;
4517 /* Skip "uncreated" artifacts */
4518 if (!a_ptr->cur_num) continue;
4520 /* Check for race in the group */
4521 if (a_ptr->tval == group_tval)
4524 object_idx[object_cnt++] = i;
4528 /* Terminate the list */
4529 object_idx[object_cnt] = 0;
4531 /* Return the number of races */
4538 * Encode the screen colors
4540 static char hack[17] = "dwsorgbuDWvyRGBU";
4544 * Hack -- load a screen dump from a file
4546 void do_cmd_load_screen(void)
4561 Term_get_size(&wid, &hgt);
4563 /* Build the filename */
4564 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4566 /* Append to the file */
4567 fff = my_fopen(buf, "r");
4570 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4578 /* Load the screen */
4579 for (y = 0; okay; y++)
4581 /* Get a line of data including control code */
4582 if (!fgets(buf, 1024, fff)) okay = FALSE;
4584 /* Get the blank line */
4585 if (buf[0] == '\n' || buf[0] == '\0') break;
4587 /* Ignore too large screen image */
4588 if (y >= hgt) continue;
4591 for (x = 0; x < wid - 1; x++)
4594 if (buf[x] == '\n' || buf[x] == '\0') break;
4596 /* Put the attr/char */
4597 Term_draw(x, y, TERM_WHITE, buf[x]);
4601 /* Dump the screen */
4602 for (y = 0; okay; y++)
4604 /* Get a line of data including control code */
4605 if (!fgets(buf, 1024, fff)) okay = FALSE;
4607 /* Get the blank line */
4608 if (buf[0] == '\n' || buf[0] == '\0') break;
4610 /* Ignore too large screen image */
4611 if (y >= hgt) continue;
4614 for (x = 0; x < wid - 1; x++)
4617 if (buf[x] == '\n' || buf[x] == '\0') break;
4619 /* Get the attr/char */
4620 (void)(Term_what(x, y, &a, &c));
4622 /* Look up the attr */
4623 for (i = 0; i < 16; i++)
4625 /* Use attr matches */
4626 if (hack[i] == buf[x]) a = (byte_hack)i;
4629 /* Put the attr/char */
4630 Term_draw(x, y, a, c);
4639 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4650 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4651 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4654 #define IM_FLAG_STR _("*", "* ")
4655 #define HAS_FLAG_STR _("+", "+ ")
4656 #define NO_FLAG_STR _("・", ". ")
4658 #define print_im_or_res_flag(IM, RES) \
4660 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4661 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4664 #define print_flag(TR) \
4666 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4670 /* XTRA HACK RESLIST */
4671 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4673 GAME_TEXT o_name[MAX_NLEN];
4674 BIT_FLAGS flgs[TR_FLAG_SIZE];
4676 if (!o_ptr->k_idx) return;
4677 if (o_ptr->tval != tval) return;
4679 /* Identified items only */
4680 if (!object_is_known(o_ptr)) return;
4683 * HACK:Ring of Lordly protection and Dragon equipment
4684 * have random resistances.
4686 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4687 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4688 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4689 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4690 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4691 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4692 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4693 || object_is_artifact(o_ptr))
4696 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4698 while (o_name[i] && (i < 26))
4701 if (iskanji(o_name[i])) i++;
4710 o_name[i] = ' '; i++;
4715 fprintf(fff, "%s %s", where, o_name);
4717 if (!(o_ptr->ident & (IDENT_MENTAL)))
4719 fputs(_("-------不明--------------- -------不明---------\n",
4720 "-------unknown------------ -------unknown------\n"), fff);
4724 object_flags_known(o_ptr, flgs);
4726 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4727 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4728 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4729 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4730 print_flag(TR_RES_POIS);
4731 print_flag(TR_RES_LITE);
4732 print_flag(TR_RES_DARK);
4733 print_flag(TR_RES_SHARDS);
4734 print_flag(TR_RES_SOUND);
4735 print_flag(TR_RES_NETHER);
4736 print_flag(TR_RES_NEXUS);
4737 print_flag(TR_RES_CHAOS);
4738 print_flag(TR_RES_DISEN);
4742 print_flag(TR_RES_BLIND);
4743 print_flag(TR_RES_FEAR);
4744 print_flag(TR_RES_CONF);
4745 print_flag(TR_FREE_ACT);
4746 print_flag(TR_SEE_INVIS);
4747 print_flag(TR_HOLD_EXP);
4748 print_flag(TR_TELEPATHY);
4749 print_flag(TR_SLOW_DIGEST);
4750 print_flag(TR_REGEN);
4751 print_flag(TR_LEVITATION);
4759 fprintf(fff, "%s\n", inven_res_label);
4765 * Display *ID* ed weapons/armors's resistances
4767 static void do_cmd_knowledge_inven(void)
4771 GAME_TEXT file_name[1024];
4775 OBJECT_TYPE_VALUE tval;
4781 /* Open a new file */
4782 fff = my_fopen_temp(file_name, 1024);
4785 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4789 fprintf(fff, "%s\n", inven_res_label);
4791 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4795 for (; j < 9; j++) fputc('\n', fff);
4797 fprintf(fff, "%s\n", inven_res_label);
4799 strcpy(where, _("装", "E "));
4800 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4802 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4804 strcpy(where, _("持", "I "));
4805 for (i = 0; i < INVEN_PACK; i++)
4807 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4810 st_ptr = &town[1].store[STORE_HOME];
4811 strcpy(where, _("家", "H "));
4812 for (i = 0; i < st_ptr->stock_num; i++)
4814 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4819 /* Display the file contents */
4820 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4822 /* Remove the file */
4827 void do_cmd_save_screen_html_aux(char *filename, int message)
4831 TERM_COLOR a = 0, old_a = 0;
4845 cptr html_head[] = {
4846 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4850 cptr html_foot[] = {
4852 "</body>\n</html>\n",
4858 Term_get_size(&wid, &hgt);
4860 /* File type is "TEXT" */
4861 FILE_TYPE(FILE_TYPE_TEXT);
4863 /* Append to the file */
4864 fff = my_fopen(filename, "w");
4868 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4874 if (message) screen_save();
4876 /* Build the filename */
4877 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4878 tmpfff = my_fopen(buf, "r");
4880 for (i = 0; html_head[i]; i++)
4881 fputs(html_head[i], fff);
4885 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4887 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4891 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4893 fprintf(fff, "%s\n", buf);
4898 /* Dump the screen */
4899 for (y = 0; y < hgt; y++)
4906 for (x = 0; x < wid - 1; x++)
4910 /* Get the attr/char */
4911 (void)(Term_what(x, y, &a, &c));
4915 case '&': cc = "&"; break;
4916 case '<': cc = "<"; break;
4917 case '>': cc = ">"; break;
4919 case 0x1f: c = '.'; break;
4920 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4925 if ((y == 0 && x == 0) || a != old_a) {
4926 rv = angband_color_table[a][1];
4927 gv = angband_color_table[a][2];
4928 bv = angband_color_table[a][3];
4929 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4930 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4934 fprintf(fff, "%s", cc);
4936 fprintf(fff, "%c", c);
4939 fprintf(fff, "</font>");
4942 for (i = 0; html_foot[i]; i++)
4943 fputs(html_foot[i], fff);
4948 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4950 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4954 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4956 fprintf(fff, "%s\n", buf);
4969 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4977 * Hack -- save a screen dump to a file
4979 static void do_cmd_save_screen_html(void)
4981 char buf[1024], tmp[256] = "screen.html";
4983 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4986 /* Build the filename */
4987 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4991 do_cmd_save_screen_html_aux(buf, 1);
4996 * Redefinable "save_screen" action
4998 void (*screendump_aux)(void) = NULL;
5002 * Hack -- save a screen dump to a file
5004 void do_cmd_save_screen(void)
5006 bool old_use_graphics = use_graphics;
5007 bool html_dump = FALSE;
5011 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5015 if (c == 'Y' || c == 'y')
5017 else if (c == 'H' || c == 'h')
5029 Term_get_size(&wid, &hgt);
5031 if (old_use_graphics)
5033 use_graphics = FALSE;
5035 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5041 do_cmd_save_screen_html();
5045 /* Do we use a special screendump function ? */
5046 else if (screendump_aux)
5048 /* Dump the screen to a graphics file */
5049 (*screendump_aux)();
5051 else /* Dump the screen as text */
5062 /* Build the filename */
5063 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5065 /* File type is "TEXT" */
5066 FILE_TYPE(FILE_TYPE_TEXT);
5068 /* Append to the file */
5069 fff = my_fopen(buf, "w");
5073 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5081 /* Dump the screen */
5082 for (y = 0; y < hgt; y++)
5085 for (x = 0; x < wid - 1; x++)
5087 /* Get the attr/char */
5088 (void)(Term_what(x, y, &a, &c));
5098 fprintf(fff, "%s\n", buf);
5105 /* Dump the screen */
5106 for (y = 0; y < hgt; y++)
5109 for (x = 0; x < wid - 1; x++)
5111 /* Get the attr/char */
5112 (void)(Term_what(x, y, &a, &c));
5115 buf[x] = hack[a&0x0F];
5122 fprintf(fff, "%s\n", buf);
5131 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5136 if (old_use_graphics)
5138 use_graphics = TRUE;
5140 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5147 * Sorting hook -- Comp function -- see below
5149 * We use "u" to point to array of monster indexes,
5150 * and "v" to select the type of sorting to perform on "u".
5152 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5154 u16b *who = (u16b*)(u);
5156 u16b *why = (u16b*)(v);
5163 /* Sort by total kills */
5166 /* Extract total kills */
5167 z1 = a_info[w1].tval;
5168 z2 = a_info[w2].tval;
5170 /* Compare total kills */
5171 if (z1 < z2) return (TRUE);
5172 if (z1 > z2) return (FALSE);
5176 /* Sort by monster level */
5179 /* Extract levels */
5180 z1 = a_info[w1].sval;
5181 z2 = a_info[w2].sval;
5183 /* Compare levels */
5184 if (z1 < z2) return (TRUE);
5185 if (z1 > z2) return (FALSE);
5189 /* Sort by monster experience */
5192 /* Extract experience */
5193 z1 = a_info[w1].level;
5194 z2 = a_info[w2].level;
5196 /* Compare experience */
5197 if (z1 < z2) return (TRUE);
5198 if (z1 > z2) return (FALSE);
5202 /* Compare indexes */
5208 * Sorting hook -- Swap function -- see below
5210 * We use "u" to point to array of monster indexes,
5211 * and "v" to select the type of sorting to perform.
5213 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5215 u16b *who = (u16b*)(u);
5230 * Check the status of "artifacts"
5232 static void do_cmd_knowledge_artifacts(void)
5244 GAME_TEXT file_name[1024];
5246 GAME_TEXT base_name[MAX_NLEN];
5250 /* Open a new file */
5251 fff = my_fopen_temp(file_name, 1024);
5254 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5259 /* Allocate the "who" array */
5260 C_MAKE(who, max_a_idx, s16b);
5262 /* Allocate the "okay" array */
5263 C_MAKE(okay, max_a_idx, bool);
5265 /* Scan the artifacts */
5266 for (k = 0; k < max_a_idx; k++)
5268 artifact_type *a_ptr = &a_info[k];
5273 /* Skip "empty" artifacts */
5274 if (!a_ptr->name) continue;
5276 /* Skip "uncreated" artifacts */
5277 if (!a_ptr->cur_num) continue;
5283 /* Check the dungeon */
5284 for (y = 0; y < cur_hgt; y++)
5286 for (x = 0; x < cur_wid; x++)
5288 cave_type *c_ptr = &cave[y][x];
5290 OBJECT_IDX this_o_idx, next_o_idx = 0;
5292 /* Scan all objects in the grid */
5293 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5296 o_ptr = &o_list[this_o_idx];
5298 /* Acquire next object */
5299 next_o_idx = o_ptr->next_o_idx;
5301 /* Ignore non-artifacts */
5302 if (!object_is_fixed_artifact(o_ptr)) continue;
5304 /* Ignore known items */
5305 if (object_is_known(o_ptr)) continue;
5307 /* Note the artifact */
5308 okay[o_ptr->name1] = FALSE;
5313 /* Check the inventory and equipment */
5314 for (i = 0; i < INVEN_TOTAL; i++)
5316 object_type *o_ptr = &inventory[i];
5318 /* Ignore non-objects */
5319 if (!o_ptr->k_idx) continue;
5321 /* Ignore non-artifacts */
5322 if (!object_is_fixed_artifact(o_ptr)) continue;
5324 /* Ignore known items */
5325 if (object_is_known(o_ptr)) continue;
5327 /* Note the artifact */
5328 okay[o_ptr->name1] = FALSE;
5331 for (k = 0; k < max_a_idx; k++)
5333 if (okay[k]) who[n++] = k;
5336 /* Select the sort method */
5337 ang_sort_comp = ang_sort_art_comp;
5338 ang_sort_swap = ang_sort_art_swap;
5340 /* Sort the array by dungeon depth of monsters */
5341 ang_sort(who, &why, n);
5343 /* Scan the artifacts */
5344 for (k = 0; k < n; k++)
5346 artifact_type *a_ptr = &a_info[who[k]];
5349 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5351 /* Obtain the base object type */
5352 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5361 /* Create fake object */
5362 object_prep(q_ptr, z);
5364 /* Make it an artifact */
5365 q_ptr->name1 = (byte)who[k];
5367 /* Display as if known */
5368 q_ptr->ident |= IDENT_STORE;
5370 /* Describe the artifact */
5371 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5374 /* Hack -- Build the artifact name */
5375 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5378 /* Free the "who" array */
5379 C_KILL(who, max_a_idx, s16b);
5381 /* Free the "okay" array */
5382 C_KILL(okay, max_a_idx, bool);
5385 /* Display the file contents */
5386 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5388 /* Remove the file */
5394 * Display known uniques
5395 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5397 static void do_cmd_knowledge_uniques(void)
5406 GAME_TEXT file_name[1024];
5409 int n_alive_surface = 0;
5410 int n_alive_over100 = 0;
5411 int n_alive_total = 0;
5414 for (i = 0; i < 10; i++) n_alive[i] = 0;
5416 /* Open a new file */
5417 fff = my_fopen_temp(file_name, 1024);
5421 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5426 /* Allocate the "who" array */
5427 C_MAKE(who, max_r_idx, s16b);
5429 /* Scan the monsters */
5430 for (i = 1; i < max_r_idx; i++)
5432 monster_race *r_ptr = &r_info[i];
5435 if (!r_ptr->name) continue;
5437 /* Require unique monsters */
5438 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5440 /* Only display "known" uniques */
5441 if (!cheat_know && !r_ptr->r_sights) continue;
5443 /* Only print rarity <= 100 uniques */
5444 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5446 /* Only "alive" uniques */
5447 if (r_ptr->max_num == 0) continue;
5451 lev = (r_ptr->level - 1) / 10;
5455 if (max_lev < lev) max_lev = lev;
5457 else n_alive_over100++;
5459 else n_alive_surface++;
5461 /* Collect "appropriate" monsters */
5465 /* Select the sort method */
5466 ang_sort_comp = ang_sort_comp_hook;
5467 ang_sort_swap = ang_sort_swap_hook;
5469 /* Sort the array by dungeon depth of monsters */
5470 ang_sort(who, &why, n);
5472 if (n_alive_surface)
5474 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5475 n_alive_total += n_alive_surface;
5477 for (i = 0; i <= max_lev; i++)
5479 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5480 n_alive_total += n_alive[i];
5482 if (n_alive_over100)
5484 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5485 n_alive_total += n_alive_over100;
5490 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5491 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5495 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5498 /* Scan the monster races */
5499 for (k = 0; k < n; k++)
5501 monster_race *r_ptr = &r_info[who[k]];
5503 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5506 /* Free the "who" array */
5507 C_KILL(who, max_r_idx, s16b);
5510 /* Display the file contents */
5511 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5513 /* Remove the file */
5519 * Display weapon-exp
5521 static void do_cmd_knowledge_weapon_exp(void)
5523 int i, num, weapon_exp;
5528 GAME_TEXT file_name[1024];
5531 /* Open a new file */
5532 fff = my_fopen_temp(file_name, 1024);
5534 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5539 for (i = 0; i < 5; i++)
5541 for (num = 0; num < 64; num++)
5543 for (j = 0; j < max_k_idx; j++)
5545 object_kind *k_ptr = &k_info[j];
5547 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5549 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5551 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5553 fprintf(fff, "%-25s ", tmp);
5554 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5555 else fprintf(fff, " ");
5556 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5557 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5566 /* Display the file contents */
5567 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5569 /* Remove the file */
5575 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5579 static void do_cmd_knowledge_spell_exp(void)
5582 int spell_exp, exp_level;
5585 const magic_type *s_ptr;
5587 GAME_TEXT file_name[1024];
5589 /* Open a new file */
5590 fff = my_fopen_temp(file_name, 1024);
5592 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5597 if (p_ptr->realm1 != REALM_NONE)
5599 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5600 for (i = 0; i < 32; i++)
5602 if (!is_magic(p_ptr->realm1))
5604 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5608 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5610 if (s_ptr->slevel >= 99) continue;
5611 spell_exp = p_ptr->spell_exp[i];
5612 exp_level = spell_exp_level(spell_exp);
5613 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5614 if (p_ptr->realm1 == REALM_HISSATSU)
5615 fprintf(fff, "[--]");
5618 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5619 else fprintf(fff, " ");
5620 fprintf(fff, "%s", exp_level_str[exp_level]);
5622 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5627 if (p_ptr->realm2 != REALM_NONE)
5629 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5630 for (i = 0; i < 32; i++)
5632 if (!is_magic(p_ptr->realm1))
5634 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5638 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5640 if (s_ptr->slevel >= 99) continue;
5642 spell_exp = p_ptr->spell_exp[i + 32];
5643 exp_level = spell_exp_level(spell_exp);
5644 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5645 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5646 else fprintf(fff, " ");
5647 fprintf(fff, "%s", exp_level_str[exp_level]);
5648 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5654 /* Display the file contents */
5655 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5657 /* Remove the file */
5663 * @brief スキル情報を表示するコマンドのメインルーチン /
5667 static void do_cmd_knowledge_skill_exp(void)
5669 int i = 0, skill_exp;
5673 GAME_TEXT file_name[1024];
5674 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5675 _("二刀流 ", "Dual Wielding "),
5676 _("乗馬 ", "Riding ")};
5678 /* Open a new file */
5679 fff = my_fopen_temp(file_name, 1024);
5681 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5686 for (i = 0; i < 3; i++)
5688 skill_exp = p_ptr->skill_exp[i];
5689 fprintf(fff, "%-20s ", skill_name[i]);
5690 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5691 else fprintf(fff, " ");
5692 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5693 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5698 /* Display the file contents */
5699 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5701 /* Remove the file */
5707 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5708 * @param Name 変換したい文字列の参照ポインタ
5711 void plural_aux(char *Name)
5713 int NameLen = strlen(Name);
5715 if (my_strstr(Name, "Disembodied hand"))
5717 strcpy(Name, "Disembodied hands that strangled people");
5719 else if (my_strstr(Name, "Colour out of space"))
5721 strcpy(Name, "Colours out of space");
5723 else if (my_strstr(Name, "stairway to hell"))
5725 strcpy(Name, "stairways to hell");
5727 else if (my_strstr(Name, "Dweller on the threshold"))
5729 strcpy(Name, "Dwellers on the threshold");
5731 else if (my_strstr(Name, " of "))
5733 cptr aider = my_strstr(Name, " of ");
5744 if (dummy[i-1] == 's')
5746 strcpy(&(dummy[i]), "es");
5751 strcpy(&(dummy[i]), "s");
5754 strcpy(&(dummy[i+1]), aider);
5755 strcpy(Name, dummy);
5757 else if (my_strstr(Name, "coins"))
5760 strcpy(dummy, "piles of ");
5761 strcat(dummy, Name);
5762 strcpy(Name, dummy);
5765 else if (my_strstr(Name, "Manes"))
5769 else if (streq(&(Name[NameLen - 2]), "ey"))
5771 strcpy(&(Name[NameLen - 2]), "eys");
5773 else if (Name[NameLen - 1] == 'y')
5775 strcpy(&(Name[NameLen - 1]), "ies");
5777 else if (streq(&(Name[NameLen - 4]), "ouse"))
5779 strcpy(&(Name[NameLen - 4]), "ice");
5781 else if (streq(&(Name[NameLen - 2]), "us"))
5783 strcpy(&(Name[NameLen - 2]), "i");
5785 else if (streq(&(Name[NameLen - 6]), "kelman"))
5787 strcpy(&(Name[NameLen - 6]), "kelmen");
5789 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5791 strcpy(&(Name[NameLen - 8]), "wordsmen");
5793 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5795 strcpy(&(Name[NameLen - 7]), "oodsmen");
5797 else if (streq(&(Name[NameLen - 7]), "eastman"))
5799 strcpy(&(Name[NameLen - 7]), "eastmen");
5801 else if (streq(&(Name[NameLen - 8]), "izardman"))
5803 strcpy(&(Name[NameLen - 8]), "izardmen");
5805 else if (streq(&(Name[NameLen - 5]), "geist"))
5807 strcpy(&(Name[NameLen - 5]), "geister");
5809 else if (streq(&(Name[NameLen - 2]), "ex"))
5811 strcpy(&(Name[NameLen - 2]), "ices");
5813 else if (streq(&(Name[NameLen - 2]), "lf"))
5815 strcpy(&(Name[NameLen - 2]), "lves");
5817 else if (suffix(Name, "ch") ||
5818 suffix(Name, "sh") ||
5819 suffix(Name, "nx") ||
5820 suffix(Name, "s") ||
5823 strcpy(&(Name[NameLen]), "es");
5827 strcpy(&(Name[NameLen]), "s");
5832 * @brief 現在のペットを表示するコマンドのメインルーチン /
5833 * Display current pets
5836 static void do_cmd_knowledge_pets(void)
5840 monster_type *m_ptr;
5841 GAME_TEXT pet_name[MAX_NLEN];
5843 int show_upkeep = 0;
5844 GAME_TEXT file_name[1024];
5847 /* Open a new file */
5848 fff = my_fopen_temp(file_name, 1024);
5850 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5855 /* Process the monsters (backwards) */
5856 for (i = m_max - 1; i >= 1; i--)
5858 /* Access the monster */
5861 /* Ignore "dead" monsters */
5862 if (!m_ptr->r_idx) continue;
5864 /* Calculate "upkeep" for pets */
5868 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5869 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5873 show_upkeep = calculate_upkeep();
5875 fprintf(fff, "----------------------------------------------\n");
5877 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5878 fprintf(fff, " 維持コスト: %d%% MP\n", show_upkeep);
5880 fprintf(fff, " Total: %d pet%s.\n",
5881 t_friends, (t_friends == 1 ? "" : "s"));
5882 fprintf(fff, " Upkeep: %d%% mana.\n", show_upkeep);
5888 /* Display the file contents */
5889 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5891 /* Remove the file */
5897 * @brief 現在のペットを表示するコマンドのメインルーチン /
5900 * @note the player ghosts are ignored.
5902 static void do_cmd_knowledge_kill_count(void)
5911 GAME_TEXT file_name[1024];
5916 /* Open a new file */
5917 fff = my_fopen_temp(file_name, 1024);
5920 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5925 /* Allocate the "who" array */
5926 C_MAKE(who, max_r_idx, s16b);
5929 /* Monsters slain */
5932 for (kk = 1; kk < max_r_idx; kk++)
5934 monster_race *r_ptr = &r_info[kk];
5936 if (r_ptr->flags1 & (RF1_UNIQUE))
5938 bool dead = (r_ptr->max_num == 0);
5947 MONSTER_NUMBER This = r_ptr->r_pkills;
5957 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5960 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5962 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5968 /* Scan the monsters */
5969 for (i = 1; i < max_r_idx; i++)
5971 monster_race *r_ptr = &r_info[i];
5973 /* Use that monster */
5974 if (r_ptr->name) who[n++] = i;
5977 /* Select the sort method */
5978 ang_sort_comp = ang_sort_comp_hook;
5979 ang_sort_swap = ang_sort_swap_hook;
5981 /* Sort the array by dungeon depth of monsters */
5982 ang_sort(who, &why, n);
5984 /* Scan the monster races */
5985 for (k = 0; k < n; k++)
5987 monster_race *r_ptr = &r_info[who[k]];
5989 if (r_ptr->flags1 & (RF1_UNIQUE))
5991 bool dead = (r_ptr->max_num == 0);
5995 fprintf(fff, " %s\n", (r_name + r_ptr->name));
6001 MONSTER_NUMBER This = r_ptr->r_pkills;
6006 /* p,tは人と数える by ita */
6007 if (my_strchr("pt", r_ptr->d_char))
6008 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
6010 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6014 if (my_strstr(r_name + r_ptr->name, "coins"))
6016 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6020 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6026 strcpy(ToPlural, (r_name + r_ptr->name));
6027 plural_aux(ToPlural);
6028 fprintf(fff, " %d %s\n", This, ToPlural);
6038 fprintf(fff,"----------------------------------------------\n");
6040 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6042 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6046 /* Free the "who" array */
6047 C_KILL(who, max_r_idx, s16b);
6050 /* Display the file contents */
6051 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6053 /* Remove the file */
6059 * @brief モンスター情報リスト中のグループを表示する /
6060 * Display the object groups.
6064 * @param per_page リストの表示行
6065 * @param grp_idx グループのID配列
6066 * @param group_text グループ名の文字列配列
6067 * @param grp_cur 現在の選択ID
6068 * @param grp_top 現在の選択リスト最上部ID
6071 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)
6075 /* Display lines until done */
6076 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6078 /* Get the group index */
6079 int grp = grp_idx[grp_top + i];
6081 /* Choose a color */
6082 byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6084 /* Erase the entire line */
6085 Term_erase(col, row + i, wid);
6087 /* Display the group label */
6088 c_put_str(attr, group_text[grp], row + i, col);
6094 * Move the cursor in a browser window
6096 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6097 IDX *list_cur, int list_cnt)
6102 IDX list = *list_cur;
6104 /* Extract direction */
6107 /* Hack -- scroll up full screen */
6112 /* Hack -- scroll down full screen */
6117 d = get_keymap_dir(ch);
6122 /* Diagonals - hack */
6123 if ((ddx[d] > 0) && ddy[d])
6128 Term_get_size(&wid, &hgt);
6130 browser_rows = hgt - 8;
6132 /* Browse group list */
6137 /* Move up or down */
6138 grp += ddy[d] * (browser_rows - 1);
6141 if (grp >= grp_cnt) grp = grp_cnt - 1;
6142 if (grp < 0) grp = 0;
6143 if (grp != old_grp) list = 0;
6146 /* Browse sub-list list */
6149 /* Move up or down */
6150 list += ddy[d] * browser_rows;
6153 if (list >= list_cnt) list = list_cnt - 1;
6154 if (list < 0) list = 0;
6166 if (col < 0) col = 0;
6167 if (col > 1) col = 1;
6174 /* Browse group list */
6179 /* Move up or down */
6183 if (grp >= grp_cnt) grp = grp_cnt - 1;
6184 if (grp < 0) grp = 0;
6185 if (grp != old_grp) list = 0;
6188 /* Browse sub-list list */
6191 /* Move up or down */
6195 if (list >= list_cnt) list = list_cnt - 1;
6196 if (list < 0) list = 0;
6207 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6211 /* Clear the display lines */
6212 for (i = 0; i < height; i++)
6214 Term_erase(col, row + i, width);
6217 /* Bigtile mode uses double width */
6218 if (use_bigtile) width /= 2;
6220 /* Display lines until done */
6221 for (i = 0; i < height; i++)
6223 /* Display columns until done */
6224 for (j = 0; j < width; j++)
6228 TERM_LEN x = col + j;
6229 TERM_LEN y = row + i;
6232 /* Bigtile mode uses double width */
6233 if (use_bigtile) x += j;
6238 /* Ignore illegal characters */
6239 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6240 (!use_graphics && ic > 0x7f))
6246 /* Force correct code for both ASCII character and tile */
6247 if (c & 0x80) a |= 0x80;
6249 /* Display symbol */
6250 Term_queue_bigchar(x, y, a, c, 0, 0);
6257 * Place the cursor at the collect position for visual mode
6259 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6261 int i = (a & 0x7f) - attr_top;
6262 int j = c - char_left;
6264 TERM_LEN x = col + j;
6265 TERM_LEN y = row + i;
6267 /* Bigtile mode uses double width */
6268 if (use_bigtile) x += j;
6270 /* Place the cursor */
6276 * Clipboard variables for copy&paste in visual mode
6278 static TERM_COLOR attr_idx = 0;
6279 static byte char_idx = 0;
6281 /* Hack -- for feature lighting */
6282 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6283 static byte char_idx_feat[F_LIT_MAX];
6286 * Do visual mode command -- Change symbols
6288 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6289 int height, int width,
6290 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6291 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6293 static TERM_COLOR attr_old = 0;
6294 static SYMBOL_CODE char_old = 0;
6299 if (*visual_list_ptr)
6302 *cur_attr_ptr = attr_old;
6303 *cur_char_ptr = char_old;
6304 *visual_list_ptr = FALSE;
6312 if (*visual_list_ptr)
6315 *visual_list_ptr = FALSE;
6316 *need_redraw = TRUE;
6324 if (!*visual_list_ptr)
6326 *visual_list_ptr = TRUE;
6328 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6329 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6331 attr_old = *cur_attr_ptr;
6332 char_old = *cur_char_ptr;
6343 /* Set the visual */
6344 attr_idx = *cur_attr_ptr;
6345 char_idx = *cur_char_ptr;
6347 /* Hack -- for feature lighting */
6348 for (i = 0; i < F_LIT_MAX; i++)
6350 attr_idx_feat[i] = 0;
6351 char_idx_feat[i] = 0;
6358 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6361 *cur_attr_ptr = attr_idx;
6362 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6363 if (!*visual_list_ptr) *need_redraw = TRUE;
6369 *cur_char_ptr = char_idx;
6370 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6371 if (!*visual_list_ptr) *need_redraw = TRUE;
6377 if (*visual_list_ptr)
6380 int d = get_keymap_dir(ch);
6381 byte a = (*cur_attr_ptr & 0x7f);
6382 byte c = *cur_char_ptr;
6384 if (use_bigtile) eff_width = width / 2;
6385 else eff_width = width;
6387 /* Restrict direction */
6388 if ((a == 0) && (ddy[d] < 0)) d = 0;
6389 if ((c == 0) && (ddx[d] < 0)) d = 0;
6390 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6391 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6396 /* Force correct code for both ASCII character and tile */
6397 if (c & 0x80) a |= 0x80;
6399 /* Set the visual */
6404 /* Move the frame */
6405 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6406 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6407 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6408 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6414 /* Visual mode command is not used */
6420 * Display the monsters in a group.
6422 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6423 int mon_cur, int mon_top, bool visual_only)
6427 /* Display lines until done */
6428 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6432 /* Get the race index */
6433 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6435 /* Access the race */
6436 monster_race *r_ptr = &r_info[r_idx];
6438 /* Choose a color */
6439 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6441 /* Display the name */
6442 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6444 /* Hack -- visual_list mode */
6447 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6449 if (p_ptr->wizard || visual_only)
6451 c_prt(attr, format("%d", r_idx), row + i, 62);
6454 /* Erase chars before overwritten by the race letter */
6455 Term_erase(69, row + i, 255);
6457 /* Display symbol */
6458 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6463 if (!(r_ptr->flags1 & RF1_UNIQUE))
6464 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6466 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6467 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6471 /* Clear remaining lines */
6472 for (; i < per_page; i++)
6474 Term_erase(col, row + i, 255);
6480 * Display known monsters.
6482 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6486 IDX grp_cur, grp_top, old_grp_cur;
6487 IDX mon_cur, mon_top;
6488 IDX grp_cnt, grp_idx[100];
6496 bool visual_list = FALSE;
6497 TERM_COLOR attr_top = 0;
6505 Term_get_size(&wid, &hgt);
6507 browser_rows = hgt - 8;
6509 /* Allocate the "mon_idx" array */
6510 C_MAKE(mon_idx, max_r_idx, s16b);
6515 if (direct_r_idx < 0)
6517 mode = visual_only ? 0x03 : 0x01;
6519 /* Check every group */
6520 for (i = 0; monster_group_text[i] != NULL; i++)
6522 /* Measure the label */
6523 len = strlen(monster_group_text[i]);
6525 /* Save the maximum length */
6526 if (len > max) max = len;
6528 /* See if any monsters are known */
6529 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6531 /* Build a list of groups with known monsters */
6532 grp_idx[grp_cnt++] = i;
6540 mon_idx[0] = direct_r_idx;
6543 /* Terminate the list */
6546 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6547 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6550 /* Terminate the list */
6551 grp_idx[grp_cnt] = -1;
6554 grp_cur = grp_top = 0;
6555 mon_cur = mon_top = 0;
6560 mode = visual_only ? 0x02 : 0x00;
6565 monster_race *r_ptr;
6572 prt(format("%s - モンスター", !visual_only ? "知識" : "表示"), 2, 0);
6573 if (direct_r_idx < 0) prt("グループ", 4, 0);
6574 prt("名前", 4, max + 3);
6575 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6577 if (!visual_only) prt("殺害数", 4, 72);
6579 prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6580 if (direct_r_idx < 0) prt("Group", 4, 0);
6581 prt("Name", 4, max + 3);
6582 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6584 if (!visual_only) prt("Kills", 4, 73);
6587 for (i = 0; i < 78; i++)
6589 Term_putch(i, 5, TERM_WHITE, '=');
6592 if (direct_r_idx < 0)
6594 for (i = 0; i < browser_rows; i++)
6596 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6603 if (direct_r_idx < 0)
6605 /* Scroll group list */
6606 if (grp_cur < grp_top) grp_top = grp_cur;
6607 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6609 /* Display a list of monster groups */
6610 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6612 if (old_grp_cur != grp_cur)
6614 old_grp_cur = grp_cur;
6616 /* Get a list of monsters in the current group */
6617 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6620 /* Scroll monster list */
6621 while (mon_cur < mon_top)
6622 mon_top = MAX(0, mon_top - browser_rows/2);
6623 while (mon_cur >= mon_top + browser_rows)
6624 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6629 /* Display a list of monsters in the current group */
6630 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6636 /* Display a monster name */
6637 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6639 /* Display visual list below first monster */
6640 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6645 prt(format("<方向>%s%s%s, ESC",
6646 (!visual_list && !visual_only) ? ", 'r'で思い出を見る" : "",
6647 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6648 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6651 prt(format("<dir>%s%s%s, ESC",
6652 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6653 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6654 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6658 /* Get the current monster */
6659 r_ptr = &r_info[mon_idx[mon_cur]];
6663 /* Mega Hack -- track this monster race */
6664 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6670 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6674 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6678 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6683 /* Do visual mode command if needed */
6684 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))
6686 if (direct_r_idx >= 0)
6711 /* Recall on screen */
6712 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6714 screen_roff(mon_idx[mon_cur], 0);
6725 /* Move the cursor */
6726 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6733 /* Free the "mon_idx" array */
6734 C_KILL(mon_idx, max_r_idx, s16b);
6739 * Display the objects in a group.
6741 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6742 int object_cur, int object_top, bool visual_only)
6746 /* Display lines until done */
6747 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6749 GAME_TEXT o_name[MAX_NLEN];
6752 object_kind *flavor_k_ptr;
6754 /* Get the object index */
6755 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6757 /* Access the object */
6758 object_kind *k_ptr = &k_info[k_idx];
6760 /* Choose a color */
6761 byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6762 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6765 if (!visual_only && k_ptr->flavor)
6767 /* Appearance of this object is shuffled */
6768 flavor_k_ptr = &k_info[k_ptr->flavor];
6772 /* Appearance of this object is very normal */
6773 flavor_k_ptr = k_ptr;
6778 attr = ((i + object_top == object_cur) ? cursor : attr);
6780 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6783 strip_name(o_name, k_idx);
6788 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6791 /* Display the name */
6792 c_prt(attr, o_name, row + i, col);
6794 /* Hack -- visual_list mode */
6797 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);
6799 if (p_ptr->wizard || visual_only)
6801 c_prt(attr, format("%d", k_idx), row + i, 70);
6804 a = flavor_k_ptr->x_attr;
6805 c = flavor_k_ptr->x_char;
6807 /* Display symbol */
6808 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6811 /* Clear remaining lines */
6812 for (; i < per_page; i++)
6814 Term_erase(col, row + i, 255);
6819 * Describe fake object
6821 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6824 object_type object_type_body;
6825 o_ptr = &object_type_body;
6828 /* Create the artifact */
6829 object_prep(o_ptr, k_idx);
6831 /* It's fully know */
6832 o_ptr->ident |= IDENT_KNOWN;
6834 /* Track the object */
6835 /* object_actual_track(o_ptr); */
6837 /* Hack - mark as fake */
6838 /* term_obj_real = FALSE; */
6841 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6843 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6851 * Display known objects
6853 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6857 IDX grp_cur, grp_top, old_grp_cur;
6858 IDX object_old, object_cur, object_top;
6868 bool visual_list = FALSE;
6869 TERM_COLOR attr_top = 0;
6877 Term_get_size(&wid, &hgt);
6879 browser_rows = hgt - 8;
6881 /* Allocate the "object_idx" array */
6882 C_MAKE(object_idx, max_k_idx, IDX);
6887 if (direct_k_idx < 0)
6889 mode = visual_only ? 0x03 : 0x01;
6891 /* Check every group */
6892 for (i = 0; object_group_text[i] != NULL; i++)
6894 /* Measure the label */
6895 len = strlen(object_group_text[i]);
6897 /* Save the maximum length */
6898 if (len > max) max = len;
6900 /* See if any monsters are known */
6901 if (collect_objects(i, object_idx, mode))
6903 /* Build a list of groups with known monsters */
6904 grp_idx[grp_cnt++] = i;
6913 object_kind *k_ptr = &k_info[direct_k_idx];
6914 object_kind *flavor_k_ptr;
6916 if (!visual_only && k_ptr->flavor)
6918 /* Appearance of this object is shuffled */
6919 flavor_k_ptr = &k_info[k_ptr->flavor];
6923 /* Appearance of this object is very normal */
6924 flavor_k_ptr = k_ptr;
6927 object_idx[0] = direct_k_idx;
6928 object_old = direct_k_idx;
6931 /* Terminate the list */
6934 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6935 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6938 /* Terminate the list */
6939 grp_idx[grp_cnt] = -1;
6942 grp_cur = grp_top = 0;
6943 object_cur = object_top = 0;
6948 mode = visual_only ? 0x02 : 0x00;
6953 object_kind *k_ptr, *flavor_k_ptr;
6960 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6961 if (direct_k_idx < 0) prt("グループ", 4, 0);
6962 prt("名前", 4, max + 3);
6963 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6966 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6967 if (direct_k_idx < 0) prt("Group", 4, 0);
6968 prt("Name", 4, max + 3);
6969 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6973 for (i = 0; i < 78; i++)
6975 Term_putch(i, 5, TERM_WHITE, '=');
6978 if (direct_k_idx < 0)
6980 for (i = 0; i < browser_rows; i++)
6982 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6989 if (direct_k_idx < 0)
6991 /* Scroll group list */
6992 if (grp_cur < grp_top) grp_top = grp_cur;
6993 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6995 /* Display a list of object groups */
6996 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6998 if (old_grp_cur != grp_cur)
7000 old_grp_cur = grp_cur;
7002 /* Get a list of objects in the current group */
7003 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
7006 /* Scroll object list */
7007 while (object_cur < object_top)
7008 object_top = MAX(0, object_top - browser_rows/2);
7009 while (object_cur >= object_top + browser_rows)
7010 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
7015 /* Display a list of objects in the current group */
7016 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
7020 object_top = object_cur;
7022 /* Display a list of objects in the current group */
7023 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
7025 /* Display visual list below first object */
7026 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7029 /* Get the current object */
7030 k_ptr = &k_info[object_idx[object_cur]];
7032 if (!visual_only && k_ptr->flavor)
7034 /* Appearance of this object is shuffled */
7035 flavor_k_ptr = &k_info[k_ptr->flavor];
7039 /* Appearance of this object is very normal */
7040 flavor_k_ptr = k_ptr;
7045 prt(format("<方向>%s%s%s, ESC",
7046 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7047 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7048 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7051 prt(format("<dir>%s%s%s, ESC",
7052 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7053 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7054 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7060 /* Mega Hack -- track this object */
7061 if (object_cnt) object_kind_track(object_idx[object_cur]);
7063 /* The "current" object changed */
7064 if (object_old != object_idx[object_cur])
7068 /* Remember the "current" object */
7069 object_old = object_idx[object_cur];
7075 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7079 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7083 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7088 /* Do visual mode command if needed */
7089 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))
7091 if (direct_k_idx >= 0)
7116 /* Recall on screen */
7117 if (!visual_list && !visual_only && (grp_cnt > 0))
7119 desc_obj_fake(object_idx[object_cur]);
7127 /* Move the cursor */
7128 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7134 /* Free the "object_idx" array */
7135 C_KILL(object_idx, max_k_idx, IDX);
7140 * Display the features in a group.
7142 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7143 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7145 int lit_col[F_LIT_MAX], i, j;
7146 int f_idx_col = use_bigtile ? 62 : 64;
7148 /* Correct columns 1 and 4 */
7149 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7150 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7151 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7153 /* Display lines until done */
7154 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7159 FEAT_IDX f_idx = feat_idx[feat_top + i];
7161 /* Access the index */
7162 feature_type *f_ptr = &f_info[f_idx];
7164 int row_i = row + i;
7166 /* Choose a color */
7167 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7169 /* Display the name */
7170 c_prt(attr, f_name + f_ptr->name, row_i, col);
7172 /* Hack -- visual_list mode */
7175 /* Display lighting level */
7176 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7178 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));
7180 if (p_ptr->wizard || visual_only)
7182 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7185 /* Display symbol */
7186 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);
7188 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7189 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7191 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7193 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7195 /* Mega-hack -- Use non-standard colour */
7196 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7198 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7202 /* Clear remaining lines */
7203 for (; i < per_page; i++)
7205 Term_erase(col, row + i, 255);
7211 * Interact with feature visuals.
7213 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7217 IDX grp_cur, grp_top, old_grp_cur;
7218 IDX feat_cur, feat_top;
7228 bool visual_list = FALSE;
7229 TERM_COLOR attr_top = 0;
7235 TERM_COLOR attr_old[F_LIT_MAX];
7236 SYMBOL_CODE char_old[F_LIT_MAX];
7237 TERM_COLOR *cur_attr_ptr;
7238 SYMBOL_CODE *cur_char_ptr;
7240 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7241 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7243 Term_get_size(&wid, &hgt);
7245 browser_rows = hgt - 8;
7247 /* Allocate the "feat_idx" array */
7248 C_MAKE(feat_idx, max_f_idx, IDX);
7253 if (direct_f_idx < 0)
7255 /* Check every group */
7256 for (i = 0; feature_group_text[i] != NULL; i++)
7258 /* Measure the label */
7259 len = strlen(feature_group_text[i]);
7261 /* Save the maximum length */
7262 if (len > max) max = len;
7264 /* See if any features are known */
7265 if (collect_features(i, feat_idx, 0x01))
7267 /* Build a list of groups with known features */
7268 grp_idx[grp_cnt++] = i;
7276 feature_type *f_ptr = &f_info[direct_f_idx];
7278 feat_idx[0] = direct_f_idx;
7281 /* Terminate the list */
7284 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7285 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7287 for (i = 0; i < F_LIT_MAX; i++)
7289 attr_old[i] = f_ptr->x_attr[i];
7290 char_old[i] = f_ptr->x_char[i];
7294 /* Terminate the list */
7295 grp_idx[grp_cnt] = -1;
7298 grp_cur = grp_top = 0;
7299 feat_cur = feat_top = 0;
7307 feature_type *f_ptr;
7314 prt("表示 - 地形", 2, 0);
7315 if (direct_f_idx < 0) prt("グループ", 4, 0);
7316 prt("名前", 4, max + 3);
7319 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7320 prt("文字 ( l/ d)", 4, 66);
7324 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7325 prt("文字 (l/d)", 4, 68);
7328 prt("Visuals - features", 2, 0);
7329 if (direct_f_idx < 0) prt("Group", 4, 0);
7330 prt("Name", 4, max + 3);
7333 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7334 prt("Sym ( l/ d)", 4, 67);
7338 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7339 prt("Sym (l/d)", 4, 69);
7343 for (i = 0; i < 78; i++)
7345 Term_putch(i, 5, TERM_WHITE, '=');
7348 if (direct_f_idx < 0)
7350 for (i = 0; i < browser_rows; i++)
7352 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7359 if (direct_f_idx < 0)
7361 /* Scroll group list */
7362 if (grp_cur < grp_top) grp_top = grp_cur;
7363 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7365 /* Display a list of feature groups */
7366 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7368 if (old_grp_cur != grp_cur)
7370 old_grp_cur = grp_cur;
7372 /* Get a list of features in the current group */
7373 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7376 /* Scroll feature list */
7377 while (feat_cur < feat_top)
7378 feat_top = MAX(0, feat_top - browser_rows/2);
7379 while (feat_cur >= feat_top + browser_rows)
7380 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7385 /* Display a list of features in the current group */
7386 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7390 feat_top = feat_cur;
7392 /* Display a list of features in the current group */
7393 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7395 /* Display visual list below first object */
7396 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7401 prt(format("<方向>%s, 'd'で標準光源効果%s, ESC",
7402 visual_list ? ", ENTERで決定, 'a'で対象明度変更" : ", 'v'でシンボル変更",
7403 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7406 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
7407 visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
7408 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7412 /* Get the current feature */
7413 f_ptr = &f_info[feat_idx[feat_cur]];
7414 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7415 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7419 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7423 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7427 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7432 if (visual_list && ((ch == 'A') || (ch == 'a')))
7434 int prev_lighting_level = *lighting_level;
7438 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7439 else (*lighting_level)--;
7443 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7444 else (*lighting_level)++;
7447 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7448 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7450 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7451 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7456 else if ((ch == 'D') || (ch == 'd'))
7458 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7459 byte prev_x_char = f_ptr->x_char[*lighting_level];
7461 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7465 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7466 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7468 if (prev_x_char != f_ptr->x_char[*lighting_level])
7469 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7471 else *need_redraw = TRUE;
7476 /* Do visual mode command if needed */
7477 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))
7481 /* Restore previous visual settings */
7483 for (i = 0; i < F_LIT_MAX; i++)
7485 f_ptr->x_attr[i] = attr_old[i];
7486 f_ptr->x_char[i] = char_old[i];
7493 if (direct_f_idx >= 0) flag = TRUE;
7494 else *lighting_level = F_LIT_STANDARD;
7497 /* Preserve current visual settings */
7500 for (i = 0; i < F_LIT_MAX; i++)
7502 attr_old[i] = f_ptr->x_attr[i];
7503 char_old[i] = f_ptr->x_char[i];
7505 *lighting_level = F_LIT_STANDARD;
7512 for (i = 0; i < F_LIT_MAX; i++)
7514 attr_idx_feat[i] = f_ptr->x_attr[i];
7515 char_idx_feat[i] = f_ptr->x_char[i];
7524 /* Allow TERM_DARK text */
7525 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7527 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7528 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7546 /* Move the cursor */
7547 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7553 /* Free the "feat_idx" array */
7554 C_KILL(feat_idx, max_f_idx, IDX);
7559 * List wanted monsters
7561 static void do_cmd_knowledge_kubi(void)
7566 GAME_TEXT file_name[1024];
7569 /* Open a new file */
7570 fff = my_fopen_temp(file_name, 1024);
7572 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7579 bool listed = FALSE;
7582 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7584 fprintf(fff, "賞金首リスト\n");
7586 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7588 fprintf(fff, "List of wanted monsters\n");
7590 fprintf(fff, "----------------------------------------------\n");
7592 for (i = 0; i < MAX_KUBI; i++)
7594 if (kubi_r_idx[i] <= 10000)
7596 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7604 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7609 /* Display the file contents */
7610 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7612 /* Remove the file */
7617 * List virtues & status
7619 static void do_cmd_knowledge_virtues(void)
7622 GAME_TEXT file_name[1024];
7624 /* Open a new file */
7625 fff = my_fopen_temp(file_name, 1024);
7627 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7634 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7639 /* Display the file contents */
7640 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7642 /* Remove the file */
7650 static void do_cmd_knowledge_dungeon(void)
7654 GAME_TEXT file_name[1024];
7657 /* Open a new file */
7658 fff = my_fopen_temp(file_name, 1024);
7660 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7667 for (i = 1; i < max_d_idx; i++)
7671 if (!d_info[i].maxdepth) continue;
7672 if (!max_dlv[i]) continue;
7673 if (d_info[i].final_guardian)
7675 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7677 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7679 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7684 /* Display the file contents */
7685 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7687 /* Remove the file */
7692 * List virtues & status
7695 static void do_cmd_knowledge_stat(void)
7699 GAME_TEXT file_name[1024];
7702 /* Open a new file */
7703 fff = my_fopen_temp(file_name, 1024);
7705 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7712 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7713 (2 * p_ptr->hitdie +
7714 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7717 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7718 else fprintf(fff, "現在の体力ランク : ???\n\n");
7719 fprintf(fff, "能力の最大値\n\n");
7721 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7722 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7723 fprintf(fff, "Limits of maximum stats\n\n");
7725 for (v_nr = 0; v_nr < 6; v_nr++)
7727 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);
7728 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7735 /* Display the file contents */
7736 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7738 /* Remove the file */
7744 * Print all active quests
7746 static void do_cmd_knowledge_quests_current(FILE *fff)
7749 char rand_tmp_str[120] = "\0";
7750 char name[MAX_NLEN];
7751 monster_race *r_ptr;
7753 int rand_level = 100;
7756 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7758 for (i = 1; i < max_q_idx; i++)
7760 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7761 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7762 (quest[i].status == QUEST_STATUS_COMPLETED))
7764 /* Set the quest number temporary */
7765 IDX old_quest = p_ptr->inside_quest;
7768 /* Clear the text */
7769 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7770 quest_text_line = 0;
7772 p_ptr->inside_quest = i;
7774 /* Get the quest text */
7775 init_flags = INIT_SHOW_TEXT;
7777 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7779 /* Reset the old quest number */
7780 p_ptr->inside_quest = old_quest;
7782 /* No info from "silent" quests */
7783 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7787 if (quest[i].type != QUEST_TYPE_RANDOM)
7789 char note[80] = "\0";
7791 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7793 switch (quest[i].type)
7795 case QUEST_TYPE_KILL_LEVEL:
7796 case QUEST_TYPE_KILL_ANY_LEVEL:
7797 r_ptr = &r_info[quest[i].r_idx];
7798 strcpy(name, r_name + r_ptr->name);
7799 if (quest[i].max_num > 1)
7802 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7803 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7806 sprintf(note," - kill %d %s, have killed %d.",
7807 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7811 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7814 case QUEST_TYPE_FIND_ARTIFACT:
7817 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7819 object_type *q_ptr = &forge;
7820 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7821 object_prep(q_ptr, k_idx);
7822 q_ptr->name1 = quest[i].k_idx;
7823 q_ptr->ident = IDENT_STORE;
7824 object_desc(name, q_ptr, OD_NAME_ONLY);
7826 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7828 case QUEST_TYPE_FIND_EXIT:
7829 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7832 case QUEST_TYPE_KILL_NUMBER:
7834 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7835 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7837 sprintf(note," - Kill %d monsters, have killed %d.",
7838 (int)quest[i].max_num, (int)quest[i].cur_num);
7842 case QUEST_TYPE_KILL_ALL:
7843 case QUEST_TYPE_TOWER:
7844 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7849 /* Print the quest info */
7850 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7851 quest[i].name, (int)quest[i].level, note);
7853 fputs(tmp_str, fff);
7855 if (quest[i].status == QUEST_STATUS_COMPLETED)
7857 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7858 fputs(tmp_str, fff);
7864 while (quest_text[j][0] && j < 10)
7866 fprintf(fff, " %s\n", quest_text[j]);
7871 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7874 rand_level = quest[i].level;
7876 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7878 /* Print the quest info */
7879 r_ptr = &r_info[quest[i].r_idx];
7880 strcpy(name, r_name + r_ptr->name);
7882 if (quest[i].max_num > 1)
7885 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7886 quest[i].name, (int)quest[i].level,
7887 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7891 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7892 quest[i].name, (int)quest[i].level,
7893 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7898 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7899 quest[i].name, (int)quest[i].level, name);
7906 /* Print the current random quest */
7907 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7909 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7913 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7916 char playtime_str[16];
7917 quest_type* const q_ptr = &quest[q_idx];
7919 if (is_fixed_quest_idx(q_idx))
7921 /* Set the quest number temporary */
7922 IDX old_quest = p_ptr->inside_quest;
7924 p_ptr->inside_quest = q_idx;
7927 init_flags = INIT_NAME_ONLY;
7929 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7931 /* Reset the old quest number */
7932 p_ptr->inside_quest = old_quest;
7934 /* No info from "silent" quests */
7935 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7938 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7939 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7941 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7943 /* Print the quest info */
7944 if (q_ptr->complev == 0)
7947 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7948 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7949 r_name+r_info[q_ptr->r_idx].name,
7950 (int)q_ptr->level, playtime_str);
7955 _(" %-35s (%3d階) - レベル%2d - %s\n",
7956 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7957 r_name+r_info[q_ptr->r_idx].name,
7965 /* Print the quest info */
7967 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7968 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7969 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7972 fputs(tmp_str, fff);
7978 * Print all finished quests
7980 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7985 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7986 for (i = 1; i < max_q_idx; i++)
7988 IDX q_idx = quest_num[i];
7989 quest_type* const q_ptr = &quest[q_idx];
7991 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7992 do_cmd_knowledge_quests_aux(fff, q_idx))
7997 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8002 * Print all failed quests
8004 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
8009 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
8010 for (i = 1; i < max_q_idx; i++)
8012 IDX q_idx = quest_num[i];
8013 quest_type* const q_ptr = &quest[q_idx];
8015 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
8016 do_cmd_knowledge_quests_aux(fff, q_idx))
8021 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8026 * Print all random quests
8028 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
8034 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
8035 for (i = 1; i < max_q_idx; i++)
8037 /* No info from "silent" quests */
8038 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8040 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
8044 /* Print the quest info */
8045 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
8046 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
8047 fputs(tmp_str, fff);
8050 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8054 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8056 QUEST_IDX *q_num = (QUEST_IDX *)u;
8057 quest_type *qa = &quest[q_num[a]];
8058 quest_type *qb = &quest[q_num[b]];
8063 return (qa->comptime != qb->comptime) ?
8064 (qa->comptime < qb->comptime) :
8065 (qa->level <= qb->level);
8068 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8070 QUEST_IDX *q_num = (QUEST_IDX *)u;
8077 q_num[a] = q_num[b];
8083 * Print quest status of all active quests
8085 static void do_cmd_knowledge_quests(void)
8088 GAME_TEXT file_name[1024];
8093 /* Open a new file */
8094 fff = my_fopen_temp(file_name, 1024);
8097 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8102 /* Allocate Memory */
8103 C_MAKE(quest_num, max_q_idx, IDX);
8105 /* Sort by compete level */
8106 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8107 ang_sort_comp = ang_sort_comp_quest_num;
8108 ang_sort_swap = ang_sort_swap_quest_num;
8109 ang_sort(quest_num, &dummy, max_q_idx);
8111 /* Dump Quest Information */
8112 do_cmd_knowledge_quests_current(fff);
8114 do_cmd_knowledge_quests_completed(fff, quest_num);
8116 do_cmd_knowledge_quests_failed(fff, quest_num);
8120 do_cmd_knowledge_quests_wiz_random(fff);
8124 /* Display the file contents */
8125 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8127 /* Remove the file */
8131 C_KILL(quest_num, max_q_idx, IDX);
8138 static void do_cmd_knowledge_home(void)
8143 GAME_TEXT file_name[1024];
8145 GAME_TEXT o_name[MAX_NLEN];
8148 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8150 /* Open a new file */
8151 fff = my_fopen_temp(file_name, 1024);
8153 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8160 /* Print all homes in the different towns */
8161 st_ptr = &town[1].store[STORE_HOME];
8163 /* Home -- if anything there */
8164 if (st_ptr->stock_num)
8169 /* Header with name of the town */
8170 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8172 /* Dump all available items */
8173 for (i = 0; i < st_ptr->stock_num; i++)
8176 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8177 object_desc(o_name, &st_ptr->stock[i], 0);
8178 if (strlen(o_name) <= 80-3)
8180 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8186 for (n = 0, t = o_name; n < 80-3; n++, t++)
8187 if(iskanji(*t)) {t++; n++;}
8188 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8190 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8191 fprintf(fff, " %.77s\n", o_name+n);
8194 object_desc(o_name, &st_ptr->stock[i], 0);
8195 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8200 /* Add an empty line */
8201 fprintf(fff, "\n\n");
8206 /* Display the file contents */
8207 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8209 /* Remove the file */
8215 * Check the status of "autopick"
8217 static void do_cmd_knowledge_autopick(void)
8221 GAME_TEXT file_name[1024];
8223 /* Open a new file */
8224 fff = my_fopen_temp(file_name, 1024);
8228 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8235 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8239 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8240 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8243 for (k = 0; k < max_autopick; k++)
8246 byte act = autopick_list[k].action;
8247 if (act & DONT_AUTOPICK)
8249 tmp = _("放置", "Leave");
8251 else if (act & DO_AUTODESTROY)
8253 tmp = _("破壊", "Destroy");
8255 else if (act & DO_AUTOPICK)
8257 tmp = _("拾う", "Pickup");
8261 tmp = _("確認", "Query");
8264 if (act & DO_DISPLAY)
8265 fprintf(fff, "%11s", format("[%s]", tmp));
8267 fprintf(fff, "%11s", format("(%s)", tmp));
8269 tmp = autopick_line_from_entry(&autopick_list[k]);
8270 fprintf(fff, " %s", tmp);
8275 /* Display the file contents */
8276 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8278 /* Remove the file */
8284 * Interact with "knowledge"
8286 void do_cmd_knowledge(void)
8289 bool need_redraw = FALSE;
8291 /* File type is "TEXT" */
8292 FILE_TYPE(FILE_TYPE_TEXT);
8295 /* Interact until done */
8300 /* Ask for a choice */
8301 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8302 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8304 /* Give some choices */
8308 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8309 prt("(2) 既知のアイテム の一覧", 7, 5);
8310 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8311 prt("(4) 既知のモンスター の一覧", 9, 5);
8312 prt("(5) 倒した敵の数 の一覧", 10, 5);
8313 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8314 prt("(7) 現在のペット の一覧", 12, 5);
8315 prt("(8) 我が家のアイテム の一覧", 13, 5);
8316 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8317 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8321 prt("(a) 自分に関する情報 の一覧", 6, 5);
8322 prt("(b) 突然変異 の一覧", 7, 5);
8323 prt("(c) 武器の経験値 の一覧", 8, 5);
8324 prt("(d) 魔法の経験値 の一覧", 9, 5);
8325 prt("(e) 技能の経験値 の一覧", 10, 5);
8326 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8327 prt("(g) 入ったダンジョン の一覧", 12, 5);
8328 prt("(h) 実行中のクエスト の一覧", 13, 5);
8329 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8334 prt("(1) Display known artifacts", 6, 5);
8335 prt("(2) Display known objects", 7, 5);
8336 prt("(3) Display remaining uniques", 8, 5);
8337 prt("(4) Display known monster", 9, 5);
8338 prt("(5) Display kill count", 10, 5);
8339 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8340 prt("(7) Display current pets", 12, 5);
8341 prt("(8) Display home inventory", 13, 5);
8342 prt("(9) Display *identified* equip.", 14, 5);
8343 prt("(0) Display terrain symbols.", 15, 5);
8347 prt("(a) Display about yourself", 6, 5);
8348 prt("(b) Display mutations", 7, 5);
8349 prt("(c) Display weapon proficiency", 8, 5);
8350 prt("(d) Display spell proficiency", 9, 5);
8351 prt("(e) Display misc. proficiency", 10, 5);
8352 prt("(f) Display virtues", 11, 5);
8353 prt("(g) Display dungeons", 12, 5);
8354 prt("(h) Display current quests", 13, 5);
8355 prt("(i) Display auto pick/destroy", 14, 5);
8359 prt(_("-続く-", "-more-"), 17, 8);
8360 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8361 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8362 /*prt("-) 前ページ", 21, 60);*/
8363 prt(_("コマンド:", "Command: "), 20, 0);
8366 if (i == ESCAPE) break;
8369 case ' ': /* Page change */
8373 case '1': /* Artifacts */
8374 do_cmd_knowledge_artifacts();
8376 case '2': /* Objects */
8377 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8379 case '3': /* Uniques */
8380 do_cmd_knowledge_uniques();
8382 case '4': /* Monsters */
8383 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8385 case '5': /* Kill count */
8386 do_cmd_knowledge_kill_count();
8388 case '6': /* wanted */
8389 if (!vanilla_town) do_cmd_knowledge_kubi();
8391 case '7': /* Pets */
8392 do_cmd_knowledge_pets();
8394 case '8': /* Home */
8395 do_cmd_knowledge_home();
8397 case '9': /* Resist list */
8398 do_cmd_knowledge_inven();
8400 case '0': /* Feature list */
8402 IDX lighting_level = F_LIT_STANDARD;
8403 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8407 case 'a': /* Max stat */
8408 do_cmd_knowledge_stat();
8410 case 'b': /* Mutations */
8411 do_cmd_knowledge_mutations();
8413 case 'c': /* weapon-exp */
8414 do_cmd_knowledge_weapon_exp();
8416 case 'd': /* spell-exp */
8417 do_cmd_knowledge_spell_exp();
8419 case 'e': /* skill-exp */
8420 do_cmd_knowledge_skill_exp();
8422 case 'f': /* Virtues */
8423 do_cmd_knowledge_virtues();
8425 case 'g': /* Dungeon */
8426 do_cmd_knowledge_dungeon();
8428 case 'h': /* Quests */
8429 do_cmd_knowledge_quests();
8431 case 'i': /* Autopick */
8432 do_cmd_knowledge_autopick();
8434 default: /* Unknown option */
8442 if (need_redraw) do_cmd_redraw();
8447 * Check on the status of an active quest
8449 void do_cmd_checkquest(void)
8451 /* File type is "TEXT" */
8452 FILE_TYPE(FILE_TYPE_TEXT);
8456 do_cmd_knowledge_quests();
8462 * Display the time and date
8464 void do_cmd_time(void)
8466 int day, hour, min, full, start, end, num;
8474 extract_day_hour_min(&day, &hour, &min);
8476 full = hour * 100 + min;
8483 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8485 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8486 else strcpy(day_buf, "*****");
8489 msg_format("%s日目, 時刻は%d:%02d %sです。",
8490 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8491 min, (hour < 12) ? "AM" : "PM");
8493 msg_format("This is day %s. The time is %d:%02d %s.",
8494 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8495 min, (hour < 12) ? "AM" : "PM");
8500 if (!randint0(10) || p_ptr->image)
8502 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8506 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8509 /* Open this file */
8510 fff = my_fopen(buf, "rt");
8514 /* Find this time */
8515 while (!my_fgets(fff, buf, sizeof(buf)))
8517 /* Ignore comments */
8518 if (!buf[0] || (buf[0] == '#')) continue;
8520 /* Ignore invalid lines */
8521 if (buf[1] != ':') continue;
8523 /* Process 'Start' */
8526 /* Extract the starting time */
8527 start = atoi(buf + 2);
8529 /* Assume valid for an hour */
8539 /* Extract the ending time */
8540 end = atoi(buf + 2);
8546 /* Ignore incorrect range */
8547 if ((start > full) || (full > end)) continue;
8549 /* Process 'Description' */
8554 /* Apply the randomizer */
8555 if (!randint0(num)) strcpy(desc, buf + 2);