3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
45 #include "player-status.h"
53 * Mark strings for auto dump
55 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
56 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
59 * Variables for auto dump
61 static FILE *auto_dump_stream;
62 static concptr auto_dump_mark;
63 static int auto_dump_line_num;
67 * @brief prf出力内容を消去する /
68 * Remove old lines automatically generated before.
69 * @param orig_file 消去を行うファイル名
71 static void remove_auto_dump(concptr orig_file)
73 FILE *tmp_fff, *orig_fff;
77 bool between_mark = FALSE;
80 long header_location = 0;
81 char header_mark_str[80];
82 char footer_mark_str[80];
85 /* Prepare a header/footer mark string */
86 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
87 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
89 mark_len = strlen(footer_mark_str);
91 /* Open an old dump file in read-only mode */
92 orig_fff = my_fopen(orig_file, "r");
94 /* If original file does not exist, nothing to do */
95 if (!orig_fff) return;
97 /* Open a new (temporary) file */
98 tmp_fff = my_fopen_temp(tmp_file, 1024);
102 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
107 /* Loop for every line */
111 if (my_fgets(orig_fff, buf, sizeof(buf)))
113 /* Read error: Assume End of File */
116 * Was looking for the footer, but not found.
118 * Since automatic dump might be edited by hand,
119 * it's dangerous to kill these lines.
120 * Seek back to the next line of the (pseudo) header,
125 fseek(orig_fff, header_location, SEEK_SET);
126 between_mark = FALSE;
130 /* Success -- End the loop */
137 /* We are looking for the header mark of automatic dump */
140 /* Is this line a header? */
141 if (!strcmp(buf, header_mark_str))
143 /* Memorise seek point of this line */
144 header_location = ftell(orig_fff);
146 /* Initialize counter for number of lines */
149 /* Look for the footer from now */
152 /* There are some changes */
159 /* Copy orginally lines */
160 fprintf(tmp_fff, "%s\n", buf);
164 /* We are looking for the footer mark of automatic dump */
167 /* Is this line a footer? */
168 if (!strncmp(buf, footer_mark_str, mark_len))
173 * Compare the number of lines
175 * If there is an inconsistency between
176 * actual number of lines and the
177 * number here, the automatic dump
178 * might be edited by hand. So it's
179 * dangerous to kill these lines.
180 * Seek back to the next line of the
181 * (pseudo) header, and read again.
183 if (!sscanf(buf + mark_len, " (%d)", &tmp)
186 fseek(orig_fff, header_location, SEEK_SET);
189 /* Look for another header */
190 between_mark = FALSE;
196 /* Ignore old line, and count number of lines */
206 /* If there are some changes, overwrite the original file with new one */
209 /* Copy contents of temporary file */
211 tmp_fff = my_fopen(tmp_file, "r");
212 orig_fff = my_fopen(orig_file, "w");
214 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
215 fprintf(orig_fff, "%s\n", buf);
221 /* Kill the temporary file */
229 * @brief prfファイルのフォーマットに従った内容を出力する /
230 * Dump a formatted line, using "vstrnfmt()".
233 static void auto_dump_printf(concptr fmt, ...)
240 /* Begin the Varargs Stuff */
243 /* Format the args, save the length */
244 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
246 /* End the Varargs Stuff */
249 /* Count number of lines */
250 for (p = buf; *p; p++)
252 if (*p == '\n') auto_dump_line_num++;
256 fprintf(auto_dump_stream, "%s", buf);
261 * @brief prfファイルをファイルオープンする /
262 * Open file to append auto dump.
264 * @param mark 出力するヘッダマーク
265 * @return ファイルポインタを取得できたらTRUEを返す
267 static bool open_auto_dump(concptr buf, concptr mark)
270 char header_mark_str[80];
272 /* Save the mark string */
273 auto_dump_mark = mark;
275 /* Prepare a header mark string */
276 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
278 /* Remove old macro dumps */
279 remove_auto_dump(buf);
281 /* Append to the file */
282 auto_dump_stream = my_fopen(buf, "a");
285 if (!auto_dump_stream) {
286 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
294 fprintf(auto_dump_stream, "%s\n", header_mark_str);
296 /* Initialize counter */
297 auto_dump_line_num = 0;
299 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
300 "# *Warning!* The lines below are an automatic dump.\n"));
301 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
302 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
308 * @brief prfファイルをファイルクローズする /
309 * Append foot part and close auto dump.
312 static void close_auto_dump(void)
314 char footer_mark_str[80];
316 /* Prepare a footer mark string */
317 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
319 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
320 "# *Warning!* The lines below are an automatic dump.\n"));
321 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
322 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
324 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
327 my_fclose(auto_dump_stream);
336 * @brief Return suffix of ordinal number
338 * @return pointer of suffix string.
340 concptr get_ordinal_number_suffix(int num)
342 num = ABS(num) % 100;
346 return (num == 11) ? "th" : "st";
348 return (num == 12) ? "th" : "nd";
350 return (num == 13) ? "th" : "rd";
359 * @brief 日記にメッセージを追加する /
360 * Take note to the diary.
361 * @param type 日記内容のID
362 * @param num 日記内容のIDに応じた数値
363 * @param note 日記内容のIDに応じた文字列参照ポインタ
366 errr do_cmd_write_nikki(int type, int num, concptr note)
370 GAME_TEXT file_name[MAX_NLEN];
372 concptr note_level = "";
373 bool do_level = TRUE;
374 char note_level_buf[40];
377 static bool disable_nikki = FALSE;
379 extract_day_hour_min(&day, &hour, &min);
381 if (disable_nikki) return(-1);
383 if (type == NIKKI_FIX_QUEST_C ||
384 type == NIKKI_FIX_QUEST_F ||
385 type == NIKKI_RAND_QUEST_C ||
386 type == NIKKI_RAND_QUEST_F ||
387 type == NIKKI_TO_QUEST)
391 old_quest = p_ptr->inside_quest;
392 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
394 /* Get the quest text */
395 init_flags = INIT_NAME_ONLY;
397 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
399 /* Reset the old quest number */
400 p_ptr->inside_quest = old_quest;
403 /* different filne name to avoid mixing */
404 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
406 /* Build the filename */
407 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
409 /* File type is "TEXT" */
410 FILE_TYPE(FILE_TYPE_TEXT);
412 fff = my_fopen(buf, "a");
417 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
423 q_idx = quest_number(dun_level);
427 if (p_ptr->inside_arena)
428 note_level = _("アリーナ:", "Arane:");
430 note_level = _("地上:", "Surface:");
431 else if (q_idx && (is_fixed_quest_idx(q_idx)
432 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
433 note_level = _("クエスト:", "Quest:");
437 sprintf(note_level_buf, "%d階(%s):", (int)dun_level, d_name+d_info[dungeon_type].name);
439 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
441 note_level = note_level_buf;
449 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
450 else fputs(_("*****日目\n", "Day *****\n"), fff);
458 fprintf(fff, "%s\n",note);
462 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
467 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
470 case NIKKI_ART_SCROLL:
472 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
477 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
480 case NIKKI_FIX_QUEST_C:
482 if (quest[num].flags & QUEST_FLAG_SILENT) break;
483 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
484 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
487 case NIKKI_FIX_QUEST_F:
489 if (quest[num].flags & QUEST_FLAG_SILENT) break;
490 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
491 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
494 case NIKKI_RAND_QUEST_C:
496 GAME_TEXT name[MAX_NLEN];
497 strcpy(name, r_name+r_info[quest[num].r_idx].name);
498 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
499 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
502 case NIKKI_RAND_QUEST_F:
504 GAME_TEXT name[MAX_NLEN];
505 strcpy(name, r_name+r_info[quest[num].r_idx].name);
506 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
507 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
510 case NIKKI_MAXDEAPTH:
512 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
513 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
514 _(d_name+d_info[dungeon_type].name, num),
515 _(num, d_name+d_info[dungeon_type].name));
520 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
521 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
522 _(d_name + d_info[num].name, (int)max_dlv[num]),
523 _((int)max_dlv[num], d_name + d_info[num].name));
529 if (q_idx && (is_fixed_quest_idx(q_idx)
530 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
532 to = _("地上", "the surface");
536 if (!(dun_level+num)) to = _("地上", "the surface");
537 else to = format(_("%d階", "level %d"), dun_level+num);
539 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
545 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
546 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]),
547 _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
549 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
554 if (quest[num].flags & QUEST_FLAG_SILENT) break;
555 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
556 hour, min, note_level, quest[num].name);
561 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
562 hour, min, note_level);
567 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
572 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
580 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
581 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
584 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
585 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
587 if (num == MAX_ARENA_MONS)
589 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
590 " won all fight to become a Chanpion.\n"));
597 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
604 to = _("地上", "the surface");
606 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
608 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
609 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
616 to = _("地上", "the surface");
618 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
620 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
621 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
626 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
629 case NIKKI_GAMESTART:
631 time_t ct = time((time_t*)0);
635 fprintf(fff, "%s %s",note, ctime(&ct));
638 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
641 case NIKKI_NAMED_PET:
643 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
646 case RECORD_NAMED_PET_NAME:
647 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
649 case RECORD_NAMED_PET_UNNAME:
650 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
652 case RECORD_NAMED_PET_DISMISS:
653 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
655 case RECORD_NAMED_PET_DEATH:
656 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
658 case RECORD_NAMED_PET_MOVED:
659 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
661 case RECORD_NAMED_PET_LOST_SIGHT:
662 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
664 case RECORD_NAMED_PET_DESTROY:
665 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
667 case RECORD_NAMED_PET_EARTHQUAKE:
668 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
670 case RECORD_NAMED_PET_GENOCIDE:
671 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
673 case RECORD_NAMED_PET_WIZ_ZAP:
674 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
676 case RECORD_NAMED_PET_TELE_LEVEL:
677 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
679 case RECORD_NAMED_PET_BLAST:
680 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
682 case RECORD_NAMED_PET_HEAL_LEPER:
683 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
685 case RECORD_NAMED_PET_COMPACT:
686 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
688 case RECORD_NAMED_PET_LOSE_PARENT:
689 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
700 case NIKKI_WIZARD_LOG:
701 fprintf(fff, "%s\n", note);
710 if (do_level) write_level = FALSE;
716 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
719 * @brief 日記のタイトル表記と内容出力 /
722 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
724 static void do_cmd_disp_nikki(void)
726 char nikki_title[256];
727 GAME_TEXT file_name[MAX_NLEN];
732 static const char subtitle[][30] = {"最強の肉体を求めて",
763 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
764 "Attack is the best form of defence.",
766 "An unexpected windfall",
767 "A drowning man will catch at a straw",
768 "Don't count your chickens before they are hatched.",
769 "It is no use crying over spilt milk.",
770 "Seeing is believing.",
771 "Strike the iron while it is hot.",
772 "I don't care what follows.",
773 "To dig a well to put out a house on fire.",
774 "Tomorrow is another day.",
775 "Easy come, easy go.",
776 "The more haste, the less speed.",
777 "Where there is life, there is hope.",
778 "There is no royal road to *WINNER*.",
779 "Danger past, God forgotten.",
780 "The best thing to do now is to run away.",
781 "Life is but an empty dream.",
782 "Dead men tell no tales.",
783 "A book that remains shut is but a block.",
784 "Misfortunes never come singly.",
785 "A little knowledge is a dangerous thing.",
786 "History repeats itself.",
787 "*WINNER* was not built in a day.",
788 "Ignorance is bliss.",
789 "To lose is to win?",
790 "No medicine can cure folly.",
791 "All good things come to an end.",
792 "M$ Empire strikes back.",
793 "To see is to believe",
795 "Quest of The World's Greatest Brain"};
797 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
799 /* Build the filename */
800 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
802 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
803 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
804 else if (IS_WIZARD_CLASS())
805 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
806 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
809 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
811 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
814 /* Display the file contents */
815 show_file(FALSE, buf, nikki_title, -1, 0);
819 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
822 static void do_cmd_bunshou(void)
825 char bunshou[80] = "\0";
827 if (get_string(_("内容: ", "diary note: "), tmp, 79))
829 strcpy(bunshou, tmp);
831 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
836 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
839 static void do_cmd_last_get(void)
844 if (record_o_name[0] == '\0') return;
846 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
847 if (!get_check(buf)) return;
851 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
852 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
857 * @brief ファイル中の全日記記録を消去する /
860 static void do_cmd_erase_nikki(void)
862 GAME_TEXT file_name[MAX_NLEN];
866 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
867 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
869 /* Build the filename */
870 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
872 /* Remove the file */
875 fff = my_fopen(buf, "w");
878 msg_format(_("記録を消去しました。", "deleted record."));
880 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
889 void do_cmd_nikki(void)
893 /* File type is "TEXT" */
894 FILE_TYPE(FILE_TYPE_TEXT);
897 /* Interact until done */
902 /* Ask for a choice */
903 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
905 /* Give some choices */
906 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
907 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
908 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
909 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
911 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
914 prt(_("コマンド:", "Command: "), 18, 0);
919 if (i == ESCAPE) break;
933 do_cmd_erase_nikki();
937 prepare_movie_hooks();
939 default: /* Unknown option */
949 * @brief 画面を再描画するコマンドのメインルーチン
950 * Hack -- redraw the screen
954 * This command performs various low level updates, clears all the "extra"
955 * windows, does a total redraw of the main window, and requests all of the
956 * interesting updates and redraws that I can think of.
958 * This command is also used to "instantiate" the results of the user
959 * selecting various things, such as graphics mode, so it must call
960 * the "TERM_XTRA_REACT" hook before redrawing the windows.
963 void do_cmd_redraw(void)
969 /* Hack -- react to changes */
970 Term_xtra(TERM_XTRA_REACT, 0);
972 /* Combine and Reorder the pack (later) */
973 p_ptr->update |= (PU_COMBINE | PU_REORDER);
974 p_ptr->update |= (PU_TORCH);
975 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
976 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
977 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
978 p_ptr->update |= (PU_MONSTERS);
980 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
982 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
983 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
989 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
992 /* Redraw every window */
993 for (j = 0; j < 8; j++)
996 if (!angband_term[j]) continue;
999 Term_activate(angband_term[j]);
1008 * @brief 名前を変更するコマンドのメインルーチン
1009 * Hack -- change name
1012 void do_cmd_change_name(void)
1027 /* Display the player */
1028 display_player(mode);
1033 display_player(mode);
1038 Term_putstr(2, 23, -1, TERM_WHITE,
1039 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1041 Term_putstr(2, 23, -1, TERM_WHITE,
1042 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1050 if (c == ESCAPE) break;
1057 /* Process the player name */
1058 process_player_name(FALSE);
1064 sprintf(tmp, "%s.txt", player_base);
1065 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1067 if (tmp[0] && (tmp[0] != ' '))
1069 file_character(tmp);
1087 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1094 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1095 * Recall the most recent message
1098 void do_cmd_message_one(void)
1100 /* Recall one message */
1101 prt(format("> %s", message_str(0)), 0, 0);
1106 * @brief メッセージのログを表示するコマンドのメインルーチン
1107 * Recall the most recent message
1111 * Show previous messages to the user -BEN-
1113 * The screen format uses line 0 and 23 for headers and prompts,
1114 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1116 * This command shows you which commands you are viewing, and allows
1117 * you to "search" for strings in the recall.
1119 * Note that messages may be longer than 80 characters, but they are
1120 * displayed using "infinite" length, with a special sub-command to
1121 * "slide" the virtual display to the left or right.
1123 * Attempt to only hilite the matching portions of the string.
1126 void do_cmd_messages(int num_now)
1130 char shower_str[81];
1131 char finder_str[81];
1133 concptr shower = NULL;
1137 Term_get_size(&wid, &hgt);
1139 /* Number of message lines in a screen */
1140 num_lines = hgt - 4;
1143 strcpy(finder_str, "");
1146 strcpy(shower_str, "");
1148 /* Total messages */
1151 /* Start on first message */
1156 /* Process requests until done */
1162 /* Dump up to 20 lines of messages */
1163 for (j = 0; (j < num_lines) && (i + j < n); j++)
1165 concptr msg = message_str(i+j);
1167 /* Dump the messages, bottom to top */
1168 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1170 /* Hilite "shower" */
1171 if (shower && shower[0])
1175 /* Display matches */
1176 while ((str = my_strstr(str, shower)) != NULL)
1178 int len = strlen(shower);
1180 /* Display the match */
1181 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1189 /* Erase remaining lines */
1190 for (; j < num_lines; j++)
1192 Term_erase(0, num_lines + 1 - j, 255);
1195 /* Display header */
1197 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1198 i, i + j - 1, n), 0, 0);
1200 /* Display prompt (not very informative) */
1201 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1202 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1204 skey = inkey_special(TRUE);
1206 /* Exit on Escape */
1207 if (skey == ESCAPE) break;
1209 /* Hack -- Save the old index */
1214 /* Hack -- handle show */
1217 prt(_("強調: ", "Show: "), hgt - 1, 0);
1219 /* Get a "shower" string, or continue */
1220 strcpy(back_str, shower_str);
1221 if (askfor(shower_str, 80))
1224 shower = shower_str[0] ? shower_str : NULL;
1226 else strcpy(shower_str, back_str);
1230 /* Hack -- handle find */
1237 prt(_("検索: ", "Find: "), hgt - 1, 0);
1239 /* Get a "finder" string, or continue */
1240 strcpy(back_str, finder_str);
1241 if (!askfor(finder_str, 80))
1243 strcpy(finder_str, back_str);
1246 else if (!finder_str[0])
1248 shower = NULL; /* Stop showing */
1253 shower = finder_str;
1256 for (z = i + 1; z < n; z++)
1258 concptr msg = message_str(z);
1261 if (my_strstr(msg, finder_str))
1272 /* Recall 1 older message */
1274 /* Go to the oldest line */
1278 /* Recall 1 newer message */
1280 /* Go to the newest line */
1284 /* Recall 1 older message */
1289 /* Go older if legal */
1290 i = MIN(i + 1, n - num_lines);
1293 /* Recall 10 older messages */
1295 /* Go older if legal */
1296 i = MIN(i + 10, n - num_lines);
1299 /* Recall 20 older messages */
1304 /* Go older if legal */
1305 i = MIN(i + num_lines, n - num_lines);
1308 /* Recall 20 newer messages */
1312 /* Go newer (if able) */
1313 i = MAX(0, i - num_lines);
1316 /* Recall 10 newer messages */
1318 /* Go newer (if able) */
1322 /* Recall 1 newer messages */
1325 /* Go newer (if able) */
1330 /* Hack -- Error of some kind */
1338 * @brief チートオプションを変更するコマンドのメインルーチン
1339 * Interact with some options for cheating
1340 * @param info 表示メッセージ
1343 static void do_cmd_options_cheat(concptr info)
1346 int i, k = 0, n = CHEAT_MAX;
1350 /* Interact with the player */
1356 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1361 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1362 prt(" << 注意 >>", 11, 0);
1363 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1364 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1365 prt(" じらないようにして下さい。", 14, 0);
1367 /* Display the options */
1368 for (i = 0; i < n; i++)
1370 byte a = TERM_WHITE;
1372 /* Color current option */
1373 if (i == k) a = TERM_L_BLUE;
1375 /* Display the option text */
1376 sprintf(buf, "%-48s: %s (%s)",
1377 cheat_info[i].o_desc,
1378 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1379 cheat_info[i].o_text);
1380 c_prt(a, buf, i + 2, 0);
1383 /* Hilite current option */
1384 move_cursor(k + 2, 50);
1390 * HACK - Try to translate the key into a direction
1391 * to allow using the roguelike keys for navigation.
1393 dir = get_keymap_dir(ch);
1394 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1408 k = (n + k - 1) % n;
1426 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1427 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1428 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1429 (*cheat_info[k].o_var) = TRUE;
1438 (*cheat_info[k].o_var) = FALSE;
1445 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1446 /* Peruse the help file */
1447 (void)show_file(TRUE, buf, NULL, 0, 0);
1464 * @brief セーブ頻度ターンの次の値を返す
1465 * @param current 現在のセーブ頻度ターン値
1466 * @return 次のセーブ頻度ターン値
1468 static s16b toggle_frequency(s16b current)
1473 case 50: return 100;
1474 case 100: return 250;
1475 case 250: return 500;
1476 case 500: return 1000;
1477 case 1000: return 2500;
1478 case 2500: return 5000;
1479 case 5000: return 10000;
1480 case 10000: return 25000;
1487 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1488 * @param info 表示メッセージ
1491 static void do_cmd_options_autosave(concptr info)
1494 int i, k = 0, n = 2;
1499 /* Interact with the player */
1503 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1504 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1508 /* Display the options */
1509 for (i = 0; i < n; i++)
1511 byte a = TERM_WHITE;
1513 /* Color current option */
1514 if (i == k) a = TERM_L_BLUE;
1516 /* Display the option text */
1517 sprintf(buf, "%-48s: %s (%s)",
1518 autosave_info[i].o_desc,
1519 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1520 autosave_info[i].o_text);
1521 c_prt(a, buf, i + 2, 0);
1523 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1525 /* Hilite current option */
1526 move_cursor(k + 2, 50);
1542 k = (n + k - 1) % n;
1560 (*autosave_info[k].o_var) = TRUE;
1569 (*autosave_info[k].o_var) = FALSE;
1577 autosave_freq = toggle_frequency(autosave_freq);
1578 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1584 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1600 * @brief 標準オプションを変更するコマンドのサブルーチン /
1601 * Interact with some options
1602 * @param page オプションページ番号
1603 * @param info 表示メッセージ
1606 void do_cmd_options_aux(int page, concptr info)
1609 int i, k = 0, n = 0, l;
1612 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1613 (!p_ptr->wizard || !allow_debug_opts);
1616 /* Lookup the options */
1617 for (i = 0; i < 24; i++) opt[i] = 0;
1619 /* Scan the options */
1620 for (i = 0; option_info[i].o_desc; i++)
1622 /* Notice options on this "page" */
1623 if (option_info[i].o_page == page) opt[n++] = i;
1627 /* Interact with the player */
1633 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1634 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1637 /* HACK -- description for easy-auto-destroy options */
1638 if (page == OPT_PAGE_AUTODESTROY)
1639 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1640 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1642 /* Display the options */
1643 for (i = 0; i < n; i++)
1645 byte a = TERM_WHITE;
1647 /* Color current option */
1648 if (i == k) a = TERM_L_BLUE;
1650 /* Display the option text */
1651 sprintf(buf, "%-48s: %s (%.19s)",
1652 option_info[opt[i]].o_desc,
1653 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1654 option_info[opt[i]].o_text);
1655 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1656 else c_prt(a, buf, i + 2, 0);
1659 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1662 /* Hilite current option */
1663 move_cursor(k + 2 + l, 50);
1669 * HACK - Try to translate the key into a direction
1670 * to allow using the roguelike keys for navigation.
1672 dir = get_keymap_dir(ch);
1673 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1687 k = (n + k - 1) % n;
1704 if (browse_only) break;
1705 (*option_info[opt[k]].o_var) = TRUE;
1714 if (browse_only) break;
1715 (*option_info[opt[k]].o_var) = FALSE;
1723 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1729 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1730 /* Peruse the help file */
1731 (void)show_file(TRUE, buf, NULL, 0, 0);
1748 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1749 * Modify the "window" options
1752 static void do_cmd_options_win(void)
1762 /* Memorize old flags */
1763 for (j = 0; j < 8; j++)
1765 /* Acquire current flags */
1766 old_flag[j] = window_flag[j];
1775 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1777 /* Display the windows */
1778 for (j = 0; j < 8; j++)
1780 byte a = TERM_WHITE;
1782 concptr s = angband_term_name[j];
1785 if (j == x) a = TERM_L_BLUE;
1787 /* Window name, staggered, centered */
1788 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1791 /* Display the options */
1792 for (i = 0; i < 16; i++)
1794 byte a = TERM_WHITE;
1796 concptr str = window_flag_desc[i];
1799 if (i == y) a = TERM_L_BLUE;
1802 if (!str) str = _("(未使用)", "(Unused option)");
1805 Term_putstr(0, i + 5, -1, a, str);
1807 /* Display the windows */
1808 for (j = 0; j < 8; j++)
1814 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1817 if (window_flag[j] & (1L << i)) c = 'X';
1820 Term_putch(35 + j * 5, i + 5, a, c);
1825 Term_gotoxy(35 + x * 5, y + 5);
1843 for (j = 0; j < 8; j++)
1845 window_flag[j] &= ~(1L << y);
1849 for (i = 0; i < 16; i++)
1851 window_flag[x] &= ~(1L << i);
1864 window_flag[x] |= (1L << y);
1872 window_flag[x] &= ~(1L << y);
1878 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1886 d = get_keymap_dir(ch);
1888 x = (x + ddx[d] + 8) % 8;
1889 y = (y + ddy[d] + 16) % 16;
1896 /* Notice changes */
1897 for (j = 0; j < 8; j++)
1902 if (!angband_term[j]) continue;
1904 /* Ignore non-changes */
1905 if (window_flag[j] == old_flag[j]) continue;
1908 Term_activate(angband_term[j]);
1925 option_fields[OPT_NUM] =
1928 { '1', " キー入力 オプション", 3 },
1929 { '2', " マップ画面 オプション", 4 },
1930 { '3', " テキスト表示 オプション", 5 },
1931 { '4', " ゲームプレイ オプション", 6 },
1932 { '5', " 行動中止関係 オプション", 7 },
1933 { '6', " 簡易自動破壊 オプション", 8 },
1934 { 'r', " プレイ記録 オプション", 9 },
1936 { 'p', "自動拾いエディタ", 11 },
1937 { 'd', " 基本ウェイト量 ", 12 },
1938 { 'h', "低ヒットポイント", 13 },
1939 { 'm', " 低魔力色閾値 ", 14 },
1940 { 'a', " 自動セーブ オプション", 15 },
1941 { 'w', "ウインドウフラグ", 16 },
1943 { 'b', " 初期 オプション (参照のみ)", 18 },
1944 { 'c', " 詐欺 オプション", 19 },
1946 { '1', "Input Options", 3 },
1947 { '2', "Map Screen Options", 4 },
1948 { '3', "Text Display Options", 5 },
1949 { '4', "Game-Play Options", 6 },
1950 { '5', "Disturbance Options", 7 },
1951 { '6', "Easy Auto-Destroyer Options", 8 },
1952 { 'r', "Play record Options", 9 },
1954 { 'p', "Auto-picker/destroyer editor", 11 },
1955 { 'd', "Base Delay Factor", 12 },
1956 { 'h', "Hitpoint Warning", 13 },
1957 { 'm', "Mana Color Threshold", 14 },
1958 { 'a', "Autosave Options", 15 },
1959 { 'w', "Window Flags", 16 },
1961 { 'b', "Birth Options (Browse Only)", 18 },
1962 { 'c', "Cheat Options", 19 },
1968 * @brief 標準オプションを変更するコマンドのメインルーチン /
1969 * Set or unset various options.
1973 * The user must use the "Ctrl-R" command to "adapt" to changes
1974 * in any options which control "visual" aspects of the game.
1977 void do_cmd_options(void)
1989 /* Does not list cheat option when cheat option is off */
1990 if (!p_ptr->noscore && !allow_debug_opts) n--;
1993 /* Why are we here */
1994 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
1998 /* Give some choices */
1999 for (i = 0; i < n; i++)
2001 byte a = TERM_WHITE;
2002 if (i == y) a = TERM_L_BLUE;
2003 Term_putstr(5, option_fields[i].row, -1, a,
2004 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2007 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2010 skey = inkey_special(TRUE);
2011 if (!(skey & SKEY_MASK)) k = (char)skey;
2015 if (k == ESCAPE) break;
2017 if (my_strchr("\n\r ", k))
2019 k = option_fields[y].key;
2023 for (i = 0; i < n; i++)
2025 if (tolower(k) == option_fields[i].key) break;
2028 /* Command is found */
2031 /* Hack -- browse help */
2032 if (k == '?') break;
2036 if (skey == SKEY_UP) d = 8;
2037 if (skey == SKEY_DOWN) d = 2;
2038 y = (y + ddy[d] + n) % n;
2043 if (k == ESCAPE) break;
2050 /* Process the general options */
2051 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2057 /* Process the general options */
2058 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2065 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2072 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2079 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2086 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2090 /* Play-record Options */
2095 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2104 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2105 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2106 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2110 /* Cheating Options */
2113 if (!p_ptr->noscore && !allow_debug_opts)
2115 /* Cheat options are not permitted */
2121 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2128 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2137 do_cmd_options_win();
2138 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2139 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2140 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2141 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2146 /* Auto-picker/destroyer editor */
2150 do_cmd_edit_autopick();
2154 /* Hack -- Delay Speed */
2160 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2162 /* Get a new value */
2165 int msec = delay_factor * delay_factor * delay_factor;
2166 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2167 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2169 if (k == ESCAPE) break;
2172 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2175 else if (isdigit(k)) delay_factor = D2I(k);
2182 /* Hack -- hitpoint warning factor */
2188 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2190 /* Get a new value */
2193 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2194 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2196 if (k == ESCAPE) break;
2199 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2202 else if (isdigit(k)) hitpoint_warn = D2I(k);
2209 /* Hack -- mana color factor */
2215 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2217 /* Get a new value */
2220 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2221 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2223 if (k == ESCAPE) break;
2226 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2229 else if (isdigit(k)) mana_warn = D2I(k);
2237 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2241 /* Unknown option */
2254 /* Hack - Redraw equippy chars */
2255 p_ptr->redraw |= (PR_EQUIPPY);
2261 * @brief prefファイルを選択して処理する /
2262 * Ask for a "user pref line" and process it
2265 * Allow absolute file names?
2267 void do_cmd_pref(void)
2274 /* Ask for a "user pref command" */
2275 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2277 /* Process that pref command */
2278 (void)process_pref_file_command(buf);
2282 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2285 void do_cmd_reload_autopick(void)
2287 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2288 /* Load the file with messages */
2289 autopick_load_pref(TRUE);
2295 * @brief マクロ情報をprefファイルに保存する /
2296 * @param fname ファイル名
2299 static errr macro_dump(concptr fname)
2301 static concptr mark = "Macro Dump";
2307 /* Build the filename */
2308 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2310 /* File type is "TEXT" */
2311 FILE_TYPE(FILE_TYPE_TEXT);
2313 /* Append to the file */
2314 if (!open_auto_dump(buf, mark)) return (-1);
2317 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2320 for (i = 0; i < macro__num; i++)
2322 /* Extract the action */
2323 ascii_to_text(buf, macro__act[i]);
2325 /* Dump the macro */
2326 auto_dump_printf("A:%s\n", buf);
2328 /* Extract the action */
2329 ascii_to_text(buf, macro__pat[i]);
2331 /* Dump normal macros */
2332 auto_dump_printf("P:%s\n", buf);
2335 auto_dump_printf("\n");
2347 * @brief マクロのトリガーキーを取得する /
2348 * Hack -- ask for a "trigger" (see below)
2349 * @param buf キー表記を保管するバッファ
2353 * Note the complex use of the "inkey()" function from "util.c".
2355 * Note that both "flush()" calls are extremely important.
2358 static void do_cmd_macro_aux(char *buf)
2366 /* Do not process macros */
2372 /* Read the pattern */
2378 /* Do not process macros */
2381 /* Do not wait for keys */
2384 /* Attempt to read a key */
2393 /* Convert the trigger */
2394 ascii_to_text(tmp, buf);
2396 /* Hack -- display the trigger */
2397 Term_addstr(-1, TERM_WHITE, tmp);
2403 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2404 * Hack -- ask for a keymap "trigger" (see below)
2405 * @param buf キー表記を取得するバッファ
2409 * Note that both "flush()" calls are extremely important. This may
2410 * no longer be true, since "util.c" is much simpler now.
2413 static void do_cmd_macro_aux_keymap(char *buf)
2423 /* Convert to ascii */
2424 ascii_to_text(tmp, buf);
2426 /* Hack -- display the trigger */
2427 Term_addstr(-1, TERM_WHITE, tmp);
2434 * @brief キーマップをprefファイルにダンプする /
2435 * Hack -- append all keymaps to the given file
2436 * @param fname ファイルネーム
2440 static errr keymap_dump(concptr fname)
2442 static concptr mark = "Keymap Dump";
2451 if (rogue_like_commands)
2453 mode = KEYMAP_MODE_ROGUE;
2459 mode = KEYMAP_MODE_ORIG;
2463 /* Build the filename */
2464 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2466 /* File type is "TEXT" */
2467 FILE_TYPE(FILE_TYPE_TEXT);
2469 /* Append to the file */
2470 if (!open_auto_dump(buf, mark)) return -1;
2473 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2476 for (i = 0; i < 256; i++)
2480 /* Loop up the keymap */
2481 act = keymap_act[mode][i];
2483 /* Skip empty keymaps */
2486 /* Encode the key */
2489 ascii_to_text(key, buf);
2491 /* Encode the action */
2492 ascii_to_text(buf, act);
2494 /* Dump the macro */
2495 auto_dump_printf("A:%s\n", buf);
2496 auto_dump_printf("C:%d:%s\n", mode, key);
2508 * @brief マクロを設定するコマンドのメインルーチン /
2509 * Interact with "macros"
2513 * Note that the macro "action" must be defined before the trigger.
2515 * Could use some helpful instructions on this page.
2518 void do_cmd_macros(void)
2530 if (rogue_like_commands)
2532 mode = KEYMAP_MODE_ROGUE;
2538 mode = KEYMAP_MODE_ORIG;
2541 /* File type is "TEXT" */
2542 FILE_TYPE(FILE_TYPE_TEXT);
2547 /* Process requests until done */
2551 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2553 /* Describe that action */
2554 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2556 /* Analyze the current action */
2557 ascii_to_text(buf, macro__buf);
2559 /* Display the current action */
2564 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2566 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2567 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2568 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2569 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2570 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2571 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2572 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2573 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2574 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2575 #endif /* ALLOW_MACROS */
2578 prt(_("コマンド: ", "Command: "), 16, 0);
2583 if (i == ESCAPE) break;
2585 /* Load a 'macro' file */
2591 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2594 prt(_("ファイル: ", "File: "), 18, 0);
2596 /* Default filename */
2597 sprintf(tmp, "%s.prf", player_base);
2599 /* Ask for a file */
2600 if (!askfor(tmp, 80)) continue;
2602 /* Process the given filename */
2603 err = process_pref_file(tmp);
2606 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2611 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2615 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2625 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2628 prt(_("ファイル: ", "File: "), 18, 0);
2630 /* Default filename */
2631 sprintf(tmp, "%s.prf", player_base);
2633 /* Ask for a file */
2634 if (!askfor(tmp, 80)) continue;
2636 /* Dump the macros */
2637 (void)macro_dump(tmp);
2640 msg_print(_("マクロを追加しました。", "Appended macros."));
2649 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2653 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2655 /* Get a macro trigger */
2656 do_cmd_macro_aux(buf);
2658 /* Acquire action */
2659 k = macro_find_exact(buf);
2665 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2671 /* Obtain the action */
2672 strcpy(macro__buf, macro__act[k]);
2674 /* Analyze the current action */
2675 ascii_to_text(buf, macro__buf);
2677 /* Display the current action */
2681 msg_print(_("マクロを確認しました。", "Found a macro."));
2685 /* Create a macro */
2689 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2692 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2694 /* Get a macro trigger */
2695 do_cmd_macro_aux(buf);
2701 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2702 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2705 prt(_("マクロ行動: ", "Action: "), 20, 0);
2707 /* Convert to text */
2708 ascii_to_text(tmp, macro__buf);
2710 /* Get an encoded action */
2711 if (askfor(tmp, 80))
2713 /* Convert to ascii */
2714 text_to_ascii(macro__buf, tmp);
2716 /* Link the macro */
2717 macro_add(buf, macro__buf);
2720 msg_print(_("マクロを追加しました。", "Added a macro."));
2724 /* Remove a macro */
2728 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2731 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2733 /* Get a macro trigger */
2734 do_cmd_macro_aux(buf);
2736 /* Link the macro */
2737 macro_add(buf, buf);
2740 msg_print(_("マクロを削除しました。", "Removed a macro."));
2747 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2750 prt(_("ファイル: ", "File: "), 18, 0);
2752 /* Default filename */
2753 sprintf(tmp, "%s.prf", player_base);
2755 /* Ask for a file */
2756 if (!askfor(tmp, 80)) continue;
2758 /* Dump the macros */
2759 (void)keymap_dump(tmp);
2762 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2765 /* Query a keymap */
2771 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2774 prt(_("押すキー: ", "Keypress: "), 18, 0);
2776 /* Get a keymap trigger */
2777 do_cmd_macro_aux_keymap(buf);
2779 /* Look up the keymap */
2780 act = keymap_act[mode][(byte)(buf[0])];
2786 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2792 /* Obtain the action */
2793 strcpy(macro__buf, act);
2795 /* Analyze the current action */
2796 ascii_to_text(buf, macro__buf);
2798 /* Display the current action */
2802 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2806 /* Create a keymap */
2810 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2813 prt(_("押すキー: ", "Keypress: "), 18, 0);
2815 /* Get a keymap trigger */
2816 do_cmd_macro_aux_keymap(buf);
2822 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2823 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2826 prt(_("行動: ", "Action: "), 20, 0);
2828 /* Convert to text */
2829 ascii_to_text(tmp, macro__buf);
2831 /* Get an encoded action */
2832 if (askfor(tmp, 80))
2834 /* Convert to ascii */
2835 text_to_ascii(macro__buf, tmp);
2837 /* Free old keymap */
2838 string_free(keymap_act[mode][(byte)(buf[0])]);
2840 /* Make new keymap */
2841 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2844 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2848 /* Remove a keymap */
2852 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2855 prt(_("押すキー: ", "Keypress: "), 18, 0);
2857 /* Get a keymap trigger */
2858 do_cmd_macro_aux_keymap(buf);
2860 /* Free old keymap */
2861 string_free(keymap_act[mode][(byte)(buf[0])]);
2863 /* Make new keymap */
2864 keymap_act[mode][(byte)(buf[0])] = NULL;
2867 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2870 /* Enter a new action */
2874 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2880 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2881 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2884 prt(_("マクロ行動: ", "Action: "), 20, 0);
2886 /* Hack -- limit the value */
2889 /* Get an encoded action */
2890 if (!askfor(buf, 80)) continue;
2892 /* Extract an action */
2893 text_to_ascii(macro__buf, buf);
2896 #endif /* ALLOW_MACROS */
2909 * @brief キャラクタ色の明暗表現
2911 static concptr lighting_level_str[F_LIT_MAX] =
2926 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2927 * @param i 指定対象となるキャラクタコード
2928 * @param num 指定されたビジュアルIDを返す参照ポインタ
2929 * @param max ビジュアルIDの最大数
2930 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2932 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2939 sprintf(str, "%d", *num);
2941 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2944 tmp = (IDX)strtol(str, NULL, 0);
2945 if (tmp >= 0 && tmp < max)
2948 else if (isupper(i))
2949 *num = (*num + max - 1) % max;
2951 *num = (*num + 1) % max;
2957 * @brief キャラクタの変更メニュー表示
2958 * @param choice_msg 選択メッセージ
2961 static void print_visuals_menu(concptr choice_msg)
2963 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2965 /* Give some choices */
2966 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2968 #ifdef ALLOW_VISUALS
2969 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2970 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2971 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2972 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2973 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2974 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2975 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2976 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2977 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2978 #endif /* ALLOW_VISUALS */
2980 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2983 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2986 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2987 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2988 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2991 * Interact with "visuals"
2993 void do_cmd_visuals(void)
2998 bool need_redraw = FALSE;
2999 concptr empty_symbol = "<< ? >>";
3001 if (use_bigtile) empty_symbol = "<< ?? >>";
3003 /* File type is "TEXT" */
3004 FILE_TYPE(FILE_TYPE_TEXT);
3007 /* Interact until done */
3012 /* Ask for a choice */
3013 print_visuals_menu(NULL);
3018 if (i == ESCAPE) break;
3022 /* Load a 'pref' file */
3025 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3028 prt(_("ファイル: ", "File: "), 17, 0);
3030 /* Default filename */
3031 sprintf(tmp, "%s.prf", player_base);
3034 if (!askfor(tmp, 70)) continue;
3036 /* Process the given filename */
3037 (void)process_pref_file(tmp);
3042 #ifdef ALLOW_VISUALS
3044 /* Dump monster attr/chars */
3047 static concptr mark = "Monster attr/chars";
3050 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3053 prt(_("ファイル: ", "File: "), 17, 0);
3055 /* Default filename */
3056 sprintf(tmp, "%s.prf", player_base);
3058 /* Get a filename */
3059 if (!askfor(tmp, 70)) continue;
3061 /* Build the filename */
3062 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3064 /* Append to the file */
3065 if (!open_auto_dump(buf, mark)) continue;
3068 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3071 for (i = 0; i < max_r_idx; i++)
3073 monster_race *r_ptr = &r_info[i];
3075 /* Skip non-entries */
3076 if (!r_ptr->name) continue;
3078 /* Dump a comment */
3079 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3081 /* Dump the monster attr/char info */
3082 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3083 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3089 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3094 /* Dump object attr/chars */
3097 static concptr mark = "Object attr/chars";
3098 KIND_OBJECT_IDX k_idx;
3101 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3104 prt(_("ファイル: ", "File: "), 17, 0);
3106 /* Default filename */
3107 sprintf(tmp, "%s.prf", player_base);
3109 /* Get a filename */
3110 if (!askfor(tmp, 70)) continue;
3112 /* Build the filename */
3113 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3115 /* Append to the file */
3116 if (!open_auto_dump(buf, mark)) continue;
3119 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3122 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3124 GAME_TEXT o_name[MAX_NLEN];
3125 object_kind *k_ptr = &k_info[k_idx];
3127 /* Skip non-entries */
3128 if (!k_ptr->name) continue;
3133 strip_name(o_name, k_idx);
3139 /* Prepare dummy object */
3140 object_prep(&forge, k_idx);
3142 /* Get un-shuffled flavor name */
3143 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3146 /* Dump a comment */
3147 auto_dump_printf("# %s\n", o_name);
3149 /* Dump the object attr/char info */
3150 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3151 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3157 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3162 /* Dump feature attr/chars */
3165 static concptr mark = "Feature attr/chars";
3168 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3171 prt(_("ファイル: ", "File: "), 17, 0);
3173 /* Default filename */
3174 sprintf(tmp, "%s.prf", player_base);
3176 /* Get a filename */
3177 if (!askfor(tmp, 70)) continue;
3179 /* Build the filename */
3180 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3182 /* Append to the file */
3183 if (!open_auto_dump(buf, mark)) continue;
3186 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3189 for (i = 0; i < max_f_idx; i++)
3191 feature_type *f_ptr = &f_info[i];
3193 /* Skip non-entries */
3194 if (!f_ptr->name) continue;
3196 /* Skip mimiccing features */
3197 if (f_ptr->mimic != i) continue;
3199 /* Dump a comment */
3200 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3202 /* Dump the feature attr/char info */
3203 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3204 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3205 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3206 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3212 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3217 /* Modify monster attr/chars (numeric operation) */
3220 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3223 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3225 /* Hack -- query until done */
3228 monster_race *r_ptr = &r_info[r];
3232 TERM_COLOR da = r_ptr->d_attr;
3233 byte dc = r_ptr->d_char;
3234 TERM_COLOR ca = r_ptr->x_attr;
3235 byte cc = r_ptr->x_char;
3237 /* Label the object */
3238 Term_putstr(5, 17, -1, TERM_WHITE,
3239 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3241 /* Label the Default values */
3242 Term_putstr(10, 19, -1, TERM_WHITE,
3243 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3245 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3246 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3248 /* Label the Current values */
3249 Term_putstr(10, 20, -1, TERM_WHITE,
3250 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3252 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3253 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3256 Term_putstr(0, 22, -1, TERM_WHITE,
3257 _("コマンド (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): "));
3262 if (i == ESCAPE) break;
3264 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3265 else if (isupper(i)) c = 'a' + i - 'A';
3275 if (!cmd_visuals_aux(i, &r, max_r_idx))
3281 while (!r_info[r].name);
3285 t = (int)r_ptr->x_attr;
3286 (void)cmd_visuals_aux(i, &t, 256);
3287 r_ptr->x_attr = (byte)t;
3291 t = (int)r_ptr->x_char;
3292 (void)cmd_visuals_aux(i, &t, 256);
3293 r_ptr->x_char = (byte)t;
3297 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3299 print_visuals_menu(choice_msg);
3307 /* Modify object attr/chars (numeric operation) */
3310 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3312 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3314 /* Hack -- query until done */
3317 object_kind *k_ptr = &k_info[k];
3321 TERM_COLOR da = k_ptr->d_attr;
3322 SYMBOL_CODE dc = k_ptr->d_char;
3323 TERM_COLOR ca = k_ptr->x_attr;
3324 SYMBOL_CODE cc = k_ptr->x_char;
3326 /* Label the object */
3327 Term_putstr(5, 17, -1, TERM_WHITE,
3328 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3329 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3331 /* Label the Default values */
3332 Term_putstr(10, 19, -1, TERM_WHITE,
3333 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3335 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3336 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3338 /* Label the Current values */
3339 Term_putstr(10, 20, -1, TERM_WHITE,
3340 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3342 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3343 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3346 Term_putstr(0, 22, -1, TERM_WHITE,
3347 _("コマンド (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): "));
3352 if (i == ESCAPE) break;
3354 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3355 else if (isupper(i)) c = 'a' + i - 'A';
3365 if (!cmd_visuals_aux(i, &k, max_k_idx))
3371 while (!k_info[k].name);
3375 t = (int)k_ptr->x_attr;
3376 (void)cmd_visuals_aux(i, &t, 256);
3377 k_ptr->x_attr = (byte)t;
3381 t = (int)k_ptr->x_char;
3382 (void)cmd_visuals_aux(i, &t, 256);
3383 k_ptr->x_char = (byte)t;
3387 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3389 print_visuals_menu(choice_msg);
3397 /* Modify feature attr/chars (numeric operation) */
3400 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3402 static IDX lighting_level = F_LIT_STANDARD;
3403 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3405 /* Hack -- query until done */
3408 feature_type *f_ptr = &f_info[f];
3412 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3413 byte dc = f_ptr->d_char[lighting_level];
3414 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3415 byte cc = f_ptr->x_char[lighting_level];
3417 /* Label the object */
3419 Term_putstr(5, 17, -1, TERM_WHITE,
3420 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3421 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3423 /* Label the Default values */
3424 Term_putstr(10, 19, -1, TERM_WHITE,
3425 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3427 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3428 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3430 /* Label the Current values */
3432 Term_putstr(10, 20, -1, TERM_WHITE,
3433 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3435 Term_putstr(10, 20, -1, TERM_WHITE,
3436 format("Current attr/char = %3d / %3d", ca, cc));
3439 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3440 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3444 Term_putstr(0, 22, -1, TERM_WHITE,
3445 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3447 Term_putstr(0, 22, -1, TERM_WHITE,
3448 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3454 if (i == ESCAPE) break;
3456 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3457 else if (isupper(i)) c = 'a' + i - 'A';
3467 if (!cmd_visuals_aux(i, &f, max_f_idx))
3473 while (!f_info[f].name || (f_info[f].mimic != f));
3477 t = (int)f_ptr->x_attr[lighting_level];
3478 (void)cmd_visuals_aux(i, &t, 256);
3479 f_ptr->x_attr[lighting_level] = (byte)t;
3483 t = (int)f_ptr->x_char[lighting_level];
3484 (void)cmd_visuals_aux(i, &t, 256);
3485 f_ptr->x_char[lighting_level] = (byte)t;
3489 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3492 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3496 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3498 print_visuals_menu(choice_msg);
3506 /* Modify monster attr/chars (visual mode) */
3508 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3511 /* Modify object attr/chars (visual mode) */
3513 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3516 /* Modify feature attr/chars (visual mode) */
3519 IDX lighting_level = F_LIT_STANDARD;
3520 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3524 #endif /* ALLOW_VISUALS */
3532 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3536 /* Unknown option */
3546 if (need_redraw) do_cmd_redraw();
3551 * Interact with "colors"
3553 void do_cmd_colors(void)
3562 /* File type is "TEXT" */
3563 FILE_TYPE(FILE_TYPE_TEXT);
3568 /* Interact until done */
3573 /* Ask for a choice */
3574 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3576 /* Give some choices */
3577 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3580 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3581 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3585 prt(_("コマンド: ", "Command: "), 8, 0);
3589 if (i == ESCAPE) break;
3591 /* Load a 'pref' file */
3595 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3598 prt(_("ファイル: ", "File: "), 10, 0);
3601 sprintf(tmp, "%s.prf", player_base);
3604 if (!askfor(tmp, 70)) continue;
3606 /* Process the given filename */
3607 (void)process_pref_file(tmp);
3609 /* Mega-Hack -- react to changes */
3610 Term_xtra(TERM_XTRA_REACT, 0);
3612 /* Mega-Hack -- redraw */
3621 static concptr mark = "Colors";
3624 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3627 prt(_("ファイル: ", "File: "), 10, 0);
3629 /* Default filename */
3630 sprintf(tmp, "%s.prf", player_base);
3632 /* Get a filename */
3633 if (!askfor(tmp, 70)) continue;
3635 /* Build the filename */
3636 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3638 /* Append to the file */
3639 if (!open_auto_dump(buf, mark)) continue;
3642 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3645 for (i = 0; i < 256; i++)
3647 int kv = angband_color_table[i][0];
3648 int rv = angband_color_table[i][1];
3649 int gv = angband_color_table[i][2];
3650 int bv = angband_color_table[i][3];
3652 concptr name = _("未知", "unknown");
3654 /* Skip non-entries */
3655 if (!kv && !rv && !gv && !bv) continue;
3657 /* Extract the color name */
3658 if (i < 16) name = color_names[i];
3660 /* Dump a comment */
3661 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3663 /* Dump the monster attr/char info */
3664 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3671 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3680 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3682 /* Hack -- query until done */
3691 /* Exhibit the normal colors */
3692 for (j = 0; j < 16; j++)
3694 /* Exhibit this color */
3695 Term_putstr(j*4, 20, -1, a, "###");
3697 /* Exhibit all colors */
3698 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3701 /* Describe the color */
3702 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3704 /* Describe the color */
3705 Term_putstr(5, 10, -1, TERM_WHITE,
3706 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3708 /* Label the Current values */
3709 Term_putstr(5, 12, -1, TERM_WHITE,
3710 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3711 angband_color_table[a][0],
3712 angband_color_table[a][1],
3713 angband_color_table[a][2],
3714 angband_color_table[a][3]));
3717 Term_putstr(0, 14, -1, TERM_WHITE,
3718 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3723 if (i == ESCAPE) break;
3726 if (i == 'n') a = (byte)(a + 1);
3727 if (i == 'N') a = (byte)(a - 1);
3728 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3729 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3730 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3731 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3732 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3733 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3734 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3735 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3737 /* Hack -- react to changes */
3738 Term_xtra(TERM_XTRA_REACT, 0);
3740 /* Hack -- redraw */
3747 /* Unknown option */
3761 * Note something in the message recall
3763 void do_cmd_note(void)
3771 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3773 /* Ignore empty notes */
3774 if (!buf[0] || (buf[0] == ' ')) return;
3776 /* Add the note to the message recall */
3777 msg_format(_("メモ: %s", "Note: %s"), buf);
3782 * Mention the current version
3784 void do_cmd_version(void)
3786 #if FAKE_VER_EXTRA > 0
3787 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3788 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3790 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3791 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3798 * Array of feeling strings
3800 static concptr do_cmd_feeling_text[11] =
3802 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3803 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3804 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3805 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3806 _("とても悪い予感がする...", "You have a very bad feeling..."),
3807 _("悪い予感がする...", "You have a bad feeling..."),
3808 _("何か緊張する。", "You feel nervous."),
3809 _("少し不運な気がする...", "You feel your luck is turning..."),
3810 _("この場所は好きになれない。", "You don't like the look of this place."),
3811 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3812 _("なんて退屈なところだ...", "What a boring place...")
3815 static concptr do_cmd_feeling_text_combat[11] =
3817 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3818 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3819 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3820 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3821 _("とても悪い予感がする...", "You have a very bad feeling..."),
3822 _("悪い予感がする...", "You have a bad feeling..."),
3823 _("何か緊張する。", "You feel nervous."),
3824 _("少し不運な気がする...", "You feel your luck is turning..."),
3825 _("この場所は好きになれない。", "You don't like the look of this place."),
3826 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3827 _("なんて退屈なところだ...", "What a boring place...")
3830 static concptr do_cmd_feeling_text_lucky[11] =
3832 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3833 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3834 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3835 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3836 _("とても良い感じがする...", "You have a very good feeling..."),
3837 _("良い感じがする...", "You have a good feeling..."),
3838 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3839 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3840 _("見た感じ悪くはない...", "You like the look of this place..."),
3841 _("全然駄目ということはないが...", "This level can't be all bad..."),
3842 _("なんて退屈なところだ...", "What a boring place...")
3847 * Note that "feeling" is set to zero unless some time has passed.
3848 * Note that this is done when the level is GENERATED, not entered.
3850 void do_cmd_feeling(void)
3852 if (p_ptr->wild_mode) return;
3854 /* No useful feeling in quests */
3855 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3857 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3861 /* No useful feeling in town */
3862 else if (p_ptr->town_num && !dun_level)
3864 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3866 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3871 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3876 /* No useful feeling in the wilderness */
3877 else if (!dun_level)
3879 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3883 /* Display the feeling */
3884 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3885 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3886 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3887 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3888 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3890 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3896 * Description of each monster group.
3898 static concptr monster_group_text[] =
3901 "ユニーク", /* "Uniques" */
3902 "乗馬可能なモンスター", /* "Riding" */
3903 "賞金首", /* "Wanted */
3904 "アンバーの王族", /* "Ambertite" */
3933 /* "古代ドラゴン/ワイアーム", */
3994 /* "Ancient Dragon/Wyrm", */
4003 "Multi-Headed Reptile",
4008 "Reptile/Amphibian",
4009 "Spider/Scorpion/Tick",
4011 /* "Major Demon", */
4028 * Symbols of monsters in each group. Note the "Uniques" group
4029 * is handled differently.
4031 static concptr monster_group_char[] =
4088 "!$&()+./=>?[\\]`{|~",
4098 * hook function to sort monsters by level
4100 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4102 u16b *who = (u16b*)(u);
4107 monster_race *r_ptr1 = &r_info[w1];
4108 monster_race *r_ptr2 = &r_info[w2];
4113 if (r_ptr2->level > r_ptr1->level) return TRUE;
4114 if (r_ptr1->level > r_ptr2->level) return FALSE;
4116 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4117 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4122 * Build a list of monster indexes in the given group. Return the number
4123 * of monsters in the group.
4125 * mode & 0x01 : check for non-empty group
4126 * mode & 0x02 : visual operation only
4128 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4134 /* Get a list of x_char in this group */
4135 concptr group_char = monster_group_char[grp_cur];
4137 /* XXX Hack -- Check if this is the "Uniques" group */
4138 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4140 /* XXX Hack -- Check if this is the "Riding" group */
4141 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4143 /* XXX Hack -- Check if this is the "Wanted" group */
4144 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4146 /* XXX Hack -- Check if this is the "Amberite" group */
4147 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4150 /* Check every race */
4151 for (i = 0; i < max_r_idx; i++)
4153 /* Access the race */
4154 monster_race *r_ptr = &r_info[i];
4156 /* Skip empty race */
4157 if (!r_ptr->name) continue ;
4159 /* Require known monsters */
4160 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4164 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4167 else if (grp_riding)
4169 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4172 else if (grp_wanted)
4174 bool wanted = FALSE;
4176 for (j = 0; j < MAX_KUBI; j++)
4178 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4179 (p_ptr->today_mon && p_ptr->today_mon == i))
4185 if (!wanted) continue;
4188 else if (grp_amberite)
4190 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4195 /* Check for race in the group */
4196 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4200 mon_idx[mon_cnt++] = i;
4202 /* XXX Hack -- Just checking for non-empty group */
4203 if (mode & 0x01) break;
4206 /* Terminate the list */
4207 mon_idx[mon_cnt] = -1;
4209 /* Select the sort method */
4210 ang_sort_comp = ang_sort_comp_monster_level;
4211 ang_sort_swap = ang_sort_swap_hook;
4213 /* Sort by monster level */
4214 ang_sort(mon_idx, &dummy_why, mon_cnt);
4216 /* Return the number of races */
4222 * Description of each monster group.
4224 static concptr object_group_text[] =
4227 "キノコ", /* "Mushrooms" */
4228 "薬", /* "Potions" */
4229 "油つぼ", /* "Flasks" */
4230 "巻物", /* "Scrolls" */
4232 "アミュレット", /* "Amulets" */
4233 "笛", /* "Whistle" */
4234 "光源", /* "Lanterns" */
4235 "魔法棒", /* "Wands" */
4238 "カード", /* "Cards" */
4249 "刀剣類", /* "Swords" */
4250 "鈍器", /* "Blunt Weapons" */
4251 "長柄武器", /* "Polearms" */
4252 "採掘道具", /* "Diggers" */
4253 "飛び道具", /* "Bows" */
4257 "軽装鎧", /* "Soft Armor" */
4258 "重装鎧", /* "Hard Armor" */
4259 "ドラゴン鎧", /* "Dragon Armor" */
4260 "盾", /* "Shields" */
4261 "クローク", /* "Cloaks" */
4262 "籠手", /* "Gloves" */
4263 "ヘルメット", /* "Helms" */
4265 "ブーツ", /* "Boots" */
4318 * TVALs of items in each group
4320 static byte object_group_tval[] =
4361 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4369 * Build a list of object indexes in the given group. Return the number
4370 * of objects in the group.
4372 * mode & 0x01 : check for non-empty group
4373 * mode & 0x02 : visual operation only
4375 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4378 int j, k, object_cnt = 0;
4380 /* Get a list of x_char in this group */
4381 byte group_tval = object_group_tval[grp_cur];
4383 /* Check every object */
4384 for (i = 0; i < max_k_idx; i++)
4386 /* Access the object */
4387 object_kind *k_ptr = &k_info[i];
4389 /* Skip empty objects */
4390 if (!k_ptr->name) continue;
4394 /* Any objects will be displayed */
4400 /* Skip non-flavoured objects */
4401 if (!k_ptr->flavor) continue;
4403 /* Require objects ever seen */
4404 if (!k_ptr->aware) continue;
4407 /* Skip items with no distribution (special artifacts) */
4408 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4412 /* Check for objects in the group */
4413 if (TV_LIFE_BOOK == group_tval)
4415 /* Hack -- All spell books */
4416 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4418 /* Add the object */
4419 object_idx[object_cnt++] = i;
4423 else if (k_ptr->tval == group_tval)
4425 /* Add the object */
4426 object_idx[object_cnt++] = i;
4430 /* XXX Hack -- Just checking for non-empty group */
4431 if (mode & 0x01) break;
4434 /* Terminate the list */
4435 object_idx[object_cnt] = -1;
4437 /* Return the number of objects */
4443 * Description of each feature group.
4445 static concptr feature_group_text[] =
4453 * Build a list of feature indexes in the given group. Return the number
4454 * of features in the group.
4456 * mode & 0x01 : check for non-empty group
4458 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4463 /* Unused; There is a single group. */
4466 /* Check every feature */
4467 for (i = 0; i < max_f_idx; i++)
4469 /* Access the index */
4470 feature_type *f_ptr = &f_info[i];
4472 /* Skip empty index */
4473 if (!f_ptr->name) continue;
4475 /* Skip mimiccing features */
4476 if (f_ptr->mimic != i) continue;
4479 feat_idx[feat_cnt++] = i;
4481 /* XXX Hack -- Just checking for non-empty group */
4482 if (mode & 0x01) break;
4485 /* Terminate the list */
4486 feat_idx[feat_cnt] = -1;
4488 /* Return the number of races */
4495 * Build a list of monster indexes in the given group. Return the number
4496 * of monsters in the group.
4498 static int collect_artifacts(int grp_cur, int object_idx[])
4500 int i, object_cnt = 0;
4502 /* Get a list of x_char in this group */
4503 byte group_tval = object_group_tval[grp_cur];
4505 /* Check every object */
4506 for (i = 0; i < max_a_idx; i++)
4508 /* Access the artifact */
4509 artifact_type *a_ptr = &a_info[i];
4511 /* Skip empty artifacts */
4512 if (!a_ptr->name) continue;
4514 /* Skip "uncreated" artifacts */
4515 if (!a_ptr->cur_num) continue;
4517 /* Check for race in the group */
4518 if (a_ptr->tval == group_tval)
4521 object_idx[object_cnt++] = i;
4525 /* Terminate the list */
4526 object_idx[object_cnt] = 0;
4528 /* Return the number of races */
4535 * Encode the screen colors
4537 static char hack[17] = "dwsorgbuDWvyRGBU";
4541 * Hack -- load a screen dump from a file
4543 void do_cmd_load_screen(void)
4548 SYMBOL_CODE c = ' ';
4554 Term_get_size(&wid, &hgt);
4556 /* Build the filename */
4557 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4559 /* Append to the file */
4560 fff = my_fopen(buf, "r");
4563 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4571 /* Load the screen */
4572 for (y = 0; okay; y++)
4574 /* Get a line of data including control code */
4575 if (!fgets(buf, 1024, fff)) okay = FALSE;
4577 /* Get the blank line */
4578 if (buf[0] == '\n' || buf[0] == '\0') break;
4580 /* Ignore too large screen image */
4581 if (y >= hgt) continue;
4584 for (x = 0; x < wid - 1; x++)
4587 if (buf[x] == '\n' || buf[x] == '\0') break;
4589 /* Put the attr/char */
4590 Term_draw(x, y, TERM_WHITE, buf[x]);
4594 /* Dump the screen */
4595 for (y = 0; okay; y++)
4597 /* Get a line of data including control code */
4598 if (!fgets(buf, 1024, fff)) okay = FALSE;
4600 /* Get the blank line */
4601 if (buf[0] == '\n' || buf[0] == '\0') break;
4603 /* Ignore too large screen image */
4604 if (y >= hgt) continue;
4607 for (x = 0; x < wid - 1; x++)
4610 if (buf[x] == '\n' || buf[x] == '\0') break;
4612 /* Get the attr/char */
4613 (void)(Term_what(x, y, &a, &c));
4615 /* Look up the attr */
4616 for (i = 0; i < 16; i++)
4618 /* Use attr matches */
4619 if (hack[i] == buf[x]) a = (byte_hack)i;
4622 /* Put the attr/char */
4623 Term_draw(x, y, a, c);
4630 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4641 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4642 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4645 #define IM_FLAG_STR _("*", "* ")
4646 #define HAS_FLAG_STR _("+", "+ ")
4647 #define NO_FLAG_STR _("・", ". ")
4649 #define print_im_or_res_flag(IM, RES) \
4651 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4652 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4655 #define print_flag(TR) \
4657 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4661 /* XTRA HACK RESLIST */
4662 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4664 GAME_TEXT o_name[MAX_NLEN];
4665 BIT_FLAGS flgs[TR_FLAG_SIZE];
4667 if (!o_ptr->k_idx) return;
4668 if (o_ptr->tval != tval) return;
4670 /* Identified items only */
4671 if (!object_is_known(o_ptr)) return;
4674 * HACK:Ring of Lordly protection and Dragon equipment
4675 * have random resistances.
4677 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4678 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4679 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4680 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4681 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4682 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4683 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4684 || object_is_artifact(o_ptr))
4687 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4689 while (o_name[i] && (i < 26))
4692 if (iskanji(o_name[i])) i++;
4701 o_name[i] = ' '; i++;
4706 fprintf(fff, "%s %s", where, o_name);
4708 if (!(o_ptr->ident & (IDENT_MENTAL)))
4710 fputs(_("-------不明--------------- -------不明---------\n",
4711 "-------unknown------------ -------unknown------\n"), fff);
4715 object_flags_known(o_ptr, flgs);
4717 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4718 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4719 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4720 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4721 print_flag(TR_RES_POIS);
4722 print_flag(TR_RES_LITE);
4723 print_flag(TR_RES_DARK);
4724 print_flag(TR_RES_SHARDS);
4725 print_flag(TR_RES_SOUND);
4726 print_flag(TR_RES_NETHER);
4727 print_flag(TR_RES_NEXUS);
4728 print_flag(TR_RES_CHAOS);
4729 print_flag(TR_RES_DISEN);
4733 print_flag(TR_RES_BLIND);
4734 print_flag(TR_RES_FEAR);
4735 print_flag(TR_RES_CONF);
4736 print_flag(TR_FREE_ACT);
4737 print_flag(TR_SEE_INVIS);
4738 print_flag(TR_HOLD_EXP);
4739 print_flag(TR_TELEPATHY);
4740 print_flag(TR_SLOW_DIGEST);
4741 print_flag(TR_REGEN);
4742 print_flag(TR_LEVITATION);
4750 fprintf(fff, "%s\n", inven_res_label);
4756 * Display *ID* ed weapons/armors's resistances
4758 static void do_cmd_knowledge_inven(void)
4761 GAME_TEXT file_name[1024];
4763 OBJECT_TYPE_VALUE tval;
4769 /* Open a new file */
4770 fff = my_fopen_temp(file_name, 1024);
4773 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4777 fprintf(fff, "%s\n", inven_res_label);
4779 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4783 for (; j < 9; j++) fputc('\n', fff);
4785 fprintf(fff, "%s\n", inven_res_label);
4787 strcpy(where, _("装", "E "));
4788 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4790 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4792 strcpy(where, _("持", "I "));
4793 for (i = 0; i < INVEN_PACK; i++)
4795 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4798 st_ptr = &town[1].store[STORE_HOME];
4799 strcpy(where, _("家", "H "));
4800 for (i = 0; i < st_ptr->stock_num; i++)
4802 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4807 /* Display the file contents */
4808 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4810 /* Remove the file */
4815 void do_cmd_save_screen_html_aux(char *filename, int message)
4820 TERM_COLOR a = 0, old_a = 0;
4834 concptr html_head[] = {
4835 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4839 concptr html_foot[] = {
4841 "</body>\n</html>\n",
4847 Term_get_size(&wid, &hgt);
4849 /* File type is "TEXT" */
4850 FILE_TYPE(FILE_TYPE_TEXT);
4852 /* Append to the file */
4853 fff = my_fopen(filename, "w");
4857 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4863 if (message) screen_save();
4865 /* Build the filename */
4866 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4867 tmpfff = my_fopen(buf, "r");
4869 for (i = 0; html_head[i]; i++)
4870 fputs(html_head[i], fff);
4874 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4876 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4880 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4882 fprintf(fff, "%s\n", buf);
4887 /* Dump the screen */
4888 for (y = 0; y < hgt; y++)
4895 for (x = 0; x < wid - 1; x++)
4899 /* Get the attr/char */
4900 (void)(Term_what(x, y, &a, &c));
4904 case '&': cc = "&"; break;
4905 case '<': cc = "<"; break;
4906 case '>': cc = ">"; break;
4908 case 0x1f: c = '.'; break;
4909 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4914 if ((y == 0 && x == 0) || a != old_a) {
4915 rv = angband_color_table[a][1];
4916 gv = angband_color_table[a][2];
4917 bv = angband_color_table[a][3];
4918 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4919 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4923 fprintf(fff, "%s", cc);
4925 fprintf(fff, "%c", c);
4928 fprintf(fff, "</font>");
4931 for (i = 0; html_foot[i]; i++)
4932 fputs(html_foot[i], fff);
4937 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4939 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4943 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4945 fprintf(fff, "%s\n", buf);
4958 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4966 * Hack -- save a screen dump to a file
4968 static void do_cmd_save_screen_html(void)
4970 char buf[1024], tmp[256] = "screen.html";
4972 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4975 /* Build the filename */
4976 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4980 do_cmd_save_screen_html_aux(buf, 1);
4985 * Redefinable "save_screen" action
4987 void (*screendump_aux)(void) = NULL;
4991 * Hack -- save a screen dump to a file
4993 void do_cmd_save_screen(void)
4995 bool old_use_graphics = use_graphics;
4996 bool html_dump = FALSE;
5000 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5004 if (c == 'Y' || c == 'y')
5006 else if (c == 'H' || c == 'h')
5018 Term_get_size(&wid, &hgt);
5020 if (old_use_graphics)
5022 use_graphics = FALSE;
5024 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5030 do_cmd_save_screen_html();
5034 /* Do we use a special screendump function ? */
5035 else if (screendump_aux)
5037 /* Dump the screen to a graphics file */
5038 (*screendump_aux)();
5040 else /* Dump the screen as text */
5044 SYMBOL_CODE c = ' ';
5048 /* Build the filename */
5049 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5051 /* File type is "TEXT" */
5052 FILE_TYPE(FILE_TYPE_TEXT);
5054 /* Append to the file */
5055 fff = my_fopen(buf, "w");
5059 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5067 /* Dump the screen */
5068 for (y = 0; y < hgt; y++)
5071 for (x = 0; x < wid - 1; x++)
5073 /* Get the attr/char */
5074 (void)(Term_what(x, y, &a, &c));
5084 fprintf(fff, "%s\n", buf);
5091 /* Dump the screen */
5092 for (y = 0; y < hgt; y++)
5095 for (x = 0; x < wid - 1; x++)
5097 /* Get the attr/char */
5098 (void)(Term_what(x, y, &a, &c));
5101 buf[x] = hack[a&0x0F];
5108 fprintf(fff, "%s\n", buf);
5117 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5122 if (old_use_graphics)
5124 use_graphics = TRUE;
5126 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5133 * Sorting hook -- Comp function -- see below
5135 * We use "u" to point to array of monster indexes,
5136 * and "v" to select the type of sorting to perform on "u".
5138 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5140 u16b *who = (u16b*)(u);
5142 u16b *why = (u16b*)(v);
5149 /* Sort by total kills */
5152 /* Extract total kills */
5153 z1 = a_info[w1].tval;
5154 z2 = a_info[w2].tval;
5156 /* Compare total kills */
5157 if (z1 < z2) return (TRUE);
5158 if (z1 > z2) return (FALSE);
5162 /* Sort by monster level */
5165 /* Extract levels */
5166 z1 = a_info[w1].sval;
5167 z2 = a_info[w2].sval;
5169 /* Compare levels */
5170 if (z1 < z2) return (TRUE);
5171 if (z1 > z2) return (FALSE);
5175 /* Sort by monster experience */
5178 /* Extract experience */
5179 z1 = a_info[w1].level;
5180 z2 = a_info[w2].level;
5182 /* Compare experience */
5183 if (z1 < z2) return (TRUE);
5184 if (z1 > z2) return (FALSE);
5188 /* Compare indexes */
5194 * Sorting hook -- Swap function -- see below
5196 * We use "u" to point to array of monster indexes,
5197 * and "v" to select the type of sorting to perform.
5199 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5201 u16b *who = (u16b*)(u);
5216 * Check the status of "artifacts"
5218 static void do_cmd_knowledge_artifacts(void)
5228 GAME_TEXT file_name[1024];
5229 GAME_TEXT base_name[MAX_NLEN];
5233 /* Open a new file */
5234 fff = my_fopen_temp(file_name, 1024);
5237 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5242 /* Allocate the "who" array */
5243 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5245 /* Allocate the "okay" array */
5246 C_MAKE(okay, max_a_idx, bool);
5248 /* Scan the artifacts */
5249 for (k = 0; k < max_a_idx; k++)
5251 artifact_type *a_ptr = &a_info[k];
5256 /* Skip "empty" artifacts */
5257 if (!a_ptr->name) continue;
5259 /* Skip "uncreated" artifacts */
5260 if (!a_ptr->cur_num) continue;
5266 /* Check the dungeon */
5267 for (y = 0; y < cur_hgt; y++)
5269 for (x = 0; x < cur_wid; x++)
5271 cave_type *c_ptr = &cave[y][x];
5273 OBJECT_IDX this_o_idx, next_o_idx = 0;
5275 /* Scan all objects in the grid */
5276 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5279 o_ptr = &o_list[this_o_idx];
5281 /* Acquire next object */
5282 next_o_idx = o_ptr->next_o_idx;
5284 /* Ignore non-artifacts */
5285 if (!object_is_fixed_artifact(o_ptr)) continue;
5287 /* Ignore known items */
5288 if (object_is_known(o_ptr)) continue;
5290 /* Note the artifact */
5291 okay[o_ptr->name1] = FALSE;
5296 /* Check the inventory and equipment */
5297 for (i = 0; i < INVEN_TOTAL; i++)
5299 object_type *o_ptr = &inventory[i];
5301 /* Ignore non-objects */
5302 if (!o_ptr->k_idx) continue;
5304 /* Ignore non-artifacts */
5305 if (!object_is_fixed_artifact(o_ptr)) continue;
5307 /* Ignore known items */
5308 if (object_is_known(o_ptr)) continue;
5310 /* Note the artifact */
5311 okay[o_ptr->name1] = FALSE;
5314 for (k = 0; k < max_a_idx; k++)
5316 if (okay[k]) who[n++] = k;
5319 /* Select the sort method */
5320 ang_sort_comp = ang_sort_art_comp;
5321 ang_sort_swap = ang_sort_art_swap;
5323 /* Sort the array by dungeon depth of monsters */
5324 ang_sort(who, &why, n);
5326 /* Scan the artifacts */
5327 for (k = 0; k < n; k++)
5329 artifact_type *a_ptr = &a_info[who[k]];
5332 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5334 /* Obtain the base object type */
5335 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5344 /* Create fake object */
5345 object_prep(q_ptr, z);
5347 /* Make it an artifact */
5348 q_ptr->name1 = (byte)who[k];
5350 /* Display as if known */
5351 q_ptr->ident |= IDENT_STORE;
5353 /* Describe the artifact */
5354 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5357 /* Hack -- Build the artifact name */
5358 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5361 /* Free the "who" array */
5362 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5364 /* Free the "okay" array */
5365 C_KILL(okay, max_a_idx, bool);
5368 /* Display the file contents */
5369 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5371 /* Remove the file */
5377 * Display known uniques
5378 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5380 static void do_cmd_knowledge_uniques(void)
5389 GAME_TEXT file_name[1024];
5392 int n_alive_surface = 0;
5393 int n_alive_over100 = 0;
5394 int n_alive_total = 0;
5397 for (i = 0; i < 10; i++) n_alive[i] = 0;
5399 /* Open a new file */
5400 fff = my_fopen_temp(file_name, 1024);
5404 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5409 /* Allocate the "who" array */
5410 C_MAKE(who, max_r_idx, MONRACE_IDX);
5412 /* Scan the monsters */
5413 for (i = 1; i < max_r_idx; i++)
5415 monster_race *r_ptr = &r_info[i];
5418 if (!r_ptr->name) continue;
5420 /* Require unique monsters */
5421 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5423 /* Only display "known" uniques */
5424 if (!cheat_know && !r_ptr->r_sights) continue;
5426 /* Only print rarity <= 100 uniques */
5427 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5429 /* Only "alive" uniques */
5430 if (r_ptr->max_num == 0) continue;
5434 lev = (r_ptr->level - 1) / 10;
5438 if (max_lev < lev) max_lev = lev;
5440 else n_alive_over100++;
5442 else n_alive_surface++;
5444 /* Collect "appropriate" monsters */
5448 /* Select the sort method */
5449 ang_sort_comp = ang_sort_comp_hook;
5450 ang_sort_swap = ang_sort_swap_hook;
5452 /* Sort the array by dungeon depth of monsters */
5453 ang_sort(who, &why, n);
5455 if (n_alive_surface)
5457 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5458 n_alive_total += n_alive_surface;
5460 for (i = 0; i <= max_lev; i++)
5462 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5463 n_alive_total += n_alive[i];
5465 if (n_alive_over100)
5467 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5468 n_alive_total += n_alive_over100;
5473 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5474 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5478 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5481 /* Scan the monster races */
5482 for (k = 0; k < n; k++)
5484 monster_race *r_ptr = &r_info[who[k]];
5486 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5489 /* Free the "who" array */
5490 C_KILL(who, max_r_idx, s16b);
5493 /* Display the file contents */
5494 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5496 /* Remove the file */
5502 * Display weapon-exp
5504 static void do_cmd_knowledge_weapon_exp(void)
5506 int i, num, weapon_exp;
5511 GAME_TEXT file_name[1024];
5514 /* Open a new file */
5515 fff = my_fopen_temp(file_name, 1024);
5517 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5522 for (i = 0; i < 5; i++)
5524 for (num = 0; num < 64; num++)
5526 for (j = 0; j < max_k_idx; j++)
5528 object_kind *k_ptr = &k_info[j];
5530 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5532 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5534 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5536 fprintf(fff, "%-25s ", tmp);
5537 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5538 else fprintf(fff, " ");
5539 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5540 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5549 /* Display the file contents */
5550 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5552 /* Remove the file */
5558 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5562 static void do_cmd_knowledge_spell_exp(void)
5565 int spell_exp, exp_level;
5568 const magic_type *s_ptr;
5570 GAME_TEXT file_name[1024];
5572 /* Open a new file */
5573 fff = my_fopen_temp(file_name, 1024);
5575 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5580 if (p_ptr->realm1 != REALM_NONE)
5582 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5583 for (i = 0; i < 32; i++)
5585 if (!is_magic(p_ptr->realm1))
5587 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5591 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5593 if (s_ptr->slevel >= 99) continue;
5594 spell_exp = p_ptr->spell_exp[i];
5595 exp_level = spell_exp_level(spell_exp);
5596 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5597 if (p_ptr->realm1 == REALM_HISSATSU)
5598 fprintf(fff, "[--]");
5601 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5602 else fprintf(fff, " ");
5603 fprintf(fff, "%s", exp_level_str[exp_level]);
5605 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5610 if (p_ptr->realm2 != REALM_NONE)
5612 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5613 for (i = 0; i < 32; i++)
5615 if (!is_magic(p_ptr->realm1))
5617 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5621 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5623 if (s_ptr->slevel >= 99) continue;
5625 spell_exp = p_ptr->spell_exp[i + 32];
5626 exp_level = spell_exp_level(spell_exp);
5627 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5628 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5629 else fprintf(fff, " ");
5630 fprintf(fff, "%s", exp_level_str[exp_level]);
5631 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5637 /* Display the file contents */
5638 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5640 /* Remove the file */
5646 * @brief スキル情報を表示するコマンドのメインルーチン /
5650 static void do_cmd_knowledge_skill_exp(void)
5652 int i = 0, skill_exp;
5656 GAME_TEXT file_name[1024];
5657 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5658 _("二刀流 ", "Dual Wielding "),
5659 _("乗馬 ", "Riding ")};
5661 /* Open a new file */
5662 fff = my_fopen_temp(file_name, 1024);
5664 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5669 for (i = 0; i < 3; i++)
5671 skill_exp = p_ptr->skill_exp[i];
5672 fprintf(fff, "%-20s ", skill_name[i]);
5673 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5674 else fprintf(fff, " ");
5675 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5676 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5681 /* Display the file contents */
5682 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5684 /* Remove the file */
5690 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5691 * @param Name 変換したい文字列の参照ポインタ
5694 void plural_aux(char *Name)
5696 int NameLen = strlen(Name);
5698 if (my_strstr(Name, "Disembodied hand"))
5700 strcpy(Name, "Disembodied hands that strangled people");
5702 else if (my_strstr(Name, "Colour out of space"))
5704 strcpy(Name, "Colours out of space");
5706 else if (my_strstr(Name, "stairway to hell"))
5708 strcpy(Name, "stairways to hell");
5710 else if (my_strstr(Name, "Dweller on the threshold"))
5712 strcpy(Name, "Dwellers on the threshold");
5714 else if (my_strstr(Name, " of "))
5716 concptr aider = my_strstr(Name, " of ");
5727 if (dummy[i-1] == 's')
5729 strcpy(&(dummy[i]), "es");
5734 strcpy(&(dummy[i]), "s");
5737 strcpy(&(dummy[i+1]), aider);
5738 strcpy(Name, dummy);
5740 else if (my_strstr(Name, "coins"))
5743 strcpy(dummy, "piles of ");
5744 strcat(dummy, Name);
5745 strcpy(Name, dummy);
5748 else if (my_strstr(Name, "Manes"))
5752 else if (streq(&(Name[NameLen - 2]), "ey"))
5754 strcpy(&(Name[NameLen - 2]), "eys");
5756 else if (Name[NameLen - 1] == 'y')
5758 strcpy(&(Name[NameLen - 1]), "ies");
5760 else if (streq(&(Name[NameLen - 4]), "ouse"))
5762 strcpy(&(Name[NameLen - 4]), "ice");
5764 else if (streq(&(Name[NameLen - 2]), "us"))
5766 strcpy(&(Name[NameLen - 2]), "i");
5768 else if (streq(&(Name[NameLen - 6]), "kelman"))
5770 strcpy(&(Name[NameLen - 6]), "kelmen");
5772 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5774 strcpy(&(Name[NameLen - 8]), "wordsmen");
5776 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5778 strcpy(&(Name[NameLen - 7]), "oodsmen");
5780 else if (streq(&(Name[NameLen - 7]), "eastman"))
5782 strcpy(&(Name[NameLen - 7]), "eastmen");
5784 else if (streq(&(Name[NameLen - 8]), "izardman"))
5786 strcpy(&(Name[NameLen - 8]), "izardmen");
5788 else if (streq(&(Name[NameLen - 5]), "geist"))
5790 strcpy(&(Name[NameLen - 5]), "geister");
5792 else if (streq(&(Name[NameLen - 2]), "ex"))
5794 strcpy(&(Name[NameLen - 2]), "ices");
5796 else if (streq(&(Name[NameLen - 2]), "lf"))
5798 strcpy(&(Name[NameLen - 2]), "lves");
5800 else if (suffix(Name, "ch") ||
5801 suffix(Name, "sh") ||
5802 suffix(Name, "nx") ||
5803 suffix(Name, "s") ||
5806 strcpy(&(Name[NameLen]), "es");
5810 strcpy(&(Name[NameLen]), "s");
5815 * @brief 現在のペットを表示するコマンドのメインルーチン /
5816 * Display current pets
5819 static void do_cmd_knowledge_pets(void)
5823 monster_type *m_ptr;
5824 GAME_TEXT pet_name[MAX_NLEN];
5826 int show_upkeep = 0;
5827 GAME_TEXT file_name[1024];
5830 /* Open a new file */
5831 fff = my_fopen_temp(file_name, 1024);
5833 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5838 /* Process the monsters (backwards) */
5839 for (i = m_max - 1; i >= 1; i--)
5841 /* Access the monster */
5844 /* Ignore "dead" monsters */
5845 if (!m_ptr->r_idx) continue;
5847 /* Calculate "upkeep" for pets */
5851 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5852 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5856 show_upkeep = calculate_upkeep();
5858 fprintf(fff, "----------------------------------------------\n");
5860 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5862 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5864 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5869 /* Display the file contents */
5870 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5872 /* Remove the file */
5878 * @brief 現在のペットを表示するコマンドのメインルーチン /
5881 * @note the player ghosts are ignored.
5883 static void do_cmd_knowledge_kill_count(void)
5890 GAME_TEXT file_name[1024];
5895 /* Open a new file */
5896 fff = my_fopen_temp(file_name, 1024);
5899 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5904 /* Allocate the "who" array */
5905 C_MAKE(who, max_r_idx, MONRACE_IDX);
5908 /* Monsters slain */
5911 for (kk = 1; kk < max_r_idx; kk++)
5913 monster_race *r_ptr = &r_info[kk];
5915 if (r_ptr->flags1 & (RF1_UNIQUE))
5917 bool dead = (r_ptr->max_num == 0);
5926 MONSTER_NUMBER This = r_ptr->r_pkills;
5936 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5939 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5941 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5947 /* Scan the monsters */
5948 for (i = 1; i < max_r_idx; i++)
5950 monster_race *r_ptr = &r_info[i];
5952 /* Use that monster */
5953 if (r_ptr->name) who[n++] = i;
5956 /* Select the sort method */
5957 ang_sort_comp = ang_sort_comp_hook;
5958 ang_sort_swap = ang_sort_swap_hook;
5960 /* Sort the array by dungeon depth of monsters */
5961 ang_sort(who, &why, n);
5963 /* Scan the monster races */
5964 for (k = 0; k < n; k++)
5966 monster_race *r_ptr = &r_info[who[k]];
5968 if (r_ptr->flags1 & (RF1_UNIQUE))
5970 bool dead = (r_ptr->max_num == 0);
5974 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5980 MONSTER_NUMBER This = r_ptr->r_pkills;
5985 /* p,tは人と数える by ita */
5986 if (my_strchr("pt", r_ptr->d_char))
5987 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5989 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5993 if (my_strstr(r_name + r_ptr->name, "coins"))
5995 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5999 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6005 strcpy(ToPlural, (r_name + r_ptr->name));
6006 plural_aux(ToPlural);
6007 fprintf(fff, " %d %s\n", This, ToPlural);
6017 fprintf(fff,"----------------------------------------------\n");
6019 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6021 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6025 /* Free the "who" array */
6026 C_KILL(who, max_r_idx, s16b);
6029 /* Display the file contents */
6030 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6032 /* Remove the file */
6038 * @brief モンスター情報リスト中のグループを表示する /
6039 * Display the object groups.
6043 * @param per_page リストの表示行
6044 * @param grp_idx グループのID配列
6045 * @param group_text グループ名の文字列配列
6046 * @param grp_cur 現在の選択ID
6047 * @param grp_top 現在の選択リスト最上部ID
6050 static void display_group_list(int col, int row, int wid, int per_page, IDX grp_idx[], concptr group_text[], int grp_cur, int grp_top)
6054 /* Display lines until done */
6055 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6057 /* Get the group index */
6058 int grp = grp_idx[grp_top + i];
6060 /* Choose a color */
6061 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6063 /* Erase the entire line */
6064 Term_erase(col, row + i, wid);
6066 /* Display the group label */
6067 c_put_str(attr, group_text[grp], row + i, col);
6073 * Move the cursor in a browser window
6075 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6076 IDX *list_cur, int list_cnt)
6081 IDX list = *list_cur;
6083 /* Extract direction */
6086 /* Hack -- scroll up full screen */
6091 /* Hack -- scroll down full screen */
6096 d = get_keymap_dir(ch);
6101 /* Diagonals - hack */
6102 if ((ddx[d] > 0) && ddy[d])
6107 Term_get_size(&wid, &hgt);
6109 browser_rows = hgt - 8;
6111 /* Browse group list */
6116 /* Move up or down */
6117 grp += ddy[d] * (browser_rows - 1);
6120 if (grp >= grp_cnt) grp = grp_cnt - 1;
6121 if (grp < 0) grp = 0;
6122 if (grp != old_grp) list = 0;
6125 /* Browse sub-list list */
6128 /* Move up or down */
6129 list += ddy[d] * browser_rows;
6132 if (list >= list_cnt) list = list_cnt - 1;
6133 if (list < 0) list = 0;
6145 if (col < 0) col = 0;
6146 if (col > 1) col = 1;
6153 /* Browse group list */
6158 /* Move up or down */
6162 if (grp >= grp_cnt) grp = grp_cnt - 1;
6163 if (grp < 0) grp = 0;
6164 if (grp != old_grp) list = 0;
6167 /* Browse sub-list list */
6170 /* Move up or down */
6174 if (list >= list_cnt) list = list_cnt - 1;
6175 if (list < 0) list = 0;
6186 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6190 /* Clear the display lines */
6191 for (i = 0; i < height; i++)
6193 Term_erase(col, row + i, width);
6196 /* Bigtile mode uses double width */
6197 if (use_bigtile) width /= 2;
6199 /* Display lines until done */
6200 for (i = 0; i < height; i++)
6202 /* Display columns until done */
6203 for (j = 0; j < width; j++)
6207 TERM_LEN x = col + j;
6208 TERM_LEN y = row + i;
6211 /* Bigtile mode uses double width */
6212 if (use_bigtile) x += j;
6217 /* Ignore illegal characters */
6218 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6219 (!use_graphics && ic > 0x7f))
6225 /* Force correct code for both ASCII character and tile */
6226 if (c & 0x80) a |= 0x80;
6228 /* Display symbol */
6229 Term_queue_bigchar(x, y, a, c, 0, 0);
6236 * Place the cursor at the collect position for visual mode
6238 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6240 int i = (a & 0x7f) - attr_top;
6241 int j = c - char_left;
6243 TERM_LEN x = col + j;
6244 TERM_LEN y = row + i;
6246 /* Bigtile mode uses double width */
6247 if (use_bigtile) x += j;
6249 /* Place the cursor */
6255 * Clipboard variables for copy&paste in visual mode
6257 static TERM_COLOR attr_idx = 0;
6258 static byte char_idx = 0;
6260 /* Hack -- for feature lighting */
6261 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6262 static byte char_idx_feat[F_LIT_MAX];
6265 * Do visual mode command -- Change symbols
6267 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6268 int height, int width,
6269 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6270 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6272 static TERM_COLOR attr_old = 0;
6273 static SYMBOL_CODE char_old = 0;
6278 if (*visual_list_ptr)
6281 *cur_attr_ptr = attr_old;
6282 *cur_char_ptr = char_old;
6283 *visual_list_ptr = FALSE;
6291 if (*visual_list_ptr)
6294 *visual_list_ptr = FALSE;
6295 *need_redraw = TRUE;
6303 if (!*visual_list_ptr)
6305 *visual_list_ptr = TRUE;
6307 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6308 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6310 attr_old = *cur_attr_ptr;
6311 char_old = *cur_char_ptr;
6322 /* Set the visual */
6323 attr_idx = *cur_attr_ptr;
6324 char_idx = *cur_char_ptr;
6326 /* Hack -- for feature lighting */
6327 for (i = 0; i < F_LIT_MAX; i++)
6329 attr_idx_feat[i] = 0;
6330 char_idx_feat[i] = 0;
6337 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6340 *cur_attr_ptr = attr_idx;
6341 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6342 if (!*visual_list_ptr) *need_redraw = TRUE;
6348 *cur_char_ptr = char_idx;
6349 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6350 if (!*visual_list_ptr) *need_redraw = TRUE;
6356 if (*visual_list_ptr)
6359 int d = get_keymap_dir(ch);
6360 byte a = (*cur_attr_ptr & 0x7f);
6361 byte c = *cur_char_ptr;
6363 if (use_bigtile) eff_width = width / 2;
6364 else eff_width = width;
6366 /* Restrict direction */
6367 if ((a == 0) && (ddy[d] < 0)) d = 0;
6368 if ((c == 0) && (ddx[d] < 0)) d = 0;
6369 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6370 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6375 /* Force correct code for both ASCII character and tile */
6376 if (c & 0x80) a |= 0x80;
6378 /* Set the visual */
6383 /* Move the frame */
6384 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6385 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6386 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6387 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6393 /* Visual mode command is not used */
6399 * Display the monsters in a group.
6401 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6402 int mon_cur, int mon_top, bool visual_only)
6406 /* Display lines until done */
6407 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6411 /* Get the race index */
6412 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6414 /* Access the race */
6415 monster_race *r_ptr = &r_info[r_idx];
6417 /* Choose a color */
6418 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6420 /* Display the name */
6421 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6423 /* Hack -- visual_list mode */
6426 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6428 if (p_ptr->wizard || visual_only)
6430 c_prt(attr, format("%d", r_idx), row + i, 62);
6433 /* Erase chars before overwritten by the race letter */
6434 Term_erase(69, row + i, 255);
6436 /* Display symbol */
6437 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6442 if (!(r_ptr->flags1 & RF1_UNIQUE))
6443 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6445 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6446 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6450 /* Clear remaining lines */
6451 for (; i < per_page; i++)
6453 Term_erase(col, row + i, 255);
6459 * Display known monsters.
6461 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6465 IDX grp_cur, grp_top, old_grp_cur;
6466 IDX mon_cur, mon_top;
6467 IDX grp_cnt, grp_idx[100];
6475 bool visual_list = FALSE;
6476 TERM_COLOR attr_top = 0;
6484 Term_get_size(&wid, &hgt);
6486 browser_rows = hgt - 8;
6488 /* Allocate the "mon_idx" array */
6489 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6494 if (direct_r_idx < 0)
6496 mode = visual_only ? 0x03 : 0x01;
6498 /* Check every group */
6499 for (i = 0; monster_group_text[i] != NULL; i++)
6501 /* Measure the label */
6502 len = strlen(monster_group_text[i]);
6504 /* Save the maximum length */
6505 if (len > max) max = len;
6507 /* See if any monsters are known */
6508 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6510 /* Build a list of groups with known monsters */
6511 grp_idx[grp_cnt++] = i;
6519 mon_idx[0] = direct_r_idx;
6522 /* Terminate the list */
6525 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6526 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6529 /* Terminate the list */
6530 grp_idx[grp_cnt] = -1;
6533 grp_cur = grp_top = 0;
6534 mon_cur = mon_top = 0;
6539 mode = visual_only ? 0x02 : 0x00;
6544 monster_race *r_ptr;
6549 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6550 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6551 prt(_("名前", "Name"), 4, max + 3);
6552 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6553 prt(_("文字", "Sym"), 4, 67);
6554 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6556 for (i = 0; i < 78; i++)
6558 Term_putch(i, 5, TERM_WHITE, '=');
6561 if (direct_r_idx < 0)
6563 for (i = 0; i < browser_rows; i++)
6565 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6572 if (direct_r_idx < 0)
6574 /* Scroll group list */
6575 if (grp_cur < grp_top) grp_top = grp_cur;
6576 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6578 /* Display a list of monster groups */
6579 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6581 if (old_grp_cur != grp_cur)
6583 old_grp_cur = grp_cur;
6585 /* Get a list of monsters in the current group */
6586 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6589 /* Scroll monster list */
6590 while (mon_cur < mon_top)
6591 mon_top = MAX(0, mon_top - browser_rows/2);
6592 while (mon_cur >= mon_top + browser_rows)
6593 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6598 /* Display a list of monsters in the current group */
6599 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6605 /* Display a monster name */
6606 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6608 /* Display visual list below first monster */
6609 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6613 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6614 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6615 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6616 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6619 /* Get the current monster */
6620 r_ptr = &r_info[mon_idx[mon_cur]];
6624 /* Mega Hack -- track this monster race */
6625 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6631 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6635 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6639 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6644 /* Do visual mode command if needed */
6645 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))
6647 if (direct_r_idx >= 0)
6672 /* Recall on screen */
6673 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6675 screen_roff(mon_idx[mon_cur], 0);
6686 /* Move the cursor */
6687 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6694 /* Free the "mon_idx" array */
6695 C_KILL(mon_idx, max_r_idx, s16b);
6700 * Display the objects in a group.
6702 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6703 int object_cur, int object_top, bool visual_only)
6707 /* Display lines until done */
6708 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6710 GAME_TEXT o_name[MAX_NLEN];
6713 object_kind *flavor_k_ptr;
6715 /* Get the object index */
6716 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6718 /* Access the object */
6719 object_kind *k_ptr = &k_info[k_idx];
6721 /* Choose a color */
6722 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6723 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6726 if (!visual_only && k_ptr->flavor)
6728 /* Appearance of this object is shuffled */
6729 flavor_k_ptr = &k_info[k_ptr->flavor];
6733 /* Appearance of this object is very normal */
6734 flavor_k_ptr = k_ptr;
6739 attr = ((i + object_top == object_cur) ? cursor : attr);
6741 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6744 strip_name(o_name, k_idx);
6749 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6752 /* Display the name */
6753 c_prt(attr, o_name, row + i, col);
6755 /* Hack -- visual_list mode */
6758 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);
6760 if (p_ptr->wizard || visual_only)
6762 c_prt(attr, format("%d", k_idx), row + i, 70);
6765 a = flavor_k_ptr->x_attr;
6766 c = flavor_k_ptr->x_char;
6768 /* Display symbol */
6769 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6772 /* Clear remaining lines */
6773 for (; i < per_page; i++)
6775 Term_erase(col, row + i, 255);
6780 * Describe fake object
6782 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6785 object_type object_type_body;
6786 o_ptr = &object_type_body;
6789 /* Create the artifact */
6790 object_prep(o_ptr, k_idx);
6792 /* It's fully know */
6793 o_ptr->ident |= IDENT_KNOWN;
6795 /* Track the object */
6796 /* object_actual_track(o_ptr); */
6798 /* Hack - mark as fake */
6799 /* term_obj_real = FALSE; */
6802 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6804 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6812 * Display known objects
6814 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6818 IDX grp_cur, grp_top, old_grp_cur;
6819 IDX object_old, object_cur, object_top;
6829 bool visual_list = FALSE;
6830 TERM_COLOR attr_top = 0;
6838 Term_get_size(&wid, &hgt);
6840 browser_rows = hgt - 8;
6842 /* Allocate the "object_idx" array */
6843 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6848 if (direct_k_idx < 0)
6850 mode = visual_only ? 0x03 : 0x01;
6852 /* Check every group */
6853 for (i = 0; object_group_text[i] != NULL; i++)
6855 /* Measure the label */
6856 len = strlen(object_group_text[i]);
6858 /* Save the maximum length */
6859 if (len > max) max = len;
6861 /* See if any monsters are known */
6862 if (collect_objects(i, object_idx, mode))
6864 /* Build a list of groups with known monsters */
6865 grp_idx[grp_cnt++] = i;
6874 object_kind *k_ptr = &k_info[direct_k_idx];
6875 object_kind *flavor_k_ptr;
6877 if (!visual_only && k_ptr->flavor)
6879 /* Appearance of this object is shuffled */
6880 flavor_k_ptr = &k_info[k_ptr->flavor];
6884 /* Appearance of this object is very normal */
6885 flavor_k_ptr = k_ptr;
6888 object_idx[0] = direct_k_idx;
6889 object_old = direct_k_idx;
6892 /* Terminate the list */
6895 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6896 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6899 /* Terminate the list */
6900 grp_idx[grp_cnt] = -1;
6903 grp_cur = grp_top = 0;
6904 object_cur = object_top = 0;
6909 mode = visual_only ? 0x02 : 0x00;
6914 object_kind *k_ptr, *flavor_k_ptr;
6921 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6922 if (direct_k_idx < 0) prt("グループ", 4, 0);
6923 prt("名前", 4, max + 3);
6924 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6927 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6928 if (direct_k_idx < 0) prt("Group", 4, 0);
6929 prt("Name", 4, max + 3);
6930 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6934 for (i = 0; i < 78; i++)
6936 Term_putch(i, 5, TERM_WHITE, '=');
6939 if (direct_k_idx < 0)
6941 for (i = 0; i < browser_rows; i++)
6943 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6950 if (direct_k_idx < 0)
6952 /* Scroll group list */
6953 if (grp_cur < grp_top) grp_top = grp_cur;
6954 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6956 /* Display a list of object groups */
6957 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6959 if (old_grp_cur != grp_cur)
6961 old_grp_cur = grp_cur;
6963 /* Get a list of objects in the current group */
6964 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6967 /* Scroll object list */
6968 while (object_cur < object_top)
6969 object_top = MAX(0, object_top - browser_rows/2);
6970 while (object_cur >= object_top + browser_rows)
6971 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6976 /* Display a list of objects in the current group */
6977 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6981 object_top = object_cur;
6983 /* Display a list of objects in the current group */
6984 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6986 /* Display visual list below first object */
6987 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6990 /* Get the current object */
6991 k_ptr = &k_info[object_idx[object_cur]];
6993 if (!visual_only && k_ptr->flavor)
6995 /* Appearance of this object is shuffled */
6996 flavor_k_ptr = &k_info[k_ptr->flavor];
7000 /* Appearance of this object is very normal */
7001 flavor_k_ptr = k_ptr;
7006 prt(format("<方向>%s%s%s, ESC",
7007 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7008 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7009 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7012 prt(format("<dir>%s%s%s, ESC",
7013 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7014 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7015 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7021 /* Mega Hack -- track this object */
7022 if (object_cnt) object_kind_track(object_idx[object_cur]);
7024 /* The "current" object changed */
7025 if (object_old != object_idx[object_cur])
7029 /* Remember the "current" object */
7030 object_old = object_idx[object_cur];
7036 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7040 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7044 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7049 /* Do visual mode command if needed */
7050 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))
7052 if (direct_k_idx >= 0)
7077 /* Recall on screen */
7078 if (!visual_list && !visual_only && (grp_cnt > 0))
7080 desc_obj_fake(object_idx[object_cur]);
7088 /* Move the cursor */
7089 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7095 /* Free the "object_idx" array */
7096 C_KILL(object_idx, max_k_idx, IDX);
7101 * Display the features in a group.
7103 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7104 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7106 int lit_col[F_LIT_MAX], i, j;
7107 int f_idx_col = use_bigtile ? 62 : 64;
7109 /* Correct columns 1 and 4 */
7110 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7111 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7112 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7114 /* Display lines until done */
7115 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7120 FEAT_IDX f_idx = feat_idx[feat_top + i];
7122 /* Access the index */
7123 feature_type *f_ptr = &f_info[f_idx];
7125 int row_i = row + i;
7127 /* Choose a color */
7128 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7130 /* Display the name */
7131 c_prt(attr, f_name + f_ptr->name, row_i, col);
7133 /* Hack -- visual_list mode */
7136 /* Display lighting level */
7137 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7139 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));
7141 if (p_ptr->wizard || visual_only)
7143 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7146 /* Display symbol */
7147 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);
7149 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7150 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7152 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7154 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7156 /* Mega-hack -- Use non-standard colour */
7157 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7159 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7163 /* Clear remaining lines */
7164 for (; i < per_page; i++)
7166 Term_erase(col, row + i, 255);
7172 * Interact with feature visuals.
7174 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7178 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7179 FEAT_IDX feat_cur, feat_top;
7181 FEAT_IDX grp_idx[100];
7185 TERM_LEN column = 0;
7189 bool visual_list = FALSE;
7190 TERM_COLOR attr_top = 0;
7193 TERM_LEN browser_rows;
7196 TERM_COLOR attr_old[F_LIT_MAX];
7197 SYMBOL_CODE char_old[F_LIT_MAX];
7198 TERM_COLOR *cur_attr_ptr;
7199 SYMBOL_CODE *cur_char_ptr;
7201 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7202 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7204 Term_get_size(&wid, &hgt);
7206 browser_rows = hgt - 8;
7208 /* Allocate the "feat_idx" array */
7209 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7214 if (direct_f_idx < 0)
7216 /* Check every group */
7217 for (i = 0; feature_group_text[i] != NULL; i++)
7219 /* Measure the label */
7220 len = strlen(feature_group_text[i]);
7222 /* Save the maximum length */
7223 if (len > max) max = len;
7225 /* See if any features are known */
7226 if (collect_features(i, feat_idx, 0x01))
7228 /* Build a list of groups with known features */
7229 grp_idx[grp_cnt++] = i;
7237 feature_type *f_ptr = &f_info[direct_f_idx];
7239 feat_idx[0] = direct_f_idx;
7242 /* Terminate the list */
7245 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7246 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7248 for (i = 0; i < F_LIT_MAX; i++)
7250 attr_old[i] = f_ptr->x_attr[i];
7251 char_old[i] = f_ptr->x_char[i];
7255 /* Terminate the list */
7256 grp_idx[grp_cnt] = -1;
7259 grp_cur = grp_top = 0;
7260 feat_cur = feat_top = 0;
7268 feature_type *f_ptr;
7274 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7275 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7276 prt(_("名前", "Name"), 4, max + 3);
7279 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7280 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7284 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7285 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7288 for (i = 0; i < 78; i++)
7290 Term_putch(i, 5, TERM_WHITE, '=');
7293 if (direct_f_idx < 0)
7295 for (i = 0; i < browser_rows; i++)
7297 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7304 if (direct_f_idx < 0)
7306 /* Scroll group list */
7307 if (grp_cur < grp_top) grp_top = grp_cur;
7308 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7310 /* Display a list of feature groups */
7311 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7313 if (old_grp_cur != grp_cur)
7315 old_grp_cur = grp_cur;
7317 /* Get a list of features in the current group */
7318 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7321 /* Scroll feature list */
7322 while (feat_cur < feat_top)
7323 feat_top = MAX(0, feat_top - browser_rows/2);
7324 while (feat_cur >= feat_top + browser_rows)
7325 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7330 /* Display a list of features in the current group */
7331 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7335 feat_top = feat_cur;
7337 /* Display a list of features in the current group */
7338 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7340 /* Display visual list below first object */
7341 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7345 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7346 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7347 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7350 /* Get the current feature */
7351 f_ptr = &f_info[feat_idx[feat_cur]];
7352 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7353 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7357 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7361 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7365 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7370 if (visual_list && ((ch == 'A') || (ch == 'a')))
7372 int prev_lighting_level = *lighting_level;
7376 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7377 else (*lighting_level)--;
7381 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7382 else (*lighting_level)++;
7385 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7386 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7388 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7389 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7394 else if ((ch == 'D') || (ch == 'd'))
7396 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7397 byte prev_x_char = f_ptr->x_char[*lighting_level];
7399 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7403 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7404 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7406 if (prev_x_char != f_ptr->x_char[*lighting_level])
7407 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7409 else *need_redraw = TRUE;
7414 /* Do visual mode command if needed */
7415 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))
7419 /* Restore previous visual settings */
7421 for (i = 0; i < F_LIT_MAX; i++)
7423 f_ptr->x_attr[i] = attr_old[i];
7424 f_ptr->x_char[i] = char_old[i];
7431 if (direct_f_idx >= 0) flag = TRUE;
7432 else *lighting_level = F_LIT_STANDARD;
7435 /* Preserve current visual settings */
7438 for (i = 0; i < F_LIT_MAX; i++)
7440 attr_old[i] = f_ptr->x_attr[i];
7441 char_old[i] = f_ptr->x_char[i];
7443 *lighting_level = F_LIT_STANDARD;
7450 for (i = 0; i < F_LIT_MAX; i++)
7452 attr_idx_feat[i] = f_ptr->x_attr[i];
7453 char_idx_feat[i] = f_ptr->x_char[i];
7462 /* Allow TERM_DARK text */
7463 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7465 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7466 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7484 /* Move the cursor */
7485 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7491 /* Free the "feat_idx" array */
7492 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7497 * List wanted monsters
7499 static void do_cmd_knowledge_kubi(void)
7504 GAME_TEXT file_name[1024];
7507 /* Open a new file */
7508 fff = my_fopen_temp(file_name, 1024);
7510 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7517 bool listed = FALSE;
7520 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7522 fprintf(fff, "賞金首リスト\n");
7524 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7526 fprintf(fff, "List of wanted monsters\n");
7528 fprintf(fff, "----------------------------------------------\n");
7530 for (i = 0; i < MAX_KUBI; i++)
7532 if (kubi_r_idx[i] <= 10000)
7534 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7542 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7547 /* Display the file contents */
7548 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7550 /* Remove the file */
7555 * List virtues & status
7557 static void do_cmd_knowledge_virtues(void)
7560 GAME_TEXT file_name[1024];
7562 /* Open a new file */
7563 fff = my_fopen_temp(file_name, 1024);
7565 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7572 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7577 /* Display the file contents */
7578 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7580 /* Remove the file */
7588 static void do_cmd_knowledge_dungeon(void)
7592 GAME_TEXT file_name[1024];
7595 /* Open a new file */
7596 fff = my_fopen_temp(file_name, 1024);
7598 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7605 for (i = 1; i < max_d_idx; i++)
7609 if (!d_info[i].maxdepth) continue;
7610 if (!max_dlv[i]) continue;
7611 if (d_info[i].final_guardian)
7613 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7615 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7617 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7622 /* Display the file contents */
7623 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7625 /* Remove the file */
7630 * List virtues & status
7633 static void do_cmd_knowledge_stat(void)
7637 GAME_TEXT file_name[1024];
7640 /* Open a new file */
7641 fff = my_fopen_temp(file_name, 1024);
7643 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7650 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7651 (2 * p_ptr->hitdie +
7652 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7655 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7656 else fprintf(fff, "現在の体力ランク : ???\n\n");
7657 fprintf(fff, "能力の最大値\n\n");
7659 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7660 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7661 fprintf(fff, "Limits of maximum stats\n\n");
7663 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7665 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);
7666 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7673 /* Display the file contents */
7674 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7676 /* Remove the file */
7682 * Print all active quests
7684 static void do_cmd_knowledge_quests_current(FILE *fff)
7687 char rand_tmp_str[120] = "\0";
7688 GAME_TEXT name[MAX_NLEN];
7689 monster_race *r_ptr;
7691 int rand_level = 100;
7694 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7696 for (i = 1; i < max_q_idx; i++)
7698 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7699 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7700 (quest[i].status == QUEST_STATUS_COMPLETED))
7702 /* Set the quest number temporary */
7703 IDX old_quest = p_ptr->inside_quest;
7706 /* Clear the text */
7707 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7708 quest_text_line = 0;
7710 p_ptr->inside_quest = i;
7712 /* Get the quest text */
7713 init_flags = INIT_SHOW_TEXT;
7715 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7717 /* Reset the old quest number */
7718 p_ptr->inside_quest = old_quest;
7720 /* No info from "silent" quests */
7721 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7725 if (quest[i].type != QUEST_TYPE_RANDOM)
7727 char note[80] = "\0";
7729 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7731 switch (quest[i].type)
7733 case QUEST_TYPE_KILL_LEVEL:
7734 case QUEST_TYPE_KILL_ANY_LEVEL:
7735 r_ptr = &r_info[quest[i].r_idx];
7736 strcpy(name, r_name + r_ptr->name);
7737 if (quest[i].max_num > 1)
7740 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7741 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7744 sprintf(note," - kill %d %s, have killed %d.",
7745 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7749 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7752 case QUEST_TYPE_FIND_ARTIFACT:
7755 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7757 object_type *q_ptr = &forge;
7758 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7759 object_prep(q_ptr, k_idx);
7760 q_ptr->name1 = quest[i].k_idx;
7761 q_ptr->ident = IDENT_STORE;
7762 object_desc(name, q_ptr, OD_NAME_ONLY);
7764 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7766 case QUEST_TYPE_FIND_EXIT:
7767 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7770 case QUEST_TYPE_KILL_NUMBER:
7772 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7773 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7775 sprintf(note," - Kill %d monsters, have killed %d.",
7776 (int)quest[i].max_num, (int)quest[i].cur_num);
7780 case QUEST_TYPE_KILL_ALL:
7781 case QUEST_TYPE_TOWER:
7782 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7787 /* Print the quest info */
7788 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7789 quest[i].name, (int)quest[i].level, note);
7791 fputs(tmp_str, fff);
7793 if (quest[i].status == QUEST_STATUS_COMPLETED)
7795 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7796 fputs(tmp_str, fff);
7802 while (quest_text[j][0] && j < 10)
7804 fprintf(fff, " %s\n", quest_text[j]);
7809 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7812 rand_level = quest[i].level;
7814 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7816 /* Print the quest info */
7817 r_ptr = &r_info[quest[i].r_idx];
7818 strcpy(name, r_name + r_ptr->name);
7820 if (quest[i].max_num > 1)
7823 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7824 quest[i].name, (int)quest[i].level,
7825 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7829 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7830 quest[i].name, (int)quest[i].level,
7831 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7836 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7837 quest[i].name, (int)quest[i].level, name);
7844 /* Print the current random quest */
7845 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7847 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7851 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7854 char playtime_str[16];
7855 quest_type* const q_ptr = &quest[q_idx];
7857 if (is_fixed_quest_idx(q_idx))
7859 /* Set the quest number temporary */
7860 IDX old_quest = p_ptr->inside_quest;
7862 p_ptr->inside_quest = q_idx;
7865 init_flags = INIT_NAME_ONLY;
7867 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7869 /* Reset the old quest number */
7870 p_ptr->inside_quest = old_quest;
7872 /* No info from "silent" quests */
7873 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7876 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7877 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7879 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7881 /* Print the quest info */
7882 if (q_ptr->complev == 0)
7885 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7886 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7887 r_name+r_info[q_ptr->r_idx].name,
7888 (int)q_ptr->level, playtime_str);
7893 _(" %-35s (%3d階) - レベル%2d - %s\n",
7894 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7895 r_name+r_info[q_ptr->r_idx].name,
7903 /* Print the quest info */
7905 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7906 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7907 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7910 fputs(tmp_str, fff);
7916 * Print all finished quests
7918 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7923 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7924 for (i = 1; i < max_q_idx; i++)
7926 IDX q_idx = quest_num[i];
7927 quest_type* const q_ptr = &quest[q_idx];
7929 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7930 do_cmd_knowledge_quests_aux(fff, q_idx))
7935 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7940 * Print all failed quests
7942 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
7947 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7948 for (i = 1; i < max_q_idx; i++)
7950 IDX q_idx = quest_num[i];
7951 quest_type* const q_ptr = &quest[q_idx];
7953 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7954 do_cmd_knowledge_quests_aux(fff, q_idx))
7959 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7964 * Print all random quests
7966 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7972 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7973 for (i = 1; i < max_q_idx; i++)
7975 /* No info from "silent" quests */
7976 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7978 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7982 /* Print the quest info */
7983 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7984 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7985 fputs(tmp_str, fff);
7988 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7992 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7994 QUEST_IDX *q_num = (QUEST_IDX *)u;
7995 quest_type *qa = &quest[q_num[a]];
7996 quest_type *qb = &quest[q_num[b]];
8001 return (qa->comptime != qb->comptime) ?
8002 (qa->comptime < qb->comptime) :
8003 (qa->level <= qb->level);
8006 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8008 QUEST_IDX *q_num = (QUEST_IDX *)u;
8015 q_num[a] = q_num[b];
8021 * Print quest status of all active quests
8023 static void do_cmd_knowledge_quests(void)
8026 GAME_TEXT file_name[1024];
8031 /* Open a new file */
8032 fff = my_fopen_temp(file_name, 1024);
8035 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8040 /* Allocate Memory */
8041 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8043 /* Sort by compete level */
8044 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8045 ang_sort_comp = ang_sort_comp_quest_num;
8046 ang_sort_swap = ang_sort_swap_quest_num;
8047 ang_sort(quest_num, &dummy, max_q_idx);
8049 /* Dump Quest Information */
8050 do_cmd_knowledge_quests_current(fff);
8052 do_cmd_knowledge_quests_completed(fff, quest_num);
8054 do_cmd_knowledge_quests_failed(fff, quest_num);
8058 do_cmd_knowledge_quests_wiz_random(fff);
8062 /* Display the file contents */
8063 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8065 /* Remove the file */
8069 C_KILL(quest_num, max_q_idx, IDX);
8076 static void do_cmd_knowledge_home(void)
8081 GAME_TEXT file_name[1024];
8083 GAME_TEXT o_name[MAX_NLEN];
8084 concptr paren = ")";
8086 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8088 /* Open a new file */
8089 fff = my_fopen_temp(file_name, 1024);
8091 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8098 /* Print all homes in the different towns */
8099 st_ptr = &town[1].store[STORE_HOME];
8101 /* Home -- if anything there */
8102 if (st_ptr->stock_num)
8107 /* Header with name of the town */
8108 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8110 /* Dump all available items */
8111 for (i = 0; i < st_ptr->stock_num; i++)
8114 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8115 object_desc(o_name, &st_ptr->stock[i], 0);
8116 if (strlen(o_name) <= 80-3)
8118 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8124 for (n = 0, t = o_name; n < 80-3; n++, t++)
8125 if(iskanji(*t)) {t++; n++;}
8126 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8128 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8129 fprintf(fff, " %.77s\n", o_name+n);
8132 object_desc(o_name, &st_ptr->stock[i], 0);
8133 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8138 /* Add an empty line */
8139 fprintf(fff, "\n\n");
8144 /* Display the file contents */
8145 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8147 /* Remove the file */
8153 * Check the status of "autopick"
8155 static void do_cmd_knowledge_autopick(void)
8159 GAME_TEXT file_name[1024];
8161 /* Open a new file */
8162 fff = my_fopen_temp(file_name, 1024);
8166 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8173 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8177 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8178 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8181 for (k = 0; k < max_autopick; k++)
8184 byte act = autopick_list[k].action;
8185 if (act & DONT_AUTOPICK)
8187 tmp = _("放置", "Leave");
8189 else if (act & DO_AUTODESTROY)
8191 tmp = _("破壊", "Destroy");
8193 else if (act & DO_AUTOPICK)
8195 tmp = _("拾う", "Pickup");
8199 tmp = _("確認", "Query");
8202 if (act & DO_DISPLAY)
8203 fprintf(fff, "%11s", format("[%s]", tmp));
8205 fprintf(fff, "%11s", format("(%s)", tmp));
8207 tmp = autopick_line_from_entry(&autopick_list[k]);
8208 fprintf(fff, " %s", tmp);
8213 /* Display the file contents */
8214 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8216 /* Remove the file */
8222 * Interact with "knowledge"
8224 void do_cmd_knowledge(void)
8227 bool need_redraw = FALSE;
8229 /* File type is "TEXT" */
8230 FILE_TYPE(FILE_TYPE_TEXT);
8233 /* Interact until done */
8238 /* Ask for a choice */
8239 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8240 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8242 /* Give some choices */
8246 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8247 prt("(2) 既知のアイテム の一覧", 7, 5);
8248 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8249 prt("(4) 既知のモンスター の一覧", 9, 5);
8250 prt("(5) 倒した敵の数 の一覧", 10, 5);
8251 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8252 prt("(7) 現在のペット の一覧", 12, 5);
8253 prt("(8) 我が家のアイテム の一覧", 13, 5);
8254 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8255 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8259 prt("(a) 自分に関する情報 の一覧", 6, 5);
8260 prt("(b) 突然変異 の一覧", 7, 5);
8261 prt("(c) 武器の経験値 の一覧", 8, 5);
8262 prt("(d) 魔法の経験値 の一覧", 9, 5);
8263 prt("(e) 技能の経験値 の一覧", 10, 5);
8264 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8265 prt("(g) 入ったダンジョン の一覧", 12, 5);
8266 prt("(h) 実行中のクエスト の一覧", 13, 5);
8267 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8272 prt("(1) Display known artifacts", 6, 5);
8273 prt("(2) Display known objects", 7, 5);
8274 prt("(3) Display remaining uniques", 8, 5);
8275 prt("(4) Display known monster", 9, 5);
8276 prt("(5) Display kill count", 10, 5);
8277 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8278 prt("(7) Display current pets", 12, 5);
8279 prt("(8) Display home inventory", 13, 5);
8280 prt("(9) Display *identified* equip.", 14, 5);
8281 prt("(0) Display terrain symbols.", 15, 5);
8285 prt("(a) Display about yourself", 6, 5);
8286 prt("(b) Display mutations", 7, 5);
8287 prt("(c) Display weapon proficiency", 8, 5);
8288 prt("(d) Display spell proficiency", 9, 5);
8289 prt("(e) Display misc. proficiency", 10, 5);
8290 prt("(f) Display virtues", 11, 5);
8291 prt("(g) Display dungeons", 12, 5);
8292 prt("(h) Display current quests", 13, 5);
8293 prt("(i) Display auto pick/destroy", 14, 5);
8297 prt(_("-続く-", "-more-"), 17, 8);
8298 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8299 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8300 /*prt("-) 前ページ", 21, 60);*/
8301 prt(_("コマンド:", "Command: "), 20, 0);
8304 if (i == ESCAPE) break;
8307 case ' ': /* Page change */
8311 case '1': /* Artifacts */
8312 do_cmd_knowledge_artifacts();
8314 case '2': /* Objects */
8315 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8317 case '3': /* Uniques */
8318 do_cmd_knowledge_uniques();
8320 case '4': /* Monsters */
8321 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8323 case '5': /* Kill count */
8324 do_cmd_knowledge_kill_count();
8326 case '6': /* wanted */
8327 if (!vanilla_town) do_cmd_knowledge_kubi();
8329 case '7': /* Pets */
8330 do_cmd_knowledge_pets();
8332 case '8': /* Home */
8333 do_cmd_knowledge_home();
8335 case '9': /* Resist list */
8336 do_cmd_knowledge_inven();
8338 case '0': /* Feature list */
8340 IDX lighting_level = F_LIT_STANDARD;
8341 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8345 case 'a': /* Max stat */
8346 do_cmd_knowledge_stat();
8348 case 'b': /* Mutations */
8349 do_cmd_knowledge_mutations();
8351 case 'c': /* weapon-exp */
8352 do_cmd_knowledge_weapon_exp();
8354 case 'd': /* spell-exp */
8355 do_cmd_knowledge_spell_exp();
8357 case 'e': /* skill-exp */
8358 do_cmd_knowledge_skill_exp();
8360 case 'f': /* Virtues */
8361 do_cmd_knowledge_virtues();
8363 case 'g': /* Dungeon */
8364 do_cmd_knowledge_dungeon();
8366 case 'h': /* Quests */
8367 do_cmd_knowledge_quests();
8369 case 'i': /* Autopick */
8370 do_cmd_knowledge_autopick();
8372 default: /* Unknown option */
8380 if (need_redraw) do_cmd_redraw();
8385 * Check on the status of an active quest
8387 void do_cmd_checkquest(void)
8389 /* File type is "TEXT" */
8390 FILE_TYPE(FILE_TYPE_TEXT);
8394 do_cmd_knowledge_quests();
8400 * Display the time and date
8402 void do_cmd_time(void)
8404 int day, hour, min, full, start, end, num;
8412 extract_day_hour_min(&day, &hour, &min);
8414 full = hour * 100 + min;
8421 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8423 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8424 else strcpy(day_buf, "*****");
8427 msg_format("%s日目, 時刻は%d:%02d %sです。",
8428 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8429 min, (hour < 12) ? "AM" : "PM");
8431 msg_format("This is day %s. The time is %d:%02d %s.",
8432 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8433 min, (hour < 12) ? "AM" : "PM");
8438 if (!randint0(10) || p_ptr->image)
8440 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8444 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8447 /* Open this file */
8448 fff = my_fopen(buf, "rt");
8452 /* Find this time */
8453 while (!my_fgets(fff, buf, sizeof(buf)))
8455 /* Ignore comments */
8456 if (!buf[0] || (buf[0] == '#')) continue;
8458 /* Ignore invalid lines */
8459 if (buf[1] != ':') continue;
8461 /* Process 'Start' */
8464 /* Extract the starting time */
8465 start = atoi(buf + 2);
8467 /* Assume valid for an hour */
8477 /* Extract the ending time */
8478 end = atoi(buf + 2);
8484 /* Ignore incorrect range */
8485 if ((start > full) || (full > end)) continue;
8487 /* Process 'Description' */
8492 /* Apply the randomizer */
8493 if (!randint0(num)) strcpy(desc, buf + 2);