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"
52 #include "object-hook.h"
59 * Mark strings for auto dump
61 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
62 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
65 * Variables for auto dump
67 static FILE *auto_dump_stream;
68 static concptr auto_dump_mark;
69 static int auto_dump_line_num;
73 * @brief prf出力内容を消去する /
74 * Remove old lines automatically generated before.
75 * @param orig_file 消去を行うファイル名
77 static void remove_auto_dump(concptr orig_file)
79 FILE *tmp_fff, *orig_fff;
83 bool between_mark = FALSE;
86 long header_location = 0;
87 char header_mark_str[80];
88 char footer_mark_str[80];
91 /* Prepare a header/footer mark string */
92 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
93 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
95 mark_len = strlen(footer_mark_str);
97 /* Open an old dump file in read-only mode */
98 orig_fff = my_fopen(orig_file, "r");
100 /* If original file does not exist, nothing to do */
101 if (!orig_fff) return;
103 /* Open a new (temporary) file */
104 tmp_fff = my_fopen_temp(tmp_file, 1024);
108 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
113 /* Loop for every line */
117 if (my_fgets(orig_fff, buf, sizeof(buf)))
119 /* Read error: Assume End of File */
122 * Was looking for the footer, but not found.
124 * Since automatic dump might be edited by hand,
125 * it's dangerous to kill these lines.
126 * Seek back to the next line of the (pseudo) header,
131 fseek(orig_fff, header_location, SEEK_SET);
132 between_mark = FALSE;
136 /* Success -- End the loop */
143 /* We are looking for the header mark of automatic dump */
146 /* Is this line a header? */
147 if (!strcmp(buf, header_mark_str))
149 /* Memorise seek point of this line */
150 header_location = ftell(orig_fff);
152 /* Initialize counter for number of lines */
155 /* Look for the footer from now */
158 /* There are some changes */
165 /* Copy orginally lines */
166 fprintf(tmp_fff, "%s\n", buf);
170 /* We are looking for the footer mark of automatic dump */
173 /* Is this line a footer? */
174 if (!strncmp(buf, footer_mark_str, mark_len))
179 * Compare the number of lines
181 * If there is an inconsistency between
182 * actual number of lines and the
183 * number here, the automatic dump
184 * might be edited by hand. So it's
185 * dangerous to kill these lines.
186 * Seek back to the next line of the
187 * (pseudo) header, and read again.
189 if (!sscanf(buf + mark_len, " (%d)", &tmp)
192 fseek(orig_fff, header_location, SEEK_SET);
195 /* Look for another header */
196 between_mark = FALSE;
202 /* Ignore old line, and count number of lines */
212 /* If there are some changes, overwrite the original file with new one */
215 /* Copy contents of temporary file */
217 tmp_fff = my_fopen(tmp_file, "r");
218 orig_fff = my_fopen(orig_file, "w");
220 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
221 fprintf(orig_fff, "%s\n", buf);
227 /* Kill the temporary file */
235 * @brief prfファイルのフォーマットに従った内容を出力する /
236 * Dump a formatted line, using "vstrnfmt()".
239 static void auto_dump_printf(concptr fmt, ...)
246 /* Begin the Varargs Stuff */
249 /* Format the args, save the length */
250 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
252 /* End the Varargs Stuff */
255 /* Count number of lines */
256 for (p = buf; *p; p++)
258 if (*p == '\n') auto_dump_line_num++;
262 fprintf(auto_dump_stream, "%s", buf);
267 * @brief prfファイルをファイルオープンする /
268 * Open file to append auto dump.
270 * @param mark 出力するヘッダマーク
271 * @return ファイルポインタを取得できたらTRUEを返す
273 static bool open_auto_dump(concptr buf, concptr mark)
276 char header_mark_str[80];
278 /* Save the mark string */
279 auto_dump_mark = mark;
281 /* Prepare a header mark string */
282 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
284 /* Remove old macro dumps */
285 remove_auto_dump(buf);
287 /* Append to the file */
288 auto_dump_stream = my_fopen(buf, "a");
291 if (!auto_dump_stream) {
292 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
300 fprintf(auto_dump_stream, "%s\n", header_mark_str);
302 /* Initialize counter */
303 auto_dump_line_num = 0;
305 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
306 "# *Warning!* The lines below are an automatic dump.\n"));
307 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
308 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
314 * @brief prfファイルをファイルクローズする /
315 * Append foot part and close auto dump.
318 static void close_auto_dump(void)
320 char footer_mark_str[80];
322 /* Prepare a footer mark string */
323 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
325 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
326 "# *Warning!* The lines below are an automatic dump.\n"));
327 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
328 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
330 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
333 my_fclose(auto_dump_stream);
342 * @brief Return suffix of ordinal number
344 * @return pointer of suffix string.
346 concptr get_ordinal_number_suffix(int num)
348 num = ABS(num) % 100;
352 return (num == 11) ? "th" : "st";
354 return (num == 12) ? "th" : "nd";
356 return (num == 13) ? "th" : "rd";
365 * @brief 日記にメッセージを追加する /
366 * Take note to the diary.
367 * @param type 日記内容のID
368 * @param num 日記内容のIDに応じた数値
369 * @param note 日記内容のIDに応じた文字列参照ポインタ
372 errr do_cmd_write_nikki(int type, int num, concptr note)
376 GAME_TEXT file_name[MAX_NLEN];
378 concptr note_level = "";
379 bool do_level = TRUE;
380 char note_level_buf[40];
383 static bool disable_nikki = FALSE;
385 extract_day_hour_min(&day, &hour, &min);
387 if (disable_nikki) return(-1);
389 if (type == NIKKI_FIX_QUEST_C ||
390 type == NIKKI_FIX_QUEST_F ||
391 type == NIKKI_RAND_QUEST_C ||
392 type == NIKKI_RAND_QUEST_F ||
393 type == NIKKI_TO_QUEST)
397 old_quest = p_ptr->inside_quest;
398 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
400 /* Get the quest text */
401 init_flags = INIT_NAME_ONLY;
403 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
405 /* Reset the old quest number */
406 p_ptr->inside_quest = old_quest;
409 /* different filne name to avoid mixing */
410 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
412 /* Build the filename */
413 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
415 /* File type is "TEXT" */
416 FILE_TYPE(FILE_TYPE_TEXT);
418 fff = my_fopen(buf, "a");
423 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
429 q_idx = quest_number(current_floor_ptr->dun_level);
433 if (p_ptr->inside_arena)
434 note_level = _("アリーナ:", "Arane:");
435 else if (!current_floor_ptr->dun_level)
436 note_level = _("地上:", "Surface:");
437 else if (q_idx && (is_fixed_quest_idx(q_idx)
438 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
439 note_level = _("クエスト:", "Quest:");
443 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
445 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
447 note_level = note_level_buf;
455 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
456 else fputs(_("*****日目\n", "Day *****\n"), fff);
464 fprintf(fff, "%s\n",note);
468 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
473 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
476 case NIKKI_ART_SCROLL:
478 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
483 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
486 case NIKKI_FIX_QUEST_C:
488 if (quest[num].flags & QUEST_FLAG_SILENT) break;
489 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
490 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
493 case NIKKI_FIX_QUEST_F:
495 if (quest[num].flags & QUEST_FLAG_SILENT) break;
496 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
497 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
500 case NIKKI_RAND_QUEST_C:
502 GAME_TEXT name[MAX_NLEN];
503 strcpy(name, r_name+r_info[quest[num].r_idx].name);
504 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
505 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
508 case NIKKI_RAND_QUEST_F:
510 GAME_TEXT name[MAX_NLEN];
511 strcpy(name, r_name+r_info[quest[num].r_idx].name);
512 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
513 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
516 case NIKKI_MAXDEAPTH:
518 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
519 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
520 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
521 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
526 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
527 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
528 _(d_name + d_info[num].name, (int)max_dlv[num]),
529 _((int)max_dlv[num], d_name + d_info[num].name));
535 if (q_idx && (is_fixed_quest_idx(q_idx)
536 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
538 to = _("地上", "the surface");
542 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
543 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
545 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
551 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
552 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
553 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
555 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
560 if (quest[num].flags & QUEST_FLAG_SILENT) break;
561 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
562 hour, min, note_level, quest[num].name);
567 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
568 hour, min, note_level);
573 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
578 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
586 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
587 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
590 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
591 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
593 if (num == MAX_ARENA_MONS)
595 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
596 " won all fight to become a Chanpion.\n"));
603 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
609 if (!current_floor_ptr->dun_level)
610 to = _("地上", "the surface");
612 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
614 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
615 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
621 if (!current_floor_ptr->dun_level)
622 to = _("地上", "the surface");
624 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
626 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
627 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
632 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
635 case NIKKI_GAMESTART:
637 time_t ct = time((time_t*)0);
641 fprintf(fff, "%s %s",note, ctime(&ct));
644 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
647 case NIKKI_NAMED_PET:
649 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
652 case RECORD_NAMED_PET_NAME:
653 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
655 case RECORD_NAMED_PET_UNNAME:
656 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
658 case RECORD_NAMED_PET_DISMISS:
659 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
661 case RECORD_NAMED_PET_DEATH:
662 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
664 case RECORD_NAMED_PET_MOVED:
665 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
667 case RECORD_NAMED_PET_LOST_SIGHT:
668 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
670 case RECORD_NAMED_PET_DESTROY:
671 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
673 case RECORD_NAMED_PET_EARTHQUAKE:
674 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
676 case RECORD_NAMED_PET_GENOCIDE:
677 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
679 case RECORD_NAMED_PET_WIZ_ZAP:
680 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
682 case RECORD_NAMED_PET_TELE_LEVEL:
683 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
685 case RECORD_NAMED_PET_BLAST:
686 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
688 case RECORD_NAMED_PET_HEAL_LEPER:
689 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
691 case RECORD_NAMED_PET_COMPACT:
692 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
694 case RECORD_NAMED_PET_LOSE_PARENT:
695 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
706 case NIKKI_WIZARD_LOG:
707 fprintf(fff, "%s\n", note);
716 if (do_level) write_level = FALSE;
722 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
725 * @brief 日記のタイトル表記と内容出力 /
728 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
730 static void do_cmd_disp_nikki(void)
732 char nikki_title[256];
733 GAME_TEXT file_name[MAX_NLEN];
738 static const char subtitle[][30] = {"最強の肉体を求めて",
769 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
770 "Attack is the best form of defence.",
772 "An unexpected windfall",
773 "A drowning man will catch at a straw",
774 "Don't count your chickens before they are hatched.",
775 "It is no use crying over spilt milk.",
776 "Seeing is believing.",
777 "Strike the iron while it is hot.",
778 "I don't care what follows.",
779 "To dig a well to put out a house on fire.",
780 "Tomorrow is another day.",
781 "Easy come, easy go.",
782 "The more haste, the less speed.",
783 "Where there is life, there is hope.",
784 "There is no royal road to *WINNER*.",
785 "Danger past, God forgotten.",
786 "The best thing to do now is to run away.",
787 "Life is but an empty dream.",
788 "Dead men tell no tales.",
789 "A book that remains shut is but a block.",
790 "Misfortunes never come singly.",
791 "A little knowledge is a dangerous thing.",
792 "History repeats itself.",
793 "*WINNER* was not built in a day.",
794 "Ignorance is bliss.",
795 "To lose is to win?",
796 "No medicine can cure folly.",
797 "All good things come to an end.",
798 "M$ Empire strikes back.",
799 "To see is to believe",
801 "Quest of The World's Greatest Brain"};
803 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
805 /* Build the filename */
806 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
808 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
809 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
810 else if (IS_WIZARD_CLASS())
811 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
812 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
815 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
817 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
820 /* Display the file contents */
821 show_file(FALSE, buf, nikki_title, -1, 0);
825 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
828 static void do_cmd_bunshou(void)
831 char bunshou[80] = "\0";
833 if (get_string(_("内容: ", "diary note: "), tmp, 79))
835 strcpy(bunshou, tmp);
837 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
842 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
845 static void do_cmd_last_get(void)
850 if (record_o_name[0] == '\0') return;
852 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
853 if (!get_check(buf)) return;
855 turn_tmp = current_world_ptr->game_turn;
856 current_world_ptr->game_turn = record_turn;
857 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
858 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
859 current_world_ptr->game_turn = turn_tmp;
863 * @brief ファイル中の全日記記録を消去する /
866 static void do_cmd_erase_nikki(void)
868 GAME_TEXT file_name[MAX_NLEN];
872 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
873 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
875 /* Build the filename */
876 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
879 fff = my_fopen(buf, "w");
882 msg_format(_("記録を消去しました。", "deleted record."));
884 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
893 void do_cmd_nikki(void)
897 /* File type is "TEXT" */
898 FILE_TYPE(FILE_TYPE_TEXT);
901 /* Interact until done */
906 /* Ask for a choice */
907 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
909 /* Give some choices */
910 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
911 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
912 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
913 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
915 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
918 prt(_("コマンド:", "Command: "), 18, 0);
923 if (i == ESCAPE) break;
937 do_cmd_erase_nikki();
941 prepare_movie_hooks();
943 default: /* Unknown option */
953 * @brief 画面を再描画するコマンドのメインルーチン
954 * Hack -- redraw the screen
958 * This command performs various low level updates, clears all the "extra"
959 * windows, does a total redraw of the main window, and requests all of the
960 * interesting updates and redraws that I can think of.
962 * This command is also used to "instantiate" the results of the user
963 * selecting various things, such as graphics mode, so it must call
964 * the "TERM_XTRA_REACT" hook before redrawing the windows.
967 void do_cmd_redraw(void)
973 /* Hack -- react to changes */
974 Term_xtra(TERM_XTRA_REACT, 0);
976 /* Combine and Reorder the pack (later) */
977 p_ptr->update |= (PU_COMBINE | PU_REORDER);
978 p_ptr->update |= (PU_TORCH);
979 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
980 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
981 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
982 p_ptr->update |= (PU_MONSTERS);
984 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
986 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
987 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
993 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
996 /* Redraw every window */
997 for (j = 0; j < 8; j++)
1000 if (!angband_term[j]) continue;
1003 Term_activate(angband_term[j]);
1012 * @brief 名前を変更するコマンドのメインルーチン
1013 * Hack -- change name
1016 void do_cmd_change_name(void)
1031 /* Display the player */
1032 display_player(mode);
1037 display_player(mode);
1042 Term_putstr(2, 23, -1, TERM_WHITE,
1043 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1045 Term_putstr(2, 23, -1, TERM_WHITE,
1046 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1054 if (c == ESCAPE) break;
1061 /* Process the player name */
1062 process_player_name(FALSE);
1068 sprintf(tmp, "%s.txt", player_base);
1069 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1071 if (tmp[0] && (tmp[0] != ' '))
1073 file_character(tmp);
1091 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1098 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1099 * Recall the most recent message
1102 void do_cmd_message_one(void)
1104 /* Recall one message */
1105 prt(format("> %s", message_str(0)), 0, 0);
1110 * @brief メッセージのログを表示するコマンドのメインルーチン
1111 * Recall the most recent message
1115 * Show previous messages to the user -BEN-
1117 * The screen format uses line 0 and 23 for headers and prompts,
1118 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1120 * This command shows you which commands you are viewing, and allows
1121 * you to "search" for strings in the recall.
1123 * Note that messages may be longer than 80 characters, but they are
1124 * displayed using "infinite" length, with a special sub-command to
1125 * "slide" the virtual display to the left or right.
1127 * Attempt to only hilite the matching portions of the string.
1130 void do_cmd_messages(int num_now)
1134 char shower_str[81];
1135 char finder_str[81];
1137 concptr shower = NULL;
1141 Term_get_size(&wid, &hgt);
1143 /* Number of message lines in a screen */
1144 num_lines = hgt - 4;
1147 strcpy(finder_str, "");
1150 strcpy(shower_str, "");
1152 /* Total messages */
1155 /* Start on first message */
1160 /* Process requests until done */
1166 /* Dump up to 20 lines of messages */
1167 for (j = 0; (j < num_lines) && (i + j < n); j++)
1169 concptr msg = message_str(i+j);
1171 /* Dump the messages, bottom to top */
1172 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1174 /* Hilite "shower" */
1175 if (shower && shower[0])
1179 /* Display matches */
1180 while ((str = my_strstr(str, shower)) != NULL)
1182 int len = strlen(shower);
1184 /* Display the match */
1185 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1193 /* Erase remaining lines */
1194 for (; j < num_lines; j++)
1196 Term_erase(0, num_lines + 1 - j, 255);
1199 /* Display header */
1201 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1202 i, i + j - 1, n), 0, 0);
1204 /* Display prompt (not very informative) */
1205 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1206 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1208 skey = inkey_special(TRUE);
1210 /* Exit on Escape */
1211 if (skey == ESCAPE) break;
1213 /* Hack -- Save the old index */
1218 /* Hack -- handle show */
1221 prt(_("強調: ", "Show: "), hgt - 1, 0);
1223 /* Get a "shower" string, or continue */
1224 strcpy(back_str, shower_str);
1225 if (askfor(shower_str, 80))
1228 shower = shower_str[0] ? shower_str : NULL;
1230 else strcpy(shower_str, back_str);
1234 /* Hack -- handle find */
1241 prt(_("検索: ", "Find: "), hgt - 1, 0);
1243 /* Get a "finder" string, or continue */
1244 strcpy(back_str, finder_str);
1245 if (!askfor(finder_str, 80))
1247 strcpy(finder_str, back_str);
1250 else if (!finder_str[0])
1252 shower = NULL; /* Stop showing */
1257 shower = finder_str;
1260 for (z = i + 1; z < n; z++)
1262 concptr msg = message_str(z);
1265 if (my_strstr(msg, finder_str))
1276 /* Recall 1 older message */
1278 /* Go to the oldest line */
1282 /* Recall 1 newer message */
1284 /* Go to the newest line */
1288 /* Recall 1 older message */
1293 /* Go older if legal */
1294 i = MIN(i + 1, n - num_lines);
1297 /* Recall 10 older messages */
1299 /* Go older if legal */
1300 i = MIN(i + 10, n - num_lines);
1303 /* Recall 20 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + num_lines, n - num_lines);
1312 /* Recall 20 newer messages */
1316 /* Go newer (if able) */
1317 i = MAX(0, i - num_lines);
1320 /* Recall 10 newer messages */
1322 /* Go newer (if able) */
1326 /* Recall 1 newer messages */
1329 /* Go newer (if able) */
1334 /* Hack -- Error of some kind */
1342 * @brief チートオプションを変更するコマンドのメインルーチン
1343 * Interact with some options for cheating
1344 * @param info 表示メッセージ
1347 static void do_cmd_options_cheat(concptr info)
1350 int i, k = 0, n = CHEAT_MAX;
1354 /* Interact with the player */
1360 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1365 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1366 prt(" << 注意 >>", 11, 0);
1367 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1368 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1369 prt(" じらないようにして下さい。", 14, 0);
1371 /* Display the options */
1372 for (i = 0; i < n; i++)
1374 byte a = TERM_WHITE;
1376 /* Color current option */
1377 if (i == k) a = TERM_L_BLUE;
1379 /* Display the option text */
1380 sprintf(buf, "%-48s: %s (%s)",
1381 cheat_info[i].o_desc,
1382 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1383 cheat_info[i].o_text);
1384 c_prt(a, buf, i + 2, 0);
1387 /* Hilite current option */
1388 move_cursor(k + 2, 50);
1394 * HACK - Try to translate the key into a direction
1395 * to allow using the roguelike keys for navigation.
1397 dir = get_keymap_dir(ch);
1398 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1412 k = (n + k - 1) % n;
1430 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1431 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1432 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1433 (*cheat_info[k].o_var) = TRUE;
1442 (*cheat_info[k].o_var) = FALSE;
1449 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1450 /* Peruse the help file */
1451 (void)show_file(TRUE, buf, NULL, 0, 0);
1468 * @brief セーブ頻度ターンの次の値を返す
1469 * @param current 現在のセーブ頻度ターン値
1470 * @return 次のセーブ頻度ターン値
1472 static s16b toggle_frequency(s16b current)
1477 case 50: return 100;
1478 case 100: return 250;
1479 case 250: return 500;
1480 case 500: return 1000;
1481 case 1000: return 2500;
1482 case 2500: return 5000;
1483 case 5000: return 10000;
1484 case 10000: return 25000;
1491 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1492 * @param info 表示メッセージ
1495 static void do_cmd_options_autosave(concptr info)
1498 int i, k = 0, n = 2;
1503 /* Interact with the player */
1507 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1508 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1512 /* Display the options */
1513 for (i = 0; i < n; i++)
1515 byte a = TERM_WHITE;
1517 /* Color current option */
1518 if (i == k) a = TERM_L_BLUE;
1520 /* Display the option text */
1521 sprintf(buf, "%-48s: %s (%s)",
1522 autosave_info[i].o_desc,
1523 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1524 autosave_info[i].o_text);
1525 c_prt(a, buf, i + 2, 0);
1527 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1529 /* Hilite current option */
1530 move_cursor(k + 2, 50);
1546 k = (n + k - 1) % n;
1564 (*autosave_info[k].o_var) = TRUE;
1573 (*autosave_info[k].o_var) = FALSE;
1581 autosave_freq = toggle_frequency(autosave_freq);
1582 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1588 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1604 * @brief 標準オプションを変更するコマンドのサブルーチン /
1605 * Interact with some options
1606 * @param page オプションページ番号
1607 * @param info 表示メッセージ
1610 void do_cmd_options_aux(int page, concptr info)
1613 int i, k = 0, n = 0, l;
1616 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1617 (!p_ptr->wizard || !allow_debug_opts);
1620 /* Lookup the options */
1621 for (i = 0; i < 24; i++) opt[i] = 0;
1623 /* Scan the options */
1624 for (i = 0; option_info[i].o_desc; i++)
1626 /* Notice options on this "page" */
1627 if (option_info[i].o_page == page) opt[n++] = i;
1631 /* Interact with the player */
1637 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1638 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1641 /* HACK -- description for easy-auto-destroy options */
1642 if (page == OPT_PAGE_AUTODESTROY)
1643 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1644 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1646 /* Display the options */
1647 for (i = 0; i < n; i++)
1649 byte a = TERM_WHITE;
1651 /* Color current option */
1652 if (i == k) a = TERM_L_BLUE;
1654 /* Display the option text */
1655 sprintf(buf, "%-48s: %s (%.19s)",
1656 option_info[opt[i]].o_desc,
1657 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1658 option_info[opt[i]].o_text);
1659 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1660 else c_prt(a, buf, i + 2, 0);
1663 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1666 /* Hilite current option */
1667 move_cursor(k + 2 + l, 50);
1673 * HACK - Try to translate the key into a direction
1674 * to allow using the roguelike keys for navigation.
1676 dir = get_keymap_dir(ch);
1677 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1691 k = (n + k - 1) % n;
1708 if (browse_only) break;
1709 (*option_info[opt[k]].o_var) = TRUE;
1718 if (browse_only) break;
1719 (*option_info[opt[k]].o_var) = FALSE;
1727 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1733 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1734 /* Peruse the help file */
1735 (void)show_file(TRUE, buf, NULL, 0, 0);
1752 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1753 * Modify the "window" options
1756 static void do_cmd_options_win(void)
1766 /* Memorize old flags */
1767 for (j = 0; j < 8; j++)
1769 /* Acquire current flags */
1770 old_flag[j] = window_flag[j];
1779 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1781 /* Display the windows */
1782 for (j = 0; j < 8; j++)
1784 byte a = TERM_WHITE;
1786 concptr s = angband_term_name[j];
1789 if (j == x) a = TERM_L_BLUE;
1791 /* Window name, staggered, centered */
1792 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1795 /* Display the options */
1796 for (i = 0; i < 16; i++)
1798 byte a = TERM_WHITE;
1800 concptr str = window_flag_desc[i];
1803 if (i == y) a = TERM_L_BLUE;
1806 if (!str) str = _("(未使用)", "(Unused option)");
1809 Term_putstr(0, i + 5, -1, a, str);
1811 /* Display the windows */
1812 for (j = 0; j < 8; j++)
1818 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1821 if (window_flag[j] & (1L << i)) c = 'X';
1824 Term_putch(35 + j * 5, i + 5, a, c);
1829 Term_gotoxy(35 + x * 5, y + 5);
1847 for (j = 0; j < 8; j++)
1849 window_flag[j] &= ~(1L << y);
1853 for (i = 0; i < 16; i++)
1855 window_flag[x] &= ~(1L << i);
1868 window_flag[x] |= (1L << y);
1876 window_flag[x] &= ~(1L << y);
1882 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1890 d = get_keymap_dir(ch);
1892 x = (x + ddx[d] + 8) % 8;
1893 y = (y + ddy[d] + 16) % 16;
1900 /* Notice changes */
1901 for (j = 0; j < 8; j++)
1906 if (!angband_term[j]) continue;
1908 /* Ignore non-changes */
1909 if (window_flag[j] == old_flag[j]) continue;
1912 Term_activate(angband_term[j]);
1929 option_fields[OPT_NUM] =
1932 { '1', " キー入力 オプション", 3 },
1933 { '2', " マップ画面 オプション", 4 },
1934 { '3', " テキスト表示 オプション", 5 },
1935 { '4', " ゲームプレイ オプション", 6 },
1936 { '5', " 行動中止関係 オプション", 7 },
1937 { '6', " 簡易自動破壊 オプション", 8 },
1938 { 'r', " プレイ記録 オプション", 9 },
1940 { 'p', "自動拾いエディタ", 11 },
1941 { 'd', " 基本ウェイト量 ", 12 },
1942 { 'h', "低ヒットポイント", 13 },
1943 { 'm', " 低魔力色閾値 ", 14 },
1944 { 'a', " 自動セーブ オプション", 15 },
1945 { 'w', "ウインドウフラグ", 16 },
1947 { 'b', " 初期 オプション (参照のみ)", 18 },
1948 { 'c', " 詐欺 オプション", 19 },
1950 { '1', "Input Options", 3 },
1951 { '2', "Map Screen Options", 4 },
1952 { '3', "Text Display Options", 5 },
1953 { '4', "Game-Play Options", 6 },
1954 { '5', "Disturbance Options", 7 },
1955 { '6', "Easy Auto-Destroyer Options", 8 },
1956 { 'r', "Play record Options", 9 },
1958 { 'p', "Auto-picker/destroyer editor", 11 },
1959 { 'd', "Base Delay Factor", 12 },
1960 { 'h', "Hitpoint Warning", 13 },
1961 { 'm', "Mana Color Threshold", 14 },
1962 { 'a', "Autosave Options", 15 },
1963 { 'w', "Window Flags", 16 },
1965 { 'b', "Birth Options (Browse Only)", 18 },
1966 { 'c', "Cheat Options", 19 },
1972 * @brief 標準オプションを変更するコマンドのメインルーチン /
1973 * Set or unset various options.
1977 * The user must use the "Ctrl-R" command to "adapt" to changes
1978 * in any options which control "visual" aspects of the game.
1981 void do_cmd_options(void)
1993 /* Does not list cheat option when cheat option is off */
1994 if (!p_ptr->noscore && !allow_debug_opts) n--;
1997 /* Why are we here */
1998 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2002 /* Give some choices */
2003 for (i = 0; i < n; i++)
2005 byte a = TERM_WHITE;
2006 if (i == y) a = TERM_L_BLUE;
2007 Term_putstr(5, option_fields[i].row, -1, a,
2008 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2011 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2014 skey = inkey_special(TRUE);
2015 if (!(skey & SKEY_MASK)) k = (char)skey;
2019 if (k == ESCAPE) break;
2021 if (my_strchr("\n\r ", k))
2023 k = option_fields[y].key;
2027 for (i = 0; i < n; i++)
2029 if (tolower(k) == option_fields[i].key) break;
2032 /* Command is found */
2035 /* Hack -- browse help */
2036 if (k == '?') break;
2040 if (skey == SKEY_UP) d = 8;
2041 if (skey == SKEY_DOWN) d = 2;
2042 y = (y + ddy[d] + n) % n;
2047 if (k == ESCAPE) break;
2054 /* Process the general options */
2055 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2061 /* Process the general options */
2062 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2069 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2076 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2083 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2090 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2094 /* Play-record Options */
2099 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2108 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2109 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2110 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2114 /* Cheating Options */
2117 if (!p_ptr->noscore && !allow_debug_opts)
2119 /* Cheat options are not permitted */
2125 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2132 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2141 do_cmd_options_win();
2142 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2143 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2144 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2145 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2150 /* Auto-picker/destroyer editor */
2154 do_cmd_edit_autopick();
2158 /* Hack -- Delay Speed */
2164 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2166 /* Get a new value */
2169 int msec = delay_factor * delay_factor * delay_factor;
2170 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2171 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2173 if (k == ESCAPE) break;
2176 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2179 else if (isdigit(k)) delay_factor = D2I(k);
2186 /* Hack -- hitpoint warning factor */
2192 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2194 /* Get a new value */
2197 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2198 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2200 if (k == ESCAPE) break;
2203 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2206 else if (isdigit(k)) hitpoint_warn = D2I(k);
2213 /* Hack -- mana color factor */
2219 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2221 /* Get a new value */
2224 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2225 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2227 if (k == ESCAPE) break;
2230 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2233 else if (isdigit(k)) mana_warn = D2I(k);
2241 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2245 /* Unknown option */
2258 /* Hack - Redraw equippy chars */
2259 p_ptr->redraw |= (PR_EQUIPPY);
2265 * @brief prefファイルを選択して処理する /
2266 * Ask for a "user pref line" and process it
2269 * Allow absolute file names?
2271 void do_cmd_pref(void)
2278 /* Ask for a "user pref command" */
2279 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2281 /* Process that pref command */
2282 (void)process_pref_file_command(buf);
2286 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2289 void do_cmd_reload_autopick(void)
2291 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2292 /* Load the file with messages */
2293 autopick_load_pref(TRUE);
2299 * @brief マクロ情報をprefファイルに保存する /
2300 * @param fname ファイル名
2303 static errr macro_dump(concptr fname)
2305 static concptr mark = "Macro Dump";
2311 /* Build the filename */
2312 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2314 /* File type is "TEXT" */
2315 FILE_TYPE(FILE_TYPE_TEXT);
2317 /* Append to the file */
2318 if (!open_auto_dump(buf, mark)) return (-1);
2321 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2324 for (i = 0; i < macro__num; i++)
2326 /* Extract the action */
2327 ascii_to_text(buf, macro__act[i]);
2329 /* Dump the macro */
2330 auto_dump_printf("A:%s\n", buf);
2332 /* Extract the action */
2333 ascii_to_text(buf, macro__pat[i]);
2335 /* Dump normal macros */
2336 auto_dump_printf("P:%s\n", buf);
2339 auto_dump_printf("\n");
2351 * @brief マクロのトリガーキーを取得する /
2352 * Hack -- ask for a "trigger" (see below)
2353 * @param buf キー表記を保管するバッファ
2357 * Note the complex use of the "inkey()" function from "util.c".
2359 * Note that both "flush()" calls are extremely important.
2362 static void do_cmd_macro_aux(char *buf)
2370 /* Do not process macros */
2376 /* Read the pattern */
2382 /* Do not process macros */
2385 /* Do not wait for keys */
2388 /* Attempt to read a key */
2397 /* Convert the trigger */
2398 ascii_to_text(tmp, buf);
2400 /* Hack -- display the trigger */
2401 Term_addstr(-1, TERM_WHITE, tmp);
2407 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2408 * Hack -- ask for a keymap "trigger" (see below)
2409 * @param buf キー表記を取得するバッファ
2413 * Note that both "flush()" calls are extremely important. This may
2414 * no longer be true, since "util.c" is much simpler now.
2417 static void do_cmd_macro_aux_keymap(char *buf)
2427 /* Convert to ascii */
2428 ascii_to_text(tmp, buf);
2430 /* Hack -- display the trigger */
2431 Term_addstr(-1, TERM_WHITE, tmp);
2438 * @brief キーマップをprefファイルにダンプする /
2439 * Hack -- append all keymaps to the given file
2440 * @param fname ファイルネーム
2444 static errr keymap_dump(concptr fname)
2446 static concptr mark = "Keymap Dump";
2455 if (rogue_like_commands)
2457 mode = KEYMAP_MODE_ROGUE;
2463 mode = KEYMAP_MODE_ORIG;
2467 /* Build the filename */
2468 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2470 /* File type is "TEXT" */
2471 FILE_TYPE(FILE_TYPE_TEXT);
2473 /* Append to the file */
2474 if (!open_auto_dump(buf, mark)) return -1;
2477 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2480 for (i = 0; i < 256; i++)
2484 /* Loop up the keymap */
2485 act = keymap_act[mode][i];
2487 /* Skip empty keymaps */
2490 /* Encode the key */
2493 ascii_to_text(key, buf);
2495 /* Encode the action */
2496 ascii_to_text(buf, act);
2498 /* Dump the macro */
2499 auto_dump_printf("A:%s\n", buf);
2500 auto_dump_printf("C:%d:%s\n", mode, key);
2512 * @brief マクロを設定するコマンドのメインルーチン /
2513 * Interact with "macros"
2517 * Note that the macro "action" must be defined before the trigger.
2519 * Could use some helpful instructions on this page.
2522 void do_cmd_macros(void)
2534 if (rogue_like_commands)
2536 mode = KEYMAP_MODE_ROGUE;
2542 mode = KEYMAP_MODE_ORIG;
2545 /* File type is "TEXT" */
2546 FILE_TYPE(FILE_TYPE_TEXT);
2551 /* Process requests until done */
2555 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2557 /* Describe that action */
2558 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2560 /* Analyze the current action */
2561 ascii_to_text(buf, macro__buf);
2563 /* Display the current action */
2568 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2570 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2571 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2572 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2573 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2574 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2575 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2576 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2577 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2578 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2579 #endif /* ALLOW_MACROS */
2582 prt(_("コマンド: ", "Command: "), 16, 0);
2587 if (i == ESCAPE) break;
2589 /* Load a 'macro' file */
2595 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2598 prt(_("ファイル: ", "File: "), 18, 0);
2600 /* Default filename */
2601 sprintf(tmp, "%s.prf", player_base);
2603 /* Ask for a file */
2604 if (!askfor(tmp, 80)) continue;
2606 /* Process the given filename */
2607 err = process_pref_file(tmp);
2610 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2615 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2619 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2629 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2632 prt(_("ファイル: ", "File: "), 18, 0);
2634 /* Default filename */
2635 sprintf(tmp, "%s.prf", player_base);
2637 /* Ask for a file */
2638 if (!askfor(tmp, 80)) continue;
2640 /* Dump the macros */
2641 (void)macro_dump(tmp);
2644 msg_print(_("マクロを追加しました。", "Appended macros."));
2653 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2657 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2659 /* Get a macro trigger */
2660 do_cmd_macro_aux(buf);
2662 /* Acquire action */
2663 k = macro_find_exact(buf);
2669 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2675 /* Obtain the action */
2676 strcpy(macro__buf, macro__act[k]);
2678 /* Analyze the current action */
2679 ascii_to_text(buf, macro__buf);
2681 /* Display the current action */
2685 msg_print(_("マクロを確認しました。", "Found a macro."));
2689 /* Create a macro */
2693 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2696 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2698 /* Get a macro trigger */
2699 do_cmd_macro_aux(buf);
2705 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2706 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2709 prt(_("マクロ行動: ", "Action: "), 20, 0);
2711 /* Convert to text */
2712 ascii_to_text(tmp, macro__buf);
2714 /* Get an encoded action */
2715 if (askfor(tmp, 80))
2717 /* Convert to ascii */
2718 text_to_ascii(macro__buf, tmp);
2720 /* Link the macro */
2721 macro_add(buf, macro__buf);
2724 msg_print(_("マクロを追加しました。", "Added a macro."));
2728 /* Remove a macro */
2732 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2735 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2737 /* Get a macro trigger */
2738 do_cmd_macro_aux(buf);
2740 /* Link the macro */
2741 macro_add(buf, buf);
2744 msg_print(_("マクロを削除しました。", "Removed a macro."));
2751 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2754 prt(_("ファイル: ", "File: "), 18, 0);
2756 /* Default filename */
2757 sprintf(tmp, "%s.prf", player_base);
2759 /* Ask for a file */
2760 if (!askfor(tmp, 80)) continue;
2762 /* Dump the macros */
2763 (void)keymap_dump(tmp);
2766 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2769 /* Query a keymap */
2775 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2778 prt(_("押すキー: ", "Keypress: "), 18, 0);
2780 /* Get a keymap trigger */
2781 do_cmd_macro_aux_keymap(buf);
2783 /* Look up the keymap */
2784 act = keymap_act[mode][(byte)(buf[0])];
2790 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2796 /* Obtain the action */
2797 strcpy(macro__buf, act);
2799 /* Analyze the current action */
2800 ascii_to_text(buf, macro__buf);
2802 /* Display the current action */
2806 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2810 /* Create a keymap */
2814 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2817 prt(_("押すキー: ", "Keypress: "), 18, 0);
2819 /* Get a keymap trigger */
2820 do_cmd_macro_aux_keymap(buf);
2826 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2827 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2830 prt(_("行動: ", "Action: "), 20, 0);
2832 /* Convert to text */
2833 ascii_to_text(tmp, macro__buf);
2835 /* Get an encoded action */
2836 if (askfor(tmp, 80))
2838 /* Convert to ascii */
2839 text_to_ascii(macro__buf, tmp);
2841 /* Free old keymap */
2842 string_free(keymap_act[mode][(byte)(buf[0])]);
2844 /* Make new keymap */
2845 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2848 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2852 /* Remove a keymap */
2856 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2859 prt(_("押すキー: ", "Keypress: "), 18, 0);
2861 /* Get a keymap trigger */
2862 do_cmd_macro_aux_keymap(buf);
2864 /* Free old keymap */
2865 string_free(keymap_act[mode][(byte)(buf[0])]);
2867 /* Make new keymap */
2868 keymap_act[mode][(byte)(buf[0])] = NULL;
2871 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2874 /* Enter a new action */
2878 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2884 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2885 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2888 prt(_("マクロ行動: ", "Action: "), 20, 0);
2890 /* Hack -- limit the value */
2893 /* Get an encoded action */
2894 if (!askfor(buf, 80)) continue;
2896 /* Extract an action */
2897 text_to_ascii(macro__buf, buf);
2900 #endif /* ALLOW_MACROS */
2913 * @brief キャラクタ色の明暗表現
2915 static concptr lighting_level_str[F_LIT_MAX] =
2930 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2931 * @param i 指定対象となるキャラクタコード
2932 * @param num 指定されたビジュアルIDを返す参照ポインタ
2933 * @param max ビジュアルIDの最大数
2934 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2936 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2943 sprintf(str, "%d", *num);
2945 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2948 tmp = (IDX)strtol(str, NULL, 0);
2949 if (tmp >= 0 && tmp < max)
2952 else if (isupper(i))
2953 *num = (*num + max - 1) % max;
2955 *num = (*num + 1) % max;
2961 * @brief キャラクタの変更メニュー表示
2962 * @param choice_msg 選択メッセージ
2965 static void print_visuals_menu(concptr choice_msg)
2967 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2969 /* Give some choices */
2970 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2972 #ifdef ALLOW_VISUALS
2973 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2974 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2975 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2976 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2977 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2978 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2979 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2980 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2981 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2982 #endif /* ALLOW_VISUALS */
2984 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2987 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2990 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2991 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2992 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2995 * Interact with "visuals"
2997 void do_cmd_visuals(void)
3002 bool need_redraw = FALSE;
3003 concptr empty_symbol = "<< ? >>";
3005 if (use_bigtile) empty_symbol = "<< ?? >>";
3007 /* File type is "TEXT" */
3008 FILE_TYPE(FILE_TYPE_TEXT);
3011 /* Interact until done */
3016 /* Ask for a choice */
3017 print_visuals_menu(NULL);
3022 if (i == ESCAPE) break;
3026 /* Load a 'pref' file */
3029 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3032 prt(_("ファイル: ", "File: "), 17, 0);
3034 /* Default filename */
3035 sprintf(tmp, "%s.prf", player_base);
3038 if (!askfor(tmp, 70)) continue;
3040 /* Process the given filename */
3041 (void)process_pref_file(tmp);
3046 #ifdef ALLOW_VISUALS
3048 /* Dump monster attr/chars */
3051 static concptr mark = "Monster attr/chars";
3054 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3057 prt(_("ファイル: ", "File: "), 17, 0);
3059 /* Default filename */
3060 sprintf(tmp, "%s.prf", player_base);
3062 /* Get a filename */
3063 if (!askfor(tmp, 70)) continue;
3065 /* Build the filename */
3066 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3068 /* Append to the file */
3069 if (!open_auto_dump(buf, mark)) continue;
3072 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3075 for (i = 0; i < max_r_idx; i++)
3077 monster_race *r_ptr = &r_info[i];
3079 /* Skip non-entries */
3080 if (!r_ptr->name) continue;
3082 /* Dump a comment */
3083 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3085 /* Dump the monster attr/char info */
3086 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3087 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3093 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3098 /* Dump object attr/chars */
3101 static concptr mark = "Object attr/chars";
3102 KIND_OBJECT_IDX k_idx;
3105 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3108 prt(_("ファイル: ", "File: "), 17, 0);
3110 /* Default filename */
3111 sprintf(tmp, "%s.prf", player_base);
3113 /* Get a filename */
3114 if (!askfor(tmp, 70)) continue;
3116 /* Build the filename */
3117 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3119 /* Append to the file */
3120 if (!open_auto_dump(buf, mark)) continue;
3123 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3126 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3128 GAME_TEXT o_name[MAX_NLEN];
3129 object_kind *k_ptr = &k_info[k_idx];
3131 /* Skip non-entries */
3132 if (!k_ptr->name) continue;
3137 strip_name(o_name, k_idx);
3143 /* Prepare dummy object */
3144 object_prep(&forge, k_idx);
3146 /* Get un-shuffled flavor name */
3147 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3150 /* Dump a comment */
3151 auto_dump_printf("# %s\n", o_name);
3153 /* Dump the object attr/char info */
3154 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3155 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3161 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3166 /* Dump feature attr/chars */
3169 static concptr mark = "Feature attr/chars";
3172 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3175 prt(_("ファイル: ", "File: "), 17, 0);
3177 /* Default filename */
3178 sprintf(tmp, "%s.prf", player_base);
3180 /* Get a filename */
3181 if (!askfor(tmp, 70)) continue;
3183 /* Build the filename */
3184 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3186 /* Append to the file */
3187 if (!open_auto_dump(buf, mark)) continue;
3190 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3193 for (i = 0; i < max_f_idx; i++)
3195 feature_type *f_ptr = &f_info[i];
3197 /* Skip non-entries */
3198 if (!f_ptr->name) continue;
3200 /* Skip mimiccing features */
3201 if (f_ptr->mimic != i) continue;
3203 /* Dump a comment */
3204 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3206 /* Dump the feature attr/char info */
3207 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3208 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3209 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3210 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3216 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3221 /* Modify monster attr/chars (numeric operation) */
3224 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3225 static MONRACE_IDX r = 0;
3227 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3229 /* Hack -- query until done */
3232 monster_race *r_ptr = &r_info[r];
3236 TERM_COLOR da = r_ptr->d_attr;
3237 byte dc = r_ptr->d_char;
3238 TERM_COLOR ca = r_ptr->x_attr;
3239 byte cc = r_ptr->x_char;
3241 /* Label the object */
3242 Term_putstr(5, 17, -1, TERM_WHITE,
3243 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3245 /* Label the Default values */
3246 Term_putstr(10, 19, -1, TERM_WHITE,
3247 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3249 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3250 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3252 /* Label the Current values */
3253 Term_putstr(10, 20, -1, TERM_WHITE,
3254 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3256 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3257 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3260 Term_putstr(0, 22, -1, TERM_WHITE,
3261 _("コマンド (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): "));
3266 if (i == ESCAPE) break;
3268 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3269 else if (isupper(i)) c = 'a' + i - 'A';
3279 if (!cmd_visuals_aux(i, &r, max_r_idx))
3285 while (!r_info[r].name);
3289 t = (int)r_ptr->x_attr;
3290 (void)cmd_visuals_aux(i, &t, 256);
3291 r_ptr->x_attr = (byte)t;
3295 t = (int)r_ptr->x_char;
3296 (void)cmd_visuals_aux(i, &t, 256);
3297 r_ptr->x_char = (byte)t;
3301 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3303 print_visuals_menu(choice_msg);
3311 /* Modify object attr/chars (numeric operation) */
3314 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3316 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3318 /* Hack -- query until done */
3321 object_kind *k_ptr = &k_info[k];
3325 TERM_COLOR da = k_ptr->d_attr;
3326 SYMBOL_CODE dc = k_ptr->d_char;
3327 TERM_COLOR ca = k_ptr->x_attr;
3328 SYMBOL_CODE cc = k_ptr->x_char;
3330 /* Label the object */
3331 Term_putstr(5, 17, -1, TERM_WHITE,
3332 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3333 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3335 /* Label the Default values */
3336 Term_putstr(10, 19, -1, TERM_WHITE,
3337 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3339 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3340 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3342 /* Label the Current values */
3343 Term_putstr(10, 20, -1, TERM_WHITE,
3344 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3346 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3347 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3350 Term_putstr(0, 22, -1, TERM_WHITE,
3351 _("コマンド (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): "));
3356 if (i == ESCAPE) break;
3358 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3359 else if (isupper(i)) c = 'a' + i - 'A';
3369 if (!cmd_visuals_aux(i, &k, max_k_idx))
3375 while (!k_info[k].name);
3379 t = (int)k_ptr->x_attr;
3380 (void)cmd_visuals_aux(i, &t, 256);
3381 k_ptr->x_attr = (byte)t;
3385 t = (int)k_ptr->x_char;
3386 (void)cmd_visuals_aux(i, &t, 256);
3387 k_ptr->x_char = (byte)t;
3391 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3393 print_visuals_menu(choice_msg);
3401 /* Modify feature attr/chars (numeric operation) */
3404 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3406 static IDX lighting_level = F_LIT_STANDARD;
3407 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3409 /* Hack -- query until done */
3412 feature_type *f_ptr = &f_info[f];
3416 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3417 byte dc = f_ptr->d_char[lighting_level];
3418 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3419 byte cc = f_ptr->x_char[lighting_level];
3421 /* Label the object */
3423 Term_putstr(5, 17, -1, TERM_WHITE,
3424 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3425 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3427 /* Label the Default values */
3428 Term_putstr(10, 19, -1, TERM_WHITE,
3429 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3431 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3432 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3434 /* Label the Current values */
3436 Term_putstr(10, 20, -1, TERM_WHITE,
3437 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3439 Term_putstr(10, 20, -1, TERM_WHITE,
3440 format("Current attr/char = %3d / %3d", ca, cc));
3443 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3444 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3448 Term_putstr(0, 22, -1, TERM_WHITE,
3449 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3451 Term_putstr(0, 22, -1, TERM_WHITE,
3452 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3458 if (i == ESCAPE) break;
3460 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3461 else if (isupper(i)) c = 'a' + i - 'A';
3471 if (!cmd_visuals_aux(i, &f, max_f_idx))
3477 while (!f_info[f].name || (f_info[f].mimic != f));
3481 t = (int)f_ptr->x_attr[lighting_level];
3482 (void)cmd_visuals_aux(i, &t, 256);
3483 f_ptr->x_attr[lighting_level] = (byte)t;
3487 t = (int)f_ptr->x_char[lighting_level];
3488 (void)cmd_visuals_aux(i, &t, 256);
3489 f_ptr->x_char[lighting_level] = (byte)t;
3493 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3496 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3500 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3502 print_visuals_menu(choice_msg);
3510 /* Modify monster attr/chars (visual mode) */
3512 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3515 /* Modify object attr/chars (visual mode) */
3517 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3520 /* Modify feature attr/chars (visual mode) */
3523 IDX lighting_level = F_LIT_STANDARD;
3524 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3528 #endif /* ALLOW_VISUALS */
3536 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3540 /* Unknown option */
3550 if (need_redraw) do_cmd_redraw();
3555 * Interact with "colors"
3557 void do_cmd_colors(void)
3566 /* File type is "TEXT" */
3567 FILE_TYPE(FILE_TYPE_TEXT);
3572 /* Interact until done */
3577 /* Ask for a choice */
3578 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3580 /* Give some choices */
3581 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3584 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3585 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3589 prt(_("コマンド: ", "Command: "), 8, 0);
3593 if (i == ESCAPE) break;
3595 /* Load a 'pref' file */
3599 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3602 prt(_("ファイル: ", "File: "), 10, 0);
3605 sprintf(tmp, "%s.prf", player_base);
3608 if (!askfor(tmp, 70)) continue;
3610 /* Process the given filename */
3611 (void)process_pref_file(tmp);
3613 /* Mega-Hack -- react to changes */
3614 Term_xtra(TERM_XTRA_REACT, 0);
3616 /* Mega-Hack -- redraw */
3625 static concptr mark = "Colors";
3628 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3631 prt(_("ファイル: ", "File: "), 10, 0);
3633 /* Default filename */
3634 sprintf(tmp, "%s.prf", player_base);
3636 /* Get a filename */
3637 if (!askfor(tmp, 70)) continue;
3639 /* Build the filename */
3640 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3642 /* Append to the file */
3643 if (!open_auto_dump(buf, mark)) continue;
3646 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3649 for (i = 0; i < 256; i++)
3651 int kv = angband_color_table[i][0];
3652 int rv = angband_color_table[i][1];
3653 int gv = angband_color_table[i][2];
3654 int bv = angband_color_table[i][3];
3656 concptr name = _("未知", "unknown");
3658 /* Skip non-entries */
3659 if (!kv && !rv && !gv && !bv) continue;
3661 /* Extract the color name */
3662 if (i < 16) name = color_names[i];
3664 /* Dump a comment */
3665 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3667 /* Dump the monster attr/char info */
3668 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3675 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3684 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3686 /* Hack -- query until done */
3695 /* Exhibit the normal colors */
3696 for (j = 0; j < 16; j++)
3698 /* Exhibit this color */
3699 Term_putstr(j*4, 20, -1, a, "###");
3701 /* Exhibit all colors */
3702 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3705 /* Describe the color */
3706 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3708 /* Describe the color */
3709 Term_putstr(5, 10, -1, TERM_WHITE,
3710 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3712 /* Label the Current values */
3713 Term_putstr(5, 12, -1, TERM_WHITE,
3714 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3715 angband_color_table[a][0],
3716 angband_color_table[a][1],
3717 angband_color_table[a][2],
3718 angband_color_table[a][3]));
3721 Term_putstr(0, 14, -1, TERM_WHITE,
3722 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3727 if (i == ESCAPE) break;
3730 if (i == 'n') a = (byte)(a + 1);
3731 if (i == 'N') a = (byte)(a - 1);
3732 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3733 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3734 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3735 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3736 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3737 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3738 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3739 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3741 /* Hack -- react to changes */
3742 Term_xtra(TERM_XTRA_REACT, 0);
3744 /* Hack -- redraw */
3751 /* Unknown option */
3765 * Note something in the message recall
3767 void do_cmd_note(void)
3775 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3777 /* Ignore empty notes */
3778 if (!buf[0] || (buf[0] == ' ')) return;
3780 /* Add the note to the message recall */
3781 msg_format(_("メモ: %s", "Note: %s"), buf);
3786 * Mention the current version
3788 void do_cmd_version(void)
3790 #if FAKE_VER_EXTRA > 0
3791 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3792 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3794 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3795 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3802 * Array of feeling strings
3804 static concptr do_cmd_feeling_text[11] =
3806 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3807 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3808 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3809 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3810 _("とても悪い予感がする...", "You have a very bad feeling..."),
3811 _("悪い予感がする...", "You have a bad feeling..."),
3812 _("何か緊張する。", "You feel nervous."),
3813 _("少し不運な気がする...", "You feel your luck is turning..."),
3814 _("この場所は好きになれない。", "You don't like the look of this place."),
3815 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3816 _("なんて退屈なところだ...", "What a boring place...")
3819 static concptr do_cmd_feeling_text_combat[11] =
3821 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3822 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3823 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3824 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3825 _("とても悪い予感がする...", "You have a very bad feeling..."),
3826 _("悪い予感がする...", "You have a bad feeling..."),
3827 _("何か緊張する。", "You feel nervous."),
3828 _("少し不運な気がする...", "You feel your luck is turning..."),
3829 _("この場所は好きになれない。", "You don't like the look of this place."),
3830 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3831 _("なんて退屈なところだ...", "What a boring place...")
3834 static concptr do_cmd_feeling_text_lucky[11] =
3836 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3837 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3838 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3839 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3840 _("とても良い感じがする...", "You have a very good feeling..."),
3841 _("良い感じがする...", "You have a good feeling..."),
3842 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3843 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3844 _("見た感じ悪くはない...", "You like the look of this place..."),
3845 _("全然駄目ということはないが...", "This level can't be all bad..."),
3846 _("なんて退屈なところだ...", "What a boring place...")
3851 * Note that "feeling" is set to zero unless some time has passed.
3852 * Note that this is done when the level is GENERATED, not entered.
3854 void do_cmd_feeling(void)
3856 if (p_ptr->wild_mode) return;
3858 /* No useful feeling in quests */
3859 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3861 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3865 /* No useful feeling in town */
3866 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3868 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3870 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3875 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3880 /* No useful feeling in the wilderness */
3881 else if (!current_floor_ptr->dun_level)
3883 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3887 /* Display the feeling */
3888 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3889 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3890 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3891 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3892 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3894 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3900 * Description of each monster group.
3902 static concptr monster_group_text[] =
3905 "ユニーク", /* "Uniques" */
3906 "乗馬可能なモンスター", /* "Riding" */
3907 "賞金首", /* "Wanted */
3908 "アンバーの王族", /* "Ambertite" */
3937 /* "古代ドラゴン/ワイアーム", */
3998 /* "Ancient Dragon/Wyrm", */
4007 "Multi-Headed Reptile",
4012 "Reptile/Amphibian",
4013 "Spider/Scorpion/Tick",
4015 /* "Major Demon", */
4032 * Symbols of monsters in each group. Note the "Uniques" group
4033 * is handled differently.
4035 static concptr monster_group_char[] =
4092 "!$&()+./=>?[\\]`{|~",
4102 * hook function to sort monsters by level
4104 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4106 u16b *who = (u16b*)(u);
4111 monster_race *r_ptr1 = &r_info[w1];
4112 monster_race *r_ptr2 = &r_info[w2];
4117 if (r_ptr2->level > r_ptr1->level) return TRUE;
4118 if (r_ptr1->level > r_ptr2->level) return FALSE;
4120 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4121 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4126 * Build a list of monster indexes in the given group. Return the number
4127 * of monsters in the group.
4129 * mode & 0x01 : check for non-empty group
4130 * mode & 0x02 : visual operation only
4132 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4138 /* Get a list of x_char in this group */
4139 concptr group_char = monster_group_char[grp_cur];
4141 /* XXX Hack -- Check if this is the "Uniques" group */
4142 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4144 /* XXX Hack -- Check if this is the "Riding" group */
4145 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4147 /* XXX Hack -- Check if this is the "Wanted" group */
4148 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4150 /* XXX Hack -- Check if this is the "Amberite" group */
4151 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4154 /* Check every race */
4155 for (i = 0; i < max_r_idx; i++)
4157 /* Access the race */
4158 monster_race *r_ptr = &r_info[i];
4160 /* Skip empty race */
4161 if (!r_ptr->name) continue ;
4163 /* Require known monsters */
4164 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4168 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4171 else if (grp_riding)
4173 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4176 else if (grp_wanted)
4178 bool wanted = FALSE;
4180 for (j = 0; j < MAX_KUBI; j++)
4182 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4183 (p_ptr->today_mon && p_ptr->today_mon == i))
4189 if (!wanted) continue;
4192 else if (grp_amberite)
4194 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4199 /* Check for race in the group */
4200 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4204 mon_idx[mon_cnt++] = i;
4206 /* XXX Hack -- Just checking for non-empty group */
4207 if (mode & 0x01) break;
4210 /* Terminate the list */
4211 mon_idx[mon_cnt] = -1;
4213 /* Select the sort method */
4214 ang_sort_comp = ang_sort_comp_monster_level;
4215 ang_sort_swap = ang_sort_swap_hook;
4217 /* Sort by monster level */
4218 ang_sort(mon_idx, &dummy_why, mon_cnt);
4220 /* Return the number of races */
4226 * Description of each monster group.
4228 static concptr object_group_text[] =
4231 "キノコ", /* "Mushrooms" */
4232 "薬", /* "Potions" */
4233 "油つぼ", /* "Flasks" */
4234 "巻物", /* "Scrolls" */
4236 "アミュレット", /* "Amulets" */
4237 "笛", /* "Whistle" */
4238 "光源", /* "Lanterns" */
4239 "魔法棒", /* "Wands" */
4242 "カード", /* "Cards" */
4253 "刀剣類", /* "Swords" */
4254 "鈍器", /* "Blunt Weapons" */
4255 "長柄武器", /* "Polearms" */
4256 "採掘道具", /* "Diggers" */
4257 "飛び道具", /* "Bows" */
4261 "軽装鎧", /* "Soft Armor" */
4262 "重装鎧", /* "Hard Armor" */
4263 "ドラゴン鎧", /* "Dragon Armor" */
4264 "盾", /* "Shields" */
4265 "クローク", /* "Cloaks" */
4266 "籠手", /* "Gloves" */
4267 "ヘルメット", /* "Helms" */
4269 "ブーツ", /* "Boots" */
4322 * TVALs of items in each group
4324 static byte object_group_tval[] =
4365 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4373 * Build a list of object indexes in the given group. Return the number
4374 * of objects in the group.
4376 * mode & 0x01 : check for non-empty group
4377 * mode & 0x02 : visual operation only
4379 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4381 KIND_OBJECT_IDX i, object_cnt = 0;
4384 /* Get a list of x_char in this group */
4385 byte group_tval = object_group_tval[grp_cur];
4387 /* Check every object */
4388 for (i = 0; i < max_k_idx; i++)
4390 /* Access the object */
4391 object_kind *k_ptr = &k_info[i];
4393 /* Skip empty objects */
4394 if (!k_ptr->name) continue;
4398 /* Any objects will be displayed */
4404 /* Skip non-flavoured objects */
4405 if (!k_ptr->flavor) continue;
4407 /* Require objects ever seen */
4408 if (!k_ptr->aware) continue;
4411 /* Skip items with no distribution (special artifacts) */
4412 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4416 /* Check for objects in the group */
4417 if (TV_LIFE_BOOK == group_tval)
4419 /* Hack -- All spell books */
4420 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4422 /* Add the object */
4423 object_idx[object_cnt++] = i;
4427 else if (k_ptr->tval == group_tval)
4429 /* Add the object */
4430 object_idx[object_cnt++] = i;
4434 /* XXX Hack -- Just checking for non-empty group */
4435 if (mode & 0x01) break;
4438 /* Terminate the list */
4439 object_idx[object_cnt] = -1;
4441 /* Return the number of objects */
4447 * Description of each feature group.
4449 static concptr feature_group_text[] =
4457 * Build a list of feature indexes in the given group. Return the number
4458 * of features in the group.
4460 * mode & 0x01 : check for non-empty group
4462 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4465 FEAT_IDX feat_cnt = 0;
4467 /* Unused; There is a single group. */
4470 /* Check every feature */
4471 for (i = 0; i < max_f_idx; i++)
4473 feature_type *f_ptr = &f_info[i];
4475 /* Skip empty index */
4476 if (!f_ptr->name) continue;
4478 /* Skip mimiccing features */
4479 if (f_ptr->mimic != i) continue;
4482 feat_idx[feat_cnt++] = i;
4484 /* XXX Hack -- Just checking for non-empty group */
4485 if (mode & 0x01) break;
4488 /* Terminate the list */
4489 feat_idx[feat_cnt] = -1;
4491 /* Return the number of races */
4498 * Build a list of monster indexes in the given group. Return the number
4499 * of monsters in the group.
4501 static int collect_artifacts(int grp_cur, int object_idx[])
4503 int i, object_cnt = 0;
4505 /* Get a list of x_char in this group */
4506 byte group_tval = object_group_tval[grp_cur];
4508 /* Check every object */
4509 for (i = 0; i < max_a_idx; i++)
4511 /* Access the artifact */
4512 artifact_type *a_ptr = &a_info[i];
4514 /* Skip empty artifacts */
4515 if (!a_ptr->name) continue;
4517 /* Skip "uncreated" artifacts */
4518 if (!a_ptr->cur_num) continue;
4520 /* Check for race in the group */
4521 if (a_ptr->tval == group_tval)
4524 object_idx[object_cnt++] = i;
4528 /* Terminate the list */
4529 object_idx[object_cnt] = 0;
4531 /* Return the number of races */
4538 * Encode the screen colors
4540 static char hack[17] = "dwsorgbuDWvyRGBU";
4544 * Hack -- load a screen dump from a file
4546 void do_cmd_load_screen(void)
4551 SYMBOL_CODE c = ' ';
4557 Term_get_size(&wid, &hgt);
4559 /* Build the filename */
4560 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4562 /* Append to the file */
4563 fff = my_fopen(buf, "r");
4566 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4574 /* Load the screen */
4575 for (y = 0; okay; y++)
4577 /* Get a line of data including control code */
4578 if (!fgets(buf, 1024, fff)) okay = FALSE;
4580 /* Get the blank line */
4581 if (buf[0] == '\n' || buf[0] == '\0') break;
4583 /* Ignore too large screen image */
4584 if (y >= hgt) continue;
4587 for (x = 0; x < wid - 1; x++)
4590 if (buf[x] == '\n' || buf[x] == '\0') break;
4592 /* Put the attr/char */
4593 Term_draw(x, y, TERM_WHITE, buf[x]);
4597 /* Dump the screen */
4598 for (y = 0; okay; y++)
4600 /* Get a line of data including control code */
4601 if (!fgets(buf, 1024, fff)) okay = FALSE;
4603 /* Get the blank line */
4604 if (buf[0] == '\n' || buf[0] == '\0') break;
4606 /* Ignore too large screen image */
4607 if (y >= hgt) continue;
4610 for (x = 0; x < wid - 1; x++)
4613 if (buf[x] == '\n' || buf[x] == '\0') break;
4615 /* Get the attr/char */
4616 (void)(Term_what(x, y, &a, &c));
4618 /* Look up the attr */
4619 for (i = 0; i < 16; i++)
4621 /* Use attr matches */
4622 if (hack[i] == buf[x]) a = (byte_hack)i;
4625 /* Put the attr/char */
4626 Term_draw(x, y, a, c);
4631 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4642 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4643 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4646 #define IM_FLAG_STR _("*", "* ")
4647 #define HAS_FLAG_STR _("+", "+ ")
4648 #define NO_FLAG_STR _("・", ". ")
4650 #define print_im_or_res_flag(IM, RES) \
4652 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4653 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4656 #define print_flag(TR) \
4658 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4662 /* XTRA HACK RESLIST */
4663 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4665 GAME_TEXT o_name[MAX_NLEN];
4666 BIT_FLAGS flgs[TR_FLAG_SIZE];
4668 if (!o_ptr->k_idx) return;
4669 if (o_ptr->tval != tval) return;
4671 /* Identified items only */
4672 if (!object_is_known(o_ptr)) return;
4675 * HACK:Ring of Lordly protection and Dragon equipment
4676 * have random resistances.
4678 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4679 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4680 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4681 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4682 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4683 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4684 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4685 || object_is_artifact(o_ptr))
4688 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4690 while (o_name[i] && (i < 26))
4693 if (iskanji(o_name[i])) i++;
4702 o_name[i] = ' '; i++;
4707 fprintf(fff, "%s %s", where, o_name);
4709 if (!(o_ptr->ident & (IDENT_MENTAL)))
4711 fputs(_("-------不明--------------- -------不明---------\n",
4712 "-------unknown------------ -------unknown------\n"), fff);
4716 object_flags_known(o_ptr, flgs);
4718 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4719 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4720 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4721 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4722 print_flag(TR_RES_POIS);
4723 print_flag(TR_RES_LITE);
4724 print_flag(TR_RES_DARK);
4725 print_flag(TR_RES_SHARDS);
4726 print_flag(TR_RES_SOUND);
4727 print_flag(TR_RES_NETHER);
4728 print_flag(TR_RES_NEXUS);
4729 print_flag(TR_RES_CHAOS);
4730 print_flag(TR_RES_DISEN);
4734 print_flag(TR_RES_BLIND);
4735 print_flag(TR_RES_FEAR);
4736 print_flag(TR_RES_CONF);
4737 print_flag(TR_FREE_ACT);
4738 print_flag(TR_SEE_INVIS);
4739 print_flag(TR_HOLD_EXP);
4740 print_flag(TR_TELEPATHY);
4741 print_flag(TR_SLOW_DIGEST);
4742 print_flag(TR_REGEN);
4743 print_flag(TR_LEVITATION);
4751 fprintf(fff, "%s\n", inven_res_label);
4757 * Display *ID* ed weapons/armors's resistances
4759 static void do_cmd_knowledge_inven(void)
4762 GAME_TEXT file_name[1024];
4764 OBJECT_TYPE_VALUE tval;
4770 /* Open a new file */
4771 fff = my_fopen_temp(file_name, 1024);
4774 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4778 fprintf(fff, "%s\n", inven_res_label);
4780 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4784 for (; j < 9; j++) fputc('\n', fff);
4786 fprintf(fff, "%s\n", inven_res_label);
4788 strcpy(where, _("装", "E "));
4789 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4791 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4793 strcpy(where, _("持", "I "));
4794 for (i = 0; i < INVEN_PACK; i++)
4796 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4799 st_ptr = &town_info[1].store[STORE_HOME];
4800 strcpy(where, _("家", "H "));
4801 for (i = 0; i < st_ptr->stock_num; i++)
4803 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4808 /* Display the file contents */
4809 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4814 void do_cmd_save_screen_html_aux(char *filename, int message)
4819 TERM_COLOR a = 0, old_a = 0;
4833 concptr html_head[] = {
4834 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4838 concptr html_foot[] = {
4840 "</body>\n</html>\n",
4846 Term_get_size(&wid, &hgt);
4848 /* File type is "TEXT" */
4849 FILE_TYPE(FILE_TYPE_TEXT);
4851 /* Append to the file */
4852 fff = my_fopen(filename, "w");
4856 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4862 if (message) screen_save();
4864 /* Build the filename */
4865 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4866 tmpfff = my_fopen(buf, "r");
4868 for (i = 0; html_head[i]; i++)
4869 fputs(html_head[i], fff);
4873 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4875 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4879 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4881 fprintf(fff, "%s\n", buf);
4886 /* Dump the screen */
4887 for (y = 0; y < hgt; y++)
4894 for (x = 0; x < wid - 1; x++)
4898 /* Get the attr/char */
4899 (void)(Term_what(x, y, &a, &c));
4903 case '&': cc = "&"; break;
4904 case '<': cc = "<"; break;
4905 case '>': cc = ">"; break;
4907 case 0x1f: c = '.'; break;
4908 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4913 if ((y == 0 && x == 0) || a != old_a) {
4914 rv = angband_color_table[a][1];
4915 gv = angband_color_table[a][2];
4916 bv = angband_color_table[a][3];
4917 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4918 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4922 fprintf(fff, "%s", cc);
4924 fprintf(fff, "%c", c);
4927 fprintf(fff, "</font>");
4930 for (i = 0; html_foot[i]; i++)
4931 fputs(html_foot[i], fff);
4936 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4938 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4942 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4944 fprintf(fff, "%s\n", buf);
4955 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4963 * Hack -- save a screen dump to a file
4965 static void do_cmd_save_screen_html(void)
4967 char buf[1024], tmp[256] = "screen.html";
4969 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4972 /* Build the filename */
4973 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4977 do_cmd_save_screen_html_aux(buf, 1);
4982 * Redefinable "save_screen" action
4984 void (*screendump_aux)(void) = NULL;
4988 * Hack -- save a screen dump to a file
4990 void do_cmd_save_screen(void)
4992 bool old_use_graphics = use_graphics;
4993 bool html_dump = FALSE;
4997 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5001 if (c == 'Y' || c == 'y')
5003 else if (c == 'H' || c == 'h')
5015 Term_get_size(&wid, &hgt);
5017 if (old_use_graphics)
5019 use_graphics = FALSE;
5021 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5027 do_cmd_save_screen_html();
5031 /* Do we use a special screendump function ? */
5032 else if (screendump_aux)
5034 /* Dump the screen to a graphics file */
5035 (*screendump_aux)();
5037 else /* Dump the screen as text */
5041 SYMBOL_CODE c = ' ';
5045 /* Build the filename */
5046 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5048 /* File type is "TEXT" */
5049 FILE_TYPE(FILE_TYPE_TEXT);
5051 /* Append to the file */
5052 fff = my_fopen(buf, "w");
5056 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5064 /* Dump the screen */
5065 for (y = 0; y < hgt; y++)
5068 for (x = 0; x < wid - 1; x++)
5070 /* Get the attr/char */
5071 (void)(Term_what(x, y, &a, &c));
5081 fprintf(fff, "%s\n", buf);
5088 /* Dump the screen */
5089 for (y = 0; y < hgt; y++)
5092 for (x = 0; x < wid - 1; x++)
5094 /* Get the attr/char */
5095 (void)(Term_what(x, y, &a, &c));
5098 buf[x] = hack[a&0x0F];
5105 fprintf(fff, "%s\n", buf);
5112 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5117 if (old_use_graphics)
5119 use_graphics = TRUE;
5121 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5128 * Sorting hook -- Comp function -- see below
5130 * We use "u" to point to array of monster indexes,
5131 * and "v" to select the type of sorting to perform on "u".
5133 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5135 u16b *who = (u16b*)(u);
5137 u16b *why = (u16b*)(v);
5144 /* Sort by total kills */
5147 /* Extract total kills */
5148 z1 = a_info[w1].tval;
5149 z2 = a_info[w2].tval;
5151 /* Compare total kills */
5152 if (z1 < z2) return (TRUE);
5153 if (z1 > z2) return (FALSE);
5157 /* Sort by monster level */
5160 /* Extract levels */
5161 z1 = a_info[w1].sval;
5162 z2 = a_info[w2].sval;
5164 /* Compare levels */
5165 if (z1 < z2) return (TRUE);
5166 if (z1 > z2) return (FALSE);
5170 /* Sort by monster experience */
5173 /* Extract experience */
5174 z1 = a_info[w1].level;
5175 z2 = a_info[w2].level;
5177 /* Compare experience */
5178 if (z1 < z2) return (TRUE);
5179 if (z1 > z2) return (FALSE);
5183 /* Compare indexes */
5189 * Sorting hook -- Swap function -- see below
5191 * We use "u" to point to array of monster indexes,
5192 * and "v" to select the type of sorting to perform.
5194 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5196 u16b *who = (u16b*)(u);
5211 * Check the status of "artifacts"
5213 static void do_cmd_knowledge_artifacts(void)
5223 GAME_TEXT file_name[1024];
5224 GAME_TEXT base_name[MAX_NLEN];
5228 /* Open a new file */
5229 fff = my_fopen_temp(file_name, 1024);
5232 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5237 /* Allocate the "who" array */
5238 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5240 /* Allocate the "okay" array */
5241 C_MAKE(okay, max_a_idx, bool);
5243 /* Scan the artifacts */
5244 for (k = 0; k < max_a_idx; k++)
5246 artifact_type *a_ptr = &a_info[k];
5251 /* Skip "empty" artifacts */
5252 if (!a_ptr->name) continue;
5254 /* Skip "uncreated" artifacts */
5255 if (!a_ptr->cur_num) continue;
5261 /* Check the dungeon */
5262 for (y = 0; y < current_floor_ptr->height; y++)
5264 for (x = 0; x < current_floor_ptr->width; x++)
5266 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5268 OBJECT_IDX this_o_idx, next_o_idx = 0;
5270 /* Scan all objects in the grid */
5271 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5274 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5275 next_o_idx = o_ptr->next_o_idx;
5277 /* Ignore non-artifacts */
5278 if (!object_is_fixed_artifact(o_ptr)) continue;
5280 /* Ignore known items */
5281 if (object_is_known(o_ptr)) continue;
5283 /* Note the artifact */
5284 okay[o_ptr->name1] = FALSE;
5289 /* Check the inventory and equipment */
5290 for (i = 0; i < INVEN_TOTAL; i++)
5292 object_type *o_ptr = &inventory[i];
5294 /* Ignore non-objects */
5295 if (!o_ptr->k_idx) continue;
5297 /* Ignore non-artifacts */
5298 if (!object_is_fixed_artifact(o_ptr)) continue;
5300 /* Ignore known items */
5301 if (object_is_known(o_ptr)) continue;
5303 /* Note the artifact */
5304 okay[o_ptr->name1] = FALSE;
5307 for (k = 0; k < max_a_idx; k++)
5309 if (okay[k]) who[n++] = k;
5312 /* Select the sort method */
5313 ang_sort_comp = ang_sort_art_comp;
5314 ang_sort_swap = ang_sort_art_swap;
5316 /* Sort the array by dungeon depth of monsters */
5317 ang_sort(who, &why, n);
5319 /* Scan the artifacts */
5320 for (k = 0; k < n; k++)
5322 artifact_type *a_ptr = &a_info[who[k]];
5325 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5327 /* Obtain the base object type */
5328 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5337 /* Create fake object */
5338 object_prep(q_ptr, z);
5340 /* Make it an artifact */
5341 q_ptr->name1 = (byte)who[k];
5343 /* Display as if known */
5344 q_ptr->ident |= IDENT_STORE;
5346 /* Describe the artifact */
5347 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5350 /* Hack -- Build the artifact name */
5351 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5354 /* Free the "who" array */
5355 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5357 /* Free the "okay" array */
5358 C_KILL(okay, max_a_idx, bool);
5361 /* Display the file contents */
5362 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5368 * Display known uniques
5369 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5371 static void do_cmd_knowledge_uniques(void)
5380 GAME_TEXT file_name[1024];
5383 int n_alive_surface = 0;
5384 int n_alive_over100 = 0;
5385 int n_alive_total = 0;
5388 for (i = 0; i < 10; i++) n_alive[i] = 0;
5390 /* Open a new file */
5391 fff = my_fopen_temp(file_name, 1024);
5395 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5400 /* Allocate the "who" array */
5401 C_MAKE(who, max_r_idx, MONRACE_IDX);
5403 /* Scan the monsters */
5404 for (i = 1; i < max_r_idx; i++)
5406 monster_race *r_ptr = &r_info[i];
5409 if (!r_ptr->name) continue;
5411 /* Require unique monsters */
5412 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5414 /* Only display "known" uniques */
5415 if (!cheat_know && !r_ptr->r_sights) continue;
5417 /* Only print rarity <= 100 uniques */
5418 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5420 /* Only "alive" uniques */
5421 if (r_ptr->max_num == 0) continue;
5425 lev = (r_ptr->level - 1) / 10;
5429 if (max_lev < lev) max_lev = lev;
5431 else n_alive_over100++;
5433 else n_alive_surface++;
5435 /* Collect "appropriate" monsters */
5439 /* Select the sort method */
5440 ang_sort_comp = ang_sort_comp_hook;
5441 ang_sort_swap = ang_sort_swap_hook;
5443 /* Sort the array by dungeon depth of monsters */
5444 ang_sort(who, &why, n);
5446 if (n_alive_surface)
5448 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5449 n_alive_total += n_alive_surface;
5451 for (i = 0; i <= max_lev; i++)
5453 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5454 n_alive_total += n_alive[i];
5456 if (n_alive_over100)
5458 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5459 n_alive_total += n_alive_over100;
5464 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5465 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5469 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5472 /* Scan the monster races */
5473 for (k = 0; k < n; k++)
5475 monster_race *r_ptr = &r_info[who[k]];
5477 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5480 /* Free the "who" array */
5481 C_KILL(who, max_r_idx, s16b);
5484 /* Display the file contents */
5485 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5491 * Display weapon-exp
5493 static void do_cmd_knowledge_weapon_exp(void)
5501 GAME_TEXT file_name[1024];
5504 /* Open a new file */
5505 fff = my_fopen_temp(file_name, 1024);
5507 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5512 for (i = 0; i < 5; i++)
5514 for (num = 0; num < 64; num++)
5516 for (j = 0; j < max_k_idx; j++)
5518 object_kind *k_ptr = &k_info[j];
5520 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5522 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5524 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5526 fprintf(fff, "%-25s ", tmp);
5527 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5528 else fprintf(fff, " ");
5529 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5530 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5539 /* Display the file contents */
5540 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5546 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5550 static void do_cmd_knowledge_spell_exp(void)
5557 const magic_type *s_ptr;
5559 GAME_TEXT file_name[1024];
5561 /* Open a new file */
5562 fff = my_fopen_temp(file_name, 1024);
5564 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5569 if (p_ptr->realm1 != REALM_NONE)
5571 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5572 for (i = 0; i < 32; i++)
5574 if (!is_magic(p_ptr->realm1))
5576 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5580 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5582 if (s_ptr->slevel >= 99) continue;
5583 spell_exp = p_ptr->spell_exp[i];
5584 exp_level = spell_exp_level(spell_exp);
5585 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5586 if (p_ptr->realm1 == REALM_HISSATSU)
5587 fprintf(fff, "[--]");
5590 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5591 else fprintf(fff, " ");
5592 fprintf(fff, "%s", exp_level_str[exp_level]);
5594 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5599 if (p_ptr->realm2 != REALM_NONE)
5601 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5602 for (i = 0; i < 32; i++)
5604 if (!is_magic(p_ptr->realm1))
5606 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5610 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5612 if (s_ptr->slevel >= 99) continue;
5614 spell_exp = p_ptr->spell_exp[i + 32];
5615 exp_level = spell_exp_level(spell_exp);
5616 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5617 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5618 else fprintf(fff, " ");
5619 fprintf(fff, "%s", exp_level_str[exp_level]);
5620 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5626 /* Display the file contents */
5627 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5633 * @brief スキル情報を表示するコマンドのメインルーチン /
5637 static void do_cmd_knowledge_skill_exp(void)
5639 int i = 0, skill_exp;
5643 char file_name[1024];
5644 char skill_name[GINOU_TEMPMAX][20] =
5646 _("マーシャルアーツ", "Martial Arts "),
5647 _("二刀流 ", "Dual Wielding "),
5648 _("乗馬 ", "Riding "),
5652 /* Open a new file */
5653 fff = my_fopen_temp(file_name, 1024);
5655 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5660 for (i = 0; i < GINOU_TEMPMAX; i++)
5662 skill_exp = p_ptr->skill_exp[i];
5663 fprintf(fff, "%-20s ", skill_name[i]);
5664 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5665 else fprintf(fff, " ");
5666 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5667 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5672 /* Display the file contents */
5673 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5679 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5680 * @param Name 変換したい文字列の参照ポインタ
5683 void plural_aux(char *Name)
5685 int NameLen = strlen(Name);
5687 if (my_strstr(Name, "Disembodied hand"))
5689 strcpy(Name, "Disembodied hands that strangled people");
5691 else if (my_strstr(Name, "Colour out of space"))
5693 strcpy(Name, "Colours out of space");
5695 else if (my_strstr(Name, "stairway to hell"))
5697 strcpy(Name, "stairways to hell");
5699 else if (my_strstr(Name, "Dweller on the threshold"))
5701 strcpy(Name, "Dwellers on the threshold");
5703 else if (my_strstr(Name, " of "))
5705 concptr aider = my_strstr(Name, " of ");
5716 if (dummy[i-1] == 's')
5718 strcpy(&(dummy[i]), "es");
5723 strcpy(&(dummy[i]), "s");
5726 strcpy(&(dummy[i+1]), aider);
5727 strcpy(Name, dummy);
5729 else if (my_strstr(Name, "coins"))
5732 strcpy(dummy, "piles of ");
5733 strcat(dummy, Name);
5734 strcpy(Name, dummy);
5737 else if (my_strstr(Name, "Manes"))
5741 else if (streq(&(Name[NameLen - 2]), "ey"))
5743 strcpy(&(Name[NameLen - 2]), "eys");
5745 else if (Name[NameLen - 1] == 'y')
5747 strcpy(&(Name[NameLen - 1]), "ies");
5749 else if (streq(&(Name[NameLen - 4]), "ouse"))
5751 strcpy(&(Name[NameLen - 4]), "ice");
5753 else if (streq(&(Name[NameLen - 2]), "us"))
5755 strcpy(&(Name[NameLen - 2]), "i");
5757 else if (streq(&(Name[NameLen - 6]), "kelman"))
5759 strcpy(&(Name[NameLen - 6]), "kelmen");
5761 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5763 strcpy(&(Name[NameLen - 8]), "wordsmen");
5765 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5767 strcpy(&(Name[NameLen - 7]), "oodsmen");
5769 else if (streq(&(Name[NameLen - 7]), "eastman"))
5771 strcpy(&(Name[NameLen - 7]), "eastmen");
5773 else if (streq(&(Name[NameLen - 8]), "izardman"))
5775 strcpy(&(Name[NameLen - 8]), "izardmen");
5777 else if (streq(&(Name[NameLen - 5]), "geist"))
5779 strcpy(&(Name[NameLen - 5]), "geister");
5781 else if (streq(&(Name[NameLen - 2]), "ex"))
5783 strcpy(&(Name[NameLen - 2]), "ices");
5785 else if (streq(&(Name[NameLen - 2]), "lf"))
5787 strcpy(&(Name[NameLen - 2]), "lves");
5789 else if (suffix(Name, "ch") ||
5790 suffix(Name, "sh") ||
5791 suffix(Name, "nx") ||
5792 suffix(Name, "s") ||
5795 strcpy(&(Name[NameLen]), "es");
5799 strcpy(&(Name[NameLen]), "s");
5804 * @brief 現在のペットを表示するコマンドのメインルーチン /
5805 * Display current pets
5808 static void do_cmd_knowledge_pets(void)
5812 monster_type *m_ptr;
5813 GAME_TEXT pet_name[MAX_NLEN];
5815 int show_upkeep = 0;
5816 GAME_TEXT file_name[1024];
5819 /* Open a new file */
5820 fff = my_fopen_temp(file_name, 1024);
5822 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5827 /* Process the monsters (backwards) */
5828 for (i = m_max - 1; i >= 1; i--)
5830 /* Access the monster */
5831 m_ptr = ¤t_floor_ptr->m_list[i];
5833 /* Ignore "dead" monsters */
5834 if (!m_ptr->r_idx) continue;
5836 /* Calculate "upkeep" for pets */
5840 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5841 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5845 show_upkeep = calculate_upkeep();
5847 fprintf(fff, "----------------------------------------------\n");
5849 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5851 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5853 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5858 /* Display the file contents */
5859 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5865 * @brief 現在のペットを表示するコマンドのメインルーチン /
5868 * @note the player ghosts are ignored.
5870 static void do_cmd_knowledge_kill_count(void)
5877 GAME_TEXT file_name[1024];
5882 /* Open a new file */
5883 fff = my_fopen_temp(file_name, 1024);
5886 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5891 /* Allocate the "who" array */
5892 C_MAKE(who, max_r_idx, MONRACE_IDX);
5895 /* Monsters slain */
5898 for (kk = 1; kk < max_r_idx; kk++)
5900 monster_race *r_ptr = &r_info[kk];
5902 if (r_ptr->flags1 & (RF1_UNIQUE))
5904 bool dead = (r_ptr->max_num == 0);
5913 MONSTER_NUMBER This = r_ptr->r_pkills;
5923 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5926 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5928 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5934 /* Scan the monsters */
5935 for (i = 1; i < max_r_idx; i++)
5937 monster_race *r_ptr = &r_info[i];
5939 /* Use that monster */
5940 if (r_ptr->name) who[n++] = i;
5943 /* Select the sort method */
5944 ang_sort_comp = ang_sort_comp_hook;
5945 ang_sort_swap = ang_sort_swap_hook;
5947 /* Sort the array by dungeon depth of monsters */
5948 ang_sort(who, &why, n);
5950 /* Scan the monster races */
5951 for (k = 0; k < n; k++)
5953 monster_race *r_ptr = &r_info[who[k]];
5955 if (r_ptr->flags1 & (RF1_UNIQUE))
5957 bool dead = (r_ptr->max_num == 0);
5961 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5967 MONSTER_NUMBER This = r_ptr->r_pkills;
5972 /* p,tは人と数える by ita */
5973 if (my_strchr("pt", r_ptr->d_char))
5974 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5976 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5980 if (my_strstr(r_name + r_ptr->name, "coins"))
5982 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5986 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5992 strcpy(ToPlural, (r_name + r_ptr->name));
5993 plural_aux(ToPlural);
5994 fprintf(fff, " %d %s\n", This, ToPlural);
6004 fprintf(fff,"----------------------------------------------\n");
6006 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6008 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6012 /* Free the "who" array */
6013 C_KILL(who, max_r_idx, s16b);
6016 /* Display the file contents */
6017 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6023 * @brief モンスター情報リスト中のグループを表示する /
6024 * Display the object groups.
6028 * @param per_page リストの表示行
6029 * @param grp_idx グループのID配列
6030 * @param group_text グループ名の文字列配列
6031 * @param grp_cur 現在の選択ID
6032 * @param grp_top 現在の選択リスト最上部ID
6035 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)
6039 /* Display lines until done */
6040 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6042 /* Get the group index */
6043 int grp = grp_idx[grp_top + i];
6045 /* Choose a color */
6046 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6048 /* Erase the entire line */
6049 Term_erase(col, row + i, wid);
6051 /* Display the group label */
6052 c_put_str(attr, group_text[grp], row + i, col);
6058 * Move the cursor in a browser window
6060 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6061 IDX *list_cur, int list_cnt)
6066 IDX list = *list_cur;
6068 /* Extract direction */
6071 /* Hack -- scroll up full screen */
6076 /* Hack -- scroll down full screen */
6081 d = get_keymap_dir(ch);
6086 /* Diagonals - hack */
6087 if ((ddx[d] > 0) && ddy[d])
6092 Term_get_size(&wid, &hgt);
6094 browser_rows = hgt - 8;
6096 /* Browse group list */
6101 /* Move up or down */
6102 grp += ddy[d] * (browser_rows - 1);
6105 if (grp >= grp_cnt) grp = grp_cnt - 1;
6106 if (grp < 0) grp = 0;
6107 if (grp != old_grp) list = 0;
6110 /* Browse sub-list list */
6113 /* Move up or down */
6114 list += ddy[d] * browser_rows;
6117 if (list >= list_cnt) list = list_cnt - 1;
6118 if (list < 0) list = 0;
6130 if (col < 0) col = 0;
6131 if (col > 1) col = 1;
6138 /* Browse group list */
6143 /* Move up or down */
6147 if (grp >= grp_cnt) grp = grp_cnt - 1;
6148 if (grp < 0) grp = 0;
6149 if (grp != old_grp) list = 0;
6152 /* Browse sub-list list */
6155 /* Move up or down */
6156 list += (IDX)ddy[d];
6159 if (list >= list_cnt) list = list_cnt - 1;
6160 if (list < 0) list = 0;
6171 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6175 /* Clear the display lines */
6176 for (i = 0; i < height; i++)
6178 Term_erase(col, row + i, width);
6181 /* Bigtile mode uses double width */
6182 if (use_bigtile) width /= 2;
6184 /* Display lines until done */
6185 for (i = 0; i < height; i++)
6187 /* Display columns until done */
6188 for (j = 0; j < width; j++)
6192 TERM_LEN x = col + j;
6193 TERM_LEN y = row + i;
6195 /* Bigtile mode uses double width */
6196 if (use_bigtile) x += j;
6201 /* Ignore illegal characters */
6202 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6203 (!use_graphics && ic > 0x7f))
6209 /* Force correct code for both ASCII character and tile */
6210 if (c & 0x80) a |= 0x80;
6212 /* Display symbol */
6213 Term_queue_bigchar(x, y, a, c, 0, 0);
6220 * Place the cursor at the collect position for visual mode
6222 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6224 int i = (a & 0x7f) - attr_top;
6225 int j = c - char_left;
6227 TERM_LEN x = col + j;
6228 TERM_LEN y = row + i;
6230 /* Bigtile mode uses double width */
6231 if (use_bigtile) x += j;
6233 /* Place the cursor */
6239 * Clipboard variables for copy&paste in visual mode
6241 static TERM_COLOR attr_idx = 0;
6242 static SYMBOL_CODE char_idx = 0;
6244 /* Hack -- for feature lighting */
6245 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6246 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6249 * Do visual mode command -- Change symbols
6251 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6252 int height, int width,
6253 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6254 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6256 static TERM_COLOR attr_old = 0;
6257 static SYMBOL_CODE char_old = 0;
6262 if (*visual_list_ptr)
6265 *cur_attr_ptr = attr_old;
6266 *cur_char_ptr = char_old;
6267 *visual_list_ptr = FALSE;
6275 if (*visual_list_ptr)
6278 *visual_list_ptr = FALSE;
6279 *need_redraw = TRUE;
6287 if (!*visual_list_ptr)
6289 *visual_list_ptr = TRUE;
6291 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6292 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6294 attr_old = *cur_attr_ptr;
6295 char_old = *cur_char_ptr;
6306 /* Set the visual */
6307 attr_idx = *cur_attr_ptr;
6308 char_idx = *cur_char_ptr;
6310 /* Hack -- for feature lighting */
6311 for (i = 0; i < F_LIT_MAX; i++)
6313 attr_idx_feat[i] = 0;
6314 char_idx_feat[i] = 0;
6321 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6324 *cur_attr_ptr = attr_idx;
6325 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6326 if (!*visual_list_ptr) *need_redraw = TRUE;
6332 *cur_char_ptr = char_idx;
6333 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6334 if (!*visual_list_ptr) *need_redraw = TRUE;
6340 if (*visual_list_ptr)
6343 int d = get_keymap_dir(ch);
6344 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6345 SYMBOL_CODE c = *cur_char_ptr;
6347 if (use_bigtile) eff_width = width / 2;
6348 else eff_width = width;
6350 /* Restrict direction */
6351 if ((a == 0) && (ddy[d] < 0)) d = 0;
6352 if ((c == 0) && (ddx[d] < 0)) d = 0;
6353 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6354 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6356 a += (TERM_COLOR)ddy[d];
6357 c += (SYMBOL_CODE)ddx[d];
6359 /* Force correct code for both ASCII character and tile */
6360 if (c & 0x80) a |= 0x80;
6362 /* Set the visual */
6367 /* Move the frame */
6368 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6369 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6370 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6371 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6377 /* Visual mode command is not used */
6383 * Display the monsters in a group.
6385 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6386 int mon_cur, int mon_top, bool visual_only)
6390 /* Display lines until done */
6391 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6395 /* Get the race index */
6396 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6398 /* Access the race */
6399 monster_race *r_ptr = &r_info[r_idx];
6401 /* Choose a color */
6402 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6404 /* Display the name */
6405 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6407 /* Hack -- visual_list mode */
6410 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6412 if (p_ptr->wizard || visual_only)
6414 c_prt(attr, format("%d", r_idx), row + i, 62);
6417 /* Erase chars before overwritten by the race letter */
6418 Term_erase(69, row + i, 255);
6420 /* Display symbol */
6421 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6426 if (!(r_ptr->flags1 & RF1_UNIQUE))
6427 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6429 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6430 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6434 /* Clear remaining lines */
6435 for (; i < per_page; i++)
6437 Term_erase(col, row + i, 255);
6443 * Display known monsters.
6445 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6449 IDX grp_cur, grp_top, old_grp_cur;
6450 IDX mon_cur, mon_top;
6451 IDX grp_cnt, grp_idx[100];
6459 bool visual_list = FALSE;
6460 TERM_COLOR attr_top = 0;
6468 Term_get_size(&wid, &hgt);
6470 browser_rows = hgt - 8;
6472 /* Allocate the "mon_idx" array */
6473 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6478 if (direct_r_idx < 0)
6480 mode = visual_only ? 0x03 : 0x01;
6482 /* Check every group */
6483 for (i = 0; monster_group_text[i] != NULL; i++)
6485 /* Measure the label */
6486 len = strlen(monster_group_text[i]);
6488 /* Save the maximum length */
6489 if (len > max) max = len;
6491 /* See if any monsters are known */
6492 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6494 /* Build a list of groups with known monsters */
6495 grp_idx[grp_cnt++] = i;
6503 mon_idx[0] = direct_r_idx;
6506 /* Terminate the list */
6509 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6510 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6513 /* Terminate the list */
6514 grp_idx[grp_cnt] = -1;
6517 grp_cur = grp_top = 0;
6518 mon_cur = mon_top = 0;
6523 mode = visual_only ? 0x02 : 0x00;
6528 monster_race *r_ptr;
6533 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6534 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6535 prt(_("名前", "Name"), 4, max + 3);
6536 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6537 prt(_("文字", "Sym"), 4, 67);
6538 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6540 for (i = 0; i < 78; i++)
6542 Term_putch(i, 5, TERM_WHITE, '=');
6545 if (direct_r_idx < 0)
6547 for (i = 0; i < browser_rows; i++)
6549 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6556 if (direct_r_idx < 0)
6558 /* Scroll group list */
6559 if (grp_cur < grp_top) grp_top = grp_cur;
6560 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6562 /* Display a list of monster groups */
6563 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6565 if (old_grp_cur != grp_cur)
6567 old_grp_cur = grp_cur;
6569 /* Get a list of monsters in the current group */
6570 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6573 /* Scroll monster list */
6574 while (mon_cur < mon_top)
6575 mon_top = MAX(0, mon_top - browser_rows/2);
6576 while (mon_cur >= mon_top + browser_rows)
6577 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6582 /* Display a list of monsters in the current group */
6583 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6589 /* Display a monster name */
6590 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6592 /* Display visual list below first monster */
6593 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6597 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6598 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6599 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6600 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6603 /* Get the current monster */
6604 r_ptr = &r_info[mon_idx[mon_cur]];
6608 /* Mega Hack -- track this monster race */
6609 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6615 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6619 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6623 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6628 /* Do visual mode command if needed */
6629 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))
6631 if (direct_r_idx >= 0)
6656 /* Recall on screen */
6657 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6659 screen_roff(mon_idx[mon_cur], 0);
6670 /* Move the cursor */
6671 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6678 /* Free the "mon_idx" array */
6679 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6684 * Display the objects in a group.
6686 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6687 int object_cur, int object_top, bool visual_only)
6691 /* Display lines until done */
6692 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6694 GAME_TEXT o_name[MAX_NLEN];
6697 object_kind *flavor_k_ptr;
6699 /* Get the object index */
6700 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6702 /* Access the object */
6703 object_kind *k_ptr = &k_info[k_idx];
6705 /* Choose a color */
6706 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6707 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6710 if (!visual_only && k_ptr->flavor)
6712 /* Appearance of this object is shuffled */
6713 flavor_k_ptr = &k_info[k_ptr->flavor];
6717 /* Appearance of this object is very normal */
6718 flavor_k_ptr = k_ptr;
6723 attr = ((i + object_top == object_cur) ? cursor : attr);
6725 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6728 strip_name(o_name, k_idx);
6733 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6736 /* Display the name */
6737 c_prt(attr, o_name, row + i, col);
6739 /* Hack -- visual_list mode */
6742 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);
6744 if (p_ptr->wizard || visual_only)
6746 c_prt(attr, format("%d", k_idx), row + i, 70);
6749 a = flavor_k_ptr->x_attr;
6750 c = flavor_k_ptr->x_char;
6752 /* Display symbol */
6753 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6756 /* Clear remaining lines */
6757 for (; i < per_page; i++)
6759 Term_erase(col, row + i, 255);
6764 * Describe fake object
6766 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6769 object_type object_type_body;
6770 o_ptr = &object_type_body;
6773 /* Create the artifact */
6774 object_prep(o_ptr, k_idx);
6776 /* It's fully know */
6777 o_ptr->ident |= IDENT_KNOWN;
6779 /* Track the object */
6780 /* object_actual_track(o_ptr); */
6782 /* Hack - mark as fake */
6783 /* term_obj_real = FALSE; */
6786 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6788 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6796 * Display known objects
6798 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6802 IDX grp_cur, grp_top, old_grp_cur;
6803 IDX object_old, object_cur, object_top;
6807 OBJECT_IDX *object_idx;
6813 bool visual_list = FALSE;
6814 TERM_COLOR attr_top = 0;
6822 Term_get_size(&wid, &hgt);
6824 browser_rows = hgt - 8;
6826 /* Allocate the "object_idx" array */
6827 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6832 if (direct_k_idx < 0)
6834 mode = visual_only ? 0x03 : 0x01;
6836 /* Check every group */
6837 for (i = 0; object_group_text[i] != NULL; i++)
6839 /* Measure the label */
6840 len = strlen(object_group_text[i]);
6842 /* Save the maximum length */
6843 if (len > max) max = len;
6845 /* See if any monsters are known */
6846 if (collect_objects(i, object_idx, mode))
6848 /* Build a list of groups with known monsters */
6849 grp_idx[grp_cnt++] = i;
6858 object_kind *k_ptr = &k_info[direct_k_idx];
6859 object_kind *flavor_k_ptr;
6861 if (!visual_only && k_ptr->flavor)
6863 /* Appearance of this object is shuffled */
6864 flavor_k_ptr = &k_info[k_ptr->flavor];
6868 /* Appearance of this object is very normal */
6869 flavor_k_ptr = k_ptr;
6872 object_idx[0] = direct_k_idx;
6873 object_old = direct_k_idx;
6876 /* Terminate the list */
6879 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6880 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6883 /* Terminate the list */
6884 grp_idx[grp_cnt] = -1;
6887 grp_cur = grp_top = 0;
6888 object_cur = object_top = 0;
6893 mode = visual_only ? 0x02 : 0x00;
6898 object_kind *k_ptr, *flavor_k_ptr;
6905 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6906 if (direct_k_idx < 0) prt("グループ", 4, 0);
6907 prt("名前", 4, max + 3);
6908 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6911 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6912 if (direct_k_idx < 0) prt("Group", 4, 0);
6913 prt("Name", 4, max + 3);
6914 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6918 for (i = 0; i < 78; i++)
6920 Term_putch(i, 5, TERM_WHITE, '=');
6923 if (direct_k_idx < 0)
6925 for (i = 0; i < browser_rows; i++)
6927 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6934 if (direct_k_idx < 0)
6936 /* Scroll group list */
6937 if (grp_cur < grp_top) grp_top = grp_cur;
6938 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6940 /* Display a list of object groups */
6941 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6943 if (old_grp_cur != grp_cur)
6945 old_grp_cur = grp_cur;
6947 /* Get a list of objects in the current group */
6948 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6951 /* Scroll object list */
6952 while (object_cur < object_top)
6953 object_top = MAX(0, object_top - browser_rows/2);
6954 while (object_cur >= object_top + browser_rows)
6955 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6960 /* Display a list of objects in the current group */
6961 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6965 object_top = object_cur;
6967 /* Display a list of objects in the current group */
6968 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6970 /* Display visual list below first object */
6971 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6974 /* Get the current object */
6975 k_ptr = &k_info[object_idx[object_cur]];
6977 if (!visual_only && k_ptr->flavor)
6979 /* Appearance of this object is shuffled */
6980 flavor_k_ptr = &k_info[k_ptr->flavor];
6984 /* Appearance of this object is very normal */
6985 flavor_k_ptr = k_ptr;
6990 prt(format("<方向>%s%s%s, ESC",
6991 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6992 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6993 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6996 prt(format("<dir>%s%s%s, ESC",
6997 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6998 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6999 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7005 /* Mega Hack -- track this object */
7006 if (object_cnt) object_kind_track(object_idx[object_cur]);
7008 /* The "current" object changed */
7009 if (object_old != object_idx[object_cur])
7013 /* Remember the "current" object */
7014 object_old = object_idx[object_cur];
7020 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7024 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7028 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7033 /* Do visual mode command if needed */
7034 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))
7036 if (direct_k_idx >= 0)
7061 /* Recall on screen */
7062 if (!visual_list && !visual_only && (grp_cnt > 0))
7064 desc_obj_fake(object_idx[object_cur]);
7072 /* Move the cursor */
7073 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7079 /* Free the "object_idx" array */
7080 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
7085 * Display the features in a group.
7087 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7088 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7090 int lit_col[F_LIT_MAX], i, j;
7091 int f_idx_col = use_bigtile ? 62 : 64;
7093 /* Correct columns 1 and 4 */
7094 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7095 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7096 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7098 /* Display lines until done */
7099 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7102 FEAT_IDX f_idx = feat_idx[feat_top + i];
7103 feature_type *f_ptr = &f_info[f_idx];
7104 int row_i = row + i;
7106 /* Choose a color */
7107 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7109 /* Display the name */
7110 c_prt(attr, f_name + f_ptr->name, row_i, col);
7112 /* Hack -- visual_list mode */
7115 /* Display lighting level */
7116 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7118 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));
7120 if (p_ptr->wizard || visual_only)
7122 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7125 /* Display symbol */
7126 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);
7128 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7129 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7131 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7133 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7135 /* Mega-hack -- Use non-standard colour */
7136 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7138 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7142 /* Clear remaining lines */
7143 for (; i < per_page; i++)
7145 Term_erase(col, row + i, 255);
7151 * Interact with feature visuals.
7153 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7157 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7158 FEAT_IDX feat_cur, feat_top;
7160 FEAT_IDX grp_idx[100];
7164 TERM_LEN column = 0;
7168 bool visual_list = FALSE;
7169 TERM_COLOR attr_top = 0;
7172 TERM_LEN browser_rows;
7175 TERM_COLOR attr_old[F_LIT_MAX];
7176 SYMBOL_CODE char_old[F_LIT_MAX];
7177 TERM_COLOR *cur_attr_ptr;
7178 SYMBOL_CODE *cur_char_ptr;
7180 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7181 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7183 Term_get_size(&wid, &hgt);
7185 browser_rows = hgt - 8;
7187 /* Allocate the "feat_idx" array */
7188 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7193 if (direct_f_idx < 0)
7195 /* Check every group */
7196 for (i = 0; feature_group_text[i] != NULL; i++)
7198 /* Measure the label */
7199 len = strlen(feature_group_text[i]);
7201 /* Save the maximum length */
7202 if (len > max) max = len;
7204 /* See if any features are known */
7205 if (collect_features(i, feat_idx, 0x01))
7207 /* Build a list of groups with known features */
7208 grp_idx[grp_cnt++] = i;
7216 feature_type *f_ptr = &f_info[direct_f_idx];
7218 feat_idx[0] = direct_f_idx;
7221 /* Terminate the list */
7224 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7225 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7227 for (i = 0; i < F_LIT_MAX; i++)
7229 attr_old[i] = f_ptr->x_attr[i];
7230 char_old[i] = f_ptr->x_char[i];
7234 /* Terminate the list */
7235 grp_idx[grp_cnt] = -1;
7238 grp_cur = grp_top = 0;
7239 feat_cur = feat_top = 0;
7247 feature_type *f_ptr;
7253 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7254 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7255 prt(_("名前", "Name"), 4, max + 3);
7258 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7259 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7263 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7264 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7267 for (i = 0; i < 78; i++)
7269 Term_putch(i, 5, TERM_WHITE, '=');
7272 if (direct_f_idx < 0)
7274 for (i = 0; i < browser_rows; i++)
7276 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7283 if (direct_f_idx < 0)
7285 /* Scroll group list */
7286 if (grp_cur < grp_top) grp_top = grp_cur;
7287 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7289 /* Display a list of feature groups */
7290 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7292 if (old_grp_cur != grp_cur)
7294 old_grp_cur = grp_cur;
7296 /* Get a list of features in the current group */
7297 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7300 /* Scroll feature list */
7301 while (feat_cur < feat_top)
7302 feat_top = MAX(0, feat_top - browser_rows/2);
7303 while (feat_cur >= feat_top + browser_rows)
7304 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7309 /* Display a list of features in the current group */
7310 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7314 feat_top = feat_cur;
7316 /* Display a list of features in the current group */
7317 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7319 /* Display visual list below first object */
7320 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7324 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7325 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7326 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7329 /* Get the current feature */
7330 f_ptr = &f_info[feat_idx[feat_cur]];
7331 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7332 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7336 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7340 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7344 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7349 if (visual_list && ((ch == 'A') || (ch == 'a')))
7351 int prev_lighting_level = *lighting_level;
7355 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7356 else (*lighting_level)--;
7360 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7361 else (*lighting_level)++;
7364 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7365 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7367 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7368 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7373 else if ((ch == 'D') || (ch == 'd'))
7375 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7376 byte prev_x_char = f_ptr->x_char[*lighting_level];
7378 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7382 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7383 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7385 if (prev_x_char != f_ptr->x_char[*lighting_level])
7386 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7388 else *need_redraw = TRUE;
7393 /* Do visual mode command if needed */
7394 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))
7398 /* Restore previous visual settings */
7400 for (i = 0; i < F_LIT_MAX; i++)
7402 f_ptr->x_attr[i] = attr_old[i];
7403 f_ptr->x_char[i] = char_old[i];
7410 if (direct_f_idx >= 0) flag = TRUE;
7411 else *lighting_level = F_LIT_STANDARD;
7414 /* Preserve current visual settings */
7417 for (i = 0; i < F_LIT_MAX; i++)
7419 attr_old[i] = f_ptr->x_attr[i];
7420 char_old[i] = f_ptr->x_char[i];
7422 *lighting_level = F_LIT_STANDARD;
7429 for (i = 0; i < F_LIT_MAX; i++)
7431 attr_idx_feat[i] = f_ptr->x_attr[i];
7432 char_idx_feat[i] = f_ptr->x_char[i];
7441 /* Allow TERM_DARK text */
7442 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7444 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7445 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7463 /* Move the cursor */
7464 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7470 /* Free the "feat_idx" array */
7471 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7476 * List wanted monsters
7478 static void do_cmd_knowledge_kubi(void)
7483 GAME_TEXT file_name[1024];
7486 /* Open a new file */
7487 fff = my_fopen_temp(file_name, 1024);
7489 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7496 bool listed = FALSE;
7498 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7499 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7501 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7502 fprintf(fff, "----------------------------------------------\n");
7504 for (i = 0; i < MAX_KUBI; i++)
7506 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7508 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7516 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7521 /* Display the file contents */
7522 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7527 * List virtues & status
7529 static void do_cmd_knowledge_virtues(void)
7532 GAME_TEXT file_name[1024];
7534 /* Open a new file */
7535 fff = my_fopen_temp(file_name, 1024);
7537 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7544 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7549 /* Display the file contents */
7550 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7557 static void do_cmd_knowledge_dungeon(void)
7561 GAME_TEXT file_name[1024];
7564 /* Open a new file */
7565 fff = my_fopen_temp(file_name, 1024);
7567 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7574 for (i = 1; i < max_d_idx; i++)
7578 if (!d_info[i].maxdepth) continue;
7579 if (!max_dlv[i]) continue;
7580 if (d_info[i].final_guardian)
7582 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7584 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7586 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7591 /* Display the file contents */
7592 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7597 * List virtues & status
7600 static void do_cmd_knowledge_stat(void)
7604 GAME_TEXT file_name[1024];
7607 /* Open a new file */
7608 fff = my_fopen_temp(file_name, 1024);
7610 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7617 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7618 (2 * p_ptr->hitdie +
7619 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7621 if (p_ptr->knowledge & KNOW_HPRATE)
7622 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7623 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7625 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7626 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7628 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);
7629 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7636 /* Display the file contents */
7637 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7643 * Print all active quests
7645 static void do_cmd_knowledge_quests_current(FILE *fff)
7648 char rand_tmp_str[120] = "\0";
7649 GAME_TEXT name[MAX_NLEN];
7650 monster_race *r_ptr;
7652 int rand_level = 100;
7655 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7657 for (i = 1; i < max_q_idx; i++)
7659 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7660 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7661 (quest[i].status == QUEST_STATUS_COMPLETED))
7663 /* Set the quest number temporary */
7664 QUEST_IDX old_quest = p_ptr->inside_quest;
7667 /* Clear the text */
7668 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7669 quest_text_line = 0;
7671 p_ptr->inside_quest = i;
7673 /* Get the quest text */
7674 init_flags = INIT_SHOW_TEXT;
7676 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7678 /* Reset the old quest number */
7679 p_ptr->inside_quest = old_quest;
7681 /* No info from "silent" quests */
7682 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7686 if (quest[i].type != QUEST_TYPE_RANDOM)
7688 char note[80] = "\0";
7690 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7692 switch (quest[i].type)
7694 case QUEST_TYPE_KILL_LEVEL:
7695 case QUEST_TYPE_KILL_ANY_LEVEL:
7696 r_ptr = &r_info[quest[i].r_idx];
7697 strcpy(name, r_name + r_ptr->name);
7698 if (quest[i].max_num > 1)
7701 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7702 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7705 sprintf(note," - kill %d %s, have killed %d.",
7706 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7710 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7713 case QUEST_TYPE_FIND_ARTIFACT:
7716 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7718 object_type *q_ptr = &forge;
7719 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7720 object_prep(q_ptr, k_idx);
7721 q_ptr->name1 = quest[i].k_idx;
7722 q_ptr->ident = IDENT_STORE;
7723 object_desc(name, q_ptr, OD_NAME_ONLY);
7725 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7727 case QUEST_TYPE_FIND_EXIT:
7728 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7731 case QUEST_TYPE_KILL_NUMBER:
7733 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7734 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7736 sprintf(note," - Kill %d monsters, have killed %d.",
7737 (int)quest[i].max_num, (int)quest[i].cur_num);
7741 case QUEST_TYPE_KILL_ALL:
7742 case QUEST_TYPE_TOWER:
7743 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7748 /* Print the quest info */
7749 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7750 quest[i].name, (int)quest[i].level, note);
7752 fputs(tmp_str, fff);
7754 if (quest[i].status == QUEST_STATUS_COMPLETED)
7756 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7757 fputs(tmp_str, fff);
7763 while (quest_text[j][0] && j < 10)
7765 fprintf(fff, " %s\n", quest_text[j]);
7770 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7773 rand_level = quest[i].level;
7775 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7777 /* Print the quest info */
7778 r_ptr = &r_info[quest[i].r_idx];
7779 strcpy(name, r_name + r_ptr->name);
7781 if (quest[i].max_num > 1)
7784 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7785 quest[i].name, (int)quest[i].level,
7786 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7790 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7791 quest[i].name, (int)quest[i].level,
7792 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7797 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7798 quest[i].name, (int)quest[i].level, name);
7805 /* Print the current random quest */
7806 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7808 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7812 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7815 char playtime_str[16];
7816 quest_type* const q_ptr = &quest[q_idx];
7818 if (is_fixed_quest_idx(q_idx))
7820 /* Set the quest number temporary */
7821 IDX old_quest = p_ptr->inside_quest;
7823 p_ptr->inside_quest = q_idx;
7826 init_flags = INIT_NAME_ONLY;
7828 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7830 /* Reset the old quest number */
7831 p_ptr->inside_quest = old_quest;
7833 /* No info from "silent" quests */
7834 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7837 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7838 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7840 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7842 /* Print the quest info */
7843 if (q_ptr->complev == 0)
7846 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7847 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7848 r_name+r_info[q_ptr->r_idx].name,
7849 (int)q_ptr->level, playtime_str);
7854 _(" %-35s (%3d階) - レベル%2d - %s\n",
7855 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7856 r_name+r_info[q_ptr->r_idx].name,
7864 /* Print the quest info */
7866 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7867 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7868 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7871 fputs(tmp_str, fff);
7877 * Print all finished quests
7879 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7882 QUEST_IDX total = 0;
7884 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7885 for (i = 1; i < max_q_idx; i++)
7887 QUEST_IDX q_idx = quest_num[i];
7888 quest_type* const q_ptr = &quest[q_idx];
7890 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7895 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7900 * Print all failed quests
7902 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7905 QUEST_IDX total = 0;
7907 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7908 for (i = 1; i < max_q_idx; i++)
7910 QUEST_IDX q_idx = quest_num[i];
7911 quest_type* const q_ptr = &quest[q_idx];
7913 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7914 do_cmd_knowledge_quests_aux(fff, q_idx))
7919 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7924 * Print all random quests
7926 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7928 GAME_TEXT tmp_str[120];
7930 QUEST_IDX total = 0;
7932 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7933 for (i = 1; i < max_q_idx; i++)
7935 /* No info from "silent" quests */
7936 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7938 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7942 /* Print the quest info */
7943 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7944 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7945 fputs(tmp_str, fff);
7948 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7952 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7954 QUEST_IDX *q_num = (QUEST_IDX *)u;
7955 quest_type *qa = &quest[q_num[a]];
7956 quest_type *qb = &quest[q_num[b]];
7961 return (qa->comptime != qb->comptime) ?
7962 (qa->comptime < qb->comptime) :
7963 (qa->level <= qb->level);
7966 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
7968 QUEST_IDX *q_num = (QUEST_IDX *)u;
7975 q_num[a] = q_num[b];
7981 * Print quest status of all active quests
7983 static void do_cmd_knowledge_quests(void)
7986 GAME_TEXT file_name[1024];
7991 /* Open a new file */
7992 fff = my_fopen_temp(file_name, 1024);
7995 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8000 /* Allocate Memory */
8001 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8003 /* Sort by compete level */
8004 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8005 ang_sort_comp = ang_sort_comp_quest_num;
8006 ang_sort_swap = ang_sort_swap_quest_num;
8007 ang_sort(quest_num, &dummy, max_q_idx);
8009 /* Dump Quest Information */
8010 do_cmd_knowledge_quests_current(fff);
8012 do_cmd_knowledge_quests_completed(fff, quest_num);
8014 do_cmd_knowledge_quests_failed(fff, quest_num);
8018 do_cmd_knowledge_quests_wiz_random(fff);
8022 /* Display the file contents */
8023 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8027 C_KILL(quest_num, max_q_idx, QUEST_IDX);
8034 static void do_cmd_knowledge_home(void)
8039 GAME_TEXT file_name[1024];
8041 GAME_TEXT o_name[MAX_NLEN];
8042 concptr paren = ")";
8044 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
8046 /* Open a new file */
8047 fff = my_fopen_temp(file_name, 1024);
8049 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8056 /* Print all homes in the different towns */
8057 st_ptr = &town_info[1].store[STORE_HOME];
8059 /* Home -- if anything there */
8060 if (st_ptr->stock_num)
8065 /* Header with name of the town */
8066 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8068 /* Dump all available items */
8069 for (i = 0; i < st_ptr->stock_num; i++)
8072 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8073 object_desc(o_name, &st_ptr->stock[i], 0);
8074 if (strlen(o_name) <= 80-3)
8076 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8082 for (n = 0, t = o_name; n < 80-3; n++, t++)
8083 if(iskanji(*t)) {t++; n++;}
8084 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8086 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8087 fprintf(fff, " %.77s\n", o_name+n);
8090 object_desc(o_name, &st_ptr->stock[i], 0);
8091 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8096 /* Add an empty line */
8097 fprintf(fff, "\n\n");
8102 /* Display the file contents */
8103 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8109 * Check the status of "autopick"
8111 static void do_cmd_knowledge_autopick(void)
8115 GAME_TEXT file_name[1024];
8117 /* Open a new file */
8118 fff = my_fopen_temp(file_name, 1024);
8122 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8129 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8133 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8134 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8137 for (k = 0; k < max_autopick; k++)
8140 byte act = autopick_list[k].action;
8141 if (act & DONT_AUTOPICK)
8143 tmp = _("放置", "Leave");
8145 else if (act & DO_AUTODESTROY)
8147 tmp = _("破壊", "Destroy");
8149 else if (act & DO_AUTOPICK)
8151 tmp = _("拾う", "Pickup");
8155 tmp = _("確認", "Query");
8158 if (act & DO_DISPLAY)
8159 fprintf(fff, "%11s", format("[%s]", tmp));
8161 fprintf(fff, "%11s", format("(%s)", tmp));
8163 tmp = autopick_line_from_entry(&autopick_list[k]);
8164 fprintf(fff, " %s", tmp);
8169 /* Display the file contents */
8170 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8176 * Interact with "knowledge"
8178 void do_cmd_knowledge(void)
8181 bool need_redraw = FALSE;
8183 /* File type is "TEXT" */
8184 FILE_TYPE(FILE_TYPE_TEXT);
8187 /* Interact until done */
8192 /* Ask for a choice */
8193 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8194 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8196 /* Give some choices */
8200 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8201 prt("(2) 既知のアイテム の一覧", 7, 5);
8202 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8203 prt("(4) 既知のモンスター の一覧", 9, 5);
8204 prt("(5) 倒した敵の数 の一覧", 10, 5);
8205 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8206 prt("(7) 現在のペット の一覧", 12, 5);
8207 prt("(8) 我が家のアイテム の一覧", 13, 5);
8208 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8209 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8213 prt("(a) 自分に関する情報 の一覧", 6, 5);
8214 prt("(b) 突然変異 の一覧", 7, 5);
8215 prt("(c) 武器の経験値 の一覧", 8, 5);
8216 prt("(d) 魔法の経験値 の一覧", 9, 5);
8217 prt("(e) 技能の経験値 の一覧", 10, 5);
8218 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8219 prt("(g) 入ったダンジョン の一覧", 12, 5);
8220 prt("(h) 実行中のクエスト の一覧", 13, 5);
8221 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8226 prt("(1) Display known artifacts", 6, 5);
8227 prt("(2) Display known objects", 7, 5);
8228 prt("(3) Display remaining uniques", 8, 5);
8229 prt("(4) Display known monster", 9, 5);
8230 prt("(5) Display kill count", 10, 5);
8231 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8232 prt("(7) Display current pets", 12, 5);
8233 prt("(8) Display home inventory", 13, 5);
8234 prt("(9) Display *identified* equip.", 14, 5);
8235 prt("(0) Display terrain symbols.", 15, 5);
8239 prt("(a) Display about yourself", 6, 5);
8240 prt("(b) Display mutations", 7, 5);
8241 prt("(c) Display weapon proficiency", 8, 5);
8242 prt("(d) Display spell proficiency", 9, 5);
8243 prt("(e) Display misc. proficiency", 10, 5);
8244 prt("(f) Display virtues", 11, 5);
8245 prt("(g) Display dungeons", 12, 5);
8246 prt("(h) Display current quests", 13, 5);
8247 prt("(i) Display auto pick/destroy", 14, 5);
8251 prt(_("-続く-", "-more-"), 17, 8);
8252 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8253 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8254 /*prt("-) 前ページ", 21, 60);*/
8255 prt(_("コマンド:", "Command: "), 20, 0);
8258 if (i == ESCAPE) break;
8261 case ' ': /* Page change */
8265 case '1': /* Artifacts */
8266 do_cmd_knowledge_artifacts();
8268 case '2': /* Objects */
8269 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8271 case '3': /* Uniques */
8272 do_cmd_knowledge_uniques();
8274 case '4': /* Monsters */
8275 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8277 case '5': /* Kill count */
8278 do_cmd_knowledge_kill_count();
8280 case '6': /* wanted */
8281 if (!vanilla_town) do_cmd_knowledge_kubi();
8283 case '7': /* Pets */
8284 do_cmd_knowledge_pets();
8286 case '8': /* Home */
8287 do_cmd_knowledge_home();
8289 case '9': /* Resist list */
8290 do_cmd_knowledge_inven();
8292 case '0': /* Feature list */
8294 IDX lighting_level = F_LIT_STANDARD;
8295 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8299 case 'a': /* Max stat */
8300 do_cmd_knowledge_stat();
8302 case 'b': /* Mutations */
8303 do_cmd_knowledge_mutations();
8305 case 'c': /* weapon-exp */
8306 do_cmd_knowledge_weapon_exp();
8308 case 'd': /* spell-exp */
8309 do_cmd_knowledge_spell_exp();
8311 case 'e': /* skill-exp */
8312 do_cmd_knowledge_skill_exp();
8314 case 'f': /* Virtues */
8315 do_cmd_knowledge_virtues();
8317 case 'g': /* Dungeon */
8318 do_cmd_knowledge_dungeon();
8320 case 'h': /* Quests */
8321 do_cmd_knowledge_quests();
8323 case 'i': /* Autopick */
8324 do_cmd_knowledge_autopick();
8326 default: /* Unknown option */
8334 if (need_redraw) do_cmd_redraw();
8339 * Check on the status of an active quest
8341 void do_cmd_checkquest(void)
8343 /* File type is "TEXT" */
8344 FILE_TYPE(FILE_TYPE_TEXT);
8348 do_cmd_knowledge_quests();
8354 * Display the time and date
8356 void do_cmd_time(void)
8358 int day, hour, min, full, start, end, num;
8366 extract_day_hour_min(&day, &hour, &min);
8368 full = hour * 100 + min;
8375 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8377 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8378 else strcpy(day_buf, "*****");
8380 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8381 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8384 if (!randint0(10) || p_ptr->image)
8386 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8390 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8393 /* Open this file */
8394 fff = my_fopen(buf, "rt");
8398 /* Find this time */
8399 while (!my_fgets(fff, buf, sizeof(buf)))
8401 /* Ignore comments */
8402 if (!buf[0] || (buf[0] == '#')) continue;
8404 /* Ignore invalid lines */
8405 if (buf[1] != ':') continue;
8407 /* Process 'Start' */
8410 /* Extract the starting time */
8411 start = atoi(buf + 2);
8413 /* Assume valid for an hour */
8423 /* Extract the ending time */
8424 end = atoi(buf + 2);
8430 /* Ignore incorrect range */
8431 if ((start > full) || (full > end)) continue;
8433 /* Process 'Description' */
8438 /* Apply the randomizer */
8439 if (!randint0(num)) strcpy(desc, buf + 2);