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 char file_name[1024];
5657 char skill_name[GINOU_TEMPMAX][20] =
5659 _("マーシャルアーツ", "Martial Arts "),
5660 _("二刀流 ", "Dual Wielding "),
5661 _("乗馬 ", "Riding "),
5665 /* Open a new file */
5666 fff = my_fopen_temp(file_name, 1024);
5668 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5673 for (i = 0; i < GINOU_TEMPMAX; i++)
5675 skill_exp = p_ptr->skill_exp[i];
5676 fprintf(fff, "%-20s ", skill_name[i]);
5677 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5678 else fprintf(fff, " ");
5679 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5680 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5685 /* Display the file contents */
5686 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5688 /* Remove the file */
5694 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5695 * @param Name 変換したい文字列の参照ポインタ
5698 void plural_aux(char *Name)
5700 int NameLen = strlen(Name);
5702 if (my_strstr(Name, "Disembodied hand"))
5704 strcpy(Name, "Disembodied hands that strangled people");
5706 else if (my_strstr(Name, "Colour out of space"))
5708 strcpy(Name, "Colours out of space");
5710 else if (my_strstr(Name, "stairway to hell"))
5712 strcpy(Name, "stairways to hell");
5714 else if (my_strstr(Name, "Dweller on the threshold"))
5716 strcpy(Name, "Dwellers on the threshold");
5718 else if (my_strstr(Name, " of "))
5720 concptr aider = my_strstr(Name, " of ");
5731 if (dummy[i-1] == 's')
5733 strcpy(&(dummy[i]), "es");
5738 strcpy(&(dummy[i]), "s");
5741 strcpy(&(dummy[i+1]), aider);
5742 strcpy(Name, dummy);
5744 else if (my_strstr(Name, "coins"))
5747 strcpy(dummy, "piles of ");
5748 strcat(dummy, Name);
5749 strcpy(Name, dummy);
5752 else if (my_strstr(Name, "Manes"))
5756 else if (streq(&(Name[NameLen - 2]), "ey"))
5758 strcpy(&(Name[NameLen - 2]), "eys");
5760 else if (Name[NameLen - 1] == 'y')
5762 strcpy(&(Name[NameLen - 1]), "ies");
5764 else if (streq(&(Name[NameLen - 4]), "ouse"))
5766 strcpy(&(Name[NameLen - 4]), "ice");
5768 else if (streq(&(Name[NameLen - 2]), "us"))
5770 strcpy(&(Name[NameLen - 2]), "i");
5772 else if (streq(&(Name[NameLen - 6]), "kelman"))
5774 strcpy(&(Name[NameLen - 6]), "kelmen");
5776 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5778 strcpy(&(Name[NameLen - 8]), "wordsmen");
5780 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5782 strcpy(&(Name[NameLen - 7]), "oodsmen");
5784 else if (streq(&(Name[NameLen - 7]), "eastman"))
5786 strcpy(&(Name[NameLen - 7]), "eastmen");
5788 else if (streq(&(Name[NameLen - 8]), "izardman"))
5790 strcpy(&(Name[NameLen - 8]), "izardmen");
5792 else if (streq(&(Name[NameLen - 5]), "geist"))
5794 strcpy(&(Name[NameLen - 5]), "geister");
5796 else if (streq(&(Name[NameLen - 2]), "ex"))
5798 strcpy(&(Name[NameLen - 2]), "ices");
5800 else if (streq(&(Name[NameLen - 2]), "lf"))
5802 strcpy(&(Name[NameLen - 2]), "lves");
5804 else if (suffix(Name, "ch") ||
5805 suffix(Name, "sh") ||
5806 suffix(Name, "nx") ||
5807 suffix(Name, "s") ||
5810 strcpy(&(Name[NameLen]), "es");
5814 strcpy(&(Name[NameLen]), "s");
5819 * @brief 現在のペットを表示するコマンドのメインルーチン /
5820 * Display current pets
5823 static void do_cmd_knowledge_pets(void)
5827 monster_type *m_ptr;
5828 GAME_TEXT pet_name[MAX_NLEN];
5830 int show_upkeep = 0;
5831 GAME_TEXT file_name[1024];
5834 /* Open a new file */
5835 fff = my_fopen_temp(file_name, 1024);
5837 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5842 /* Process the monsters (backwards) */
5843 for (i = m_max - 1; i >= 1; i--)
5845 /* Access the monster */
5848 /* Ignore "dead" monsters */
5849 if (!m_ptr->r_idx) continue;
5851 /* Calculate "upkeep" for pets */
5855 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5856 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5860 show_upkeep = calculate_upkeep();
5862 fprintf(fff, "----------------------------------------------\n");
5864 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5866 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5868 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5873 /* Display the file contents */
5874 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5876 /* Remove the file */
5882 * @brief 現在のペットを表示するコマンドのメインルーチン /
5885 * @note the player ghosts are ignored.
5887 static void do_cmd_knowledge_kill_count(void)
5894 GAME_TEXT file_name[1024];
5899 /* Open a new file */
5900 fff = my_fopen_temp(file_name, 1024);
5903 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5908 /* Allocate the "who" array */
5909 C_MAKE(who, max_r_idx, MONRACE_IDX);
5912 /* Monsters slain */
5915 for (kk = 1; kk < max_r_idx; kk++)
5917 monster_race *r_ptr = &r_info[kk];
5919 if (r_ptr->flags1 & (RF1_UNIQUE))
5921 bool dead = (r_ptr->max_num == 0);
5930 MONSTER_NUMBER This = r_ptr->r_pkills;
5940 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5943 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5945 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5951 /* Scan the monsters */
5952 for (i = 1; i < max_r_idx; i++)
5954 monster_race *r_ptr = &r_info[i];
5956 /* Use that monster */
5957 if (r_ptr->name) who[n++] = i;
5960 /* Select the sort method */
5961 ang_sort_comp = ang_sort_comp_hook;
5962 ang_sort_swap = ang_sort_swap_hook;
5964 /* Sort the array by dungeon depth of monsters */
5965 ang_sort(who, &why, n);
5967 /* Scan the monster races */
5968 for (k = 0; k < n; k++)
5970 monster_race *r_ptr = &r_info[who[k]];
5972 if (r_ptr->flags1 & (RF1_UNIQUE))
5974 bool dead = (r_ptr->max_num == 0);
5978 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5984 MONSTER_NUMBER This = r_ptr->r_pkills;
5989 /* p,tは人と数える by ita */
5990 if (my_strchr("pt", r_ptr->d_char))
5991 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5993 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5997 if (my_strstr(r_name + r_ptr->name, "coins"))
5999 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6003 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6009 strcpy(ToPlural, (r_name + r_ptr->name));
6010 plural_aux(ToPlural);
6011 fprintf(fff, " %d %s\n", This, ToPlural);
6021 fprintf(fff,"----------------------------------------------\n");
6023 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6025 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6029 /* Free the "who" array */
6030 C_KILL(who, max_r_idx, s16b);
6033 /* Display the file contents */
6034 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6036 /* Remove the file */
6042 * @brief モンスター情報リスト中のグループを表示する /
6043 * Display the object groups.
6047 * @param per_page リストの表示行
6048 * @param grp_idx グループのID配列
6049 * @param group_text グループ名の文字列配列
6050 * @param grp_cur 現在の選択ID
6051 * @param grp_top 現在の選択リスト最上部ID
6054 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)
6058 /* Display lines until done */
6059 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6061 /* Get the group index */
6062 int grp = grp_idx[grp_top + i];
6064 /* Choose a color */
6065 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6067 /* Erase the entire line */
6068 Term_erase(col, row + i, wid);
6070 /* Display the group label */
6071 c_put_str(attr, group_text[grp], row + i, col);
6077 * Move the cursor in a browser window
6079 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6080 IDX *list_cur, int list_cnt)
6085 IDX list = *list_cur;
6087 /* Extract direction */
6090 /* Hack -- scroll up full screen */
6095 /* Hack -- scroll down full screen */
6100 d = get_keymap_dir(ch);
6105 /* Diagonals - hack */
6106 if ((ddx[d] > 0) && ddy[d])
6111 Term_get_size(&wid, &hgt);
6113 browser_rows = hgt - 8;
6115 /* Browse group list */
6120 /* Move up or down */
6121 grp += ddy[d] * (browser_rows - 1);
6124 if (grp >= grp_cnt) grp = grp_cnt - 1;
6125 if (grp < 0) grp = 0;
6126 if (grp != old_grp) list = 0;
6129 /* Browse sub-list list */
6132 /* Move up or down */
6133 list += ddy[d] * browser_rows;
6136 if (list >= list_cnt) list = list_cnt - 1;
6137 if (list < 0) list = 0;
6149 if (col < 0) col = 0;
6150 if (col > 1) col = 1;
6157 /* Browse group list */
6162 /* Move up or down */
6166 if (grp >= grp_cnt) grp = grp_cnt - 1;
6167 if (grp < 0) grp = 0;
6168 if (grp != old_grp) list = 0;
6171 /* Browse sub-list list */
6174 /* Move up or down */
6178 if (list >= list_cnt) list = list_cnt - 1;
6179 if (list < 0) list = 0;
6190 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6194 /* Clear the display lines */
6195 for (i = 0; i < height; i++)
6197 Term_erase(col, row + i, width);
6200 /* Bigtile mode uses double width */
6201 if (use_bigtile) width /= 2;
6203 /* Display lines until done */
6204 for (i = 0; i < height; i++)
6206 /* Display columns until done */
6207 for (j = 0; j < width; j++)
6211 TERM_LEN x = col + j;
6212 TERM_LEN y = row + i;
6215 /* Bigtile mode uses double width */
6216 if (use_bigtile) x += j;
6221 /* Ignore illegal characters */
6222 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6223 (!use_graphics && ic > 0x7f))
6229 /* Force correct code for both ASCII character and tile */
6230 if (c & 0x80) a |= 0x80;
6232 /* Display symbol */
6233 Term_queue_bigchar(x, y, a, c, 0, 0);
6240 * Place the cursor at the collect position for visual mode
6242 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6244 int i = (a & 0x7f) - attr_top;
6245 int j = c - char_left;
6247 TERM_LEN x = col + j;
6248 TERM_LEN y = row + i;
6250 /* Bigtile mode uses double width */
6251 if (use_bigtile) x += j;
6253 /* Place the cursor */
6259 * Clipboard variables for copy&paste in visual mode
6261 static TERM_COLOR attr_idx = 0;
6262 static byte char_idx = 0;
6264 /* Hack -- for feature lighting */
6265 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6266 static byte char_idx_feat[F_LIT_MAX];
6269 * Do visual mode command -- Change symbols
6271 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6272 int height, int width,
6273 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6274 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6276 static TERM_COLOR attr_old = 0;
6277 static SYMBOL_CODE char_old = 0;
6282 if (*visual_list_ptr)
6285 *cur_attr_ptr = attr_old;
6286 *cur_char_ptr = char_old;
6287 *visual_list_ptr = FALSE;
6295 if (*visual_list_ptr)
6298 *visual_list_ptr = FALSE;
6299 *need_redraw = TRUE;
6307 if (!*visual_list_ptr)
6309 *visual_list_ptr = TRUE;
6311 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6312 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6314 attr_old = *cur_attr_ptr;
6315 char_old = *cur_char_ptr;
6326 /* Set the visual */
6327 attr_idx = *cur_attr_ptr;
6328 char_idx = *cur_char_ptr;
6330 /* Hack -- for feature lighting */
6331 for (i = 0; i < F_LIT_MAX; i++)
6333 attr_idx_feat[i] = 0;
6334 char_idx_feat[i] = 0;
6341 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6344 *cur_attr_ptr = attr_idx;
6345 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6346 if (!*visual_list_ptr) *need_redraw = TRUE;
6352 *cur_char_ptr = char_idx;
6353 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6354 if (!*visual_list_ptr) *need_redraw = TRUE;
6360 if (*visual_list_ptr)
6363 int d = get_keymap_dir(ch);
6364 byte a = (*cur_attr_ptr & 0x7f);
6365 byte c = *cur_char_ptr;
6367 if (use_bigtile) eff_width = width / 2;
6368 else eff_width = width;
6370 /* Restrict direction */
6371 if ((a == 0) && (ddy[d] < 0)) d = 0;
6372 if ((c == 0) && (ddx[d] < 0)) d = 0;
6373 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6374 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6379 /* Force correct code for both ASCII character and tile */
6380 if (c & 0x80) a |= 0x80;
6382 /* Set the visual */
6387 /* Move the frame */
6388 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6389 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6390 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6391 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6397 /* Visual mode command is not used */
6403 * Display the monsters in a group.
6405 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6406 int mon_cur, int mon_top, bool visual_only)
6410 /* Display lines until done */
6411 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6415 /* Get the race index */
6416 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6418 /* Access the race */
6419 monster_race *r_ptr = &r_info[r_idx];
6421 /* Choose a color */
6422 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6424 /* Display the name */
6425 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6427 /* Hack -- visual_list mode */
6430 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6432 if (p_ptr->wizard || visual_only)
6434 c_prt(attr, format("%d", r_idx), row + i, 62);
6437 /* Erase chars before overwritten by the race letter */
6438 Term_erase(69, row + i, 255);
6440 /* Display symbol */
6441 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6446 if (!(r_ptr->flags1 & RF1_UNIQUE))
6447 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6449 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6450 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6454 /* Clear remaining lines */
6455 for (; i < per_page; i++)
6457 Term_erase(col, row + i, 255);
6463 * Display known monsters.
6465 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6469 IDX grp_cur, grp_top, old_grp_cur;
6470 IDX mon_cur, mon_top;
6471 IDX grp_cnt, grp_idx[100];
6479 bool visual_list = FALSE;
6480 TERM_COLOR attr_top = 0;
6488 Term_get_size(&wid, &hgt);
6490 browser_rows = hgt - 8;
6492 /* Allocate the "mon_idx" array */
6493 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6498 if (direct_r_idx < 0)
6500 mode = visual_only ? 0x03 : 0x01;
6502 /* Check every group */
6503 for (i = 0; monster_group_text[i] != NULL; i++)
6505 /* Measure the label */
6506 len = strlen(monster_group_text[i]);
6508 /* Save the maximum length */
6509 if (len > max) max = len;
6511 /* See if any monsters are known */
6512 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6514 /* Build a list of groups with known monsters */
6515 grp_idx[grp_cnt++] = i;
6523 mon_idx[0] = direct_r_idx;
6526 /* Terminate the list */
6529 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6530 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6533 /* Terminate the list */
6534 grp_idx[grp_cnt] = -1;
6537 grp_cur = grp_top = 0;
6538 mon_cur = mon_top = 0;
6543 mode = visual_only ? 0x02 : 0x00;
6548 monster_race *r_ptr;
6553 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6554 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6555 prt(_("名前", "Name"), 4, max + 3);
6556 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6557 prt(_("文字", "Sym"), 4, 67);
6558 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6560 for (i = 0; i < 78; i++)
6562 Term_putch(i, 5, TERM_WHITE, '=');
6565 if (direct_r_idx < 0)
6567 for (i = 0; i < browser_rows; i++)
6569 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6576 if (direct_r_idx < 0)
6578 /* Scroll group list */
6579 if (grp_cur < grp_top) grp_top = grp_cur;
6580 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6582 /* Display a list of monster groups */
6583 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6585 if (old_grp_cur != grp_cur)
6587 old_grp_cur = grp_cur;
6589 /* Get a list of monsters in the current group */
6590 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6593 /* Scroll monster list */
6594 while (mon_cur < mon_top)
6595 mon_top = MAX(0, mon_top - browser_rows/2);
6596 while (mon_cur >= mon_top + browser_rows)
6597 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6602 /* Display a list of monsters in the current group */
6603 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6609 /* Display a monster name */
6610 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6612 /* Display visual list below first monster */
6613 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6617 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6618 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6619 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6620 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6623 /* Get the current monster */
6624 r_ptr = &r_info[mon_idx[mon_cur]];
6628 /* Mega Hack -- track this monster race */
6629 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6635 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6639 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6643 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6648 /* Do visual mode command if needed */
6649 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))
6651 if (direct_r_idx >= 0)
6676 /* Recall on screen */
6677 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6679 screen_roff(mon_idx[mon_cur], 0);
6690 /* Move the cursor */
6691 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6698 /* Free the "mon_idx" array */
6699 C_KILL(mon_idx, max_r_idx, s16b);
6704 * Display the objects in a group.
6706 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6707 int object_cur, int object_top, bool visual_only)
6711 /* Display lines until done */
6712 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6714 GAME_TEXT o_name[MAX_NLEN];
6717 object_kind *flavor_k_ptr;
6719 /* Get the object index */
6720 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6722 /* Access the object */
6723 object_kind *k_ptr = &k_info[k_idx];
6725 /* Choose a color */
6726 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6727 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6730 if (!visual_only && k_ptr->flavor)
6732 /* Appearance of this object is shuffled */
6733 flavor_k_ptr = &k_info[k_ptr->flavor];
6737 /* Appearance of this object is very normal */
6738 flavor_k_ptr = k_ptr;
6743 attr = ((i + object_top == object_cur) ? cursor : attr);
6745 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6748 strip_name(o_name, k_idx);
6753 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6756 /* Display the name */
6757 c_prt(attr, o_name, row + i, col);
6759 /* Hack -- visual_list mode */
6762 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);
6764 if (p_ptr->wizard || visual_only)
6766 c_prt(attr, format("%d", k_idx), row + i, 70);
6769 a = flavor_k_ptr->x_attr;
6770 c = flavor_k_ptr->x_char;
6772 /* Display symbol */
6773 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6776 /* Clear remaining lines */
6777 for (; i < per_page; i++)
6779 Term_erase(col, row + i, 255);
6784 * Describe fake object
6786 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6789 object_type object_type_body;
6790 o_ptr = &object_type_body;
6793 /* Create the artifact */
6794 object_prep(o_ptr, k_idx);
6796 /* It's fully know */
6797 o_ptr->ident |= IDENT_KNOWN;
6799 /* Track the object */
6800 /* object_actual_track(o_ptr); */
6802 /* Hack - mark as fake */
6803 /* term_obj_real = FALSE; */
6806 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6808 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6816 * Display known objects
6818 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6822 IDX grp_cur, grp_top, old_grp_cur;
6823 IDX object_old, object_cur, object_top;
6833 bool visual_list = FALSE;
6834 TERM_COLOR attr_top = 0;
6842 Term_get_size(&wid, &hgt);
6844 browser_rows = hgt - 8;
6846 /* Allocate the "object_idx" array */
6847 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6852 if (direct_k_idx < 0)
6854 mode = visual_only ? 0x03 : 0x01;
6856 /* Check every group */
6857 for (i = 0; object_group_text[i] != NULL; i++)
6859 /* Measure the label */
6860 len = strlen(object_group_text[i]);
6862 /* Save the maximum length */
6863 if (len > max) max = len;
6865 /* See if any monsters are known */
6866 if (collect_objects(i, object_idx, mode))
6868 /* Build a list of groups with known monsters */
6869 grp_idx[grp_cnt++] = i;
6878 object_kind *k_ptr = &k_info[direct_k_idx];
6879 object_kind *flavor_k_ptr;
6881 if (!visual_only && k_ptr->flavor)
6883 /* Appearance of this object is shuffled */
6884 flavor_k_ptr = &k_info[k_ptr->flavor];
6888 /* Appearance of this object is very normal */
6889 flavor_k_ptr = k_ptr;
6892 object_idx[0] = direct_k_idx;
6893 object_old = direct_k_idx;
6896 /* Terminate the list */
6899 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6900 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6903 /* Terminate the list */
6904 grp_idx[grp_cnt] = -1;
6907 grp_cur = grp_top = 0;
6908 object_cur = object_top = 0;
6913 mode = visual_only ? 0x02 : 0x00;
6918 object_kind *k_ptr, *flavor_k_ptr;
6925 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6926 if (direct_k_idx < 0) prt("グループ", 4, 0);
6927 prt("名前", 4, max + 3);
6928 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6931 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6932 if (direct_k_idx < 0) prt("Group", 4, 0);
6933 prt("Name", 4, max + 3);
6934 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6938 for (i = 0; i < 78; i++)
6940 Term_putch(i, 5, TERM_WHITE, '=');
6943 if (direct_k_idx < 0)
6945 for (i = 0; i < browser_rows; i++)
6947 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6954 if (direct_k_idx < 0)
6956 /* Scroll group list */
6957 if (grp_cur < grp_top) grp_top = grp_cur;
6958 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6960 /* Display a list of object groups */
6961 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6963 if (old_grp_cur != grp_cur)
6965 old_grp_cur = grp_cur;
6967 /* Get a list of objects in the current group */
6968 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6971 /* Scroll object list */
6972 while (object_cur < object_top)
6973 object_top = MAX(0, object_top - browser_rows/2);
6974 while (object_cur >= object_top + browser_rows)
6975 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6980 /* Display a list of objects in the current group */
6981 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6985 object_top = object_cur;
6987 /* Display a list of objects in the current group */
6988 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6990 /* Display visual list below first object */
6991 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6994 /* Get the current object */
6995 k_ptr = &k_info[object_idx[object_cur]];
6997 if (!visual_only && k_ptr->flavor)
6999 /* Appearance of this object is shuffled */
7000 flavor_k_ptr = &k_info[k_ptr->flavor];
7004 /* Appearance of this object is very normal */
7005 flavor_k_ptr = k_ptr;
7010 prt(format("<方向>%s%s%s, ESC",
7011 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7012 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7013 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7016 prt(format("<dir>%s%s%s, ESC",
7017 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7018 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7019 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7025 /* Mega Hack -- track this object */
7026 if (object_cnt) object_kind_track(object_idx[object_cur]);
7028 /* The "current" object changed */
7029 if (object_old != object_idx[object_cur])
7033 /* Remember the "current" object */
7034 object_old = object_idx[object_cur];
7040 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7044 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7048 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7053 /* Do visual mode command if needed */
7054 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))
7056 if (direct_k_idx >= 0)
7081 /* Recall on screen */
7082 if (!visual_list && !visual_only && (grp_cnt > 0))
7084 desc_obj_fake(object_idx[object_cur]);
7092 /* Move the cursor */
7093 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7099 /* Free the "object_idx" array */
7100 C_KILL(object_idx, max_k_idx, IDX);
7105 * Display the features in a group.
7107 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7108 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7110 int lit_col[F_LIT_MAX], i, j;
7111 int f_idx_col = use_bigtile ? 62 : 64;
7113 /* Correct columns 1 and 4 */
7114 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7115 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7116 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7118 /* Display lines until done */
7119 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7124 FEAT_IDX f_idx = feat_idx[feat_top + i];
7126 /* Access the index */
7127 feature_type *f_ptr = &f_info[f_idx];
7129 int row_i = row + i;
7131 /* Choose a color */
7132 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7134 /* Display the name */
7135 c_prt(attr, f_name + f_ptr->name, row_i, col);
7137 /* Hack -- visual_list mode */
7140 /* Display lighting level */
7141 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7143 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));
7145 if (p_ptr->wizard || visual_only)
7147 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7150 /* Display symbol */
7151 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);
7153 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7154 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7156 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7158 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7160 /* Mega-hack -- Use non-standard colour */
7161 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7163 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7167 /* Clear remaining lines */
7168 for (; i < per_page; i++)
7170 Term_erase(col, row + i, 255);
7176 * Interact with feature visuals.
7178 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7182 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7183 FEAT_IDX feat_cur, feat_top;
7185 FEAT_IDX grp_idx[100];
7189 TERM_LEN column = 0;
7193 bool visual_list = FALSE;
7194 TERM_COLOR attr_top = 0;
7197 TERM_LEN browser_rows;
7200 TERM_COLOR attr_old[F_LIT_MAX];
7201 SYMBOL_CODE char_old[F_LIT_MAX];
7202 TERM_COLOR *cur_attr_ptr;
7203 SYMBOL_CODE *cur_char_ptr;
7205 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7206 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7208 Term_get_size(&wid, &hgt);
7210 browser_rows = hgt - 8;
7212 /* Allocate the "feat_idx" array */
7213 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7218 if (direct_f_idx < 0)
7220 /* Check every group */
7221 for (i = 0; feature_group_text[i] != NULL; i++)
7223 /* Measure the label */
7224 len = strlen(feature_group_text[i]);
7226 /* Save the maximum length */
7227 if (len > max) max = len;
7229 /* See if any features are known */
7230 if (collect_features(i, feat_idx, 0x01))
7232 /* Build a list of groups with known features */
7233 grp_idx[grp_cnt++] = i;
7241 feature_type *f_ptr = &f_info[direct_f_idx];
7243 feat_idx[0] = direct_f_idx;
7246 /* Terminate the list */
7249 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7250 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7252 for (i = 0; i < F_LIT_MAX; i++)
7254 attr_old[i] = f_ptr->x_attr[i];
7255 char_old[i] = f_ptr->x_char[i];
7259 /* Terminate the list */
7260 grp_idx[grp_cnt] = -1;
7263 grp_cur = grp_top = 0;
7264 feat_cur = feat_top = 0;
7272 feature_type *f_ptr;
7278 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7279 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7280 prt(_("名前", "Name"), 4, max + 3);
7283 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7284 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7288 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7289 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7292 for (i = 0; i < 78; i++)
7294 Term_putch(i, 5, TERM_WHITE, '=');
7297 if (direct_f_idx < 0)
7299 for (i = 0; i < browser_rows; i++)
7301 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7308 if (direct_f_idx < 0)
7310 /* Scroll group list */
7311 if (grp_cur < grp_top) grp_top = grp_cur;
7312 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7314 /* Display a list of feature groups */
7315 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7317 if (old_grp_cur != grp_cur)
7319 old_grp_cur = grp_cur;
7321 /* Get a list of features in the current group */
7322 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7325 /* Scroll feature list */
7326 while (feat_cur < feat_top)
7327 feat_top = MAX(0, feat_top - browser_rows/2);
7328 while (feat_cur >= feat_top + browser_rows)
7329 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7334 /* Display a list of features in the current group */
7335 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7339 feat_top = feat_cur;
7341 /* Display a list of features in the current group */
7342 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7344 /* Display visual list below first object */
7345 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7349 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7350 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7351 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7354 /* Get the current feature */
7355 f_ptr = &f_info[feat_idx[feat_cur]];
7356 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7357 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7361 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7365 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7369 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7374 if (visual_list && ((ch == 'A') || (ch == 'a')))
7376 int prev_lighting_level = *lighting_level;
7380 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7381 else (*lighting_level)--;
7385 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7386 else (*lighting_level)++;
7389 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7390 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7392 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7393 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7398 else if ((ch == 'D') || (ch == 'd'))
7400 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7401 byte prev_x_char = f_ptr->x_char[*lighting_level];
7403 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7407 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7408 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7410 if (prev_x_char != f_ptr->x_char[*lighting_level])
7411 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7413 else *need_redraw = TRUE;
7418 /* Do visual mode command if needed */
7419 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))
7423 /* Restore previous visual settings */
7425 for (i = 0; i < F_LIT_MAX; i++)
7427 f_ptr->x_attr[i] = attr_old[i];
7428 f_ptr->x_char[i] = char_old[i];
7435 if (direct_f_idx >= 0) flag = TRUE;
7436 else *lighting_level = F_LIT_STANDARD;
7439 /* Preserve current visual settings */
7442 for (i = 0; i < F_LIT_MAX; i++)
7444 attr_old[i] = f_ptr->x_attr[i];
7445 char_old[i] = f_ptr->x_char[i];
7447 *lighting_level = F_LIT_STANDARD;
7454 for (i = 0; i < F_LIT_MAX; i++)
7456 attr_idx_feat[i] = f_ptr->x_attr[i];
7457 char_idx_feat[i] = f_ptr->x_char[i];
7466 /* Allow TERM_DARK text */
7467 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7469 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7470 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7488 /* Move the cursor */
7489 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7495 /* Free the "feat_idx" array */
7496 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7501 * List wanted monsters
7503 static void do_cmd_knowledge_kubi(void)
7508 GAME_TEXT file_name[1024];
7511 /* Open a new file */
7512 fff = my_fopen_temp(file_name, 1024);
7514 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7521 bool listed = FALSE;
7524 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7526 fprintf(fff, "賞金首リスト\n");
7528 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7530 fprintf(fff, "List of wanted monsters\n");
7532 fprintf(fff, "----------------------------------------------\n");
7534 for (i = 0; i < MAX_KUBI; i++)
7536 if (kubi_r_idx[i] <= 10000)
7538 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7546 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7551 /* Display the file contents */
7552 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7554 /* Remove the file */
7559 * List virtues & status
7561 static void do_cmd_knowledge_virtues(void)
7564 GAME_TEXT file_name[1024];
7566 /* Open a new file */
7567 fff = my_fopen_temp(file_name, 1024);
7569 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7576 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7581 /* Display the file contents */
7582 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7584 /* Remove the file */
7592 static void do_cmd_knowledge_dungeon(void)
7596 GAME_TEXT file_name[1024];
7599 /* Open a new file */
7600 fff = my_fopen_temp(file_name, 1024);
7602 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7609 for (i = 1; i < max_d_idx; i++)
7613 if (!d_info[i].maxdepth) continue;
7614 if (!max_dlv[i]) continue;
7615 if (d_info[i].final_guardian)
7617 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7619 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7621 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7626 /* Display the file contents */
7627 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7629 /* Remove the file */
7634 * List virtues & status
7637 static void do_cmd_knowledge_stat(void)
7641 GAME_TEXT file_name[1024];
7644 /* Open a new file */
7645 fff = my_fopen_temp(file_name, 1024);
7647 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7654 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7655 (2 * p_ptr->hitdie +
7656 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7659 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7660 else fprintf(fff, "現在の体力ランク : ???\n\n");
7661 fprintf(fff, "能力の最大値\n\n");
7663 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7664 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7665 fprintf(fff, "Limits of maximum stats\n\n");
7667 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7669 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);
7670 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7677 /* Display the file contents */
7678 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7680 /* Remove the file */
7686 * Print all active quests
7688 static void do_cmd_knowledge_quests_current(FILE *fff)
7691 char rand_tmp_str[120] = "\0";
7692 GAME_TEXT name[MAX_NLEN];
7693 monster_race *r_ptr;
7695 int rand_level = 100;
7698 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7700 for (i = 1; i < max_q_idx; i++)
7702 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7703 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7704 (quest[i].status == QUEST_STATUS_COMPLETED))
7706 /* Set the quest number temporary */
7707 IDX old_quest = p_ptr->inside_quest;
7710 /* Clear the text */
7711 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7712 quest_text_line = 0;
7714 p_ptr->inside_quest = i;
7716 /* Get the quest text */
7717 init_flags = INIT_SHOW_TEXT;
7719 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7721 /* Reset the old quest number */
7722 p_ptr->inside_quest = old_quest;
7724 /* No info from "silent" quests */
7725 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7729 if (quest[i].type != QUEST_TYPE_RANDOM)
7731 char note[80] = "\0";
7733 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7735 switch (quest[i].type)
7737 case QUEST_TYPE_KILL_LEVEL:
7738 case QUEST_TYPE_KILL_ANY_LEVEL:
7739 r_ptr = &r_info[quest[i].r_idx];
7740 strcpy(name, r_name + r_ptr->name);
7741 if (quest[i].max_num > 1)
7744 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7745 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7748 sprintf(note," - kill %d %s, have killed %d.",
7749 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7753 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7756 case QUEST_TYPE_FIND_ARTIFACT:
7759 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7761 object_type *q_ptr = &forge;
7762 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7763 object_prep(q_ptr, k_idx);
7764 q_ptr->name1 = quest[i].k_idx;
7765 q_ptr->ident = IDENT_STORE;
7766 object_desc(name, q_ptr, OD_NAME_ONLY);
7768 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7770 case QUEST_TYPE_FIND_EXIT:
7771 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7774 case QUEST_TYPE_KILL_NUMBER:
7776 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7777 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7779 sprintf(note," - Kill %d monsters, have killed %d.",
7780 (int)quest[i].max_num, (int)quest[i].cur_num);
7784 case QUEST_TYPE_KILL_ALL:
7785 case QUEST_TYPE_TOWER:
7786 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7791 /* Print the quest info */
7792 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7793 quest[i].name, (int)quest[i].level, note);
7795 fputs(tmp_str, fff);
7797 if (quest[i].status == QUEST_STATUS_COMPLETED)
7799 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7800 fputs(tmp_str, fff);
7806 while (quest_text[j][0] && j < 10)
7808 fprintf(fff, " %s\n", quest_text[j]);
7813 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7816 rand_level = quest[i].level;
7818 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7820 /* Print the quest info */
7821 r_ptr = &r_info[quest[i].r_idx];
7822 strcpy(name, r_name + r_ptr->name);
7824 if (quest[i].max_num > 1)
7827 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7828 quest[i].name, (int)quest[i].level,
7829 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7833 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7834 quest[i].name, (int)quest[i].level,
7835 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7840 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7841 quest[i].name, (int)quest[i].level, name);
7848 /* Print the current random quest */
7849 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7851 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7855 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7858 char playtime_str[16];
7859 quest_type* const q_ptr = &quest[q_idx];
7861 if (is_fixed_quest_idx(q_idx))
7863 /* Set the quest number temporary */
7864 IDX old_quest = p_ptr->inside_quest;
7866 p_ptr->inside_quest = q_idx;
7869 init_flags = INIT_NAME_ONLY;
7871 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7873 /* Reset the old quest number */
7874 p_ptr->inside_quest = old_quest;
7876 /* No info from "silent" quests */
7877 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7880 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7881 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7883 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7885 /* Print the quest info */
7886 if (q_ptr->complev == 0)
7889 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7890 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7891 r_name+r_info[q_ptr->r_idx].name,
7892 (int)q_ptr->level, playtime_str);
7897 _(" %-35s (%3d階) - レベル%2d - %s\n",
7898 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7899 r_name+r_info[q_ptr->r_idx].name,
7907 /* Print the quest info */
7909 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7910 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7911 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7914 fputs(tmp_str, fff);
7920 * Print all finished quests
7922 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7927 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7928 for (i = 1; i < max_q_idx; i++)
7930 IDX q_idx = quest_num[i];
7931 quest_type* const q_ptr = &quest[q_idx];
7933 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7934 do_cmd_knowledge_quests_aux(fff, q_idx))
7939 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7944 * Print all failed quests
7946 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
7951 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7952 for (i = 1; i < max_q_idx; i++)
7954 IDX q_idx = quest_num[i];
7955 quest_type* const q_ptr = &quest[q_idx];
7957 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7958 do_cmd_knowledge_quests_aux(fff, q_idx))
7963 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7968 * Print all random quests
7970 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7976 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7977 for (i = 1; i < max_q_idx; i++)
7979 /* No info from "silent" quests */
7980 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7982 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7986 /* Print the quest info */
7987 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7988 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7989 fputs(tmp_str, fff);
7992 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7996 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7998 QUEST_IDX *q_num = (QUEST_IDX *)u;
7999 quest_type *qa = &quest[q_num[a]];
8000 quest_type *qb = &quest[q_num[b]];
8005 return (qa->comptime != qb->comptime) ?
8006 (qa->comptime < qb->comptime) :
8007 (qa->level <= qb->level);
8010 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8012 QUEST_IDX *q_num = (QUEST_IDX *)u;
8019 q_num[a] = q_num[b];
8025 * Print quest status of all active quests
8027 static void do_cmd_knowledge_quests(void)
8030 GAME_TEXT file_name[1024];
8035 /* Open a new file */
8036 fff = my_fopen_temp(file_name, 1024);
8039 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8044 /* Allocate Memory */
8045 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8047 /* Sort by compete level */
8048 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8049 ang_sort_comp = ang_sort_comp_quest_num;
8050 ang_sort_swap = ang_sort_swap_quest_num;
8051 ang_sort(quest_num, &dummy, max_q_idx);
8053 /* Dump Quest Information */
8054 do_cmd_knowledge_quests_current(fff);
8056 do_cmd_knowledge_quests_completed(fff, quest_num);
8058 do_cmd_knowledge_quests_failed(fff, quest_num);
8062 do_cmd_knowledge_quests_wiz_random(fff);
8066 /* Display the file contents */
8067 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8069 /* Remove the file */
8073 C_KILL(quest_num, max_q_idx, IDX);
8080 static void do_cmd_knowledge_home(void)
8085 GAME_TEXT file_name[1024];
8087 GAME_TEXT o_name[MAX_NLEN];
8088 concptr paren = ")";
8090 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8092 /* Open a new file */
8093 fff = my_fopen_temp(file_name, 1024);
8095 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8102 /* Print all homes in the different towns */
8103 st_ptr = &town[1].store[STORE_HOME];
8105 /* Home -- if anything there */
8106 if (st_ptr->stock_num)
8111 /* Header with name of the town */
8112 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8114 /* Dump all available items */
8115 for (i = 0; i < st_ptr->stock_num; i++)
8118 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8119 object_desc(o_name, &st_ptr->stock[i], 0);
8120 if (strlen(o_name) <= 80-3)
8122 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8128 for (n = 0, t = o_name; n < 80-3; n++, t++)
8129 if(iskanji(*t)) {t++; n++;}
8130 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8132 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8133 fprintf(fff, " %.77s\n", o_name+n);
8136 object_desc(o_name, &st_ptr->stock[i], 0);
8137 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8142 /* Add an empty line */
8143 fprintf(fff, "\n\n");
8148 /* Display the file contents */
8149 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8151 /* Remove the file */
8157 * Check the status of "autopick"
8159 static void do_cmd_knowledge_autopick(void)
8163 GAME_TEXT file_name[1024];
8165 /* Open a new file */
8166 fff = my_fopen_temp(file_name, 1024);
8170 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8177 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8181 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8182 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8185 for (k = 0; k < max_autopick; k++)
8188 byte act = autopick_list[k].action;
8189 if (act & DONT_AUTOPICK)
8191 tmp = _("放置", "Leave");
8193 else if (act & DO_AUTODESTROY)
8195 tmp = _("破壊", "Destroy");
8197 else if (act & DO_AUTOPICK)
8199 tmp = _("拾う", "Pickup");
8203 tmp = _("確認", "Query");
8206 if (act & DO_DISPLAY)
8207 fprintf(fff, "%11s", format("[%s]", tmp));
8209 fprintf(fff, "%11s", format("(%s)", tmp));
8211 tmp = autopick_line_from_entry(&autopick_list[k]);
8212 fprintf(fff, " %s", tmp);
8217 /* Display the file contents */
8218 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8220 /* Remove the file */
8226 * Interact with "knowledge"
8228 void do_cmd_knowledge(void)
8231 bool need_redraw = FALSE;
8233 /* File type is "TEXT" */
8234 FILE_TYPE(FILE_TYPE_TEXT);
8237 /* Interact until done */
8242 /* Ask for a choice */
8243 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8244 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8246 /* Give some choices */
8250 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8251 prt("(2) 既知のアイテム の一覧", 7, 5);
8252 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8253 prt("(4) 既知のモンスター の一覧", 9, 5);
8254 prt("(5) 倒した敵の数 の一覧", 10, 5);
8255 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8256 prt("(7) 現在のペット の一覧", 12, 5);
8257 prt("(8) 我が家のアイテム の一覧", 13, 5);
8258 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8259 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8263 prt("(a) 自分に関する情報 の一覧", 6, 5);
8264 prt("(b) 突然変異 の一覧", 7, 5);
8265 prt("(c) 武器の経験値 の一覧", 8, 5);
8266 prt("(d) 魔法の経験値 の一覧", 9, 5);
8267 prt("(e) 技能の経験値 の一覧", 10, 5);
8268 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8269 prt("(g) 入ったダンジョン の一覧", 12, 5);
8270 prt("(h) 実行中のクエスト の一覧", 13, 5);
8271 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8276 prt("(1) Display known artifacts", 6, 5);
8277 prt("(2) Display known objects", 7, 5);
8278 prt("(3) Display remaining uniques", 8, 5);
8279 prt("(4) Display known monster", 9, 5);
8280 prt("(5) Display kill count", 10, 5);
8281 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8282 prt("(7) Display current pets", 12, 5);
8283 prt("(8) Display home inventory", 13, 5);
8284 prt("(9) Display *identified* equip.", 14, 5);
8285 prt("(0) Display terrain symbols.", 15, 5);
8289 prt("(a) Display about yourself", 6, 5);
8290 prt("(b) Display mutations", 7, 5);
8291 prt("(c) Display weapon proficiency", 8, 5);
8292 prt("(d) Display spell proficiency", 9, 5);
8293 prt("(e) Display misc. proficiency", 10, 5);
8294 prt("(f) Display virtues", 11, 5);
8295 prt("(g) Display dungeons", 12, 5);
8296 prt("(h) Display current quests", 13, 5);
8297 prt("(i) Display auto pick/destroy", 14, 5);
8301 prt(_("-続く-", "-more-"), 17, 8);
8302 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8303 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8304 /*prt("-) 前ページ", 21, 60);*/
8305 prt(_("コマンド:", "Command: "), 20, 0);
8308 if (i == ESCAPE) break;
8311 case ' ': /* Page change */
8315 case '1': /* Artifacts */
8316 do_cmd_knowledge_artifacts();
8318 case '2': /* Objects */
8319 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8321 case '3': /* Uniques */
8322 do_cmd_knowledge_uniques();
8324 case '4': /* Monsters */
8325 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8327 case '5': /* Kill count */
8328 do_cmd_knowledge_kill_count();
8330 case '6': /* wanted */
8331 if (!vanilla_town) do_cmd_knowledge_kubi();
8333 case '7': /* Pets */
8334 do_cmd_knowledge_pets();
8336 case '8': /* Home */
8337 do_cmd_knowledge_home();
8339 case '9': /* Resist list */
8340 do_cmd_knowledge_inven();
8342 case '0': /* Feature list */
8344 IDX lighting_level = F_LIT_STANDARD;
8345 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8349 case 'a': /* Max stat */
8350 do_cmd_knowledge_stat();
8352 case 'b': /* Mutations */
8353 do_cmd_knowledge_mutations();
8355 case 'c': /* weapon-exp */
8356 do_cmd_knowledge_weapon_exp();
8358 case 'd': /* spell-exp */
8359 do_cmd_knowledge_spell_exp();
8361 case 'e': /* skill-exp */
8362 do_cmd_knowledge_skill_exp();
8364 case 'f': /* Virtues */
8365 do_cmd_knowledge_virtues();
8367 case 'g': /* Dungeon */
8368 do_cmd_knowledge_dungeon();
8370 case 'h': /* Quests */
8371 do_cmd_knowledge_quests();
8373 case 'i': /* Autopick */
8374 do_cmd_knowledge_autopick();
8376 default: /* Unknown option */
8384 if (need_redraw) do_cmd_redraw();
8389 * Check on the status of an active quest
8391 void do_cmd_checkquest(void)
8393 /* File type is "TEXT" */
8394 FILE_TYPE(FILE_TYPE_TEXT);
8398 do_cmd_knowledge_quests();
8404 * Display the time and date
8406 void do_cmd_time(void)
8408 int day, hour, min, full, start, end, num;
8416 extract_day_hour_min(&day, &hour, &min);
8418 full = hour * 100 + min;
8425 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8427 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8428 else strcpy(day_buf, "*****");
8431 msg_format("%s日目, 時刻は%d:%02d %sです。",
8432 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8433 min, (hour < 12) ? "AM" : "PM");
8435 msg_format("This is day %s. The time is %d:%02d %s.",
8436 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8437 min, (hour < 12) ? "AM" : "PM");
8442 if (!randint0(10) || p_ptr->image)
8444 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8448 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8451 /* Open this file */
8452 fff = my_fopen(buf, "rt");
8456 /* Find this time */
8457 while (!my_fgets(fff, buf, sizeof(buf)))
8459 /* Ignore comments */
8460 if (!buf[0] || (buf[0] == '#')) continue;
8462 /* Ignore invalid lines */
8463 if (buf[1] != ':') continue;
8465 /* Process 'Start' */
8468 /* Extract the starting time */
8469 start = atoi(buf + 2);
8471 /* Assume valid for an hour */
8481 /* Extract the ending time */
8482 end = atoi(buf + 2);
8488 /* Ignore incorrect range */
8489 if ((start > full) || (full > end)) continue;
8491 /* Process 'Description' */
8496 /* Apply the randomizer */
8497 if (!randint0(num)) strcpy(desc, buf + 2);