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);
878 /* Remove the file */
881 fff = my_fopen(buf, "w");
884 msg_format(_("記録を消去しました。", "deleted record."));
886 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
895 void do_cmd_nikki(void)
899 /* File type is "TEXT" */
900 FILE_TYPE(FILE_TYPE_TEXT);
903 /* Interact until done */
908 /* Ask for a choice */
909 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
911 /* Give some choices */
912 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
913 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
914 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
915 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
917 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
920 prt(_("コマンド:", "Command: "), 18, 0);
925 if (i == ESCAPE) break;
939 do_cmd_erase_nikki();
943 prepare_movie_hooks();
945 default: /* Unknown option */
955 * @brief 画面を再描画するコマンドのメインルーチン
956 * Hack -- redraw the screen
960 * This command performs various low level updates, clears all the "extra"
961 * windows, does a total redraw of the main window, and requests all of the
962 * interesting updates and redraws that I can think of.
964 * This command is also used to "instantiate" the results of the user
965 * selecting various things, such as graphics mode, so it must call
966 * the "TERM_XTRA_REACT" hook before redrawing the windows.
969 void do_cmd_redraw(void)
975 /* Hack -- react to changes */
976 Term_xtra(TERM_XTRA_REACT, 0);
978 /* Combine and Reorder the pack (later) */
979 p_ptr->update |= (PU_COMBINE | PU_REORDER);
980 p_ptr->update |= (PU_TORCH);
981 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
982 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
983 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
984 p_ptr->update |= (PU_MONSTERS);
986 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
988 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
989 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
995 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
998 /* Redraw every window */
999 for (j = 0; j < 8; j++)
1002 if (!angband_term[j]) continue;
1005 Term_activate(angband_term[j]);
1014 * @brief 名前を変更するコマンドのメインルーチン
1015 * Hack -- change name
1018 void do_cmd_change_name(void)
1033 /* Display the player */
1034 display_player(mode);
1039 display_player(mode);
1044 Term_putstr(2, 23, -1, TERM_WHITE,
1045 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1047 Term_putstr(2, 23, -1, TERM_WHITE,
1048 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1056 if (c == ESCAPE) break;
1063 /* Process the player name */
1064 process_player_name(FALSE);
1070 sprintf(tmp, "%s.txt", player_base);
1071 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1073 if (tmp[0] && (tmp[0] != ' '))
1075 file_character(tmp);
1093 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1100 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1101 * Recall the most recent message
1104 void do_cmd_message_one(void)
1106 /* Recall one message */
1107 prt(format("> %s", message_str(0)), 0, 0);
1112 * @brief メッセージのログを表示するコマンドのメインルーチン
1113 * Recall the most recent message
1117 * Show previous messages to the user -BEN-
1119 * The screen format uses line 0 and 23 for headers and prompts,
1120 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1122 * This command shows you which commands you are viewing, and allows
1123 * you to "search" for strings in the recall.
1125 * Note that messages may be longer than 80 characters, but they are
1126 * displayed using "infinite" length, with a special sub-command to
1127 * "slide" the virtual display to the left or right.
1129 * Attempt to only hilite the matching portions of the string.
1132 void do_cmd_messages(int num_now)
1136 char shower_str[81];
1137 char finder_str[81];
1139 concptr shower = NULL;
1143 Term_get_size(&wid, &hgt);
1145 /* Number of message lines in a screen */
1146 num_lines = hgt - 4;
1149 strcpy(finder_str, "");
1152 strcpy(shower_str, "");
1154 /* Total messages */
1157 /* Start on first message */
1162 /* Process requests until done */
1168 /* Dump up to 20 lines of messages */
1169 for (j = 0; (j < num_lines) && (i + j < n); j++)
1171 concptr msg = message_str(i+j);
1173 /* Dump the messages, bottom to top */
1174 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1176 /* Hilite "shower" */
1177 if (shower && shower[0])
1181 /* Display matches */
1182 while ((str = my_strstr(str, shower)) != NULL)
1184 int len = strlen(shower);
1186 /* Display the match */
1187 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1195 /* Erase remaining lines */
1196 for (; j < num_lines; j++)
1198 Term_erase(0, num_lines + 1 - j, 255);
1201 /* Display header */
1203 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1204 i, i + j - 1, n), 0, 0);
1206 /* Display prompt (not very informative) */
1207 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1208 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1210 skey = inkey_special(TRUE);
1212 /* Exit on Escape */
1213 if (skey == ESCAPE) break;
1215 /* Hack -- Save the old index */
1220 /* Hack -- handle show */
1223 prt(_("強調: ", "Show: "), hgt - 1, 0);
1225 /* Get a "shower" string, or continue */
1226 strcpy(back_str, shower_str);
1227 if (askfor(shower_str, 80))
1230 shower = shower_str[0] ? shower_str : NULL;
1232 else strcpy(shower_str, back_str);
1236 /* Hack -- handle find */
1243 prt(_("検索: ", "Find: "), hgt - 1, 0);
1245 /* Get a "finder" string, or continue */
1246 strcpy(back_str, finder_str);
1247 if (!askfor(finder_str, 80))
1249 strcpy(finder_str, back_str);
1252 else if (!finder_str[0])
1254 shower = NULL; /* Stop showing */
1259 shower = finder_str;
1262 for (z = i + 1; z < n; z++)
1264 concptr msg = message_str(z);
1267 if (my_strstr(msg, finder_str))
1278 /* Recall 1 older message */
1280 /* Go to the oldest line */
1284 /* Recall 1 newer message */
1286 /* Go to the newest line */
1290 /* Recall 1 older message */
1295 /* Go older if legal */
1296 i = MIN(i + 1, n - num_lines);
1299 /* Recall 10 older messages */
1301 /* Go older if legal */
1302 i = MIN(i + 10, n - num_lines);
1305 /* Recall 20 older messages */
1310 /* Go older if legal */
1311 i = MIN(i + num_lines, n - num_lines);
1314 /* Recall 20 newer messages */
1318 /* Go newer (if able) */
1319 i = MAX(0, i - num_lines);
1322 /* Recall 10 newer messages */
1324 /* Go newer (if able) */
1328 /* Recall 1 newer messages */
1331 /* Go newer (if able) */
1336 /* Hack -- Error of some kind */
1344 * @brief チートオプションを変更するコマンドのメインルーチン
1345 * Interact with some options for cheating
1346 * @param info 表示メッセージ
1349 static void do_cmd_options_cheat(concptr info)
1352 int i, k = 0, n = CHEAT_MAX;
1356 /* Interact with the player */
1362 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1367 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1368 prt(" << 注意 >>", 11, 0);
1369 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1370 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1371 prt(" じらないようにして下さい。", 14, 0);
1373 /* Display the options */
1374 for (i = 0; i < n; i++)
1376 byte a = TERM_WHITE;
1378 /* Color current option */
1379 if (i == k) a = TERM_L_BLUE;
1381 /* Display the option text */
1382 sprintf(buf, "%-48s: %s (%s)",
1383 cheat_info[i].o_desc,
1384 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1385 cheat_info[i].o_text);
1386 c_prt(a, buf, i + 2, 0);
1389 /* Hilite current option */
1390 move_cursor(k + 2, 50);
1396 * HACK - Try to translate the key into a direction
1397 * to allow using the roguelike keys for navigation.
1399 dir = get_keymap_dir(ch);
1400 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1414 k = (n + k - 1) % n;
1432 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1433 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1434 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1435 (*cheat_info[k].o_var) = TRUE;
1444 (*cheat_info[k].o_var) = FALSE;
1451 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1452 /* Peruse the help file */
1453 (void)show_file(TRUE, buf, NULL, 0, 0);
1470 * @brief セーブ頻度ターンの次の値を返す
1471 * @param current 現在のセーブ頻度ターン値
1472 * @return 次のセーブ頻度ターン値
1474 static s16b toggle_frequency(s16b current)
1479 case 50: return 100;
1480 case 100: return 250;
1481 case 250: return 500;
1482 case 500: return 1000;
1483 case 1000: return 2500;
1484 case 2500: return 5000;
1485 case 5000: return 10000;
1486 case 10000: return 25000;
1493 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1494 * @param info 表示メッセージ
1497 static void do_cmd_options_autosave(concptr info)
1500 int i, k = 0, n = 2;
1505 /* Interact with the player */
1509 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1510 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1514 /* Display the options */
1515 for (i = 0; i < n; i++)
1517 byte a = TERM_WHITE;
1519 /* Color current option */
1520 if (i == k) a = TERM_L_BLUE;
1522 /* Display the option text */
1523 sprintf(buf, "%-48s: %s (%s)",
1524 autosave_info[i].o_desc,
1525 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1526 autosave_info[i].o_text);
1527 c_prt(a, buf, i + 2, 0);
1529 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1531 /* Hilite current option */
1532 move_cursor(k + 2, 50);
1548 k = (n + k - 1) % n;
1566 (*autosave_info[k].o_var) = TRUE;
1575 (*autosave_info[k].o_var) = FALSE;
1583 autosave_freq = toggle_frequency(autosave_freq);
1584 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1590 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1606 * @brief 標準オプションを変更するコマンドのサブルーチン /
1607 * Interact with some options
1608 * @param page オプションページ番号
1609 * @param info 表示メッセージ
1612 void do_cmd_options_aux(int page, concptr info)
1615 int i, k = 0, n = 0, l;
1618 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1619 (!p_ptr->wizard || !allow_debug_opts);
1622 /* Lookup the options */
1623 for (i = 0; i < 24; i++) opt[i] = 0;
1625 /* Scan the options */
1626 for (i = 0; option_info[i].o_desc; i++)
1628 /* Notice options on this "page" */
1629 if (option_info[i].o_page == page) opt[n++] = i;
1633 /* Interact with the player */
1639 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1640 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1643 /* HACK -- description for easy-auto-destroy options */
1644 if (page == OPT_PAGE_AUTODESTROY)
1645 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1646 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1648 /* Display the options */
1649 for (i = 0; i < n; i++)
1651 byte a = TERM_WHITE;
1653 /* Color current option */
1654 if (i == k) a = TERM_L_BLUE;
1656 /* Display the option text */
1657 sprintf(buf, "%-48s: %s (%.19s)",
1658 option_info[opt[i]].o_desc,
1659 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1660 option_info[opt[i]].o_text);
1661 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1662 else c_prt(a, buf, i + 2, 0);
1665 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1668 /* Hilite current option */
1669 move_cursor(k + 2 + l, 50);
1675 * HACK - Try to translate the key into a direction
1676 * to allow using the roguelike keys for navigation.
1678 dir = get_keymap_dir(ch);
1679 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1693 k = (n + k - 1) % n;
1710 if (browse_only) break;
1711 (*option_info[opt[k]].o_var) = TRUE;
1720 if (browse_only) break;
1721 (*option_info[opt[k]].o_var) = FALSE;
1729 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1735 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1736 /* Peruse the help file */
1737 (void)show_file(TRUE, buf, NULL, 0, 0);
1754 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1755 * Modify the "window" options
1758 static void do_cmd_options_win(void)
1768 /* Memorize old flags */
1769 for (j = 0; j < 8; j++)
1771 /* Acquire current flags */
1772 old_flag[j] = window_flag[j];
1781 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1783 /* Display the windows */
1784 for (j = 0; j < 8; j++)
1786 byte a = TERM_WHITE;
1788 concptr s = angband_term_name[j];
1791 if (j == x) a = TERM_L_BLUE;
1793 /* Window name, staggered, centered */
1794 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1797 /* Display the options */
1798 for (i = 0; i < 16; i++)
1800 byte a = TERM_WHITE;
1802 concptr str = window_flag_desc[i];
1805 if (i == y) a = TERM_L_BLUE;
1808 if (!str) str = _("(未使用)", "(Unused option)");
1811 Term_putstr(0, i + 5, -1, a, str);
1813 /* Display the windows */
1814 for (j = 0; j < 8; j++)
1820 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1823 if (window_flag[j] & (1L << i)) c = 'X';
1826 Term_putch(35 + j * 5, i + 5, a, c);
1831 Term_gotoxy(35 + x * 5, y + 5);
1849 for (j = 0; j < 8; j++)
1851 window_flag[j] &= ~(1L << y);
1855 for (i = 0; i < 16; i++)
1857 window_flag[x] &= ~(1L << i);
1870 window_flag[x] |= (1L << y);
1878 window_flag[x] &= ~(1L << y);
1884 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1892 d = get_keymap_dir(ch);
1894 x = (x + ddx[d] + 8) % 8;
1895 y = (y + ddy[d] + 16) % 16;
1902 /* Notice changes */
1903 for (j = 0; j < 8; j++)
1908 if (!angband_term[j]) continue;
1910 /* Ignore non-changes */
1911 if (window_flag[j] == old_flag[j]) continue;
1914 Term_activate(angband_term[j]);
1931 option_fields[OPT_NUM] =
1934 { '1', " キー入力 オプション", 3 },
1935 { '2', " マップ画面 オプション", 4 },
1936 { '3', " テキスト表示 オプション", 5 },
1937 { '4', " ゲームプレイ オプション", 6 },
1938 { '5', " 行動中止関係 オプション", 7 },
1939 { '6', " 簡易自動破壊 オプション", 8 },
1940 { 'r', " プレイ記録 オプション", 9 },
1942 { 'p', "自動拾いエディタ", 11 },
1943 { 'd', " 基本ウェイト量 ", 12 },
1944 { 'h', "低ヒットポイント", 13 },
1945 { 'm', " 低魔力色閾値 ", 14 },
1946 { 'a', " 自動セーブ オプション", 15 },
1947 { 'w', "ウインドウフラグ", 16 },
1949 { 'b', " 初期 オプション (参照のみ)", 18 },
1950 { 'c', " 詐欺 オプション", 19 },
1952 { '1', "Input Options", 3 },
1953 { '2', "Map Screen Options", 4 },
1954 { '3', "Text Display Options", 5 },
1955 { '4', "Game-Play Options", 6 },
1956 { '5', "Disturbance Options", 7 },
1957 { '6', "Easy Auto-Destroyer Options", 8 },
1958 { 'r', "Play record Options", 9 },
1960 { 'p', "Auto-picker/destroyer editor", 11 },
1961 { 'd', "Base Delay Factor", 12 },
1962 { 'h', "Hitpoint Warning", 13 },
1963 { 'm', "Mana Color Threshold", 14 },
1964 { 'a', "Autosave Options", 15 },
1965 { 'w', "Window Flags", 16 },
1967 { 'b', "Birth Options (Browse Only)", 18 },
1968 { 'c', "Cheat Options", 19 },
1974 * @brief 標準オプションを変更するコマンドのメインルーチン /
1975 * Set or unset various options.
1979 * The user must use the "Ctrl-R" command to "adapt" to changes
1980 * in any options which control "visual" aspects of the game.
1983 void do_cmd_options(void)
1995 /* Does not list cheat option when cheat option is off */
1996 if (!p_ptr->noscore && !allow_debug_opts) n--;
1999 /* Why are we here */
2000 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2004 /* Give some choices */
2005 for (i = 0; i < n; i++)
2007 byte a = TERM_WHITE;
2008 if (i == y) a = TERM_L_BLUE;
2009 Term_putstr(5, option_fields[i].row, -1, a,
2010 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2013 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2016 skey = inkey_special(TRUE);
2017 if (!(skey & SKEY_MASK)) k = (char)skey;
2021 if (k == ESCAPE) break;
2023 if (my_strchr("\n\r ", k))
2025 k = option_fields[y].key;
2029 for (i = 0; i < n; i++)
2031 if (tolower(k) == option_fields[i].key) break;
2034 /* Command is found */
2037 /* Hack -- browse help */
2038 if (k == '?') break;
2042 if (skey == SKEY_UP) d = 8;
2043 if (skey == SKEY_DOWN) d = 2;
2044 y = (y + ddy[d] + n) % n;
2049 if (k == ESCAPE) break;
2056 /* Process the general options */
2057 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2063 /* Process the general options */
2064 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2071 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2078 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2085 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2092 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2096 /* Play-record Options */
2101 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2110 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2111 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2112 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2116 /* Cheating Options */
2119 if (!p_ptr->noscore && !allow_debug_opts)
2121 /* Cheat options are not permitted */
2127 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2134 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2143 do_cmd_options_win();
2144 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2145 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2146 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2147 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2152 /* Auto-picker/destroyer editor */
2156 do_cmd_edit_autopick();
2160 /* Hack -- Delay Speed */
2166 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2168 /* Get a new value */
2171 int msec = delay_factor * delay_factor * delay_factor;
2172 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2173 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2175 if (k == ESCAPE) break;
2178 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2181 else if (isdigit(k)) delay_factor = D2I(k);
2188 /* Hack -- hitpoint warning factor */
2194 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2196 /* Get a new value */
2199 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2200 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2202 if (k == ESCAPE) break;
2205 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2208 else if (isdigit(k)) hitpoint_warn = D2I(k);
2215 /* Hack -- mana color factor */
2221 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2223 /* Get a new value */
2226 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2227 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2229 if (k == ESCAPE) break;
2232 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2235 else if (isdigit(k)) mana_warn = D2I(k);
2243 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2247 /* Unknown option */
2260 /* Hack - Redraw equippy chars */
2261 p_ptr->redraw |= (PR_EQUIPPY);
2267 * @brief prefファイルを選択して処理する /
2268 * Ask for a "user pref line" and process it
2271 * Allow absolute file names?
2273 void do_cmd_pref(void)
2280 /* Ask for a "user pref command" */
2281 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2283 /* Process that pref command */
2284 (void)process_pref_file_command(buf);
2288 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2291 void do_cmd_reload_autopick(void)
2293 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2294 /* Load the file with messages */
2295 autopick_load_pref(TRUE);
2301 * @brief マクロ情報をprefファイルに保存する /
2302 * @param fname ファイル名
2305 static errr macro_dump(concptr fname)
2307 static concptr mark = "Macro Dump";
2313 /* Build the filename */
2314 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2316 /* File type is "TEXT" */
2317 FILE_TYPE(FILE_TYPE_TEXT);
2319 /* Append to the file */
2320 if (!open_auto_dump(buf, mark)) return (-1);
2323 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2326 for (i = 0; i < macro__num; i++)
2328 /* Extract the action */
2329 ascii_to_text(buf, macro__act[i]);
2331 /* Dump the macro */
2332 auto_dump_printf("A:%s\n", buf);
2334 /* Extract the action */
2335 ascii_to_text(buf, macro__pat[i]);
2337 /* Dump normal macros */
2338 auto_dump_printf("P:%s\n", buf);
2341 auto_dump_printf("\n");
2353 * @brief マクロのトリガーキーを取得する /
2354 * Hack -- ask for a "trigger" (see below)
2355 * @param buf キー表記を保管するバッファ
2359 * Note the complex use of the "inkey()" function from "util.c".
2361 * Note that both "flush()" calls are extremely important.
2364 static void do_cmd_macro_aux(char *buf)
2372 /* Do not process macros */
2378 /* Read the pattern */
2384 /* Do not process macros */
2387 /* Do not wait for keys */
2390 /* Attempt to read a key */
2399 /* Convert the trigger */
2400 ascii_to_text(tmp, buf);
2402 /* Hack -- display the trigger */
2403 Term_addstr(-1, TERM_WHITE, tmp);
2409 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2410 * Hack -- ask for a keymap "trigger" (see below)
2411 * @param buf キー表記を取得するバッファ
2415 * Note that both "flush()" calls are extremely important. This may
2416 * no longer be true, since "util.c" is much simpler now.
2419 static void do_cmd_macro_aux_keymap(char *buf)
2429 /* Convert to ascii */
2430 ascii_to_text(tmp, buf);
2432 /* Hack -- display the trigger */
2433 Term_addstr(-1, TERM_WHITE, tmp);
2440 * @brief キーマップをprefファイルにダンプする /
2441 * Hack -- append all keymaps to the given file
2442 * @param fname ファイルネーム
2446 static errr keymap_dump(concptr fname)
2448 static concptr mark = "Keymap Dump";
2457 if (rogue_like_commands)
2459 mode = KEYMAP_MODE_ROGUE;
2465 mode = KEYMAP_MODE_ORIG;
2469 /* Build the filename */
2470 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2472 /* File type is "TEXT" */
2473 FILE_TYPE(FILE_TYPE_TEXT);
2475 /* Append to the file */
2476 if (!open_auto_dump(buf, mark)) return -1;
2479 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2482 for (i = 0; i < 256; i++)
2486 /* Loop up the keymap */
2487 act = keymap_act[mode][i];
2489 /* Skip empty keymaps */
2492 /* Encode the key */
2495 ascii_to_text(key, buf);
2497 /* Encode the action */
2498 ascii_to_text(buf, act);
2500 /* Dump the macro */
2501 auto_dump_printf("A:%s\n", buf);
2502 auto_dump_printf("C:%d:%s\n", mode, key);
2514 * @brief マクロを設定するコマンドのメインルーチン /
2515 * Interact with "macros"
2519 * Note that the macro "action" must be defined before the trigger.
2521 * Could use some helpful instructions on this page.
2524 void do_cmd_macros(void)
2536 if (rogue_like_commands)
2538 mode = KEYMAP_MODE_ROGUE;
2544 mode = KEYMAP_MODE_ORIG;
2547 /* File type is "TEXT" */
2548 FILE_TYPE(FILE_TYPE_TEXT);
2553 /* Process requests until done */
2557 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2559 /* Describe that action */
2560 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2562 /* Analyze the current action */
2563 ascii_to_text(buf, macro__buf);
2565 /* Display the current action */
2570 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2572 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2573 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2574 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2575 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2576 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2577 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2578 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2579 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2580 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2581 #endif /* ALLOW_MACROS */
2584 prt(_("コマンド: ", "Command: "), 16, 0);
2589 if (i == ESCAPE) break;
2591 /* Load a 'macro' file */
2597 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2600 prt(_("ファイル: ", "File: "), 18, 0);
2602 /* Default filename */
2603 sprintf(tmp, "%s.prf", player_base);
2605 /* Ask for a file */
2606 if (!askfor(tmp, 80)) continue;
2608 /* Process the given filename */
2609 err = process_pref_file(tmp);
2612 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2617 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2621 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2631 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2634 prt(_("ファイル: ", "File: "), 18, 0);
2636 /* Default filename */
2637 sprintf(tmp, "%s.prf", player_base);
2639 /* Ask for a file */
2640 if (!askfor(tmp, 80)) continue;
2642 /* Dump the macros */
2643 (void)macro_dump(tmp);
2646 msg_print(_("マクロを追加しました。", "Appended macros."));
2655 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2659 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2661 /* Get a macro trigger */
2662 do_cmd_macro_aux(buf);
2664 /* Acquire action */
2665 k = macro_find_exact(buf);
2671 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2677 /* Obtain the action */
2678 strcpy(macro__buf, macro__act[k]);
2680 /* Analyze the current action */
2681 ascii_to_text(buf, macro__buf);
2683 /* Display the current action */
2687 msg_print(_("マクロを確認しました。", "Found a macro."));
2691 /* Create a macro */
2695 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2698 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2700 /* Get a macro trigger */
2701 do_cmd_macro_aux(buf);
2707 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2708 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2711 prt(_("マクロ行動: ", "Action: "), 20, 0);
2713 /* Convert to text */
2714 ascii_to_text(tmp, macro__buf);
2716 /* Get an encoded action */
2717 if (askfor(tmp, 80))
2719 /* Convert to ascii */
2720 text_to_ascii(macro__buf, tmp);
2722 /* Link the macro */
2723 macro_add(buf, macro__buf);
2726 msg_print(_("マクロを追加しました。", "Added a macro."));
2730 /* Remove a macro */
2734 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2737 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2739 /* Get a macro trigger */
2740 do_cmd_macro_aux(buf);
2742 /* Link the macro */
2743 macro_add(buf, buf);
2746 msg_print(_("マクロを削除しました。", "Removed a macro."));
2753 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2756 prt(_("ファイル: ", "File: "), 18, 0);
2758 /* Default filename */
2759 sprintf(tmp, "%s.prf", player_base);
2761 /* Ask for a file */
2762 if (!askfor(tmp, 80)) continue;
2764 /* Dump the macros */
2765 (void)keymap_dump(tmp);
2768 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2771 /* Query a keymap */
2777 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2780 prt(_("押すキー: ", "Keypress: "), 18, 0);
2782 /* Get a keymap trigger */
2783 do_cmd_macro_aux_keymap(buf);
2785 /* Look up the keymap */
2786 act = keymap_act[mode][(byte)(buf[0])];
2792 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2798 /* Obtain the action */
2799 strcpy(macro__buf, act);
2801 /* Analyze the current action */
2802 ascii_to_text(buf, macro__buf);
2804 /* Display the current action */
2808 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2812 /* Create a keymap */
2816 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2819 prt(_("押すキー: ", "Keypress: "), 18, 0);
2821 /* Get a keymap trigger */
2822 do_cmd_macro_aux_keymap(buf);
2828 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2829 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2832 prt(_("行動: ", "Action: "), 20, 0);
2834 /* Convert to text */
2835 ascii_to_text(tmp, macro__buf);
2837 /* Get an encoded action */
2838 if (askfor(tmp, 80))
2840 /* Convert to ascii */
2841 text_to_ascii(macro__buf, tmp);
2843 /* Free old keymap */
2844 string_free(keymap_act[mode][(byte)(buf[0])]);
2846 /* Make new keymap */
2847 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2850 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2854 /* Remove a keymap */
2858 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2861 prt(_("押すキー: ", "Keypress: "), 18, 0);
2863 /* Get a keymap trigger */
2864 do_cmd_macro_aux_keymap(buf);
2866 /* Free old keymap */
2867 string_free(keymap_act[mode][(byte)(buf[0])]);
2869 /* Make new keymap */
2870 keymap_act[mode][(byte)(buf[0])] = NULL;
2873 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2876 /* Enter a new action */
2880 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2886 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2887 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2890 prt(_("マクロ行動: ", "Action: "), 20, 0);
2892 /* Hack -- limit the value */
2895 /* Get an encoded action */
2896 if (!askfor(buf, 80)) continue;
2898 /* Extract an action */
2899 text_to_ascii(macro__buf, buf);
2902 #endif /* ALLOW_MACROS */
2915 * @brief キャラクタ色の明暗表現
2917 static concptr lighting_level_str[F_LIT_MAX] =
2932 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2933 * @param i 指定対象となるキャラクタコード
2934 * @param num 指定されたビジュアルIDを返す参照ポインタ
2935 * @param max ビジュアルIDの最大数
2936 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2938 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2945 sprintf(str, "%d", *num);
2947 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2950 tmp = (IDX)strtol(str, NULL, 0);
2951 if (tmp >= 0 && tmp < max)
2954 else if (isupper(i))
2955 *num = (*num + max - 1) % max;
2957 *num = (*num + 1) % max;
2963 * @brief キャラクタの変更メニュー表示
2964 * @param choice_msg 選択メッセージ
2967 static void print_visuals_menu(concptr choice_msg)
2969 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2971 /* Give some choices */
2972 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2974 #ifdef ALLOW_VISUALS
2975 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2976 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2977 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2978 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2979 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2980 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2981 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2982 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2983 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2984 #endif /* ALLOW_VISUALS */
2986 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2989 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2992 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2993 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2994 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2997 * Interact with "visuals"
2999 void do_cmd_visuals(void)
3004 bool need_redraw = FALSE;
3005 concptr empty_symbol = "<< ? >>";
3007 if (use_bigtile) empty_symbol = "<< ?? >>";
3009 /* File type is "TEXT" */
3010 FILE_TYPE(FILE_TYPE_TEXT);
3013 /* Interact until done */
3018 /* Ask for a choice */
3019 print_visuals_menu(NULL);
3024 if (i == ESCAPE) break;
3028 /* Load a 'pref' file */
3031 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3034 prt(_("ファイル: ", "File: "), 17, 0);
3036 /* Default filename */
3037 sprintf(tmp, "%s.prf", player_base);
3040 if (!askfor(tmp, 70)) continue;
3042 /* Process the given filename */
3043 (void)process_pref_file(tmp);
3048 #ifdef ALLOW_VISUALS
3050 /* Dump monster attr/chars */
3053 static concptr mark = "Monster attr/chars";
3056 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3059 prt(_("ファイル: ", "File: "), 17, 0);
3061 /* Default filename */
3062 sprintf(tmp, "%s.prf", player_base);
3064 /* Get a filename */
3065 if (!askfor(tmp, 70)) continue;
3067 /* Build the filename */
3068 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3070 /* Append to the file */
3071 if (!open_auto_dump(buf, mark)) continue;
3074 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3077 for (i = 0; i < max_r_idx; i++)
3079 monster_race *r_ptr = &r_info[i];
3081 /* Skip non-entries */
3082 if (!r_ptr->name) continue;
3084 /* Dump a comment */
3085 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3087 /* Dump the monster attr/char info */
3088 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3089 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3095 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3100 /* Dump object attr/chars */
3103 static concptr mark = "Object attr/chars";
3104 KIND_OBJECT_IDX k_idx;
3107 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3110 prt(_("ファイル: ", "File: "), 17, 0);
3112 /* Default filename */
3113 sprintf(tmp, "%s.prf", player_base);
3115 /* Get a filename */
3116 if (!askfor(tmp, 70)) continue;
3118 /* Build the filename */
3119 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3121 /* Append to the file */
3122 if (!open_auto_dump(buf, mark)) continue;
3125 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3128 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3130 GAME_TEXT o_name[MAX_NLEN];
3131 object_kind *k_ptr = &k_info[k_idx];
3133 /* Skip non-entries */
3134 if (!k_ptr->name) continue;
3139 strip_name(o_name, k_idx);
3145 /* Prepare dummy object */
3146 object_prep(&forge, k_idx);
3148 /* Get un-shuffled flavor name */
3149 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3152 /* Dump a comment */
3153 auto_dump_printf("# %s\n", o_name);
3155 /* Dump the object attr/char info */
3156 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3157 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3163 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3168 /* Dump feature attr/chars */
3171 static concptr mark = "Feature attr/chars";
3174 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3177 prt(_("ファイル: ", "File: "), 17, 0);
3179 /* Default filename */
3180 sprintf(tmp, "%s.prf", player_base);
3182 /* Get a filename */
3183 if (!askfor(tmp, 70)) continue;
3185 /* Build the filename */
3186 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3188 /* Append to the file */
3189 if (!open_auto_dump(buf, mark)) continue;
3192 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3195 for (i = 0; i < max_f_idx; i++)
3197 feature_type *f_ptr = &f_info[i];
3199 /* Skip non-entries */
3200 if (!f_ptr->name) continue;
3202 /* Skip mimiccing features */
3203 if (f_ptr->mimic != i) continue;
3205 /* Dump a comment */
3206 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3208 /* Dump the feature attr/char info */
3209 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3210 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3211 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3212 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3218 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3223 /* Modify monster attr/chars (numeric operation) */
3226 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3227 static MONRACE_IDX r = 0;
3229 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3231 /* Hack -- query until done */
3234 monster_race *r_ptr = &r_info[r];
3238 TERM_COLOR da = r_ptr->d_attr;
3239 byte dc = r_ptr->d_char;
3240 TERM_COLOR ca = r_ptr->x_attr;
3241 byte cc = r_ptr->x_char;
3243 /* Label the object */
3244 Term_putstr(5, 17, -1, TERM_WHITE,
3245 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3247 /* Label the Default values */
3248 Term_putstr(10, 19, -1, TERM_WHITE,
3249 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3251 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3252 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3254 /* Label the Current values */
3255 Term_putstr(10, 20, -1, TERM_WHITE,
3256 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3258 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3259 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3262 Term_putstr(0, 22, -1, TERM_WHITE,
3263 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3268 if (i == ESCAPE) break;
3270 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3271 else if (isupper(i)) c = 'a' + i - 'A';
3281 if (!cmd_visuals_aux(i, &r, max_r_idx))
3287 while (!r_info[r].name);
3291 t = (int)r_ptr->x_attr;
3292 (void)cmd_visuals_aux(i, &t, 256);
3293 r_ptr->x_attr = (byte)t;
3297 t = (int)r_ptr->x_char;
3298 (void)cmd_visuals_aux(i, &t, 256);
3299 r_ptr->x_char = (byte)t;
3303 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3305 print_visuals_menu(choice_msg);
3313 /* Modify object attr/chars (numeric operation) */
3316 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3318 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3320 /* Hack -- query until done */
3323 object_kind *k_ptr = &k_info[k];
3327 TERM_COLOR da = k_ptr->d_attr;
3328 SYMBOL_CODE dc = k_ptr->d_char;
3329 TERM_COLOR ca = k_ptr->x_attr;
3330 SYMBOL_CODE cc = k_ptr->x_char;
3332 /* Label the object */
3333 Term_putstr(5, 17, -1, TERM_WHITE,
3334 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3335 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3337 /* Label the Default values */
3338 Term_putstr(10, 19, -1, TERM_WHITE,
3339 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3341 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3342 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3344 /* Label the Current values */
3345 Term_putstr(10, 20, -1, TERM_WHITE,
3346 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3348 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3349 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3352 Term_putstr(0, 22, -1, TERM_WHITE,
3353 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3358 if (i == ESCAPE) break;
3360 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3361 else if (isupper(i)) c = 'a' + i - 'A';
3371 if (!cmd_visuals_aux(i, &k, max_k_idx))
3377 while (!k_info[k].name);
3381 t = (int)k_ptr->x_attr;
3382 (void)cmd_visuals_aux(i, &t, 256);
3383 k_ptr->x_attr = (byte)t;
3387 t = (int)k_ptr->x_char;
3388 (void)cmd_visuals_aux(i, &t, 256);
3389 k_ptr->x_char = (byte)t;
3393 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3395 print_visuals_menu(choice_msg);
3403 /* Modify feature attr/chars (numeric operation) */
3406 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3408 static IDX lighting_level = F_LIT_STANDARD;
3409 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3411 /* Hack -- query until done */
3414 feature_type *f_ptr = &f_info[f];
3418 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3419 byte dc = f_ptr->d_char[lighting_level];
3420 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3421 byte cc = f_ptr->x_char[lighting_level];
3423 /* Label the object */
3425 Term_putstr(5, 17, -1, TERM_WHITE,
3426 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3427 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3429 /* Label the Default values */
3430 Term_putstr(10, 19, -1, TERM_WHITE,
3431 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3433 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3434 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3436 /* Label the Current values */
3438 Term_putstr(10, 20, -1, TERM_WHITE,
3439 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3441 Term_putstr(10, 20, -1, TERM_WHITE,
3442 format("Current attr/char = %3d / %3d", ca, cc));
3445 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3446 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3450 Term_putstr(0, 22, -1, TERM_WHITE,
3451 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3453 Term_putstr(0, 22, -1, TERM_WHITE,
3454 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3460 if (i == ESCAPE) break;
3462 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3463 else if (isupper(i)) c = 'a' + i - 'A';
3473 if (!cmd_visuals_aux(i, &f, max_f_idx))
3479 while (!f_info[f].name || (f_info[f].mimic != f));
3483 t = (int)f_ptr->x_attr[lighting_level];
3484 (void)cmd_visuals_aux(i, &t, 256);
3485 f_ptr->x_attr[lighting_level] = (byte)t;
3489 t = (int)f_ptr->x_char[lighting_level];
3490 (void)cmd_visuals_aux(i, &t, 256);
3491 f_ptr->x_char[lighting_level] = (byte)t;
3495 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3498 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3502 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3504 print_visuals_menu(choice_msg);
3512 /* Modify monster attr/chars (visual mode) */
3514 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3517 /* Modify object attr/chars (visual mode) */
3519 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3522 /* Modify feature attr/chars (visual mode) */
3525 IDX lighting_level = F_LIT_STANDARD;
3526 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3530 #endif /* ALLOW_VISUALS */
3538 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3542 /* Unknown option */
3552 if (need_redraw) do_cmd_redraw();
3557 * Interact with "colors"
3559 void do_cmd_colors(void)
3568 /* File type is "TEXT" */
3569 FILE_TYPE(FILE_TYPE_TEXT);
3574 /* Interact until done */
3579 /* Ask for a choice */
3580 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3582 /* Give some choices */
3583 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3586 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3587 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3591 prt(_("コマンド: ", "Command: "), 8, 0);
3595 if (i == ESCAPE) break;
3597 /* Load a 'pref' file */
3601 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3604 prt(_("ファイル: ", "File: "), 10, 0);
3607 sprintf(tmp, "%s.prf", player_base);
3610 if (!askfor(tmp, 70)) continue;
3612 /* Process the given filename */
3613 (void)process_pref_file(tmp);
3615 /* Mega-Hack -- react to changes */
3616 Term_xtra(TERM_XTRA_REACT, 0);
3618 /* Mega-Hack -- redraw */
3627 static concptr mark = "Colors";
3630 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3633 prt(_("ファイル: ", "File: "), 10, 0);
3635 /* Default filename */
3636 sprintf(tmp, "%s.prf", player_base);
3638 /* Get a filename */
3639 if (!askfor(tmp, 70)) continue;
3641 /* Build the filename */
3642 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3644 /* Append to the file */
3645 if (!open_auto_dump(buf, mark)) continue;
3648 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3651 for (i = 0; i < 256; i++)
3653 int kv = angband_color_table[i][0];
3654 int rv = angband_color_table[i][1];
3655 int gv = angband_color_table[i][2];
3656 int bv = angband_color_table[i][3];
3658 concptr name = _("未知", "unknown");
3660 /* Skip non-entries */
3661 if (!kv && !rv && !gv && !bv) continue;
3663 /* Extract the color name */
3664 if (i < 16) name = color_names[i];
3666 /* Dump a comment */
3667 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3669 /* Dump the monster attr/char info */
3670 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3677 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3686 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3688 /* Hack -- query until done */
3697 /* Exhibit the normal colors */
3698 for (j = 0; j < 16; j++)
3700 /* Exhibit this color */
3701 Term_putstr(j*4, 20, -1, a, "###");
3703 /* Exhibit all colors */
3704 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3707 /* Describe the color */
3708 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3710 /* Describe the color */
3711 Term_putstr(5, 10, -1, TERM_WHITE,
3712 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3714 /* Label the Current values */
3715 Term_putstr(5, 12, -1, TERM_WHITE,
3716 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3717 angband_color_table[a][0],
3718 angband_color_table[a][1],
3719 angband_color_table[a][2],
3720 angband_color_table[a][3]));
3723 Term_putstr(0, 14, -1, TERM_WHITE,
3724 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3729 if (i == ESCAPE) break;
3732 if (i == 'n') a = (byte)(a + 1);
3733 if (i == 'N') a = (byte)(a - 1);
3734 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3735 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3736 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3737 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3738 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3739 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3740 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3741 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3743 /* Hack -- react to changes */
3744 Term_xtra(TERM_XTRA_REACT, 0);
3746 /* Hack -- redraw */
3753 /* Unknown option */
3767 * Note something in the message recall
3769 void do_cmd_note(void)
3777 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3779 /* Ignore empty notes */
3780 if (!buf[0] || (buf[0] == ' ')) return;
3782 /* Add the note to the message recall */
3783 msg_format(_("メモ: %s", "Note: %s"), buf);
3788 * Mention the current version
3790 void do_cmd_version(void)
3792 #if FAKE_VER_EXTRA > 0
3793 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3794 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3796 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3797 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3804 * Array of feeling strings
3806 static concptr do_cmd_feeling_text[11] =
3808 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3809 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3810 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3811 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3812 _("とても悪い予感がする...", "You have a very bad feeling..."),
3813 _("悪い予感がする...", "You have a bad feeling..."),
3814 _("何か緊張する。", "You feel nervous."),
3815 _("少し不運な気がする...", "You feel your luck is turning..."),
3816 _("この場所は好きになれない。", "You don't like the look of this place."),
3817 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3818 _("なんて退屈なところだ...", "What a boring place...")
3821 static concptr do_cmd_feeling_text_combat[11] =
3823 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3824 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3825 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3826 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3827 _("とても悪い予感がする...", "You have a very bad feeling..."),
3828 _("悪い予感がする...", "You have a bad feeling..."),
3829 _("何か緊張する。", "You feel nervous."),
3830 _("少し不運な気がする...", "You feel your luck is turning..."),
3831 _("この場所は好きになれない。", "You don't like the look of this place."),
3832 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3833 _("なんて退屈なところだ...", "What a boring place...")
3836 static concptr do_cmd_feeling_text_lucky[11] =
3838 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3839 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3840 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3841 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3842 _("とても良い感じがする...", "You have a very good feeling..."),
3843 _("良い感じがする...", "You have a good feeling..."),
3844 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3845 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3846 _("見た感じ悪くはない...", "You like the look of this place..."),
3847 _("全然駄目ということはないが...", "This level can't be all bad..."),
3848 _("なんて退屈なところだ...", "What a boring place...")
3853 * Note that "feeling" is set to zero unless some time has passed.
3854 * Note that this is done when the level is GENERATED, not entered.
3856 void do_cmd_feeling(void)
3858 if (p_ptr->wild_mode) return;
3860 /* No useful feeling in quests */
3861 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3863 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3867 /* No useful feeling in town */
3868 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3870 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3872 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3877 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3882 /* No useful feeling in the wilderness */
3883 else if (!current_floor_ptr->dun_level)
3885 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3889 /* Display the feeling */
3890 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3891 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3892 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3893 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3894 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3896 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3902 * Description of each monster group.
3904 static concptr monster_group_text[] =
3907 "ユニーク", /* "Uniques" */
3908 "乗馬可能なモンスター", /* "Riding" */
3909 "賞金首", /* "Wanted */
3910 "アンバーの王族", /* "Ambertite" */
3939 /* "古代ドラゴン/ワイアーム", */
4000 /* "Ancient Dragon/Wyrm", */
4009 "Multi-Headed Reptile",
4014 "Reptile/Amphibian",
4015 "Spider/Scorpion/Tick",
4017 /* "Major Demon", */
4034 * Symbols of monsters in each group. Note the "Uniques" group
4035 * is handled differently.
4037 static concptr monster_group_char[] =
4094 "!$&()+./=>?[\\]`{|~",
4104 * hook function to sort monsters by level
4106 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4108 u16b *who = (u16b*)(u);
4113 monster_race *r_ptr1 = &r_info[w1];
4114 monster_race *r_ptr2 = &r_info[w2];
4119 if (r_ptr2->level > r_ptr1->level) return TRUE;
4120 if (r_ptr1->level > r_ptr2->level) return FALSE;
4122 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4123 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4128 * Build a list of monster indexes in the given group. Return the number
4129 * of monsters in the group.
4131 * mode & 0x01 : check for non-empty group
4132 * mode & 0x02 : visual operation only
4134 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4140 /* Get a list of x_char in this group */
4141 concptr group_char = monster_group_char[grp_cur];
4143 /* XXX Hack -- Check if this is the "Uniques" group */
4144 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4146 /* XXX Hack -- Check if this is the "Riding" group */
4147 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4149 /* XXX Hack -- Check if this is the "Wanted" group */
4150 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4152 /* XXX Hack -- Check if this is the "Amberite" group */
4153 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4156 /* Check every race */
4157 for (i = 0; i < max_r_idx; i++)
4159 /* Access the race */
4160 monster_race *r_ptr = &r_info[i];
4162 /* Skip empty race */
4163 if (!r_ptr->name) continue ;
4165 /* Require known monsters */
4166 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4170 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4173 else if (grp_riding)
4175 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4178 else if (grp_wanted)
4180 bool wanted = FALSE;
4182 for (j = 0; j < MAX_KUBI; j++)
4184 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4185 (p_ptr->today_mon && p_ptr->today_mon == i))
4191 if (!wanted) continue;
4194 else if (grp_amberite)
4196 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4201 /* Check for race in the group */
4202 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4206 mon_idx[mon_cnt++] = i;
4208 /* XXX Hack -- Just checking for non-empty group */
4209 if (mode & 0x01) break;
4212 /* Terminate the list */
4213 mon_idx[mon_cnt] = -1;
4215 /* Select the sort method */
4216 ang_sort_comp = ang_sort_comp_monster_level;
4217 ang_sort_swap = ang_sort_swap_hook;
4219 /* Sort by monster level */
4220 ang_sort(mon_idx, &dummy_why, mon_cnt);
4222 /* Return the number of races */
4228 * Description of each monster group.
4230 static concptr object_group_text[] =
4233 "キノコ", /* "Mushrooms" */
4234 "薬", /* "Potions" */
4235 "油つぼ", /* "Flasks" */
4236 "巻物", /* "Scrolls" */
4238 "アミュレット", /* "Amulets" */
4239 "笛", /* "Whistle" */
4240 "光源", /* "Lanterns" */
4241 "魔法棒", /* "Wands" */
4244 "カード", /* "Cards" */
4255 "刀剣類", /* "Swords" */
4256 "鈍器", /* "Blunt Weapons" */
4257 "長柄武器", /* "Polearms" */
4258 "採掘道具", /* "Diggers" */
4259 "飛び道具", /* "Bows" */
4263 "軽装鎧", /* "Soft Armor" */
4264 "重装鎧", /* "Hard Armor" */
4265 "ドラゴン鎧", /* "Dragon Armor" */
4266 "盾", /* "Shields" */
4267 "クローク", /* "Cloaks" */
4268 "籠手", /* "Gloves" */
4269 "ヘルメット", /* "Helms" */
4271 "ブーツ", /* "Boots" */
4324 * TVALs of items in each group
4326 static byte object_group_tval[] =
4367 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4375 * Build a list of object indexes in the given group. Return the number
4376 * of objects in the group.
4378 * mode & 0x01 : check for non-empty group
4379 * mode & 0x02 : visual operation only
4381 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4383 KIND_OBJECT_IDX i, object_cnt = 0;
4386 /* Get a list of x_char in this group */
4387 byte group_tval = object_group_tval[grp_cur];
4389 /* Check every object */
4390 for (i = 0; i < max_k_idx; i++)
4392 /* Access the object */
4393 object_kind *k_ptr = &k_info[i];
4395 /* Skip empty objects */
4396 if (!k_ptr->name) continue;
4400 /* Any objects will be displayed */
4406 /* Skip non-flavoured objects */
4407 if (!k_ptr->flavor) continue;
4409 /* Require objects ever seen */
4410 if (!k_ptr->aware) continue;
4413 /* Skip items with no distribution (special artifacts) */
4414 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4418 /* Check for objects in the group */
4419 if (TV_LIFE_BOOK == group_tval)
4421 /* Hack -- All spell books */
4422 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4424 /* Add the object */
4425 object_idx[object_cnt++] = i;
4429 else if (k_ptr->tval == group_tval)
4431 /* Add the object */
4432 object_idx[object_cnt++] = i;
4436 /* XXX Hack -- Just checking for non-empty group */
4437 if (mode & 0x01) break;
4440 /* Terminate the list */
4441 object_idx[object_cnt] = -1;
4443 /* Return the number of objects */
4449 * Description of each feature group.
4451 static concptr feature_group_text[] =
4459 * Build a list of feature indexes in the given group. Return the number
4460 * of features in the group.
4462 * mode & 0x01 : check for non-empty group
4464 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4467 FEAT_IDX feat_cnt = 0;
4469 /* Unused; There is a single group. */
4472 /* Check every feature */
4473 for (i = 0; i < max_f_idx; i++)
4475 /* Access the index */
4476 feature_type *f_ptr = &f_info[i];
4478 /* Skip empty index */
4479 if (!f_ptr->name) continue;
4481 /* Skip mimiccing features */
4482 if (f_ptr->mimic != i) continue;
4485 feat_idx[feat_cnt++] = i;
4487 /* XXX Hack -- Just checking for non-empty group */
4488 if (mode & 0x01) break;
4491 /* Terminate the list */
4492 feat_idx[feat_cnt] = -1;
4494 /* Return the number of races */
4501 * Build a list of monster indexes in the given group. Return the number
4502 * of monsters in the group.
4504 static int collect_artifacts(int grp_cur, int object_idx[])
4506 int i, object_cnt = 0;
4508 /* Get a list of x_char in this group */
4509 byte group_tval = object_group_tval[grp_cur];
4511 /* Check every object */
4512 for (i = 0; i < max_a_idx; i++)
4514 /* Access the artifact */
4515 artifact_type *a_ptr = &a_info[i];
4517 /* Skip empty artifacts */
4518 if (!a_ptr->name) continue;
4520 /* Skip "uncreated" artifacts */
4521 if (!a_ptr->cur_num) continue;
4523 /* Check for race in the group */
4524 if (a_ptr->tval == group_tval)
4527 object_idx[object_cnt++] = i;
4531 /* Terminate the list */
4532 object_idx[object_cnt] = 0;
4534 /* Return the number of races */
4541 * Encode the screen colors
4543 static char hack[17] = "dwsorgbuDWvyRGBU";
4547 * Hack -- load a screen dump from a file
4549 void do_cmd_load_screen(void)
4554 SYMBOL_CODE c = ' ';
4560 Term_get_size(&wid, &hgt);
4562 /* Build the filename */
4563 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4565 /* Append to the file */
4566 fff = my_fopen(buf, "r");
4569 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4577 /* Load the screen */
4578 for (y = 0; okay; y++)
4580 /* Get a line of data including control code */
4581 if (!fgets(buf, 1024, fff)) okay = FALSE;
4583 /* Get the blank line */
4584 if (buf[0] == '\n' || buf[0] == '\0') break;
4586 /* Ignore too large screen image */
4587 if (y >= hgt) continue;
4590 for (x = 0; x < wid - 1; x++)
4593 if (buf[x] == '\n' || buf[x] == '\0') break;
4595 /* Put the attr/char */
4596 Term_draw(x, y, TERM_WHITE, buf[x]);
4600 /* Dump the screen */
4601 for (y = 0; okay; y++)
4603 /* Get a line of data including control code */
4604 if (!fgets(buf, 1024, fff)) okay = FALSE;
4606 /* Get the blank line */
4607 if (buf[0] == '\n' || buf[0] == '\0') break;
4609 /* Ignore too large screen image */
4610 if (y >= hgt) continue;
4613 for (x = 0; x < wid - 1; x++)
4616 if (buf[x] == '\n' || buf[x] == '\0') break;
4618 /* Get the attr/char */
4619 (void)(Term_what(x, y, &a, &c));
4621 /* Look up the attr */
4622 for (i = 0; i < 16; i++)
4624 /* Use attr matches */
4625 if (hack[i] == buf[x]) a = (byte_hack)i;
4628 /* Put the attr/char */
4629 Term_draw(x, y, a, c);
4636 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4647 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4648 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4651 #define IM_FLAG_STR _("*", "* ")
4652 #define HAS_FLAG_STR _("+", "+ ")
4653 #define NO_FLAG_STR _("・", ". ")
4655 #define print_im_or_res_flag(IM, RES) \
4657 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4658 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4661 #define print_flag(TR) \
4663 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4667 /* XTRA HACK RESLIST */
4668 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4670 GAME_TEXT o_name[MAX_NLEN];
4671 BIT_FLAGS flgs[TR_FLAG_SIZE];
4673 if (!o_ptr->k_idx) return;
4674 if (o_ptr->tval != tval) return;
4676 /* Identified items only */
4677 if (!object_is_known(o_ptr)) return;
4680 * HACK:Ring of Lordly protection and Dragon equipment
4681 * have random resistances.
4683 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4684 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4685 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4686 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4687 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4688 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4689 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4690 || object_is_artifact(o_ptr))
4693 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4695 while (o_name[i] && (i < 26))
4698 if (iskanji(o_name[i])) i++;
4707 o_name[i] = ' '; i++;
4712 fprintf(fff, "%s %s", where, o_name);
4714 if (!(o_ptr->ident & (IDENT_MENTAL)))
4716 fputs(_("-------不明--------------- -------不明---------\n",
4717 "-------unknown------------ -------unknown------\n"), fff);
4721 object_flags_known(o_ptr, flgs);
4723 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4724 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4725 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4726 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4727 print_flag(TR_RES_POIS);
4728 print_flag(TR_RES_LITE);
4729 print_flag(TR_RES_DARK);
4730 print_flag(TR_RES_SHARDS);
4731 print_flag(TR_RES_SOUND);
4732 print_flag(TR_RES_NETHER);
4733 print_flag(TR_RES_NEXUS);
4734 print_flag(TR_RES_CHAOS);
4735 print_flag(TR_RES_DISEN);
4739 print_flag(TR_RES_BLIND);
4740 print_flag(TR_RES_FEAR);
4741 print_flag(TR_RES_CONF);
4742 print_flag(TR_FREE_ACT);
4743 print_flag(TR_SEE_INVIS);
4744 print_flag(TR_HOLD_EXP);
4745 print_flag(TR_TELEPATHY);
4746 print_flag(TR_SLOW_DIGEST);
4747 print_flag(TR_REGEN);
4748 print_flag(TR_LEVITATION);
4756 fprintf(fff, "%s\n", inven_res_label);
4762 * Display *ID* ed weapons/armors's resistances
4764 static void do_cmd_knowledge_inven(void)
4767 GAME_TEXT file_name[1024];
4769 OBJECT_TYPE_VALUE tval;
4775 /* Open a new file */
4776 fff = my_fopen_temp(file_name, 1024);
4779 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4783 fprintf(fff, "%s\n", inven_res_label);
4785 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4789 for (; j < 9; j++) fputc('\n', fff);
4791 fprintf(fff, "%s\n", inven_res_label);
4793 strcpy(where, _("装", "E "));
4794 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4796 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4798 strcpy(where, _("持", "I "));
4799 for (i = 0; i < INVEN_PACK; i++)
4801 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4804 st_ptr = &town_info[1].store[STORE_HOME];
4805 strcpy(where, _("家", "H "));
4806 for (i = 0; i < st_ptr->stock_num; i++)
4808 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4813 /* Display the file contents */
4814 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4816 /* Remove the file */
4821 void do_cmd_save_screen_html_aux(char *filename, int message)
4826 TERM_COLOR a = 0, old_a = 0;
4840 concptr html_head[] = {
4841 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4845 concptr html_foot[] = {
4847 "</body>\n</html>\n",
4853 Term_get_size(&wid, &hgt);
4855 /* File type is "TEXT" */
4856 FILE_TYPE(FILE_TYPE_TEXT);
4858 /* Append to the file */
4859 fff = my_fopen(filename, "w");
4863 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4869 if (message) screen_save();
4871 /* Build the filename */
4872 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4873 tmpfff = my_fopen(buf, "r");
4875 for (i = 0; html_head[i]; i++)
4876 fputs(html_head[i], fff);
4880 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4882 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4886 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4888 fprintf(fff, "%s\n", buf);
4893 /* Dump the screen */
4894 for (y = 0; y < hgt; y++)
4901 for (x = 0; x < wid - 1; x++)
4905 /* Get the attr/char */
4906 (void)(Term_what(x, y, &a, &c));
4910 case '&': cc = "&"; break;
4911 case '<': cc = "<"; break;
4912 case '>': cc = ">"; break;
4914 case 0x1f: c = '.'; break;
4915 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4920 if ((y == 0 && x == 0) || a != old_a) {
4921 rv = angband_color_table[a][1];
4922 gv = angband_color_table[a][2];
4923 bv = angband_color_table[a][3];
4924 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4925 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4929 fprintf(fff, "%s", cc);
4931 fprintf(fff, "%c", c);
4934 fprintf(fff, "</font>");
4937 for (i = 0; html_foot[i]; i++)
4938 fputs(html_foot[i], fff);
4943 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4945 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4949 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4951 fprintf(fff, "%s\n", buf);
4964 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4972 * Hack -- save a screen dump to a file
4974 static void do_cmd_save_screen_html(void)
4976 char buf[1024], tmp[256] = "screen.html";
4978 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4981 /* Build the filename */
4982 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4986 do_cmd_save_screen_html_aux(buf, 1);
4991 * Redefinable "save_screen" action
4993 void (*screendump_aux)(void) = NULL;
4997 * Hack -- save a screen dump to a file
4999 void do_cmd_save_screen(void)
5001 bool old_use_graphics = use_graphics;
5002 bool html_dump = FALSE;
5006 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5010 if (c == 'Y' || c == 'y')
5012 else if (c == 'H' || c == 'h')
5024 Term_get_size(&wid, &hgt);
5026 if (old_use_graphics)
5028 use_graphics = FALSE;
5030 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5036 do_cmd_save_screen_html();
5040 /* Do we use a special screendump function ? */
5041 else if (screendump_aux)
5043 /* Dump the screen to a graphics file */
5044 (*screendump_aux)();
5046 else /* Dump the screen as text */
5050 SYMBOL_CODE c = ' ';
5054 /* Build the filename */
5055 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5057 /* File type is "TEXT" */
5058 FILE_TYPE(FILE_TYPE_TEXT);
5060 /* Append to the file */
5061 fff = my_fopen(buf, "w");
5065 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5073 /* Dump the screen */
5074 for (y = 0; y < hgt; y++)
5077 for (x = 0; x < wid - 1; x++)
5079 /* Get the attr/char */
5080 (void)(Term_what(x, y, &a, &c));
5090 fprintf(fff, "%s\n", buf);
5097 /* Dump the screen */
5098 for (y = 0; y < hgt; y++)
5101 for (x = 0; x < wid - 1; x++)
5103 /* Get the attr/char */
5104 (void)(Term_what(x, y, &a, &c));
5107 buf[x] = hack[a&0x0F];
5114 fprintf(fff, "%s\n", buf);
5123 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5128 if (old_use_graphics)
5130 use_graphics = TRUE;
5132 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5139 * Sorting hook -- Comp function -- see below
5141 * We use "u" to point to array of monster indexes,
5142 * and "v" to select the type of sorting to perform on "u".
5144 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5146 u16b *who = (u16b*)(u);
5148 u16b *why = (u16b*)(v);
5155 /* Sort by total kills */
5158 /* Extract total kills */
5159 z1 = a_info[w1].tval;
5160 z2 = a_info[w2].tval;
5162 /* Compare total kills */
5163 if (z1 < z2) return (TRUE);
5164 if (z1 > z2) return (FALSE);
5168 /* Sort by monster level */
5171 /* Extract levels */
5172 z1 = a_info[w1].sval;
5173 z2 = a_info[w2].sval;
5175 /* Compare levels */
5176 if (z1 < z2) return (TRUE);
5177 if (z1 > z2) return (FALSE);
5181 /* Sort by monster experience */
5184 /* Extract experience */
5185 z1 = a_info[w1].level;
5186 z2 = a_info[w2].level;
5188 /* Compare experience */
5189 if (z1 < z2) return (TRUE);
5190 if (z1 > z2) return (FALSE);
5194 /* Compare indexes */
5200 * Sorting hook -- Swap function -- see below
5202 * We use "u" to point to array of monster indexes,
5203 * and "v" to select the type of sorting to perform.
5205 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5207 u16b *who = (u16b*)(u);
5222 * Check the status of "artifacts"
5224 static void do_cmd_knowledge_artifacts(void)
5234 GAME_TEXT file_name[1024];
5235 GAME_TEXT base_name[MAX_NLEN];
5239 /* Open a new file */
5240 fff = my_fopen_temp(file_name, 1024);
5243 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5248 /* Allocate the "who" array */
5249 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5251 /* Allocate the "okay" array */
5252 C_MAKE(okay, max_a_idx, bool);
5254 /* Scan the artifacts */
5255 for (k = 0; k < max_a_idx; k++)
5257 artifact_type *a_ptr = &a_info[k];
5262 /* Skip "empty" artifacts */
5263 if (!a_ptr->name) continue;
5265 /* Skip "uncreated" artifacts */
5266 if (!a_ptr->cur_num) continue;
5272 /* Check the dungeon */
5273 for (y = 0; y < current_floor_ptr->height; y++)
5275 for (x = 0; x < current_floor_ptr->width; x++)
5277 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5279 OBJECT_IDX this_o_idx, next_o_idx = 0;
5281 /* Scan all objects in the grid */
5282 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5285 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5286 next_o_idx = o_ptr->next_o_idx;
5288 /* Ignore non-artifacts */
5289 if (!object_is_fixed_artifact(o_ptr)) continue;
5291 /* Ignore known items */
5292 if (object_is_known(o_ptr)) continue;
5294 /* Note the artifact */
5295 okay[o_ptr->name1] = FALSE;
5300 /* Check the inventory and equipment */
5301 for (i = 0; i < INVEN_TOTAL; i++)
5303 object_type *o_ptr = &inventory[i];
5305 /* Ignore non-objects */
5306 if (!o_ptr->k_idx) continue;
5308 /* Ignore non-artifacts */
5309 if (!object_is_fixed_artifact(o_ptr)) continue;
5311 /* Ignore known items */
5312 if (object_is_known(o_ptr)) continue;
5314 /* Note the artifact */
5315 okay[o_ptr->name1] = FALSE;
5318 for (k = 0; k < max_a_idx; k++)
5320 if (okay[k]) who[n++] = k;
5323 /* Select the sort method */
5324 ang_sort_comp = ang_sort_art_comp;
5325 ang_sort_swap = ang_sort_art_swap;
5327 /* Sort the array by dungeon depth of monsters */
5328 ang_sort(who, &why, n);
5330 /* Scan the artifacts */
5331 for (k = 0; k < n; k++)
5333 artifact_type *a_ptr = &a_info[who[k]];
5336 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5338 /* Obtain the base object type */
5339 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5348 /* Create fake object */
5349 object_prep(q_ptr, z);
5351 /* Make it an artifact */
5352 q_ptr->name1 = (byte)who[k];
5354 /* Display as if known */
5355 q_ptr->ident |= IDENT_STORE;
5357 /* Describe the artifact */
5358 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5361 /* Hack -- Build the artifact name */
5362 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5365 /* Free the "who" array */
5366 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5368 /* Free the "okay" array */
5369 C_KILL(okay, max_a_idx, bool);
5372 /* Display the file contents */
5373 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5375 /* Remove the file */
5381 * Display known uniques
5382 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5384 static void do_cmd_knowledge_uniques(void)
5393 GAME_TEXT file_name[1024];
5396 int n_alive_surface = 0;
5397 int n_alive_over100 = 0;
5398 int n_alive_total = 0;
5401 for (i = 0; i < 10; i++) n_alive[i] = 0;
5403 /* Open a new file */
5404 fff = my_fopen_temp(file_name, 1024);
5408 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5413 /* Allocate the "who" array */
5414 C_MAKE(who, max_r_idx, MONRACE_IDX);
5416 /* Scan the monsters */
5417 for (i = 1; i < max_r_idx; i++)
5419 monster_race *r_ptr = &r_info[i];
5422 if (!r_ptr->name) continue;
5424 /* Require unique monsters */
5425 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5427 /* Only display "known" uniques */
5428 if (!cheat_know && !r_ptr->r_sights) continue;
5430 /* Only print rarity <= 100 uniques */
5431 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5433 /* Only "alive" uniques */
5434 if (r_ptr->max_num == 0) continue;
5438 lev = (r_ptr->level - 1) / 10;
5442 if (max_lev < lev) max_lev = lev;
5444 else n_alive_over100++;
5446 else n_alive_surface++;
5448 /* Collect "appropriate" monsters */
5452 /* Select the sort method */
5453 ang_sort_comp = ang_sort_comp_hook;
5454 ang_sort_swap = ang_sort_swap_hook;
5456 /* Sort the array by dungeon depth of monsters */
5457 ang_sort(who, &why, n);
5459 if (n_alive_surface)
5461 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5462 n_alive_total += n_alive_surface;
5464 for (i = 0; i <= max_lev; i++)
5466 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5467 n_alive_total += n_alive[i];
5469 if (n_alive_over100)
5471 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5472 n_alive_total += n_alive_over100;
5477 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5478 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5482 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5485 /* Scan the monster races */
5486 for (k = 0; k < n; k++)
5488 monster_race *r_ptr = &r_info[who[k]];
5490 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5493 /* Free the "who" array */
5494 C_KILL(who, max_r_idx, s16b);
5497 /* Display the file contents */
5498 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5500 /* Remove the file */
5506 * Display weapon-exp
5508 static void do_cmd_knowledge_weapon_exp(void)
5516 GAME_TEXT file_name[1024];
5519 /* Open a new file */
5520 fff = my_fopen_temp(file_name, 1024);
5522 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5527 for (i = 0; i < 5; i++)
5529 for (num = 0; num < 64; num++)
5531 for (j = 0; j < max_k_idx; j++)
5533 object_kind *k_ptr = &k_info[j];
5535 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5537 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5539 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5541 fprintf(fff, "%-25s ", tmp);
5542 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5543 else fprintf(fff, " ");
5544 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5545 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5554 /* Display the file contents */
5555 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5557 /* Remove the file */
5563 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5567 static void do_cmd_knowledge_spell_exp(void)
5574 const magic_type *s_ptr;
5576 GAME_TEXT file_name[1024];
5578 /* Open a new file */
5579 fff = my_fopen_temp(file_name, 1024);
5581 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5586 if (p_ptr->realm1 != REALM_NONE)
5588 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5589 for (i = 0; i < 32; i++)
5591 if (!is_magic(p_ptr->realm1))
5593 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5597 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5599 if (s_ptr->slevel >= 99) continue;
5600 spell_exp = p_ptr->spell_exp[i];
5601 exp_level = spell_exp_level(spell_exp);
5602 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5603 if (p_ptr->realm1 == REALM_HISSATSU)
5604 fprintf(fff, "[--]");
5607 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5608 else fprintf(fff, " ");
5609 fprintf(fff, "%s", exp_level_str[exp_level]);
5611 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5616 if (p_ptr->realm2 != REALM_NONE)
5618 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5619 for (i = 0; i < 32; i++)
5621 if (!is_magic(p_ptr->realm1))
5623 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5627 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5629 if (s_ptr->slevel >= 99) continue;
5631 spell_exp = p_ptr->spell_exp[i + 32];
5632 exp_level = spell_exp_level(spell_exp);
5633 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5634 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5635 else fprintf(fff, " ");
5636 fprintf(fff, "%s", exp_level_str[exp_level]);
5637 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5643 /* Display the file contents */
5644 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5646 /* Remove the file */
5652 * @brief スキル情報を表示するコマンドのメインルーチン /
5656 static void do_cmd_knowledge_skill_exp(void)
5658 int i = 0, skill_exp;
5662 char file_name[1024];
5663 char skill_name[GINOU_TEMPMAX][20] =
5665 _("マーシャルアーツ", "Martial Arts "),
5666 _("二刀流 ", "Dual Wielding "),
5667 _("乗馬 ", "Riding "),
5671 /* Open a new file */
5672 fff = my_fopen_temp(file_name, 1024);
5674 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5679 for (i = 0; i < GINOU_TEMPMAX; i++)
5681 skill_exp = p_ptr->skill_exp[i];
5682 fprintf(fff, "%-20s ", skill_name[i]);
5683 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5684 else fprintf(fff, " ");
5685 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5686 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5691 /* Display the file contents */
5692 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5694 /* Remove the file */
5700 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5701 * @param Name 変換したい文字列の参照ポインタ
5704 void plural_aux(char *Name)
5706 int NameLen = strlen(Name);
5708 if (my_strstr(Name, "Disembodied hand"))
5710 strcpy(Name, "Disembodied hands that strangled people");
5712 else if (my_strstr(Name, "Colour out of space"))
5714 strcpy(Name, "Colours out of space");
5716 else if (my_strstr(Name, "stairway to hell"))
5718 strcpy(Name, "stairways to hell");
5720 else if (my_strstr(Name, "Dweller on the threshold"))
5722 strcpy(Name, "Dwellers on the threshold");
5724 else if (my_strstr(Name, " of "))
5726 concptr aider = my_strstr(Name, " of ");
5737 if (dummy[i-1] == 's')
5739 strcpy(&(dummy[i]), "es");
5744 strcpy(&(dummy[i]), "s");
5747 strcpy(&(dummy[i+1]), aider);
5748 strcpy(Name, dummy);
5750 else if (my_strstr(Name, "coins"))
5753 strcpy(dummy, "piles of ");
5754 strcat(dummy, Name);
5755 strcpy(Name, dummy);
5758 else if (my_strstr(Name, "Manes"))
5762 else if (streq(&(Name[NameLen - 2]), "ey"))
5764 strcpy(&(Name[NameLen - 2]), "eys");
5766 else if (Name[NameLen - 1] == 'y')
5768 strcpy(&(Name[NameLen - 1]), "ies");
5770 else if (streq(&(Name[NameLen - 4]), "ouse"))
5772 strcpy(&(Name[NameLen - 4]), "ice");
5774 else if (streq(&(Name[NameLen - 2]), "us"))
5776 strcpy(&(Name[NameLen - 2]), "i");
5778 else if (streq(&(Name[NameLen - 6]), "kelman"))
5780 strcpy(&(Name[NameLen - 6]), "kelmen");
5782 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5784 strcpy(&(Name[NameLen - 8]), "wordsmen");
5786 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5788 strcpy(&(Name[NameLen - 7]), "oodsmen");
5790 else if (streq(&(Name[NameLen - 7]), "eastman"))
5792 strcpy(&(Name[NameLen - 7]), "eastmen");
5794 else if (streq(&(Name[NameLen - 8]), "izardman"))
5796 strcpy(&(Name[NameLen - 8]), "izardmen");
5798 else if (streq(&(Name[NameLen - 5]), "geist"))
5800 strcpy(&(Name[NameLen - 5]), "geister");
5802 else if (streq(&(Name[NameLen - 2]), "ex"))
5804 strcpy(&(Name[NameLen - 2]), "ices");
5806 else if (streq(&(Name[NameLen - 2]), "lf"))
5808 strcpy(&(Name[NameLen - 2]), "lves");
5810 else if (suffix(Name, "ch") ||
5811 suffix(Name, "sh") ||
5812 suffix(Name, "nx") ||
5813 suffix(Name, "s") ||
5816 strcpy(&(Name[NameLen]), "es");
5820 strcpy(&(Name[NameLen]), "s");
5825 * @brief 現在のペットを表示するコマンドのメインルーチン /
5826 * Display current pets
5829 static void do_cmd_knowledge_pets(void)
5833 monster_type *m_ptr;
5834 GAME_TEXT pet_name[MAX_NLEN];
5836 int show_upkeep = 0;
5837 GAME_TEXT file_name[1024];
5840 /* Open a new file */
5841 fff = my_fopen_temp(file_name, 1024);
5843 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5848 /* Process the monsters (backwards) */
5849 for (i = m_max - 1; i >= 1; i--)
5851 /* Access the monster */
5852 m_ptr = ¤t_floor_ptr->m_list[i];
5854 /* Ignore "dead" monsters */
5855 if (!m_ptr->r_idx) continue;
5857 /* Calculate "upkeep" for pets */
5861 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5862 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5866 show_upkeep = calculate_upkeep();
5868 fprintf(fff, "----------------------------------------------\n");
5870 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5872 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5874 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5879 /* Display the file contents */
5880 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5882 /* Remove the file */
5888 * @brief 現在のペットを表示するコマンドのメインルーチン /
5891 * @note the player ghosts are ignored.
5893 static void do_cmd_knowledge_kill_count(void)
5900 GAME_TEXT file_name[1024];
5905 /* Open a new file */
5906 fff = my_fopen_temp(file_name, 1024);
5909 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5914 /* Allocate the "who" array */
5915 C_MAKE(who, max_r_idx, MONRACE_IDX);
5918 /* Monsters slain */
5921 for (kk = 1; kk < max_r_idx; kk++)
5923 monster_race *r_ptr = &r_info[kk];
5925 if (r_ptr->flags1 & (RF1_UNIQUE))
5927 bool dead = (r_ptr->max_num == 0);
5936 MONSTER_NUMBER This = r_ptr->r_pkills;
5946 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5949 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5951 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5957 /* Scan the monsters */
5958 for (i = 1; i < max_r_idx; i++)
5960 monster_race *r_ptr = &r_info[i];
5962 /* Use that monster */
5963 if (r_ptr->name) who[n++] = i;
5966 /* Select the sort method */
5967 ang_sort_comp = ang_sort_comp_hook;
5968 ang_sort_swap = ang_sort_swap_hook;
5970 /* Sort the array by dungeon depth of monsters */
5971 ang_sort(who, &why, n);
5973 /* Scan the monster races */
5974 for (k = 0; k < n; k++)
5976 monster_race *r_ptr = &r_info[who[k]];
5978 if (r_ptr->flags1 & (RF1_UNIQUE))
5980 bool dead = (r_ptr->max_num == 0);
5984 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5990 MONSTER_NUMBER This = r_ptr->r_pkills;
5995 /* p,tは人と数える by ita */
5996 if (my_strchr("pt", r_ptr->d_char))
5997 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5999 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6003 if (my_strstr(r_name + r_ptr->name, "coins"))
6005 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6009 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6015 strcpy(ToPlural, (r_name + r_ptr->name));
6016 plural_aux(ToPlural);
6017 fprintf(fff, " %d %s\n", This, ToPlural);
6027 fprintf(fff,"----------------------------------------------\n");
6029 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6031 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6035 /* Free the "who" array */
6036 C_KILL(who, max_r_idx, s16b);
6039 /* Display the file contents */
6040 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6042 /* Remove the file */
6048 * @brief モンスター情報リスト中のグループを表示する /
6049 * Display the object groups.
6053 * @param per_page リストの表示行
6054 * @param grp_idx グループのID配列
6055 * @param group_text グループ名の文字列配列
6056 * @param grp_cur 現在の選択ID
6057 * @param grp_top 現在の選択リスト最上部ID
6060 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)
6064 /* Display lines until done */
6065 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6067 /* Get the group index */
6068 int grp = grp_idx[grp_top + i];
6070 /* Choose a color */
6071 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6073 /* Erase the entire line */
6074 Term_erase(col, row + i, wid);
6076 /* Display the group label */
6077 c_put_str(attr, group_text[grp], row + i, col);
6083 * Move the cursor in a browser window
6085 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6086 IDX *list_cur, int list_cnt)
6091 IDX list = *list_cur;
6093 /* Extract direction */
6096 /* Hack -- scroll up full screen */
6101 /* Hack -- scroll down full screen */
6106 d = get_keymap_dir(ch);
6111 /* Diagonals - hack */
6112 if ((ddx[d] > 0) && ddy[d])
6117 Term_get_size(&wid, &hgt);
6119 browser_rows = hgt - 8;
6121 /* Browse group list */
6126 /* Move up or down */
6127 grp += ddy[d] * (browser_rows - 1);
6130 if (grp >= grp_cnt) grp = grp_cnt - 1;
6131 if (grp < 0) grp = 0;
6132 if (grp != old_grp) list = 0;
6135 /* Browse sub-list list */
6138 /* Move up or down */
6139 list += ddy[d] * browser_rows;
6142 if (list >= list_cnt) list = list_cnt - 1;
6143 if (list < 0) list = 0;
6155 if (col < 0) col = 0;
6156 if (col > 1) col = 1;
6163 /* Browse group list */
6168 /* Move up or down */
6172 if (grp >= grp_cnt) grp = grp_cnt - 1;
6173 if (grp < 0) grp = 0;
6174 if (grp != old_grp) list = 0;
6177 /* Browse sub-list list */
6180 /* Move up or down */
6181 list += (IDX)ddy[d];
6184 if (list >= list_cnt) list = list_cnt - 1;
6185 if (list < 0) list = 0;
6196 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6200 /* Clear the display lines */
6201 for (i = 0; i < height; i++)
6203 Term_erase(col, row + i, width);
6206 /* Bigtile mode uses double width */
6207 if (use_bigtile) width /= 2;
6209 /* Display lines until done */
6210 for (i = 0; i < height; i++)
6212 /* Display columns until done */
6213 for (j = 0; j < width; j++)
6217 TERM_LEN x = col + j;
6218 TERM_LEN y = row + i;
6220 /* Bigtile mode uses double width */
6221 if (use_bigtile) x += j;
6226 /* Ignore illegal characters */
6227 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6228 (!use_graphics && ic > 0x7f))
6234 /* Force correct code for both ASCII character and tile */
6235 if (c & 0x80) a |= 0x80;
6237 /* Display symbol */
6238 Term_queue_bigchar(x, y, a, c, 0, 0);
6245 * Place the cursor at the collect position for visual mode
6247 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6249 int i = (a & 0x7f) - attr_top;
6250 int j = c - char_left;
6252 TERM_LEN x = col + j;
6253 TERM_LEN y = row + i;
6255 /* Bigtile mode uses double width */
6256 if (use_bigtile) x += j;
6258 /* Place the cursor */
6264 * Clipboard variables for copy&paste in visual mode
6266 static TERM_COLOR attr_idx = 0;
6267 static SYMBOL_CODE char_idx = 0;
6269 /* Hack -- for feature lighting */
6270 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6271 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6274 * Do visual mode command -- Change symbols
6276 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6277 int height, int width,
6278 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6279 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6281 static TERM_COLOR attr_old = 0;
6282 static SYMBOL_CODE char_old = 0;
6287 if (*visual_list_ptr)
6290 *cur_attr_ptr = attr_old;
6291 *cur_char_ptr = char_old;
6292 *visual_list_ptr = FALSE;
6300 if (*visual_list_ptr)
6303 *visual_list_ptr = FALSE;
6304 *need_redraw = TRUE;
6312 if (!*visual_list_ptr)
6314 *visual_list_ptr = TRUE;
6316 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6317 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6319 attr_old = *cur_attr_ptr;
6320 char_old = *cur_char_ptr;
6331 /* Set the visual */
6332 attr_idx = *cur_attr_ptr;
6333 char_idx = *cur_char_ptr;
6335 /* Hack -- for feature lighting */
6336 for (i = 0; i < F_LIT_MAX; i++)
6338 attr_idx_feat[i] = 0;
6339 char_idx_feat[i] = 0;
6346 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6349 *cur_attr_ptr = attr_idx;
6350 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6351 if (!*visual_list_ptr) *need_redraw = TRUE;
6357 *cur_char_ptr = char_idx;
6358 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6359 if (!*visual_list_ptr) *need_redraw = TRUE;
6365 if (*visual_list_ptr)
6368 int d = get_keymap_dir(ch);
6369 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6370 SYMBOL_CODE c = *cur_char_ptr;
6372 if (use_bigtile) eff_width = width / 2;
6373 else eff_width = width;
6375 /* Restrict direction */
6376 if ((a == 0) && (ddy[d] < 0)) d = 0;
6377 if ((c == 0) && (ddx[d] < 0)) d = 0;
6378 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6379 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6381 a += (TERM_COLOR)ddy[d];
6382 c += (SYMBOL_CODE)ddx[d];
6384 /* Force correct code for both ASCII character and tile */
6385 if (c & 0x80) a |= 0x80;
6387 /* Set the visual */
6392 /* Move the frame */
6393 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6394 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6395 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6396 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6402 /* Visual mode command is not used */
6408 * Display the monsters in a group.
6410 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6411 int mon_cur, int mon_top, bool visual_only)
6415 /* Display lines until done */
6416 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6420 /* Get the race index */
6421 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6423 /* Access the race */
6424 monster_race *r_ptr = &r_info[r_idx];
6426 /* Choose a color */
6427 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6429 /* Display the name */
6430 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6432 /* Hack -- visual_list mode */
6435 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6437 if (p_ptr->wizard || visual_only)
6439 c_prt(attr, format("%d", r_idx), row + i, 62);
6442 /* Erase chars before overwritten by the race letter */
6443 Term_erase(69, row + i, 255);
6445 /* Display symbol */
6446 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6451 if (!(r_ptr->flags1 & RF1_UNIQUE))
6452 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6454 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6455 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6459 /* Clear remaining lines */
6460 for (; i < per_page; i++)
6462 Term_erase(col, row + i, 255);
6468 * Display known monsters.
6470 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6474 IDX grp_cur, grp_top, old_grp_cur;
6475 IDX mon_cur, mon_top;
6476 IDX grp_cnt, grp_idx[100];
6484 bool visual_list = FALSE;
6485 TERM_COLOR attr_top = 0;
6493 Term_get_size(&wid, &hgt);
6495 browser_rows = hgt - 8;
6497 /* Allocate the "mon_idx" array */
6498 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6503 if (direct_r_idx < 0)
6505 mode = visual_only ? 0x03 : 0x01;
6507 /* Check every group */
6508 for (i = 0; monster_group_text[i] != NULL; i++)
6510 /* Measure the label */
6511 len = strlen(monster_group_text[i]);
6513 /* Save the maximum length */
6514 if (len > max) max = len;
6516 /* See if any monsters are known */
6517 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6519 /* Build a list of groups with known monsters */
6520 grp_idx[grp_cnt++] = i;
6528 mon_idx[0] = direct_r_idx;
6531 /* Terminate the list */
6534 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6535 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6538 /* Terminate the list */
6539 grp_idx[grp_cnt] = -1;
6542 grp_cur = grp_top = 0;
6543 mon_cur = mon_top = 0;
6548 mode = visual_only ? 0x02 : 0x00;
6553 monster_race *r_ptr;
6558 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6559 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6560 prt(_("名前", "Name"), 4, max + 3);
6561 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6562 prt(_("文字", "Sym"), 4, 67);
6563 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6565 for (i = 0; i < 78; i++)
6567 Term_putch(i, 5, TERM_WHITE, '=');
6570 if (direct_r_idx < 0)
6572 for (i = 0; i < browser_rows; i++)
6574 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6581 if (direct_r_idx < 0)
6583 /* Scroll group list */
6584 if (grp_cur < grp_top) grp_top = grp_cur;
6585 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6587 /* Display a list of monster groups */
6588 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6590 if (old_grp_cur != grp_cur)
6592 old_grp_cur = grp_cur;
6594 /* Get a list of monsters in the current group */
6595 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6598 /* Scroll monster list */
6599 while (mon_cur < mon_top)
6600 mon_top = MAX(0, mon_top - browser_rows/2);
6601 while (mon_cur >= mon_top + browser_rows)
6602 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6607 /* Display a list of monsters in the current group */
6608 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6614 /* Display a monster name */
6615 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6617 /* Display visual list below first monster */
6618 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6622 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6623 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6624 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6625 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6628 /* Get the current monster */
6629 r_ptr = &r_info[mon_idx[mon_cur]];
6633 /* Mega Hack -- track this monster race */
6634 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6640 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6644 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6648 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6653 /* Do visual mode command if needed */
6654 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))
6656 if (direct_r_idx >= 0)
6681 /* Recall on screen */
6682 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6684 screen_roff(mon_idx[mon_cur], 0);
6695 /* Move the cursor */
6696 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6703 /* Free the "mon_idx" array */
6704 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6709 * Display the objects in a group.
6711 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6712 int object_cur, int object_top, bool visual_only)
6716 /* Display lines until done */
6717 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6719 GAME_TEXT o_name[MAX_NLEN];
6722 object_kind *flavor_k_ptr;
6724 /* Get the object index */
6725 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6727 /* Access the object */
6728 object_kind *k_ptr = &k_info[k_idx];
6730 /* Choose a color */
6731 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6732 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6735 if (!visual_only && k_ptr->flavor)
6737 /* Appearance of this object is shuffled */
6738 flavor_k_ptr = &k_info[k_ptr->flavor];
6742 /* Appearance of this object is very normal */
6743 flavor_k_ptr = k_ptr;
6748 attr = ((i + object_top == object_cur) ? cursor : attr);
6750 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6753 strip_name(o_name, k_idx);
6758 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6761 /* Display the name */
6762 c_prt(attr, o_name, row + i, col);
6764 /* Hack -- visual_list mode */
6767 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);
6769 if (p_ptr->wizard || visual_only)
6771 c_prt(attr, format("%d", k_idx), row + i, 70);
6774 a = flavor_k_ptr->x_attr;
6775 c = flavor_k_ptr->x_char;
6777 /* Display symbol */
6778 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6781 /* Clear remaining lines */
6782 for (; i < per_page; i++)
6784 Term_erase(col, row + i, 255);
6789 * Describe fake object
6791 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6794 object_type object_type_body;
6795 o_ptr = &object_type_body;
6798 /* Create the artifact */
6799 object_prep(o_ptr, k_idx);
6801 /* It's fully know */
6802 o_ptr->ident |= IDENT_KNOWN;
6804 /* Track the object */
6805 /* object_actual_track(o_ptr); */
6807 /* Hack - mark as fake */
6808 /* term_obj_real = FALSE; */
6811 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6813 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6821 * Display known objects
6823 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6827 IDX grp_cur, grp_top, old_grp_cur;
6828 IDX object_old, object_cur, object_top;
6832 OBJECT_IDX *object_idx;
6838 bool visual_list = FALSE;
6839 TERM_COLOR attr_top = 0;
6847 Term_get_size(&wid, &hgt);
6849 browser_rows = hgt - 8;
6851 /* Allocate the "object_idx" array */
6852 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6857 if (direct_k_idx < 0)
6859 mode = visual_only ? 0x03 : 0x01;
6861 /* Check every group */
6862 for (i = 0; object_group_text[i] != NULL; i++)
6864 /* Measure the label */
6865 len = strlen(object_group_text[i]);
6867 /* Save the maximum length */
6868 if (len > max) max = len;
6870 /* See if any monsters are known */
6871 if (collect_objects(i, object_idx, mode))
6873 /* Build a list of groups with known monsters */
6874 grp_idx[grp_cnt++] = i;
6883 object_kind *k_ptr = &k_info[direct_k_idx];
6884 object_kind *flavor_k_ptr;
6886 if (!visual_only && k_ptr->flavor)
6888 /* Appearance of this object is shuffled */
6889 flavor_k_ptr = &k_info[k_ptr->flavor];
6893 /* Appearance of this object is very normal */
6894 flavor_k_ptr = k_ptr;
6897 object_idx[0] = direct_k_idx;
6898 object_old = direct_k_idx;
6901 /* Terminate the list */
6904 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6905 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6908 /* Terminate the list */
6909 grp_idx[grp_cnt] = -1;
6912 grp_cur = grp_top = 0;
6913 object_cur = object_top = 0;
6918 mode = visual_only ? 0x02 : 0x00;
6923 object_kind *k_ptr, *flavor_k_ptr;
6930 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6931 if (direct_k_idx < 0) prt("グループ", 4, 0);
6932 prt("名前", 4, max + 3);
6933 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6936 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6937 if (direct_k_idx < 0) prt("Group", 4, 0);
6938 prt("Name", 4, max + 3);
6939 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6943 for (i = 0; i < 78; i++)
6945 Term_putch(i, 5, TERM_WHITE, '=');
6948 if (direct_k_idx < 0)
6950 for (i = 0; i < browser_rows; i++)
6952 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6959 if (direct_k_idx < 0)
6961 /* Scroll group list */
6962 if (grp_cur < grp_top) grp_top = grp_cur;
6963 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6965 /* Display a list of object groups */
6966 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6968 if (old_grp_cur != grp_cur)
6970 old_grp_cur = grp_cur;
6972 /* Get a list of objects in the current group */
6973 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6976 /* Scroll object list */
6977 while (object_cur < object_top)
6978 object_top = MAX(0, object_top - browser_rows/2);
6979 while (object_cur >= object_top + browser_rows)
6980 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6985 /* Display a list of objects in the current group */
6986 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6990 object_top = object_cur;
6992 /* Display a list of objects in the current group */
6993 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6995 /* Display visual list below first object */
6996 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6999 /* Get the current object */
7000 k_ptr = &k_info[object_idx[object_cur]];
7002 if (!visual_only && k_ptr->flavor)
7004 /* Appearance of this object is shuffled */
7005 flavor_k_ptr = &k_info[k_ptr->flavor];
7009 /* Appearance of this object is very normal */
7010 flavor_k_ptr = k_ptr;
7015 prt(format("<方向>%s%s%s, ESC",
7016 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7017 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7018 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7021 prt(format("<dir>%s%s%s, ESC",
7022 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7023 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7024 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7030 /* Mega Hack -- track this object */
7031 if (object_cnt) object_kind_track(object_idx[object_cur]);
7033 /* The "current" object changed */
7034 if (object_old != object_idx[object_cur])
7038 /* Remember the "current" object */
7039 object_old = object_idx[object_cur];
7045 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7049 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7053 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7058 /* Do visual mode command if needed */
7059 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))
7061 if (direct_k_idx >= 0)
7086 /* Recall on screen */
7087 if (!visual_list && !visual_only && (grp_cnt > 0))
7089 desc_obj_fake(object_idx[object_cur]);
7097 /* Move the cursor */
7098 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7104 /* Free the "object_idx" array */
7105 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
7110 * Display the features in a group.
7112 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7113 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7115 int lit_col[F_LIT_MAX], i, j;
7116 int f_idx_col = use_bigtile ? 62 : 64;
7118 /* Correct columns 1 and 4 */
7119 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7120 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7121 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7123 /* Display lines until done */
7124 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7129 FEAT_IDX f_idx = feat_idx[feat_top + i];
7131 /* Access the index */
7132 feature_type *f_ptr = &f_info[f_idx];
7134 int row_i = row + i;
7136 /* Choose a color */
7137 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7139 /* Display the name */
7140 c_prt(attr, f_name + f_ptr->name, row_i, col);
7142 /* Hack -- visual_list mode */
7145 /* Display lighting level */
7146 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7148 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));
7150 if (p_ptr->wizard || visual_only)
7152 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7155 /* Display symbol */
7156 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);
7158 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7159 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7161 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7163 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7165 /* Mega-hack -- Use non-standard colour */
7166 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7168 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7172 /* Clear remaining lines */
7173 for (; i < per_page; i++)
7175 Term_erase(col, row + i, 255);
7181 * Interact with feature visuals.
7183 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7187 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7188 FEAT_IDX feat_cur, feat_top;
7190 FEAT_IDX grp_idx[100];
7194 TERM_LEN column = 0;
7198 bool visual_list = FALSE;
7199 TERM_COLOR attr_top = 0;
7202 TERM_LEN browser_rows;
7205 TERM_COLOR attr_old[F_LIT_MAX];
7206 SYMBOL_CODE char_old[F_LIT_MAX];
7207 TERM_COLOR *cur_attr_ptr;
7208 SYMBOL_CODE *cur_char_ptr;
7210 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7211 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7213 Term_get_size(&wid, &hgt);
7215 browser_rows = hgt - 8;
7217 /* Allocate the "feat_idx" array */
7218 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7223 if (direct_f_idx < 0)
7225 /* Check every group */
7226 for (i = 0; feature_group_text[i] != NULL; i++)
7228 /* Measure the label */
7229 len = strlen(feature_group_text[i]);
7231 /* Save the maximum length */
7232 if (len > max) max = len;
7234 /* See if any features are known */
7235 if (collect_features(i, feat_idx, 0x01))
7237 /* Build a list of groups with known features */
7238 grp_idx[grp_cnt++] = i;
7246 feature_type *f_ptr = &f_info[direct_f_idx];
7248 feat_idx[0] = direct_f_idx;
7251 /* Terminate the list */
7254 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7255 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7257 for (i = 0; i < F_LIT_MAX; i++)
7259 attr_old[i] = f_ptr->x_attr[i];
7260 char_old[i] = f_ptr->x_char[i];
7264 /* Terminate the list */
7265 grp_idx[grp_cnt] = -1;
7268 grp_cur = grp_top = 0;
7269 feat_cur = feat_top = 0;
7277 feature_type *f_ptr;
7283 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7284 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7285 prt(_("名前", "Name"), 4, max + 3);
7288 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7289 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7293 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7294 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7297 for (i = 0; i < 78; i++)
7299 Term_putch(i, 5, TERM_WHITE, '=');
7302 if (direct_f_idx < 0)
7304 for (i = 0; i < browser_rows; i++)
7306 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7313 if (direct_f_idx < 0)
7315 /* Scroll group list */
7316 if (grp_cur < grp_top) grp_top = grp_cur;
7317 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7319 /* Display a list of feature groups */
7320 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7322 if (old_grp_cur != grp_cur)
7324 old_grp_cur = grp_cur;
7326 /* Get a list of features in the current group */
7327 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7330 /* Scroll feature list */
7331 while (feat_cur < feat_top)
7332 feat_top = MAX(0, feat_top - browser_rows/2);
7333 while (feat_cur >= feat_top + browser_rows)
7334 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7339 /* Display a list of features in the current group */
7340 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7344 feat_top = feat_cur;
7346 /* Display a list of features in the current group */
7347 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7349 /* Display visual list below first object */
7350 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7354 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7355 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7356 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7359 /* Get the current feature */
7360 f_ptr = &f_info[feat_idx[feat_cur]];
7361 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7362 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7366 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7370 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7374 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7379 if (visual_list && ((ch == 'A') || (ch == 'a')))
7381 int prev_lighting_level = *lighting_level;
7385 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7386 else (*lighting_level)--;
7390 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7391 else (*lighting_level)++;
7394 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7395 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7397 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7398 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7403 else if ((ch == 'D') || (ch == 'd'))
7405 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7406 byte prev_x_char = f_ptr->x_char[*lighting_level];
7408 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7412 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7413 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7415 if (prev_x_char != f_ptr->x_char[*lighting_level])
7416 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7418 else *need_redraw = TRUE;
7423 /* Do visual mode command if needed */
7424 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))
7428 /* Restore previous visual settings */
7430 for (i = 0; i < F_LIT_MAX; i++)
7432 f_ptr->x_attr[i] = attr_old[i];
7433 f_ptr->x_char[i] = char_old[i];
7440 if (direct_f_idx >= 0) flag = TRUE;
7441 else *lighting_level = F_LIT_STANDARD;
7444 /* Preserve current visual settings */
7447 for (i = 0; i < F_LIT_MAX; i++)
7449 attr_old[i] = f_ptr->x_attr[i];
7450 char_old[i] = f_ptr->x_char[i];
7452 *lighting_level = F_LIT_STANDARD;
7459 for (i = 0; i < F_LIT_MAX; i++)
7461 attr_idx_feat[i] = f_ptr->x_attr[i];
7462 char_idx_feat[i] = f_ptr->x_char[i];
7471 /* Allow TERM_DARK text */
7472 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7474 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7475 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7493 /* Move the cursor */
7494 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7500 /* Free the "feat_idx" array */
7501 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7506 * List wanted monsters
7508 static void do_cmd_knowledge_kubi(void)
7513 GAME_TEXT file_name[1024];
7516 /* Open a new file */
7517 fff = my_fopen_temp(file_name, 1024);
7519 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7526 bool listed = FALSE;
7528 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7529 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7531 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7532 fprintf(fff, "----------------------------------------------\n");
7534 for (i = 0; i < MAX_KUBI; i++)
7536 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7538 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7546 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7551 /* Display the file contents */
7552 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7554 /* Remove the file */
7559 * List virtues & status
7561 static void do_cmd_knowledge_virtues(void)
7564 GAME_TEXT file_name[1024];
7566 /* Open a new file */
7567 fff = my_fopen_temp(file_name, 1024);
7569 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7576 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7581 /* Display the file contents */
7582 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7584 /* Remove the file */
7591 static void do_cmd_knowledge_dungeon(void)
7595 GAME_TEXT file_name[1024];
7598 /* Open a new file */
7599 fff = my_fopen_temp(file_name, 1024);
7601 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7608 for (i = 1; i < max_d_idx; i++)
7612 if (!d_info[i].maxdepth) continue;
7613 if (!max_dlv[i]) continue;
7614 if (d_info[i].final_guardian)
7616 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7618 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7620 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7625 /* Display the file contents */
7626 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7628 /* Remove the file */
7633 * List virtues & status
7636 static void do_cmd_knowledge_stat(void)
7640 GAME_TEXT file_name[1024];
7643 /* Open a new file */
7644 fff = my_fopen_temp(file_name, 1024);
7646 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7653 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7654 (2 * p_ptr->hitdie +
7655 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7657 if (p_ptr->knowledge & KNOW_HPRATE)
7658 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7659 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7661 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7662 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7664 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);
7665 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7672 /* Display the file contents */
7673 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7675 /* Remove the file */
7681 * Print all active quests
7683 static void do_cmd_knowledge_quests_current(FILE *fff)
7686 char rand_tmp_str[120] = "\0";
7687 GAME_TEXT name[MAX_NLEN];
7688 monster_race *r_ptr;
7690 int rand_level = 100;
7693 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7695 for (i = 1; i < max_q_idx; i++)
7697 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7698 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7699 (quest[i].status == QUEST_STATUS_COMPLETED))
7701 /* Set the quest number temporary */
7702 QUEST_IDX old_quest = p_ptr->inside_quest;
7705 /* Clear the text */
7706 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7707 quest_text_line = 0;
7709 p_ptr->inside_quest = i;
7711 /* Get the quest text */
7712 init_flags = INIT_SHOW_TEXT;
7714 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7716 /* Reset the old quest number */
7717 p_ptr->inside_quest = old_quest;
7719 /* No info from "silent" quests */
7720 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7724 if (quest[i].type != QUEST_TYPE_RANDOM)
7726 char note[80] = "\0";
7728 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7730 switch (quest[i].type)
7732 case QUEST_TYPE_KILL_LEVEL:
7733 case QUEST_TYPE_KILL_ANY_LEVEL:
7734 r_ptr = &r_info[quest[i].r_idx];
7735 strcpy(name, r_name + r_ptr->name);
7736 if (quest[i].max_num > 1)
7739 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7740 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7743 sprintf(note," - kill %d %s, have killed %d.",
7744 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7748 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7751 case QUEST_TYPE_FIND_ARTIFACT:
7754 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7756 object_type *q_ptr = &forge;
7757 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7758 object_prep(q_ptr, k_idx);
7759 q_ptr->name1 = quest[i].k_idx;
7760 q_ptr->ident = IDENT_STORE;
7761 object_desc(name, q_ptr, OD_NAME_ONLY);
7763 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7765 case QUEST_TYPE_FIND_EXIT:
7766 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7769 case QUEST_TYPE_KILL_NUMBER:
7771 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7772 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7774 sprintf(note," - Kill %d monsters, have killed %d.",
7775 (int)quest[i].max_num, (int)quest[i].cur_num);
7779 case QUEST_TYPE_KILL_ALL:
7780 case QUEST_TYPE_TOWER:
7781 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7786 /* Print the quest info */
7787 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7788 quest[i].name, (int)quest[i].level, note);
7790 fputs(tmp_str, fff);
7792 if (quest[i].status == QUEST_STATUS_COMPLETED)
7794 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7795 fputs(tmp_str, fff);
7801 while (quest_text[j][0] && j < 10)
7803 fprintf(fff, " %s\n", quest_text[j]);
7808 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7811 rand_level = quest[i].level;
7813 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7815 /* Print the quest info */
7816 r_ptr = &r_info[quest[i].r_idx];
7817 strcpy(name, r_name + r_ptr->name);
7819 if (quest[i].max_num > 1)
7822 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7823 quest[i].name, (int)quest[i].level,
7824 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7828 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7829 quest[i].name, (int)quest[i].level,
7830 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7835 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7836 quest[i].name, (int)quest[i].level, name);
7843 /* Print the current random quest */
7844 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7846 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7850 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7853 char playtime_str[16];
7854 quest_type* const q_ptr = &quest[q_idx];
7856 if (is_fixed_quest_idx(q_idx))
7858 /* Set the quest number temporary */
7859 IDX old_quest = p_ptr->inside_quest;
7861 p_ptr->inside_quest = q_idx;
7864 init_flags = INIT_NAME_ONLY;
7866 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7868 /* Reset the old quest number */
7869 p_ptr->inside_quest = old_quest;
7871 /* No info from "silent" quests */
7872 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7875 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7876 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7878 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7880 /* Print the quest info */
7881 if (q_ptr->complev == 0)
7884 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7885 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7886 r_name+r_info[q_ptr->r_idx].name,
7887 (int)q_ptr->level, playtime_str);
7892 _(" %-35s (%3d階) - レベル%2d - %s\n",
7893 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7894 r_name+r_info[q_ptr->r_idx].name,
7902 /* Print the quest info */
7904 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7905 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7906 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7909 fputs(tmp_str, fff);
7915 * Print all finished quests
7917 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7920 QUEST_IDX total = 0;
7922 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7923 for (i = 1; i < max_q_idx; i++)
7925 QUEST_IDX q_idx = quest_num[i];
7926 quest_type* const q_ptr = &quest[q_idx];
7928 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7933 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7938 * Print all failed quests
7940 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7943 QUEST_IDX total = 0;
7945 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7946 for (i = 1; i < max_q_idx; i++)
7948 QUEST_IDX q_idx = quest_num[i];
7949 quest_type* const q_ptr = &quest[q_idx];
7951 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7952 do_cmd_knowledge_quests_aux(fff, q_idx))
7957 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7962 * Print all random quests
7964 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7966 GAME_TEXT tmp_str[120];
7968 QUEST_IDX total = 0;
7970 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7971 for (i = 1; i < max_q_idx; i++)
7973 /* No info from "silent" quests */
7974 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7976 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7980 /* Print the quest info */
7981 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7982 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7983 fputs(tmp_str, fff);
7986 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7990 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7992 QUEST_IDX *q_num = (QUEST_IDX *)u;
7993 quest_type *qa = &quest[q_num[a]];
7994 quest_type *qb = &quest[q_num[b]];
7999 return (qa->comptime != qb->comptime) ?
8000 (qa->comptime < qb->comptime) :
8001 (qa->level <= qb->level);
8004 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8006 QUEST_IDX *q_num = (QUEST_IDX *)u;
8013 q_num[a] = q_num[b];
8019 * Print quest status of all active quests
8021 static void do_cmd_knowledge_quests(void)
8024 GAME_TEXT file_name[1024];
8029 /* Open a new file */
8030 fff = my_fopen_temp(file_name, 1024);
8033 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8038 /* Allocate Memory */
8039 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8041 /* Sort by compete level */
8042 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8043 ang_sort_comp = ang_sort_comp_quest_num;
8044 ang_sort_swap = ang_sort_swap_quest_num;
8045 ang_sort(quest_num, &dummy, max_q_idx);
8047 /* Dump Quest Information */
8048 do_cmd_knowledge_quests_current(fff);
8050 do_cmd_knowledge_quests_completed(fff, quest_num);
8052 do_cmd_knowledge_quests_failed(fff, quest_num);
8056 do_cmd_knowledge_quests_wiz_random(fff);
8060 /* Display the file contents */
8061 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8063 /* Remove the file */
8067 C_KILL(quest_num, max_q_idx, QUEST_IDX);
8074 static void do_cmd_knowledge_home(void)
8079 GAME_TEXT file_name[1024];
8081 GAME_TEXT o_name[MAX_NLEN];
8082 concptr paren = ")";
8084 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
8086 /* Open a new file */
8087 fff = my_fopen_temp(file_name, 1024);
8089 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8096 /* Print all homes in the different towns */
8097 st_ptr = &town_info[1].store[STORE_HOME];
8099 /* Home -- if anything there */
8100 if (st_ptr->stock_num)
8105 /* Header with name of the town */
8106 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8108 /* Dump all available items */
8109 for (i = 0; i < st_ptr->stock_num; i++)
8112 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8113 object_desc(o_name, &st_ptr->stock[i], 0);
8114 if (strlen(o_name) <= 80-3)
8116 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8122 for (n = 0, t = o_name; n < 80-3; n++, t++)
8123 if(iskanji(*t)) {t++; n++;}
8124 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8126 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8127 fprintf(fff, " %.77s\n", o_name+n);
8130 object_desc(o_name, &st_ptr->stock[i], 0);
8131 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8136 /* Add an empty line */
8137 fprintf(fff, "\n\n");
8142 /* Display the file contents */
8143 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8145 /* Remove the file */
8151 * Check the status of "autopick"
8153 static void do_cmd_knowledge_autopick(void)
8157 GAME_TEXT file_name[1024];
8159 /* Open a new file */
8160 fff = my_fopen_temp(file_name, 1024);
8164 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8171 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8175 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8176 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8179 for (k = 0; k < max_autopick; k++)
8182 byte act = autopick_list[k].action;
8183 if (act & DONT_AUTOPICK)
8185 tmp = _("放置", "Leave");
8187 else if (act & DO_AUTODESTROY)
8189 tmp = _("破壊", "Destroy");
8191 else if (act & DO_AUTOPICK)
8193 tmp = _("拾う", "Pickup");
8197 tmp = _("確認", "Query");
8200 if (act & DO_DISPLAY)
8201 fprintf(fff, "%11s", format("[%s]", tmp));
8203 fprintf(fff, "%11s", format("(%s)", tmp));
8205 tmp = autopick_line_from_entry(&autopick_list[k]);
8206 fprintf(fff, " %s", tmp);
8211 /* Display the file contents */
8212 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8214 /* Remove the file */
8220 * Interact with "knowledge"
8222 void do_cmd_knowledge(void)
8225 bool need_redraw = FALSE;
8227 /* File type is "TEXT" */
8228 FILE_TYPE(FILE_TYPE_TEXT);
8231 /* Interact until done */
8236 /* Ask for a choice */
8237 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8238 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8240 /* Give some choices */
8244 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8245 prt("(2) 既知のアイテム の一覧", 7, 5);
8246 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8247 prt("(4) 既知のモンスター の一覧", 9, 5);
8248 prt("(5) 倒した敵の数 の一覧", 10, 5);
8249 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8250 prt("(7) 現在のペット の一覧", 12, 5);
8251 prt("(8) 我が家のアイテム の一覧", 13, 5);
8252 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8253 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8257 prt("(a) 自分に関する情報 の一覧", 6, 5);
8258 prt("(b) 突然変異 の一覧", 7, 5);
8259 prt("(c) 武器の経験値 の一覧", 8, 5);
8260 prt("(d) 魔法の経験値 の一覧", 9, 5);
8261 prt("(e) 技能の経験値 の一覧", 10, 5);
8262 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8263 prt("(g) 入ったダンジョン の一覧", 12, 5);
8264 prt("(h) 実行中のクエスト の一覧", 13, 5);
8265 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8270 prt("(1) Display known artifacts", 6, 5);
8271 prt("(2) Display known objects", 7, 5);
8272 prt("(3) Display remaining uniques", 8, 5);
8273 prt("(4) Display known monster", 9, 5);
8274 prt("(5) Display kill count", 10, 5);
8275 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8276 prt("(7) Display current pets", 12, 5);
8277 prt("(8) Display home inventory", 13, 5);
8278 prt("(9) Display *identified* equip.", 14, 5);
8279 prt("(0) Display terrain symbols.", 15, 5);
8283 prt("(a) Display about yourself", 6, 5);
8284 prt("(b) Display mutations", 7, 5);
8285 prt("(c) Display weapon proficiency", 8, 5);
8286 prt("(d) Display spell proficiency", 9, 5);
8287 prt("(e) Display misc. proficiency", 10, 5);
8288 prt("(f) Display virtues", 11, 5);
8289 prt("(g) Display dungeons", 12, 5);
8290 prt("(h) Display current quests", 13, 5);
8291 prt("(i) Display auto pick/destroy", 14, 5);
8295 prt(_("-続く-", "-more-"), 17, 8);
8296 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8297 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8298 /*prt("-) 前ページ", 21, 60);*/
8299 prt(_("コマンド:", "Command: "), 20, 0);
8302 if (i == ESCAPE) break;
8305 case ' ': /* Page change */
8309 case '1': /* Artifacts */
8310 do_cmd_knowledge_artifacts();
8312 case '2': /* Objects */
8313 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8315 case '3': /* Uniques */
8316 do_cmd_knowledge_uniques();
8318 case '4': /* Monsters */
8319 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8321 case '5': /* Kill count */
8322 do_cmd_knowledge_kill_count();
8324 case '6': /* wanted */
8325 if (!vanilla_town) do_cmd_knowledge_kubi();
8327 case '7': /* Pets */
8328 do_cmd_knowledge_pets();
8330 case '8': /* Home */
8331 do_cmd_knowledge_home();
8333 case '9': /* Resist list */
8334 do_cmd_knowledge_inven();
8336 case '0': /* Feature list */
8338 IDX lighting_level = F_LIT_STANDARD;
8339 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8343 case 'a': /* Max stat */
8344 do_cmd_knowledge_stat();
8346 case 'b': /* Mutations */
8347 do_cmd_knowledge_mutations();
8349 case 'c': /* weapon-exp */
8350 do_cmd_knowledge_weapon_exp();
8352 case 'd': /* spell-exp */
8353 do_cmd_knowledge_spell_exp();
8355 case 'e': /* skill-exp */
8356 do_cmd_knowledge_skill_exp();
8358 case 'f': /* Virtues */
8359 do_cmd_knowledge_virtues();
8361 case 'g': /* Dungeon */
8362 do_cmd_knowledge_dungeon();
8364 case 'h': /* Quests */
8365 do_cmd_knowledge_quests();
8367 case 'i': /* Autopick */
8368 do_cmd_knowledge_autopick();
8370 default: /* Unknown option */
8378 if (need_redraw) do_cmd_redraw();
8383 * Check on the status of an active quest
8385 void do_cmd_checkquest(void)
8387 /* File type is "TEXT" */
8388 FILE_TYPE(FILE_TYPE_TEXT);
8392 do_cmd_knowledge_quests();
8398 * Display the time and date
8400 void do_cmd_time(void)
8402 int day, hour, min, full, start, end, num;
8410 extract_day_hour_min(&day, &hour, &min);
8412 full = hour * 100 + min;
8419 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8421 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8422 else strcpy(day_buf, "*****");
8424 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8425 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8428 if (!randint0(10) || p_ptr->image)
8430 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8434 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8437 /* Open this file */
8438 fff = my_fopen(buf, "rt");
8442 /* Find this time */
8443 while (!my_fgets(fff, buf, sizeof(buf)))
8445 /* Ignore comments */
8446 if (!buf[0] || (buf[0] == '#')) continue;
8448 /* Ignore invalid lines */
8449 if (buf[1] != ':') continue;
8451 /* Process 'Start' */
8454 /* Extract the starting time */
8455 start = atoi(buf + 2);
8457 /* Assume valid for an hour */
8467 /* Extract the ending time */
8468 end = atoi(buf + 2);
8474 /* Ignore incorrect range */
8475 if ((start > full) || (full > end)) continue;
8477 /* Process 'Description' */
8482 /* Apply the randomizer */
8483 if (!randint0(num)) strcpy(desc, buf + 2);