3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
45 #include "player-status.h"
52 #include "object-hook.h"
59 * Mark strings for auto dump
61 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
62 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
65 * Variables for auto dump
67 static FILE *auto_dump_stream;
68 static concptr auto_dump_mark;
69 static int auto_dump_line_num;
73 * @brief prf出力内容を消去する /
74 * Remove old lines automatically generated before.
75 * @param orig_file 消去を行うファイル名
77 static void remove_auto_dump(concptr orig_file)
79 FILE *tmp_fff, *orig_fff;
83 bool between_mark = FALSE;
86 long header_location = 0;
87 char header_mark_str[80];
88 char footer_mark_str[80];
91 /* Prepare a header/footer mark string */
92 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
93 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
95 mark_len = strlen(footer_mark_str);
97 /* Open an old dump file in read-only mode */
98 orig_fff = my_fopen(orig_file, "r");
100 /* If original file does not exist, nothing to do */
101 if (!orig_fff) return;
103 /* Open a new (temporary) file */
104 tmp_fff = my_fopen_temp(tmp_file, 1024);
108 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
113 /* Loop for every line */
117 if (my_fgets(orig_fff, buf, sizeof(buf)))
119 /* Read error: Assume End of File */
122 * Was looking for the footer, but not found.
124 * Since automatic dump might be edited by hand,
125 * it's dangerous to kill these lines.
126 * Seek back to the next line of the (pseudo) header,
131 fseek(orig_fff, header_location, SEEK_SET);
132 between_mark = FALSE;
136 /* Success -- End the loop */
143 /* We are looking for the header mark of automatic dump */
146 /* Is this line a header? */
147 if (!strcmp(buf, header_mark_str))
149 /* Memorise seek point of this line */
150 header_location = ftell(orig_fff);
152 /* Initialize counter for number of lines */
155 /* Look for the footer from now */
158 /* There are some changes */
165 /* Copy orginally lines */
166 fprintf(tmp_fff, "%s\n", buf);
170 /* We are looking for the footer mark of automatic dump */
173 /* Is this line a footer? */
174 if (!strncmp(buf, footer_mark_str, mark_len))
179 * Compare the number of lines
181 * If there is an inconsistency between
182 * actual number of lines and the
183 * number here, the automatic dump
184 * might be edited by hand. So it's
185 * dangerous to kill these lines.
186 * Seek back to the next line of the
187 * (pseudo) header, and read again.
189 if (!sscanf(buf + mark_len, " (%d)", &tmp)
192 fseek(orig_fff, header_location, SEEK_SET);
195 /* Look for another header */
196 between_mark = FALSE;
202 /* Ignore old line, and count number of lines */
212 /* If there are some changes, overwrite the original file with new one */
215 /* Copy contents of temporary file */
217 tmp_fff = my_fopen(tmp_file, "r");
218 orig_fff = my_fopen(orig_file, "w");
220 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
221 fprintf(orig_fff, "%s\n", buf);
227 /* Kill the temporary file */
235 * @brief prfファイルのフォーマットに従った内容を出力する /
236 * Dump a formatted line, using "vstrnfmt()".
239 static void auto_dump_printf(concptr fmt, ...)
246 /* Begin the Varargs Stuff */
249 /* Format the args, save the length */
250 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
252 /* End the Varargs Stuff */
255 /* Count number of lines */
256 for (p = buf; *p; p++)
258 if (*p == '\n') auto_dump_line_num++;
262 fprintf(auto_dump_stream, "%s", buf);
267 * @brief prfファイルをファイルオープンする /
268 * Open file to append auto dump.
270 * @param mark 出力するヘッダマーク
271 * @return ファイルポインタを取得できたらTRUEを返す
273 static bool open_auto_dump(concptr buf, concptr mark)
276 char header_mark_str[80];
278 /* Save the mark string */
279 auto_dump_mark = mark;
281 /* Prepare a header mark string */
282 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
284 /* Remove old macro dumps */
285 remove_auto_dump(buf);
287 /* Append to the file */
288 auto_dump_stream = my_fopen(buf, "a");
291 if (!auto_dump_stream) {
292 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
300 fprintf(auto_dump_stream, "%s\n", header_mark_str);
302 /* Initialize counter */
303 auto_dump_line_num = 0;
305 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
306 "# *Warning!* The lines below are an automatic dump.\n"));
307 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
308 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
314 * @brief prfファイルをファイルクローズする /
315 * Append foot part and close auto dump.
318 static void close_auto_dump(void)
320 char footer_mark_str[80];
322 /* Prepare a footer mark string */
323 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
325 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
326 "# *Warning!* The lines below are an automatic dump.\n"));
327 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
328 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
330 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
333 my_fclose(auto_dump_stream);
342 * @brief Return suffix of ordinal number
344 * @return pointer of suffix string.
346 concptr get_ordinal_number_suffix(int num)
348 num = ABS(num) % 100;
352 return (num == 11) ? "th" : "st";
354 return (num == 12) ? "th" : "nd";
356 return (num == 13) ? "th" : "rd";
365 * @brief 日記にメッセージを追加する /
366 * Take note to the diary.
367 * @param type 日記内容のID
368 * @param num 日記内容のIDに応じた数値
369 * @param note 日記内容のIDに応じた文字列参照ポインタ
372 errr do_cmd_write_nikki(int type, int num, concptr note)
376 GAME_TEXT file_name[MAX_NLEN];
378 concptr note_level = "";
379 bool do_level = TRUE;
380 char note_level_buf[40];
383 static bool disable_nikki = FALSE;
385 extract_day_hour_min(&day, &hour, &min);
387 if (disable_nikki) return(-1);
389 if (type == NIKKI_FIX_QUEST_C ||
390 type == NIKKI_FIX_QUEST_F ||
391 type == NIKKI_RAND_QUEST_C ||
392 type == NIKKI_RAND_QUEST_F ||
393 type == NIKKI_TO_QUEST)
397 old_quest = p_ptr->inside_quest;
398 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
400 /* Get the quest text */
401 init_flags = INIT_NAME_ONLY;
403 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
405 /* Reset the old quest number */
406 p_ptr->inside_quest = old_quest;
409 /* different filne name to avoid mixing */
410 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
412 /* Build the filename */
413 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
415 /* File type is "TEXT" */
416 FILE_TYPE(FILE_TYPE_TEXT);
418 fff = my_fopen(buf, "a");
423 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
429 q_idx = quest_number(current_floor_ptr->dun_level);
433 if (p_ptr->inside_arena)
434 note_level = _("アリーナ:", "Arane:");
435 else if (!current_floor_ptr->dun_level)
436 note_level = _("地上:", "Surface:");
437 else if (q_idx && (is_fixed_quest_idx(q_idx)
438 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
439 note_level = _("クエスト:", "Quest:");
443 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
445 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
447 note_level = note_level_buf;
455 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
456 else fputs(_("*****日目\n", "Day *****\n"), fff);
464 fprintf(fff, "%s\n",note);
468 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
473 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
476 case NIKKI_ART_SCROLL:
478 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
483 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
486 case NIKKI_FIX_QUEST_C:
488 if (quest[num].flags & QUEST_FLAG_SILENT) break;
489 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
490 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
493 case NIKKI_FIX_QUEST_F:
495 if (quest[num].flags & QUEST_FLAG_SILENT) break;
496 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
497 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
500 case NIKKI_RAND_QUEST_C:
502 GAME_TEXT name[MAX_NLEN];
503 strcpy(name, r_name+r_info[quest[num].r_idx].name);
504 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
505 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
508 case NIKKI_RAND_QUEST_F:
510 GAME_TEXT name[MAX_NLEN];
511 strcpy(name, r_name+r_info[quest[num].r_idx].name);
512 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
513 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
516 case NIKKI_MAXDEAPTH:
518 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
519 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
520 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
521 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
526 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
527 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
528 _(d_name + d_info[num].name, (int)max_dlv[num]),
529 _((int)max_dlv[num], d_name + d_info[num].name));
535 if (q_idx && (is_fixed_quest_idx(q_idx)
536 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
538 to = _("地上", "the surface");
542 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
543 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
545 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
551 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
552 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
553 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
555 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
560 if (quest[num].flags & QUEST_FLAG_SILENT) break;
561 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
562 hour, min, note_level, quest[num].name);
567 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
568 hour, min, note_level);
573 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
578 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
586 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
587 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
590 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
591 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
593 if (num == MAX_ARENA_MONS)
595 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
596 " won all fight to become a Chanpion.\n"));
603 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
609 if (!current_floor_ptr->dun_level)
610 to = _("地上", "the surface");
612 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
614 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
615 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
621 if (!current_floor_ptr->dun_level)
622 to = _("地上", "the surface");
624 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
626 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
627 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
632 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
635 case NIKKI_GAMESTART:
637 time_t ct = time((time_t*)0);
641 fprintf(fff, "%s %s",note, ctime(&ct));
644 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
647 case NIKKI_NAMED_PET:
649 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
652 case RECORD_NAMED_PET_NAME:
653 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
655 case RECORD_NAMED_PET_UNNAME:
656 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
658 case RECORD_NAMED_PET_DISMISS:
659 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
661 case RECORD_NAMED_PET_DEATH:
662 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
664 case RECORD_NAMED_PET_MOVED:
665 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
667 case RECORD_NAMED_PET_LOST_SIGHT:
668 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
670 case RECORD_NAMED_PET_DESTROY:
671 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
673 case RECORD_NAMED_PET_EARTHQUAKE:
674 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
676 case RECORD_NAMED_PET_GENOCIDE:
677 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
679 case RECORD_NAMED_PET_WIZ_ZAP:
680 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
682 case RECORD_NAMED_PET_TELE_LEVEL:
683 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
685 case RECORD_NAMED_PET_BLAST:
686 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
688 case RECORD_NAMED_PET_HEAL_LEPER:
689 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
691 case RECORD_NAMED_PET_COMPACT:
692 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
694 case RECORD_NAMED_PET_LOSE_PARENT:
695 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
706 case NIKKI_WIZARD_LOG:
707 fprintf(fff, "%s\n", note);
716 if (do_level) write_level = FALSE;
722 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
725 * @brief 日記のタイトル表記と内容出力 /
728 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
730 static void do_cmd_disp_nikki(void)
732 char nikki_title[256];
733 GAME_TEXT file_name[MAX_NLEN];
738 static const char subtitle[][30] = {"最強の肉体を求めて",
769 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
770 "Attack is the best form of defence.",
772 "An unexpected windfall",
773 "A drowning man will catch at a straw",
774 "Don't count your chickens before they are hatched.",
775 "It is no use crying over spilt milk.",
776 "Seeing is believing.",
777 "Strike the iron while it is hot.",
778 "I don't care what follows.",
779 "To dig a well to put out a house on fire.",
780 "Tomorrow is another day.",
781 "Easy come, easy go.",
782 "The more haste, the less speed.",
783 "Where there is life, there is hope.",
784 "There is no royal road to *WINNER*.",
785 "Danger past, God forgotten.",
786 "The best thing to do now is to run away.",
787 "Life is but an empty dream.",
788 "Dead men tell no tales.",
789 "A book that remains shut is but a block.",
790 "Misfortunes never come singly.",
791 "A little knowledge is a dangerous thing.",
792 "History repeats itself.",
793 "*WINNER* was not built in a day.",
794 "Ignorance is bliss.",
795 "To lose is to win?",
796 "No medicine can cure folly.",
797 "All good things come to an end.",
798 "M$ Empire strikes back.",
799 "To see is to believe",
801 "Quest of The World's Greatest Brain"};
803 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
805 /* Build the filename */
806 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
808 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
809 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
810 else if (IS_WIZARD_CLASS())
811 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
812 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
815 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
817 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
820 /* Display the file contents */
821 show_file(FALSE, buf, nikki_title, -1, 0);
825 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
828 static void do_cmd_bunshou(void)
831 char bunshou[80] = "\0";
833 if (get_string(_("内容: ", "diary note: "), tmp, 79))
835 strcpy(bunshou, tmp);
837 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
842 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
845 static void do_cmd_last_get(void)
850 if (record_o_name[0] == '\0') return;
852 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
853 if (!get_check(buf)) return;
855 turn_tmp = current_world_ptr->game_turn;
856 current_world_ptr->game_turn = record_turn;
857 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
858 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
859 current_world_ptr->game_turn = turn_tmp;
863 * @brief ファイル中の全日記記録を消去する /
866 static void do_cmd_erase_nikki(void)
868 GAME_TEXT file_name[MAX_NLEN];
872 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
873 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
875 /* Build the filename */
876 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
879 fff = my_fopen(buf, "w");
882 msg_format(_("記録を消去しました。", "deleted record."));
884 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
893 void do_cmd_nikki(void)
897 /* File type is "TEXT" */
898 FILE_TYPE(FILE_TYPE_TEXT);
901 /* Interact until done */
906 /* Ask for a choice */
907 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
909 /* Give some choices */
910 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
911 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
912 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
913 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
915 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
918 prt(_("コマンド:", "Command: "), 18, 0);
923 if (i == ESCAPE) break;
937 do_cmd_erase_nikki();
941 prepare_movie_hooks();
943 default: /* Unknown option */
953 * @brief 画面を再描画するコマンドのメインルーチン
954 * Hack -- redraw the screen
958 * This command performs various low level updates, clears all the "extra"
959 * windows, does a total redraw of the main window, and requests all of the
960 * interesting updates and redraws that I can think of.
962 * This command is also used to "instantiate" the results of the user
963 * selecting various things, such as graphics mode, so it must call
964 * the "TERM_XTRA_REACT" hook before redrawing the windows.
967 void do_cmd_redraw(void)
973 /* Hack -- react to changes */
974 Term_xtra(TERM_XTRA_REACT, 0);
976 /* Combine and Reorder the pack (later) */
977 p_ptr->update |= (PU_COMBINE | PU_REORDER);
978 p_ptr->update |= (PU_TORCH);
979 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
980 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
981 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
982 p_ptr->update |= (PU_MONSTERS);
984 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
986 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
987 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
993 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
996 /* Redraw every window */
997 for (j = 0; j < 8; j++)
1000 if (!angband_term[j]) continue;
1003 Term_activate(angband_term[j]);
1012 * @brief 名前を変更するコマンドのメインルーチン
1013 * Hack -- change name
1016 void do_cmd_change_name(void)
1031 /* Display the player */
1032 display_player(mode);
1037 display_player(mode);
1042 Term_putstr(2, 23, -1, TERM_WHITE,
1043 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1045 Term_putstr(2, 23, -1, TERM_WHITE,
1046 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1054 if (c == ESCAPE) break;
1061 /* Process the player name */
1062 process_player_name(FALSE);
1068 sprintf(tmp, "%s.txt", player_base);
1069 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1071 if (tmp[0] && (tmp[0] != ' '))
1073 file_character(tmp);
1091 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1098 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1099 * Recall the most recent message
1102 void do_cmd_message_one(void)
1104 /* Recall one message */
1105 prt(format("> %s", message_str(0)), 0, 0);
1110 * @brief メッセージのログを表示するコマンドのメインルーチン
1111 * Recall the most recent message
1115 * Show previous messages to the user -BEN-
1117 * The screen format uses line 0 and 23 for headers and prompts,
1118 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1120 * This command shows you which commands you are viewing, and allows
1121 * you to "search" for strings in the recall.
1123 * Note that messages may be longer than 80 characters, but they are
1124 * displayed using "infinite" length, with a special sub-command to
1125 * "slide" the virtual display to the left or right.
1127 * Attempt to only hilite the matching portions of the string.
1130 void do_cmd_messages(int num_now)
1134 char shower_str[81];
1135 char finder_str[81];
1137 concptr shower = NULL;
1141 Term_get_size(&wid, &hgt);
1143 /* Number of message lines in a screen */
1144 num_lines = hgt - 4;
1147 strcpy(finder_str, "");
1150 strcpy(shower_str, "");
1152 /* Total messages */
1155 /* Start on first message */
1160 /* Process requests until done */
1166 /* Dump up to 20 lines of messages */
1167 for (j = 0; (j < num_lines) && (i + j < n); j++)
1169 concptr msg = message_str(i+j);
1171 /* Dump the messages, bottom to top */
1172 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1174 /* Hilite "shower" */
1175 if (shower && shower[0])
1179 /* Display matches */
1180 while ((str = my_strstr(str, shower)) != NULL)
1182 int len = strlen(shower);
1184 /* Display the match */
1185 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1193 /* Erase remaining lines */
1194 for (; j < num_lines; j++)
1196 Term_erase(0, num_lines + 1 - j, 255);
1199 /* Display header */
1201 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1202 i, i + j - 1, n), 0, 0);
1204 /* Display prompt (not very informative) */
1205 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1206 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1208 skey = inkey_special(TRUE);
1210 /* Exit on Escape */
1211 if (skey == ESCAPE) break;
1213 /* Hack -- Save the old index */
1218 /* Hack -- handle show */
1221 prt(_("強調: ", "Show: "), hgt - 1, 0);
1223 /* Get a "shower" string, or continue */
1224 strcpy(back_str, shower_str);
1225 if (askfor(shower_str, 80))
1228 shower = shower_str[0] ? shower_str : NULL;
1230 else strcpy(shower_str, back_str);
1234 /* Hack -- handle find */
1241 prt(_("検索: ", "Find: "), hgt - 1, 0);
1243 /* Get a "finder" string, or continue */
1244 strcpy(back_str, finder_str);
1245 if (!askfor(finder_str, 80))
1247 strcpy(finder_str, back_str);
1250 else if (!finder_str[0])
1252 shower = NULL; /* Stop showing */
1257 shower = finder_str;
1260 for (z = i + 1; z < n; z++)
1262 concptr msg = message_str(z);
1265 if (my_strstr(msg, finder_str))
1276 /* Recall 1 older message */
1278 /* Go to the oldest line */
1282 /* Recall 1 newer message */
1284 /* Go to the newest line */
1288 /* Recall 1 older message */
1293 /* Go older if legal */
1294 i = MIN(i + 1, n - num_lines);
1297 /* Recall 10 older messages */
1299 /* Go older if legal */
1300 i = MIN(i + 10, n - num_lines);
1303 /* Recall 20 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + num_lines, n - num_lines);
1312 /* Recall 20 newer messages */
1316 /* Go newer (if able) */
1317 i = MAX(0, i - num_lines);
1320 /* Recall 10 newer messages */
1322 /* Go newer (if able) */
1326 /* Recall 1 newer messages */
1329 /* Go newer (if able) */
1334 /* Hack -- Error of some kind */
1342 * @brief チートオプションを変更するコマンドのメインルーチン
1343 * Interact with some options for cheating
1344 * @param info 表示メッセージ
1347 static void do_cmd_options_cheat(concptr info)
1350 int i, k = 0, n = CHEAT_MAX;
1354 /* Interact with the player */
1360 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1365 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1366 prt(" << 注意 >>", 11, 0);
1367 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1368 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1369 prt(" じらないようにして下さい。", 14, 0);
1371 /* Display the options */
1372 for (i = 0; i < n; i++)
1374 byte a = TERM_WHITE;
1376 /* Color current option */
1377 if (i == k) a = TERM_L_BLUE;
1379 /* Display the option text */
1380 sprintf(buf, "%-48s: %s (%s)",
1381 cheat_info[i].o_desc,
1382 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1383 cheat_info[i].o_text);
1384 c_prt(a, buf, i + 2, 0);
1387 /* Hilite current option */
1388 move_cursor(k + 2, 50);
1394 * HACK - Try to translate the key into a direction
1395 * to allow using the roguelike keys for navigation.
1397 dir = get_keymap_dir(ch);
1398 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1412 k = (n + k - 1) % n;
1430 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1431 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1432 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1433 (*cheat_info[k].o_var) = TRUE;
1442 (*cheat_info[k].o_var) = FALSE;
1449 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1450 /* Peruse the help file */
1451 (void)show_file(TRUE, buf, NULL, 0, 0);
1468 * @brief セーブ頻度ターンの次の値を返す
1469 * @param current 現在のセーブ頻度ターン値
1470 * @return 次のセーブ頻度ターン値
1472 static s16b toggle_frequency(s16b current)
1477 case 50: return 100;
1478 case 100: return 250;
1479 case 250: return 500;
1480 case 500: return 1000;
1481 case 1000: return 2500;
1482 case 2500: return 5000;
1483 case 5000: return 10000;
1484 case 10000: return 25000;
1491 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1492 * @param info 表示メッセージ
1495 static void do_cmd_options_autosave(concptr info)
1498 int i, k = 0, n = 2;
1503 /* Interact with the player */
1507 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1508 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1512 /* Display the options */
1513 for (i = 0; i < n; i++)
1515 byte a = TERM_WHITE;
1517 /* Color current option */
1518 if (i == k) a = TERM_L_BLUE;
1520 /* Display the option text */
1521 sprintf(buf, "%-48s: %s (%s)",
1522 autosave_info[i].o_desc,
1523 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1524 autosave_info[i].o_text);
1525 c_prt(a, buf, i + 2, 0);
1527 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1529 /* Hilite current option */
1530 move_cursor(k + 2, 50);
1546 k = (n + k - 1) % n;
1564 (*autosave_info[k].o_var) = TRUE;
1573 (*autosave_info[k].o_var) = FALSE;
1581 autosave_freq = toggle_frequency(autosave_freq);
1582 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1588 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1604 * @brief 標準オプションを変更するコマンドのサブルーチン /
1605 * Interact with some options
1606 * @param page オプションページ番号
1607 * @param info 表示メッセージ
1610 void do_cmd_options_aux(int page, concptr info)
1613 int i, k = 0, n = 0, l;
1616 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1617 (!p_ptr->wizard || !allow_debug_opts);
1620 /* Lookup the options */
1621 for (i = 0; i < 24; i++) opt[i] = 0;
1623 /* Scan the options */
1624 for (i = 0; option_info[i].o_desc; i++)
1626 /* Notice options on this "page" */
1627 if (option_info[i].o_page == page) opt[n++] = i;
1631 /* Interact with the player */
1637 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1638 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1641 /* HACK -- description for easy-auto-destroy options */
1642 if (page == OPT_PAGE_AUTODESTROY)
1643 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1644 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1646 /* Display the options */
1647 for (i = 0; i < n; i++)
1649 byte a = TERM_WHITE;
1651 /* Color current option */
1652 if (i == k) a = TERM_L_BLUE;
1654 /* Display the option text */
1655 sprintf(buf, "%-48s: %s (%.19s)",
1656 option_info[opt[i]].o_desc,
1657 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1658 option_info[opt[i]].o_text);
1659 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1660 else c_prt(a, buf, i + 2, 0);
1663 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1666 /* Hilite current option */
1667 move_cursor(k + 2 + l, 50);
1673 * HACK - Try to translate the key into a direction
1674 * to allow using the roguelike keys for navigation.
1676 dir = get_keymap_dir(ch);
1677 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1691 k = (n + k - 1) % n;
1708 if (browse_only) break;
1709 (*option_info[opt[k]].o_var) = TRUE;
1718 if (browse_only) break;
1719 (*option_info[opt[k]].o_var) = FALSE;
1727 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1733 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1734 /* Peruse the help file */
1735 (void)show_file(TRUE, buf, NULL, 0, 0);
1752 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1753 * Modify the "window" options
1756 static void do_cmd_options_win(void)
1766 /* Memorize old flags */
1767 for (j = 0; j < 8; j++)
1769 /* Acquire current flags */
1770 old_flag[j] = window_flag[j];
1779 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1781 /* Display the windows */
1782 for (j = 0; j < 8; j++)
1784 byte a = TERM_WHITE;
1786 concptr s = angband_term_name[j];
1789 if (j == x) a = TERM_L_BLUE;
1791 /* Window name, staggered, centered */
1792 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1795 /* Display the options */
1796 for (i = 0; i < 16; i++)
1798 byte a = TERM_WHITE;
1800 concptr str = window_flag_desc[i];
1803 if (i == y) a = TERM_L_BLUE;
1806 if (!str) str = _("(未使用)", "(Unused option)");
1809 Term_putstr(0, i + 5, -1, a, str);
1811 /* Display the windows */
1812 for (j = 0; j < 8; j++)
1818 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1821 if (window_flag[j] & (1L << i)) c = 'X';
1824 Term_putch(35 + j * 5, i + 5, a, c);
1829 Term_gotoxy(35 + x * 5, y + 5);
1847 for (j = 0; j < 8; j++)
1849 window_flag[j] &= ~(1L << y);
1853 for (i = 0; i < 16; i++)
1855 window_flag[x] &= ~(1L << i);
1868 window_flag[x] |= (1L << y);
1876 window_flag[x] &= ~(1L << y);
1882 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1890 d = get_keymap_dir(ch);
1892 x = (x + ddx[d] + 8) % 8;
1893 y = (y + ddy[d] + 16) % 16;
1900 /* Notice changes */
1901 for (j = 0; j < 8; j++)
1906 if (!angband_term[j]) continue;
1908 /* Ignore non-changes */
1909 if (window_flag[j] == old_flag[j]) continue;
1912 Term_activate(angband_term[j]);
1929 option_fields[OPT_NUM] =
1932 { '1', " キー入力 オプション", 3 },
1933 { '2', " マップ画面 オプション", 4 },
1934 { '3', " テキスト表示 オプション", 5 },
1935 { '4', " ゲームプレイ オプション", 6 },
1936 { '5', " 行動中止関係 オプション", 7 },
1937 { '6', " 簡易自動破壊 オプション", 8 },
1938 { 'r', " プレイ記録 オプション", 9 },
1940 { 'p', "自動拾いエディタ", 11 },
1941 { 'd', " 基本ウェイト量 ", 12 },
1942 { 'h', "低ヒットポイント", 13 },
1943 { 'm', " 低魔力色閾値 ", 14 },
1944 { 'a', " 自動セーブ オプション", 15 },
1945 { 'w', "ウインドウフラグ", 16 },
1947 { 'b', " 初期 オプション (参照のみ)", 18 },
1948 { 'c', " 詐欺 オプション", 19 },
1950 { '1', "Input Options", 3 },
1951 { '2', "Map Screen Options", 4 },
1952 { '3', "Text Display Options", 5 },
1953 { '4', "Game-Play Options", 6 },
1954 { '5', "Disturbance Options", 7 },
1955 { '6', "Easy Auto-Destroyer Options", 8 },
1956 { 'r', "Play record Options", 9 },
1958 { 'p', "Auto-picker/destroyer editor", 11 },
1959 { 'd', "Base Delay Factor", 12 },
1960 { 'h', "Hitpoint Warning", 13 },
1961 { 'm', "Mana Color Threshold", 14 },
1962 { 'a', "Autosave Options", 15 },
1963 { 'w', "Window Flags", 16 },
1965 { 'b', "Birth Options (Browse Only)", 18 },
1966 { 'c', "Cheat Options", 19 },
1972 * @brief 標準オプションを変更するコマンドのメインルーチン /
1973 * Set or unset various options.
1977 * The user must use the "Ctrl-R" command to "adapt" to changes
1978 * in any options which control "visual" aspects of the game.
1981 void do_cmd_options(void)
1993 /* Does not list cheat option when cheat option is off */
1994 if (!p_ptr->noscore && !allow_debug_opts) n--;
1997 /* Why are we here */
1998 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2002 /* Give some choices */
2003 for (i = 0; i < n; i++)
2005 byte a = TERM_WHITE;
2006 if (i == y) a = TERM_L_BLUE;
2007 Term_putstr(5, option_fields[i].row, -1, a,
2008 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2011 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2014 skey = inkey_special(TRUE);
2015 if (!(skey & SKEY_MASK)) k = (char)skey;
2019 if (k == ESCAPE) break;
2021 if (my_strchr("\n\r ", k))
2023 k = option_fields[y].key;
2027 for (i = 0; i < n; i++)
2029 if (tolower(k) == option_fields[i].key) break;
2032 /* Command is found */
2035 /* Hack -- browse help */
2036 if (k == '?') break;
2040 if (skey == SKEY_UP) d = 8;
2041 if (skey == SKEY_DOWN) d = 2;
2042 y = (y + ddy[d] + n) % n;
2047 if (k == ESCAPE) break;
2054 /* Process the general options */
2055 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2061 /* Process the general options */
2062 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2069 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2076 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2083 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2090 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2094 /* Play-record Options */
2099 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2108 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2109 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2110 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2114 /* Cheating Options */
2117 if (!p_ptr->noscore && !allow_debug_opts)
2119 /* Cheat options are not permitted */
2125 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2132 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2141 do_cmd_options_win();
2142 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2143 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2144 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2145 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2150 /* Auto-picker/destroyer editor */
2154 do_cmd_edit_autopick();
2158 /* Hack -- Delay Speed */
2164 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2166 /* Get a new value */
2169 int msec = delay_factor * delay_factor * delay_factor;
2170 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2171 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2173 if (k == ESCAPE) break;
2176 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2179 else if (isdigit(k)) delay_factor = D2I(k);
2186 /* Hack -- hitpoint warning factor */
2192 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2194 /* Get a new value */
2197 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2198 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2200 if (k == ESCAPE) break;
2203 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2206 else if (isdigit(k)) hitpoint_warn = D2I(k);
2213 /* Hack -- mana color factor */
2219 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2221 /* Get a new value */
2224 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2225 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2227 if (k == ESCAPE) break;
2230 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2233 else if (isdigit(k)) mana_warn = D2I(k);
2241 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2245 /* Unknown option */
2258 /* Hack - Redraw equippy chars */
2259 p_ptr->redraw |= (PR_EQUIPPY);
2265 * @brief prefファイルを選択して処理する /
2266 * Ask for a "user pref line" and process it
2269 * Allow absolute file names?
2271 void do_cmd_pref(void)
2278 /* Ask for a "user pref command" */
2279 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2281 /* Process that pref command */
2282 (void)process_pref_file_command(buf);
2286 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2289 void do_cmd_reload_autopick(void)
2291 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2292 /* Load the file with messages */
2293 autopick_load_pref(TRUE);
2299 * @brief マクロ情報をprefファイルに保存する /
2300 * @param fname ファイル名
2303 static errr macro_dump(concptr fname)
2305 static concptr mark = "Macro Dump";
2311 /* Build the filename */
2312 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2314 /* File type is "TEXT" */
2315 FILE_TYPE(FILE_TYPE_TEXT);
2317 /* Append to the file */
2318 if (!open_auto_dump(buf, mark)) return (-1);
2321 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2324 for (i = 0; i < macro__num; i++)
2326 /* Extract the action */
2327 ascii_to_text(buf, macro__act[i]);
2329 /* Dump the macro */
2330 auto_dump_printf("A:%s\n", buf);
2332 /* Extract the action */
2333 ascii_to_text(buf, macro__pat[i]);
2335 /* Dump normal macros */
2336 auto_dump_printf("P:%s\n", buf);
2339 auto_dump_printf("\n");
2351 * @brief マクロのトリガーキーを取得する /
2352 * Hack -- ask for a "trigger" (see below)
2353 * @param buf キー表記を保管するバッファ
2357 * Note the complex use of the "inkey()" function from "util.c".
2359 * Note that both "flush()" calls are extremely important.
2362 static void do_cmd_macro_aux(char *buf)
2370 /* Do not process macros */
2376 /* Read the pattern */
2382 /* Do not process macros */
2385 /* Do not wait for keys */
2388 /* Attempt to read a key */
2397 /* Convert the trigger */
2398 ascii_to_text(tmp, buf);
2400 /* Hack -- display the trigger */
2401 Term_addstr(-1, TERM_WHITE, tmp);
2407 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2408 * Hack -- ask for a keymap "trigger" (see below)
2409 * @param buf キー表記を取得するバッファ
2413 * Note that both "flush()" calls are extremely important. This may
2414 * no longer be true, since "util.c" is much simpler now.
2417 static void do_cmd_macro_aux_keymap(char *buf)
2427 /* Convert to ascii */
2428 ascii_to_text(tmp, buf);
2430 /* Hack -- display the trigger */
2431 Term_addstr(-1, TERM_WHITE, tmp);
2438 * @brief キーマップをprefファイルにダンプする /
2439 * Hack -- append all keymaps to the given file
2440 * @param fname ファイルネーム
2444 static errr keymap_dump(concptr fname)
2446 static concptr mark = "Keymap Dump";
2455 if (rogue_like_commands)
2457 mode = KEYMAP_MODE_ROGUE;
2463 mode = KEYMAP_MODE_ORIG;
2467 /* Build the filename */
2468 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2470 /* File type is "TEXT" */
2471 FILE_TYPE(FILE_TYPE_TEXT);
2473 /* Append to the file */
2474 if (!open_auto_dump(buf, mark)) return -1;
2477 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2480 for (i = 0; i < 256; i++)
2484 /* Loop up the keymap */
2485 act = keymap_act[mode][i];
2487 /* Skip empty keymaps */
2490 /* Encode the key */
2493 ascii_to_text(key, buf);
2495 /* Encode the action */
2496 ascii_to_text(buf, act);
2498 /* Dump the macro */
2499 auto_dump_printf("A:%s\n", buf);
2500 auto_dump_printf("C:%d:%s\n", mode, key);
2512 * @brief マクロを設定するコマンドのメインルーチン /
2513 * Interact with "macros"
2517 * Note that the macro "action" must be defined before the trigger.
2519 * Could use some helpful instructions on this page.
2522 void do_cmd_macros(void)
2534 if (rogue_like_commands)
2536 mode = KEYMAP_MODE_ROGUE;
2542 mode = KEYMAP_MODE_ORIG;
2545 /* File type is "TEXT" */
2546 FILE_TYPE(FILE_TYPE_TEXT);
2551 /* Process requests until done */
2555 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2557 /* Describe that action */
2558 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2560 /* Analyze the current action */
2561 ascii_to_text(buf, macro__buf);
2563 /* Display the current action */
2568 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2570 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2571 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2572 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2573 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2574 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2575 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2576 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2577 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2578 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2579 #endif /* ALLOW_MACROS */
2582 prt(_("コマンド: ", "Command: "), 16, 0);
2587 if (i == ESCAPE) break;
2589 /* Load a 'macro' file */
2595 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2598 prt(_("ファイル: ", "File: "), 18, 0);
2600 /* Default filename */
2601 sprintf(tmp, "%s.prf", player_base);
2603 /* Ask for a file */
2604 if (!askfor(tmp, 80)) continue;
2606 /* Process the given filename */
2607 err = process_pref_file(tmp);
2610 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2615 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2619 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2629 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2632 prt(_("ファイル: ", "File: "), 18, 0);
2634 /* Default filename */
2635 sprintf(tmp, "%s.prf", player_base);
2637 /* Ask for a file */
2638 if (!askfor(tmp, 80)) continue;
2640 /* Dump the macros */
2641 (void)macro_dump(tmp);
2644 msg_print(_("マクロを追加しました。", "Appended macros."));
2653 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2657 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2659 /* Get a macro trigger */
2660 do_cmd_macro_aux(buf);
2662 /* Acquire action */
2663 k = macro_find_exact(buf);
2669 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2675 /* Obtain the action */
2676 strcpy(macro__buf, macro__act[k]);
2678 /* Analyze the current action */
2679 ascii_to_text(buf, macro__buf);
2681 /* Display the current action */
2685 msg_print(_("マクロを確認しました。", "Found a macro."));
2689 /* Create a macro */
2693 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2696 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2698 /* Get a macro trigger */
2699 do_cmd_macro_aux(buf);
2705 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2706 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2709 prt(_("マクロ行動: ", "Action: "), 20, 0);
2711 /* Convert to text */
2712 ascii_to_text(tmp, macro__buf);
2714 /* Get an encoded action */
2715 if (askfor(tmp, 80))
2717 /* Convert to ascii */
2718 text_to_ascii(macro__buf, tmp);
2720 /* Link the macro */
2721 macro_add(buf, macro__buf);
2724 msg_print(_("マクロを追加しました。", "Added a macro."));
2728 /* Remove a macro */
2732 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2735 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2737 /* Get a macro trigger */
2738 do_cmd_macro_aux(buf);
2740 /* Link the macro */
2741 macro_add(buf, buf);
2744 msg_print(_("マクロを削除しました。", "Removed a macro."));
2751 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2754 prt(_("ファイル: ", "File: "), 18, 0);
2756 /* Default filename */
2757 sprintf(tmp, "%s.prf", player_base);
2759 /* Ask for a file */
2760 if (!askfor(tmp, 80)) continue;
2762 /* Dump the macros */
2763 (void)keymap_dump(tmp);
2766 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2769 /* Query a keymap */
2775 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2778 prt(_("押すキー: ", "Keypress: "), 18, 0);
2780 /* Get a keymap trigger */
2781 do_cmd_macro_aux_keymap(buf);
2783 /* Look up the keymap */
2784 act = keymap_act[mode][(byte)(buf[0])];
2790 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2796 /* Obtain the action */
2797 strcpy(macro__buf, act);
2799 /* Analyze the current action */
2800 ascii_to_text(buf, macro__buf);
2802 /* Display the current action */
2806 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2810 /* Create a keymap */
2814 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2817 prt(_("押すキー: ", "Keypress: "), 18, 0);
2819 /* Get a keymap trigger */
2820 do_cmd_macro_aux_keymap(buf);
2826 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2827 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2830 prt(_("行動: ", "Action: "), 20, 0);
2832 /* Convert to text */
2833 ascii_to_text(tmp, macro__buf);
2835 /* Get an encoded action */
2836 if (askfor(tmp, 80))
2838 /* Convert to ascii */
2839 text_to_ascii(macro__buf, tmp);
2841 /* Free old keymap */
2842 string_free(keymap_act[mode][(byte)(buf[0])]);
2844 /* Make new keymap */
2845 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2848 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2852 /* Remove a keymap */
2856 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2859 prt(_("押すキー: ", "Keypress: "), 18, 0);
2861 /* Get a keymap trigger */
2862 do_cmd_macro_aux_keymap(buf);
2864 /* Free old keymap */
2865 string_free(keymap_act[mode][(byte)(buf[0])]);
2867 /* Make new keymap */
2868 keymap_act[mode][(byte)(buf[0])] = NULL;
2871 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2874 /* Enter a new action */
2878 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2884 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2885 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2888 prt(_("マクロ行動: ", "Action: "), 20, 0);
2890 /* Hack -- limit the value */
2893 /* Get an encoded action */
2894 if (!askfor(buf, 80)) continue;
2896 /* Extract an action */
2897 text_to_ascii(macro__buf, buf);
2900 #endif /* ALLOW_MACROS */
2913 * @brief キャラクタ色の明暗表現
2915 static concptr lighting_level_str[F_LIT_MAX] =
2930 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2931 * @param i 指定対象となるキャラクタコード
2932 * @param num 指定されたビジュアルIDを返す参照ポインタ
2933 * @param max ビジュアルIDの最大数
2934 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2936 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2943 sprintf(str, "%d", *num);
2945 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2948 tmp = (IDX)strtol(str, NULL, 0);
2949 if (tmp >= 0 && tmp < max)
2952 else if (isupper(i))
2953 *num = (*num + max - 1) % max;
2955 *num = (*num + 1) % max;
2961 * @brief キャラクタの変更メニュー表示
2962 * @param choice_msg 選択メッセージ
2965 static void print_visuals_menu(concptr choice_msg)
2967 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2969 /* Give some choices */
2970 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2972 #ifdef ALLOW_VISUALS
2973 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2974 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2975 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2976 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2977 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2978 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2979 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2980 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2981 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2982 #endif /* ALLOW_VISUALS */
2984 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2987 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2990 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2991 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2992 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2995 * Interact with "visuals"
2997 void do_cmd_visuals(void)
3002 bool need_redraw = FALSE;
3003 concptr empty_symbol = "<< ? >>";
3005 if (use_bigtile) empty_symbol = "<< ?? >>";
3007 /* File type is "TEXT" */
3008 FILE_TYPE(FILE_TYPE_TEXT);
3011 /* Interact until done */
3016 /* Ask for a choice */
3017 print_visuals_menu(NULL);
3022 if (i == ESCAPE) break;
3026 /* Load a 'pref' file */
3029 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3032 prt(_("ファイル: ", "File: "), 17, 0);
3034 /* Default filename */
3035 sprintf(tmp, "%s.prf", player_base);
3038 if (!askfor(tmp, 70)) continue;
3040 /* Process the given filename */
3041 (void)process_pref_file(tmp);
3046 #ifdef ALLOW_VISUALS
3048 /* Dump monster attr/chars */
3051 static concptr mark = "Monster attr/chars";
3054 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3057 prt(_("ファイル: ", "File: "), 17, 0);
3059 /* Default filename */
3060 sprintf(tmp, "%s.prf", player_base);
3062 /* Get a filename */
3063 if (!askfor(tmp, 70)) continue;
3065 /* Build the filename */
3066 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3068 /* Append to the file */
3069 if (!open_auto_dump(buf, mark)) continue;
3072 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3075 for (i = 0; i < max_r_idx; i++)
3077 monster_race *r_ptr = &r_info[i];
3079 /* Skip non-entries */
3080 if (!r_ptr->name) continue;
3082 /* Dump a comment */
3083 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3085 /* Dump the monster attr/char info */
3086 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3087 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3093 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3098 /* Dump object attr/chars */
3101 static concptr mark = "Object attr/chars";
3102 KIND_OBJECT_IDX k_idx;
3105 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3108 prt(_("ファイル: ", "File: "), 17, 0);
3110 /* Default filename */
3111 sprintf(tmp, "%s.prf", player_base);
3113 /* Get a filename */
3114 if (!askfor(tmp, 70)) continue;
3116 /* Build the filename */
3117 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3119 /* Append to the file */
3120 if (!open_auto_dump(buf, mark)) continue;
3123 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3126 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3128 GAME_TEXT o_name[MAX_NLEN];
3129 object_kind *k_ptr = &k_info[k_idx];
3131 /* Skip non-entries */
3132 if (!k_ptr->name) continue;
3137 strip_name(o_name, k_idx);
3143 /* Prepare dummy object */
3144 object_prep(&forge, k_idx);
3146 /* Get un-shuffled flavor name */
3147 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3150 /* Dump a comment */
3151 auto_dump_printf("# %s\n", o_name);
3153 /* Dump the object attr/char info */
3154 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3155 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3161 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3166 /* Dump feature attr/chars */
3169 static concptr mark = "Feature attr/chars";
3172 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3175 prt(_("ファイル: ", "File: "), 17, 0);
3177 /* Default filename */
3178 sprintf(tmp, "%s.prf", player_base);
3180 /* Get a filename */
3181 if (!askfor(tmp, 70)) continue;
3183 /* Build the filename */
3184 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3186 /* Append to the file */
3187 if (!open_auto_dump(buf, mark)) continue;
3190 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3193 for (i = 0; i < max_f_idx; i++)
3195 feature_type *f_ptr = &f_info[i];
3197 /* Skip non-entries */
3198 if (!f_ptr->name) continue;
3200 /* Skip mimiccing features */
3201 if (f_ptr->mimic != i) continue;
3203 /* Dump a comment */
3204 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3206 /* Dump the feature attr/char info */
3207 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3208 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3209 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3210 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3216 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3221 /* Modify monster attr/chars (numeric operation) */
3224 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3225 static MONRACE_IDX r = 0;
3227 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3229 /* Hack -- query until done */
3232 monster_race *r_ptr = &r_info[r];
3236 TERM_COLOR da = r_ptr->d_attr;
3237 byte dc = r_ptr->d_char;
3238 TERM_COLOR ca = r_ptr->x_attr;
3239 byte cc = r_ptr->x_char;
3241 /* Label the object */
3242 Term_putstr(5, 17, -1, TERM_WHITE,
3243 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3245 /* Label the Default values */
3246 Term_putstr(10, 19, -1, TERM_WHITE,
3247 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3249 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3250 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3252 /* Label the Current values */
3253 Term_putstr(10, 20, -1, TERM_WHITE,
3254 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3256 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3257 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3260 Term_putstr(0, 22, -1, TERM_WHITE,
3261 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3266 if (i == ESCAPE) break;
3268 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3269 else if (isupper(i)) c = 'a' + i - 'A';
3279 if (!cmd_visuals_aux(i, &r, max_r_idx))
3285 while (!r_info[r].name);
3289 t = (int)r_ptr->x_attr;
3290 (void)cmd_visuals_aux(i, &t, 256);
3291 r_ptr->x_attr = (byte)t;
3295 t = (int)r_ptr->x_char;
3296 (void)cmd_visuals_aux(i, &t, 256);
3297 r_ptr->x_char = (byte)t;
3301 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3303 print_visuals_menu(choice_msg);
3311 /* Modify object attr/chars (numeric operation) */
3314 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3316 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3318 /* Hack -- query until done */
3321 object_kind *k_ptr = &k_info[k];
3325 TERM_COLOR da = k_ptr->d_attr;
3326 SYMBOL_CODE dc = k_ptr->d_char;
3327 TERM_COLOR ca = k_ptr->x_attr;
3328 SYMBOL_CODE cc = k_ptr->x_char;
3330 /* Label the object */
3331 Term_putstr(5, 17, -1, TERM_WHITE,
3332 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3333 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3335 /* Label the Default values */
3336 Term_putstr(10, 19, -1, TERM_WHITE,
3337 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3339 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3340 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3342 /* Label the Current values */
3343 Term_putstr(10, 20, -1, TERM_WHITE,
3344 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3346 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3347 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3350 Term_putstr(0, 22, -1, TERM_WHITE,
3351 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3356 if (i == ESCAPE) break;
3358 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3359 else if (isupper(i)) c = 'a' + i - 'A';
3369 if (!cmd_visuals_aux(i, &k, max_k_idx))
3375 while (!k_info[k].name);
3379 t = (int)k_ptr->x_attr;
3380 (void)cmd_visuals_aux(i, &t, 256);
3381 k_ptr->x_attr = (byte)t;
3385 t = (int)k_ptr->x_char;
3386 (void)cmd_visuals_aux(i, &t, 256);
3387 k_ptr->x_char = (byte)t;
3391 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3393 print_visuals_menu(choice_msg);
3401 /* Modify feature attr/chars (numeric operation) */
3404 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3406 static IDX lighting_level = F_LIT_STANDARD;
3407 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3409 /* Hack -- query until done */
3412 feature_type *f_ptr = &f_info[f];
3416 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3417 byte dc = f_ptr->d_char[lighting_level];
3418 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3419 byte cc = f_ptr->x_char[lighting_level];
3421 /* Label the object */
3423 Term_putstr(5, 17, -1, TERM_WHITE,
3424 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3425 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3427 /* Label the Default values */
3428 Term_putstr(10, 19, -1, TERM_WHITE,
3429 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3431 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3432 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3434 /* Label the Current values */
3436 Term_putstr(10, 20, -1, TERM_WHITE,
3437 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3439 Term_putstr(10, 20, -1, TERM_WHITE,
3440 format("Current attr/char = %3d / %3d", ca, cc));
3443 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3444 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3448 Term_putstr(0, 22, -1, TERM_WHITE,
3449 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3451 Term_putstr(0, 22, -1, TERM_WHITE,
3452 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3458 if (i == ESCAPE) break;
3460 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3461 else if (isupper(i)) c = 'a' + i - 'A';
3471 if (!cmd_visuals_aux(i, &f, max_f_idx))
3477 while (!f_info[f].name || (f_info[f].mimic != f));
3481 t = (int)f_ptr->x_attr[lighting_level];
3482 (void)cmd_visuals_aux(i, &t, 256);
3483 f_ptr->x_attr[lighting_level] = (byte)t;
3487 t = (int)f_ptr->x_char[lighting_level];
3488 (void)cmd_visuals_aux(i, &t, 256);
3489 f_ptr->x_char[lighting_level] = (byte)t;
3493 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3496 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3500 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3502 print_visuals_menu(choice_msg);
3510 /* Modify monster attr/chars (visual mode) */
3512 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3515 /* Modify object attr/chars (visual mode) */
3517 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3520 /* Modify feature attr/chars (visual mode) */
3523 IDX lighting_level = F_LIT_STANDARD;
3524 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3528 #endif /* ALLOW_VISUALS */
3536 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3540 /* Unknown option */
3550 if (need_redraw) do_cmd_redraw();
3555 * Interact with "colors"
3557 void do_cmd_colors(void)
3566 /* File type is "TEXT" */
3567 FILE_TYPE(FILE_TYPE_TEXT);
3572 /* Interact until done */
3577 /* Ask for a choice */
3578 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3580 /* Give some choices */
3581 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3584 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3585 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3589 prt(_("コマンド: ", "Command: "), 8, 0);
3593 if (i == ESCAPE) break;
3595 /* Load a 'pref' file */
3599 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3602 prt(_("ファイル: ", "File: "), 10, 0);
3605 sprintf(tmp, "%s.prf", player_base);
3608 if (!askfor(tmp, 70)) continue;
3610 /* Process the given filename */
3611 (void)process_pref_file(tmp);
3613 /* Mega-Hack -- react to changes */
3614 Term_xtra(TERM_XTRA_REACT, 0);
3616 /* Mega-Hack -- redraw */
3625 static concptr mark = "Colors";
3628 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3631 prt(_("ファイル: ", "File: "), 10, 0);
3633 /* Default filename */
3634 sprintf(tmp, "%s.prf", player_base);
3636 /* Get a filename */
3637 if (!askfor(tmp, 70)) continue;
3639 /* Build the filename */
3640 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3642 /* Append to the file */
3643 if (!open_auto_dump(buf, mark)) continue;
3646 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3649 for (i = 0; i < 256; i++)
3651 int kv = angband_color_table[i][0];
3652 int rv = angband_color_table[i][1];
3653 int gv = angband_color_table[i][2];
3654 int bv = angband_color_table[i][3];
3656 concptr name = _("未知", "unknown");
3658 /* Skip non-entries */
3659 if (!kv && !rv && !gv && !bv) continue;
3661 /* Extract the color name */
3662 if (i < 16) name = color_names[i];
3664 /* Dump a comment */
3665 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3667 /* Dump the monster attr/char info */
3668 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3675 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3684 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3686 /* Hack -- query until done */
3695 /* Exhibit the normal colors */
3696 for (j = 0; j < 16; j++)
3698 /* Exhibit this color */
3699 Term_putstr(j*4, 20, -1, a, "###");
3701 /* Exhibit all colors */
3702 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3705 /* Describe the color */
3706 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3708 /* Describe the color */
3709 Term_putstr(5, 10, -1, TERM_WHITE,
3710 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3712 /* Label the Current values */
3713 Term_putstr(5, 12, -1, TERM_WHITE,
3714 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3715 angband_color_table[a][0],
3716 angband_color_table[a][1],
3717 angband_color_table[a][2],
3718 angband_color_table[a][3]));
3721 Term_putstr(0, 14, -1, TERM_WHITE,
3722 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3727 if (i == ESCAPE) break;
3730 if (i == 'n') a = (byte)(a + 1);
3731 if (i == 'N') a = (byte)(a - 1);
3732 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3733 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3734 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3735 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3736 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3737 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3738 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3739 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3741 /* Hack -- react to changes */
3742 Term_xtra(TERM_XTRA_REACT, 0);
3744 /* Hack -- redraw */
3751 /* Unknown option */
3765 * Note something in the message recall
3767 void do_cmd_note(void)
3775 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3777 /* Ignore empty notes */
3778 if (!buf[0] || (buf[0] == ' ')) return;
3780 /* Add the note to the message recall */
3781 msg_format(_("メモ: %s", "Note: %s"), buf);
3786 * Mention the current version
3788 void do_cmd_version(void)
3790 #if FAKE_VER_EXTRA > 0
3791 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3792 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3794 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3795 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3802 * Array of feeling strings
3804 static concptr do_cmd_feeling_text[11] =
3806 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3807 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3808 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3809 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3810 _("とても悪い予感がする...", "You have a very bad feeling..."),
3811 _("悪い予感がする...", "You have a bad feeling..."),
3812 _("何か緊張する。", "You feel nervous."),
3813 _("少し不運な気がする...", "You feel your luck is turning..."),
3814 _("この場所は好きになれない。", "You don't like the look of this place."),
3815 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3816 _("なんて退屈なところだ...", "What a boring place...")
3819 static concptr do_cmd_feeling_text_combat[11] =
3821 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3822 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3823 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3824 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3825 _("とても悪い予感がする...", "You have a very bad feeling..."),
3826 _("悪い予感がする...", "You have a bad feeling..."),
3827 _("何か緊張する。", "You feel nervous."),
3828 _("少し不運な気がする...", "You feel your luck is turning..."),
3829 _("この場所は好きになれない。", "You don't like the look of this place."),
3830 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3831 _("なんて退屈なところだ...", "What a boring place...")
3834 static concptr do_cmd_feeling_text_lucky[11] =
3836 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3837 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3838 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3839 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3840 _("とても良い感じがする...", "You have a very good feeling..."),
3841 _("良い感じがする...", "You have a good feeling..."),
3842 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3843 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3844 _("見た感じ悪くはない...", "You like the look of this place..."),
3845 _("全然駄目ということはないが...", "This level can't be all bad..."),
3846 _("なんて退屈なところだ...", "What a boring place...")
3851 * Note that "feeling" is set to zero unless some time has passed.
3852 * Note that this is done when the level is GENERATED, not entered.
3854 void do_cmd_feeling(void)
3856 if (p_ptr->wild_mode) return;
3858 /* No useful feeling in quests */
3859 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3861 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3865 /* No useful feeling in town */
3866 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3868 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3870 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3875 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3880 /* No useful feeling in the wilderness */
3881 else if (!current_floor_ptr->dun_level)
3883 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3887 /* Display the feeling */
3888 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3889 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3890 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3891 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3892 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3894 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3900 * Description of each monster group.
3902 static concptr monster_group_text[] =
3905 "ユニーク", /* "Uniques" */
3906 "乗馬可能なモンスター", /* "Riding" */
3907 "賞金首", /* "Wanted */
3908 "アンバーの王族", /* "Ambertite" */
3937 /* "古代ドラゴン/ワイアーム", */
3998 /* "Ancient Dragon/Wyrm", */
4007 "Multi-Headed Reptile",
4012 "Reptile/Amphibian",
4013 "Spider/Scorpion/Tick",
4015 /* "Major Demon", */
4032 * Symbols of monsters in each group. Note the "Uniques" group
4033 * is handled differently.
4035 static concptr monster_group_char[] =
4092 "!$&()+./=>?[\\]`{|~",
4102 * hook function to sort monsters by level
4104 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4106 u16b *who = (u16b*)(u);
4111 monster_race *r_ptr1 = &r_info[w1];
4112 monster_race *r_ptr2 = &r_info[w2];
4117 if (r_ptr2->level > r_ptr1->level) return TRUE;
4118 if (r_ptr1->level > r_ptr2->level) return FALSE;
4120 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4121 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4126 * Build a list of monster indexes in the given group. Return the number
4127 * of monsters in the group.
4129 * mode & 0x01 : check for non-empty group
4130 * mode & 0x02 : visual operation only
4132 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4138 /* Get a list of x_char in this group */
4139 concptr group_char = monster_group_char[grp_cur];
4141 /* XXX Hack -- Check if this is the "Uniques" group */
4142 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4144 /* XXX Hack -- Check if this is the "Riding" group */
4145 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4147 /* XXX Hack -- Check if this is the "Wanted" group */
4148 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4150 /* XXX Hack -- Check if this is the "Amberite" group */
4151 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4154 /* Check every race */
4155 for (i = 0; i < max_r_idx; i++)
4157 /* Access the race */
4158 monster_race *r_ptr = &r_info[i];
4160 /* Skip empty race */
4161 if (!r_ptr->name) continue ;
4163 /* Require known monsters */
4164 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4168 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4171 else if (grp_riding)
4173 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4176 else if (grp_wanted)
4178 bool wanted = FALSE;
4180 for (j = 0; j < MAX_KUBI; j++)
4182 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4183 (p_ptr->today_mon && p_ptr->today_mon == i))
4189 if (!wanted) continue;
4192 else if (grp_amberite)
4194 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4199 /* Check for race in the group */
4200 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4204 mon_idx[mon_cnt++] = i;
4206 /* XXX Hack -- Just checking for non-empty group */
4207 if (mode & 0x01) break;
4210 /* Terminate the list */
4211 mon_idx[mon_cnt] = -1;
4213 /* Select the sort method */
4214 ang_sort_comp = ang_sort_comp_monster_level;
4215 ang_sort_swap = ang_sort_swap_hook;
4217 /* Sort by monster level */
4218 ang_sort(mon_idx, &dummy_why, mon_cnt);
4220 /* Return the number of races */
4226 * Description of each monster group.
4228 static concptr object_group_text[] =
4231 "キノコ", /* "Mushrooms" */
4232 "薬", /* "Potions" */
4233 "油つぼ", /* "Flasks" */
4234 "巻物", /* "Scrolls" */
4236 "アミュレット", /* "Amulets" */
4237 "笛", /* "Whistle" */
4238 "光源", /* "Lanterns" */
4239 "魔法棒", /* "Wands" */
4242 "カード", /* "Cards" */
4253 "刀剣類", /* "Swords" */
4254 "鈍器", /* "Blunt Weapons" */
4255 "長柄武器", /* "Polearms" */
4256 "採掘道具", /* "Diggers" */
4257 "飛び道具", /* "Bows" */
4261 "軽装鎧", /* "Soft Armor" */
4262 "重装鎧", /* "Hard Armor" */
4263 "ドラゴン鎧", /* "Dragon Armor" */
4264 "盾", /* "Shields" */
4265 "クローク", /* "Cloaks" */
4266 "籠手", /* "Gloves" */
4267 "ヘルメット", /* "Helms" */
4269 "ブーツ", /* "Boots" */
4322 * TVALs of items in each group
4324 static byte object_group_tval[] =
4365 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4373 * Build a list of object indexes in the given group. Return the number
4374 * of objects in the group.
4376 * mode & 0x01 : check for non-empty group
4377 * mode & 0x02 : visual operation only
4379 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4381 KIND_OBJECT_IDX i, object_cnt = 0;
4384 /* Get a list of x_char in this group */
4385 byte group_tval = object_group_tval[grp_cur];
4387 /* Check every object */
4388 for (i = 0; i < max_k_idx; i++)
4390 /* Access the object */
4391 object_kind *k_ptr = &k_info[i];
4393 /* Skip empty objects */
4394 if (!k_ptr->name) continue;
4398 /* Any objects will be displayed */
4404 /* Skip non-flavoured objects */
4405 if (!k_ptr->flavor) continue;
4407 /* Require objects ever seen */
4408 if (!k_ptr->aware) continue;
4411 /* Skip items with no distribution (special artifacts) */
4412 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4416 /* Check for objects in the group */
4417 if (TV_LIFE_BOOK == group_tval)
4419 /* Hack -- All spell books */
4420 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4422 /* Add the object */
4423 object_idx[object_cnt++] = i;
4427 else if (k_ptr->tval == group_tval)
4429 /* Add the object */
4430 object_idx[object_cnt++] = i;
4434 /* XXX Hack -- Just checking for non-empty group */
4435 if (mode & 0x01) break;
4438 /* Terminate the list */
4439 object_idx[object_cnt] = -1;
4441 /* Return the number of objects */
4447 * Description of each feature group.
4449 static concptr feature_group_text[] =
4457 * Build a list of feature indexes in the given group. Return the number
4458 * of features in the group.
4460 * mode & 0x01 : check for non-empty group
4462 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4465 FEAT_IDX feat_cnt = 0;
4467 /* Unused; There is a single group. */
4470 /* Check every feature */
4471 for (i = 0; i < max_f_idx; i++)
4473 /* Access the index */
4474 feature_type *f_ptr = &f_info[i];
4476 /* Skip empty index */
4477 if (!f_ptr->name) continue;
4479 /* Skip mimiccing features */
4480 if (f_ptr->mimic != i) continue;
4483 feat_idx[feat_cnt++] = i;
4485 /* XXX Hack -- Just checking for non-empty group */
4486 if (mode & 0x01) break;
4489 /* Terminate the list */
4490 feat_idx[feat_cnt] = -1;
4492 /* Return the number of races */
4499 * Build a list of monster indexes in the given group. Return the number
4500 * of monsters in the group.
4502 static int collect_artifacts(int grp_cur, int object_idx[])
4504 int i, object_cnt = 0;
4506 /* Get a list of x_char in this group */
4507 byte group_tval = object_group_tval[grp_cur];
4509 /* Check every object */
4510 for (i = 0; i < max_a_idx; i++)
4512 /* Access the artifact */
4513 artifact_type *a_ptr = &a_info[i];
4515 /* Skip empty artifacts */
4516 if (!a_ptr->name) continue;
4518 /* Skip "uncreated" artifacts */
4519 if (!a_ptr->cur_num) continue;
4521 /* Check for race in the group */
4522 if (a_ptr->tval == group_tval)
4525 object_idx[object_cnt++] = i;
4529 /* Terminate the list */
4530 object_idx[object_cnt] = 0;
4532 /* Return the number of races */
4539 * Encode the screen colors
4541 static char hack[17] = "dwsorgbuDWvyRGBU";
4545 * Hack -- load a screen dump from a file
4547 void do_cmd_load_screen(void)
4552 SYMBOL_CODE c = ' ';
4558 Term_get_size(&wid, &hgt);
4560 /* Build the filename */
4561 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4563 /* Append to the file */
4564 fff = my_fopen(buf, "r");
4567 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4575 /* Load the screen */
4576 for (y = 0; okay; y++)
4578 /* Get a line of data including control code */
4579 if (!fgets(buf, 1024, fff)) okay = FALSE;
4581 /* Get the blank line */
4582 if (buf[0] == '\n' || buf[0] == '\0') break;
4584 /* Ignore too large screen image */
4585 if (y >= hgt) continue;
4588 for (x = 0; x < wid - 1; x++)
4591 if (buf[x] == '\n' || buf[x] == '\0') break;
4593 /* Put the attr/char */
4594 Term_draw(x, y, TERM_WHITE, buf[x]);
4598 /* Dump the screen */
4599 for (y = 0; okay; y++)
4601 /* Get a line of data including control code */
4602 if (!fgets(buf, 1024, fff)) okay = FALSE;
4604 /* Get the blank line */
4605 if (buf[0] == '\n' || buf[0] == '\0') break;
4607 /* Ignore too large screen image */
4608 if (y >= hgt) continue;
4611 for (x = 0; x < wid - 1; x++)
4614 if (buf[x] == '\n' || buf[x] == '\0') break;
4616 /* Get the attr/char */
4617 (void)(Term_what(x, y, &a, &c));
4619 /* Look up the attr */
4620 for (i = 0; i < 16; i++)
4622 /* Use attr matches */
4623 if (hack[i] == buf[x]) a = (byte_hack)i;
4626 /* Put the attr/char */
4627 Term_draw(x, y, a, c);
4632 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4643 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4644 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4647 #define IM_FLAG_STR _("*", "* ")
4648 #define HAS_FLAG_STR _("+", "+ ")
4649 #define NO_FLAG_STR _("・", ". ")
4651 #define print_im_or_res_flag(IM, RES) \
4653 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4654 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4657 #define print_flag(TR) \
4659 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4663 /* XTRA HACK RESLIST */
4664 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4666 GAME_TEXT o_name[MAX_NLEN];
4667 BIT_FLAGS flgs[TR_FLAG_SIZE];
4669 if (!o_ptr->k_idx) return;
4670 if (o_ptr->tval != tval) return;
4672 /* Identified items only */
4673 if (!object_is_known(o_ptr)) return;
4676 * HACK:Ring of Lordly protection and Dragon equipment
4677 * have random resistances.
4679 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4680 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4681 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4682 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4683 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4684 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4685 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4686 || object_is_artifact(o_ptr))
4689 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4691 while (o_name[i] && (i < 26))
4694 if (iskanji(o_name[i])) i++;
4703 o_name[i] = ' '; i++;
4708 fprintf(fff, "%s %s", where, o_name);
4710 if (!(o_ptr->ident & (IDENT_MENTAL)))
4712 fputs(_("-------不明--------------- -------不明---------\n",
4713 "-------unknown------------ -------unknown------\n"), fff);
4717 object_flags_known(o_ptr, flgs);
4719 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4720 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4721 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4722 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4723 print_flag(TR_RES_POIS);
4724 print_flag(TR_RES_LITE);
4725 print_flag(TR_RES_DARK);
4726 print_flag(TR_RES_SHARDS);
4727 print_flag(TR_RES_SOUND);
4728 print_flag(TR_RES_NETHER);
4729 print_flag(TR_RES_NEXUS);
4730 print_flag(TR_RES_CHAOS);
4731 print_flag(TR_RES_DISEN);
4735 print_flag(TR_RES_BLIND);
4736 print_flag(TR_RES_FEAR);
4737 print_flag(TR_RES_CONF);
4738 print_flag(TR_FREE_ACT);
4739 print_flag(TR_SEE_INVIS);
4740 print_flag(TR_HOLD_EXP);
4741 print_flag(TR_TELEPATHY);
4742 print_flag(TR_SLOW_DIGEST);
4743 print_flag(TR_REGEN);
4744 print_flag(TR_LEVITATION);
4752 fprintf(fff, "%s\n", inven_res_label);
4758 * Display *ID* ed weapons/armors's resistances
4760 static void do_cmd_knowledge_inven(void)
4763 GAME_TEXT file_name[1024];
4765 OBJECT_TYPE_VALUE tval;
4771 /* Open a new file */
4772 fff = my_fopen_temp(file_name, 1024);
4775 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4779 fprintf(fff, "%s\n", inven_res_label);
4781 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4785 for (; j < 9; j++) fputc('\n', fff);
4787 fprintf(fff, "%s\n", inven_res_label);
4789 strcpy(where, _("装", "E "));
4790 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4792 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4794 strcpy(where, _("持", "I "));
4795 for (i = 0; i < INVEN_PACK; i++)
4797 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4800 st_ptr = &town_info[1].store[STORE_HOME];
4801 strcpy(where, _("家", "H "));
4802 for (i = 0; i < st_ptr->stock_num; i++)
4804 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4809 /* Display the file contents */
4810 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4815 void do_cmd_save_screen_html_aux(char *filename, int message)
4820 TERM_COLOR a = 0, old_a = 0;
4834 concptr html_head[] = {
4835 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4839 concptr html_foot[] = {
4841 "</body>\n</html>\n",
4847 Term_get_size(&wid, &hgt);
4849 /* File type is "TEXT" */
4850 FILE_TYPE(FILE_TYPE_TEXT);
4852 /* Append to the file */
4853 fff = my_fopen(filename, "w");
4857 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4863 if (message) screen_save();
4865 /* Build the filename */
4866 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4867 tmpfff = my_fopen(buf, "r");
4869 for (i = 0; html_head[i]; i++)
4870 fputs(html_head[i], fff);
4874 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4876 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4880 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4882 fprintf(fff, "%s\n", buf);
4887 /* Dump the screen */
4888 for (y = 0; y < hgt; y++)
4895 for (x = 0; x < wid - 1; x++)
4899 /* Get the attr/char */
4900 (void)(Term_what(x, y, &a, &c));
4904 case '&': cc = "&"; break;
4905 case '<': cc = "<"; break;
4906 case '>': cc = ">"; break;
4908 case 0x1f: c = '.'; break;
4909 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4914 if ((y == 0 && x == 0) || a != old_a) {
4915 rv = angband_color_table[a][1];
4916 gv = angband_color_table[a][2];
4917 bv = angband_color_table[a][3];
4918 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4919 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4923 fprintf(fff, "%s", cc);
4925 fprintf(fff, "%c", c);
4928 fprintf(fff, "</font>");
4931 for (i = 0; html_foot[i]; i++)
4932 fputs(html_foot[i], fff);
4937 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4939 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4943 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4945 fprintf(fff, "%s\n", buf);
4956 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4964 * Hack -- save a screen dump to a file
4966 static void do_cmd_save_screen_html(void)
4968 char buf[1024], tmp[256] = "screen.html";
4970 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4973 /* Build the filename */
4974 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4978 do_cmd_save_screen_html_aux(buf, 1);
4983 * Redefinable "save_screen" action
4985 void (*screendump_aux)(void) = NULL;
4989 * Hack -- save a screen dump to a file
4991 void do_cmd_save_screen(void)
4993 bool old_use_graphics = use_graphics;
4994 bool html_dump = FALSE;
4998 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5002 if (c == 'Y' || c == 'y')
5004 else if (c == 'H' || c == 'h')
5016 Term_get_size(&wid, &hgt);
5018 if (old_use_graphics)
5020 use_graphics = FALSE;
5022 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5028 do_cmd_save_screen_html();
5032 /* Do we use a special screendump function ? */
5033 else if (screendump_aux)
5035 /* Dump the screen to a graphics file */
5036 (*screendump_aux)();
5038 else /* Dump the screen as text */
5042 SYMBOL_CODE c = ' ';
5046 /* Build the filename */
5047 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5049 /* File type is "TEXT" */
5050 FILE_TYPE(FILE_TYPE_TEXT);
5052 /* Append to the file */
5053 fff = my_fopen(buf, "w");
5057 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5065 /* Dump the screen */
5066 for (y = 0; y < hgt; y++)
5069 for (x = 0; x < wid - 1; x++)
5071 /* Get the attr/char */
5072 (void)(Term_what(x, y, &a, &c));
5082 fprintf(fff, "%s\n", buf);
5089 /* Dump the screen */
5090 for (y = 0; y < hgt; y++)
5093 for (x = 0; x < wid - 1; x++)
5095 /* Get the attr/char */
5096 (void)(Term_what(x, y, &a, &c));
5099 buf[x] = hack[a&0x0F];
5106 fprintf(fff, "%s\n", buf);
5113 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5118 if (old_use_graphics)
5120 use_graphics = TRUE;
5122 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5129 * Sorting hook -- Comp function -- see below
5131 * We use "u" to point to array of monster indexes,
5132 * and "v" to select the type of sorting to perform on "u".
5134 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5136 u16b *who = (u16b*)(u);
5138 u16b *why = (u16b*)(v);
5145 /* Sort by total kills */
5148 /* Extract total kills */
5149 z1 = a_info[w1].tval;
5150 z2 = a_info[w2].tval;
5152 /* Compare total kills */
5153 if (z1 < z2) return (TRUE);
5154 if (z1 > z2) return (FALSE);
5158 /* Sort by monster level */
5161 /* Extract levels */
5162 z1 = a_info[w1].sval;
5163 z2 = a_info[w2].sval;
5165 /* Compare levels */
5166 if (z1 < z2) return (TRUE);
5167 if (z1 > z2) return (FALSE);
5171 /* Sort by monster experience */
5174 /* Extract experience */
5175 z1 = a_info[w1].level;
5176 z2 = a_info[w2].level;
5178 /* Compare experience */
5179 if (z1 < z2) return (TRUE);
5180 if (z1 > z2) return (FALSE);
5184 /* Compare indexes */
5190 * Sorting hook -- Swap function -- see below
5192 * We use "u" to point to array of monster indexes,
5193 * and "v" to select the type of sorting to perform.
5195 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5197 u16b *who = (u16b*)(u);
5212 * Check the status of "artifacts"
5214 static void do_cmd_knowledge_artifacts(void)
5224 GAME_TEXT file_name[1024];
5225 GAME_TEXT base_name[MAX_NLEN];
5229 /* Open a new file */
5230 fff = my_fopen_temp(file_name, 1024);
5233 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5238 /* Allocate the "who" array */
5239 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5241 /* Allocate the "okay" array */
5242 C_MAKE(okay, max_a_idx, bool);
5244 /* Scan the artifacts */
5245 for (k = 0; k < max_a_idx; k++)
5247 artifact_type *a_ptr = &a_info[k];
5252 /* Skip "empty" artifacts */
5253 if (!a_ptr->name) continue;
5255 /* Skip "uncreated" artifacts */
5256 if (!a_ptr->cur_num) continue;
5262 /* Check the dungeon */
5263 for (y = 0; y < current_floor_ptr->height; y++)
5265 for (x = 0; x < current_floor_ptr->width; x++)
5267 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5269 OBJECT_IDX this_o_idx, next_o_idx = 0;
5271 /* Scan all objects in the grid */
5272 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5275 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5276 next_o_idx = o_ptr->next_o_idx;
5278 /* Ignore non-artifacts */
5279 if (!object_is_fixed_artifact(o_ptr)) continue;
5281 /* Ignore known items */
5282 if (object_is_known(o_ptr)) continue;
5284 /* Note the artifact */
5285 okay[o_ptr->name1] = FALSE;
5290 /* Check the inventory and equipment */
5291 for (i = 0; i < INVEN_TOTAL; i++)
5293 object_type *o_ptr = &inventory[i];
5295 /* Ignore non-objects */
5296 if (!o_ptr->k_idx) continue;
5298 /* Ignore non-artifacts */
5299 if (!object_is_fixed_artifact(o_ptr)) continue;
5301 /* Ignore known items */
5302 if (object_is_known(o_ptr)) continue;
5304 /* Note the artifact */
5305 okay[o_ptr->name1] = FALSE;
5308 for (k = 0; k < max_a_idx; k++)
5310 if (okay[k]) who[n++] = k;
5313 /* Select the sort method */
5314 ang_sort_comp = ang_sort_art_comp;
5315 ang_sort_swap = ang_sort_art_swap;
5317 /* Sort the array by dungeon depth of monsters */
5318 ang_sort(who, &why, n);
5320 /* Scan the artifacts */
5321 for (k = 0; k < n; k++)
5323 artifact_type *a_ptr = &a_info[who[k]];
5326 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5328 /* Obtain the base object type */
5329 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5338 /* Create fake object */
5339 object_prep(q_ptr, z);
5341 /* Make it an artifact */
5342 q_ptr->name1 = (byte)who[k];
5344 /* Display as if known */
5345 q_ptr->ident |= IDENT_STORE;
5347 /* Describe the artifact */
5348 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5351 /* Hack -- Build the artifact name */
5352 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5355 /* Free the "who" array */
5356 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5358 /* Free the "okay" array */
5359 C_KILL(okay, max_a_idx, bool);
5362 /* Display the file contents */
5363 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5369 * Display known uniques
5370 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5372 static void do_cmd_knowledge_uniques(void)
5381 GAME_TEXT file_name[1024];
5384 int n_alive_surface = 0;
5385 int n_alive_over100 = 0;
5386 int n_alive_total = 0;
5389 for (i = 0; i < 10; i++) n_alive[i] = 0;
5391 /* Open a new file */
5392 fff = my_fopen_temp(file_name, 1024);
5396 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5401 /* Allocate the "who" array */
5402 C_MAKE(who, max_r_idx, MONRACE_IDX);
5404 /* Scan the monsters */
5405 for (i = 1; i < max_r_idx; i++)
5407 monster_race *r_ptr = &r_info[i];
5410 if (!r_ptr->name) continue;
5412 /* Require unique monsters */
5413 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5415 /* Only display "known" uniques */
5416 if (!cheat_know && !r_ptr->r_sights) continue;
5418 /* Only print rarity <= 100 uniques */
5419 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5421 /* Only "alive" uniques */
5422 if (r_ptr->max_num == 0) continue;
5426 lev = (r_ptr->level - 1) / 10;
5430 if (max_lev < lev) max_lev = lev;
5432 else n_alive_over100++;
5434 else n_alive_surface++;
5436 /* Collect "appropriate" monsters */
5440 /* Select the sort method */
5441 ang_sort_comp = ang_sort_comp_hook;
5442 ang_sort_swap = ang_sort_swap_hook;
5444 /* Sort the array by dungeon depth of monsters */
5445 ang_sort(who, &why, n);
5447 if (n_alive_surface)
5449 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5450 n_alive_total += n_alive_surface;
5452 for (i = 0; i <= max_lev; i++)
5454 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5455 n_alive_total += n_alive[i];
5457 if (n_alive_over100)
5459 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5460 n_alive_total += n_alive_over100;
5465 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5466 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5470 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5473 /* Scan the monster races */
5474 for (k = 0; k < n; k++)
5476 monster_race *r_ptr = &r_info[who[k]];
5478 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5481 /* Free the "who" array */
5482 C_KILL(who, max_r_idx, s16b);
5485 /* Display the file contents */
5486 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5492 * Display weapon-exp
5494 static void do_cmd_knowledge_weapon_exp(void)
5502 GAME_TEXT file_name[1024];
5505 /* Open a new file */
5506 fff = my_fopen_temp(file_name, 1024);
5508 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5513 for (i = 0; i < 5; i++)
5515 for (num = 0; num < 64; num++)
5517 for (j = 0; j < max_k_idx; j++)
5519 object_kind *k_ptr = &k_info[j];
5521 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5523 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5525 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5527 fprintf(fff, "%-25s ", tmp);
5528 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5529 else fprintf(fff, " ");
5530 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5531 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5540 /* Display the file contents */
5541 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5547 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5551 static void do_cmd_knowledge_spell_exp(void)
5558 const magic_type *s_ptr;
5560 GAME_TEXT file_name[1024];
5562 /* Open a new file */
5563 fff = my_fopen_temp(file_name, 1024);
5565 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5570 if (p_ptr->realm1 != REALM_NONE)
5572 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5573 for (i = 0; i < 32; i++)
5575 if (!is_magic(p_ptr->realm1))
5577 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5581 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5583 if (s_ptr->slevel >= 99) continue;
5584 spell_exp = p_ptr->spell_exp[i];
5585 exp_level = spell_exp_level(spell_exp);
5586 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5587 if (p_ptr->realm1 == REALM_HISSATSU)
5588 fprintf(fff, "[--]");
5591 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5592 else fprintf(fff, " ");
5593 fprintf(fff, "%s", exp_level_str[exp_level]);
5595 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5600 if (p_ptr->realm2 != REALM_NONE)
5602 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5603 for (i = 0; i < 32; i++)
5605 if (!is_magic(p_ptr->realm1))
5607 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5611 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5613 if (s_ptr->slevel >= 99) continue;
5615 spell_exp = p_ptr->spell_exp[i + 32];
5616 exp_level = spell_exp_level(spell_exp);
5617 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5618 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5619 else fprintf(fff, " ");
5620 fprintf(fff, "%s", exp_level_str[exp_level]);
5621 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5627 /* Display the file contents */
5628 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5634 * @brief スキル情報を表示するコマンドのメインルーチン /
5638 static void do_cmd_knowledge_skill_exp(void)
5640 int i = 0, skill_exp;
5644 char file_name[1024];
5645 char skill_name[GINOU_TEMPMAX][20] =
5647 _("マーシャルアーツ", "Martial Arts "),
5648 _("二刀流 ", "Dual Wielding "),
5649 _("乗馬 ", "Riding "),
5653 /* Open a new file */
5654 fff = my_fopen_temp(file_name, 1024);
5656 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5661 for (i = 0; i < GINOU_TEMPMAX; i++)
5663 skill_exp = p_ptr->skill_exp[i];
5664 fprintf(fff, "%-20s ", skill_name[i]);
5665 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5666 else fprintf(fff, " ");
5667 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5668 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5673 /* Display the file contents */
5674 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5680 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5681 * @param Name 変換したい文字列の参照ポインタ
5684 void plural_aux(char *Name)
5686 int NameLen = strlen(Name);
5688 if (my_strstr(Name, "Disembodied hand"))
5690 strcpy(Name, "Disembodied hands that strangled people");
5692 else if (my_strstr(Name, "Colour out of space"))
5694 strcpy(Name, "Colours out of space");
5696 else if (my_strstr(Name, "stairway to hell"))
5698 strcpy(Name, "stairways to hell");
5700 else if (my_strstr(Name, "Dweller on the threshold"))
5702 strcpy(Name, "Dwellers on the threshold");
5704 else if (my_strstr(Name, " of "))
5706 concptr aider = my_strstr(Name, " of ");
5717 if (dummy[i-1] == 's')
5719 strcpy(&(dummy[i]), "es");
5724 strcpy(&(dummy[i]), "s");
5727 strcpy(&(dummy[i+1]), aider);
5728 strcpy(Name, dummy);
5730 else if (my_strstr(Name, "coins"))
5733 strcpy(dummy, "piles of ");
5734 strcat(dummy, Name);
5735 strcpy(Name, dummy);
5738 else if (my_strstr(Name, "Manes"))
5742 else if (streq(&(Name[NameLen - 2]), "ey"))
5744 strcpy(&(Name[NameLen - 2]), "eys");
5746 else if (Name[NameLen - 1] == 'y')
5748 strcpy(&(Name[NameLen - 1]), "ies");
5750 else if (streq(&(Name[NameLen - 4]), "ouse"))
5752 strcpy(&(Name[NameLen - 4]), "ice");
5754 else if (streq(&(Name[NameLen - 2]), "us"))
5756 strcpy(&(Name[NameLen - 2]), "i");
5758 else if (streq(&(Name[NameLen - 6]), "kelman"))
5760 strcpy(&(Name[NameLen - 6]), "kelmen");
5762 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5764 strcpy(&(Name[NameLen - 8]), "wordsmen");
5766 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5768 strcpy(&(Name[NameLen - 7]), "oodsmen");
5770 else if (streq(&(Name[NameLen - 7]), "eastman"))
5772 strcpy(&(Name[NameLen - 7]), "eastmen");
5774 else if (streq(&(Name[NameLen - 8]), "izardman"))
5776 strcpy(&(Name[NameLen - 8]), "izardmen");
5778 else if (streq(&(Name[NameLen - 5]), "geist"))
5780 strcpy(&(Name[NameLen - 5]), "geister");
5782 else if (streq(&(Name[NameLen - 2]), "ex"))
5784 strcpy(&(Name[NameLen - 2]), "ices");
5786 else if (streq(&(Name[NameLen - 2]), "lf"))
5788 strcpy(&(Name[NameLen - 2]), "lves");
5790 else if (suffix(Name, "ch") ||
5791 suffix(Name, "sh") ||
5792 suffix(Name, "nx") ||
5793 suffix(Name, "s") ||
5796 strcpy(&(Name[NameLen]), "es");
5800 strcpy(&(Name[NameLen]), "s");
5805 * @brief 現在のペットを表示するコマンドのメインルーチン /
5806 * Display current pets
5809 static void do_cmd_knowledge_pets(void)
5813 monster_type *m_ptr;
5814 GAME_TEXT pet_name[MAX_NLEN];
5816 int show_upkeep = 0;
5817 GAME_TEXT file_name[1024];
5820 /* Open a new file */
5821 fff = my_fopen_temp(file_name, 1024);
5823 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5828 /* Process the monsters (backwards) */
5829 for (i = m_max - 1; i >= 1; i--)
5831 /* Access the monster */
5832 m_ptr = ¤t_floor_ptr->m_list[i];
5834 /* Ignore "dead" monsters */
5835 if (!m_ptr->r_idx) continue;
5837 /* Calculate "upkeep" for pets */
5841 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5842 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5846 show_upkeep = calculate_upkeep();
5848 fprintf(fff, "----------------------------------------------\n");
5850 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5852 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5854 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5859 /* Display the file contents */
5860 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5866 * @brief 現在のペットを表示するコマンドのメインルーチン /
5869 * @note the player ghosts are ignored.
5871 static void do_cmd_knowledge_kill_count(void)
5878 GAME_TEXT file_name[1024];
5883 /* Open a new file */
5884 fff = my_fopen_temp(file_name, 1024);
5887 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5892 /* Allocate the "who" array */
5893 C_MAKE(who, max_r_idx, MONRACE_IDX);
5896 /* Monsters slain */
5899 for (kk = 1; kk < max_r_idx; kk++)
5901 monster_race *r_ptr = &r_info[kk];
5903 if (r_ptr->flags1 & (RF1_UNIQUE))
5905 bool dead = (r_ptr->max_num == 0);
5914 MONSTER_NUMBER This = r_ptr->r_pkills;
5924 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5927 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5929 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5935 /* Scan the monsters */
5936 for (i = 1; i < max_r_idx; i++)
5938 monster_race *r_ptr = &r_info[i];
5940 /* Use that monster */
5941 if (r_ptr->name) who[n++] = i;
5944 /* Select the sort method */
5945 ang_sort_comp = ang_sort_comp_hook;
5946 ang_sort_swap = ang_sort_swap_hook;
5948 /* Sort the array by dungeon depth of monsters */
5949 ang_sort(who, &why, n);
5951 /* Scan the monster races */
5952 for (k = 0; k < n; k++)
5954 monster_race *r_ptr = &r_info[who[k]];
5956 if (r_ptr->flags1 & (RF1_UNIQUE))
5958 bool dead = (r_ptr->max_num == 0);
5962 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5968 MONSTER_NUMBER This = r_ptr->r_pkills;
5973 /* p,tは人と数える by ita */
5974 if (my_strchr("pt", r_ptr->d_char))
5975 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5977 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5981 if (my_strstr(r_name + r_ptr->name, "coins"))
5983 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5987 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5993 strcpy(ToPlural, (r_name + r_ptr->name));
5994 plural_aux(ToPlural);
5995 fprintf(fff, " %d %s\n", This, ToPlural);
6005 fprintf(fff,"----------------------------------------------\n");
6007 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6009 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6013 /* Free the "who" array */
6014 C_KILL(who, max_r_idx, s16b);
6017 /* Display the file contents */
6018 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6024 * @brief モンスター情報リスト中のグループを表示する /
6025 * Display the object groups.
6029 * @param per_page リストの表示行
6030 * @param grp_idx グループのID配列
6031 * @param group_text グループ名の文字列配列
6032 * @param grp_cur 現在の選択ID
6033 * @param grp_top 現在の選択リスト最上部ID
6036 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)
6040 /* Display lines until done */
6041 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6043 /* Get the group index */
6044 int grp = grp_idx[grp_top + i];
6046 /* Choose a color */
6047 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6049 /* Erase the entire line */
6050 Term_erase(col, row + i, wid);
6052 /* Display the group label */
6053 c_put_str(attr, group_text[grp], row + i, col);
6059 * Move the cursor in a browser window
6061 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6062 IDX *list_cur, int list_cnt)
6067 IDX list = *list_cur;
6069 /* Extract direction */
6072 /* Hack -- scroll up full screen */
6077 /* Hack -- scroll down full screen */
6082 d = get_keymap_dir(ch);
6087 /* Diagonals - hack */
6088 if ((ddx[d] > 0) && ddy[d])
6093 Term_get_size(&wid, &hgt);
6095 browser_rows = hgt - 8;
6097 /* Browse group list */
6102 /* Move up or down */
6103 grp += ddy[d] * (browser_rows - 1);
6106 if (grp >= grp_cnt) grp = grp_cnt - 1;
6107 if (grp < 0) grp = 0;
6108 if (grp != old_grp) list = 0;
6111 /* Browse sub-list list */
6114 /* Move up or down */
6115 list += ddy[d] * browser_rows;
6118 if (list >= list_cnt) list = list_cnt - 1;
6119 if (list < 0) list = 0;
6131 if (col < 0) col = 0;
6132 if (col > 1) col = 1;
6139 /* Browse group list */
6144 /* Move up or down */
6148 if (grp >= grp_cnt) grp = grp_cnt - 1;
6149 if (grp < 0) grp = 0;
6150 if (grp != old_grp) list = 0;
6153 /* Browse sub-list list */
6156 /* Move up or down */
6157 list += (IDX)ddy[d];
6160 if (list >= list_cnt) list = list_cnt - 1;
6161 if (list < 0) list = 0;
6172 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6176 /* Clear the display lines */
6177 for (i = 0; i < height; i++)
6179 Term_erase(col, row + i, width);
6182 /* Bigtile mode uses double width */
6183 if (use_bigtile) width /= 2;
6185 /* Display lines until done */
6186 for (i = 0; i < height; i++)
6188 /* Display columns until done */
6189 for (j = 0; j < width; j++)
6193 TERM_LEN x = col + j;
6194 TERM_LEN y = row + i;
6196 /* Bigtile mode uses double width */
6197 if (use_bigtile) x += j;
6202 /* Ignore illegal characters */
6203 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6204 (!use_graphics && ic > 0x7f))
6210 /* Force correct code for both ASCII character and tile */
6211 if (c & 0x80) a |= 0x80;
6213 /* Display symbol */
6214 Term_queue_bigchar(x, y, a, c, 0, 0);
6221 * Place the cursor at the collect position for visual mode
6223 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6225 int i = (a & 0x7f) - attr_top;
6226 int j = c - char_left;
6228 TERM_LEN x = col + j;
6229 TERM_LEN y = row + i;
6231 /* Bigtile mode uses double width */
6232 if (use_bigtile) x += j;
6234 /* Place the cursor */
6240 * Clipboard variables for copy&paste in visual mode
6242 static TERM_COLOR attr_idx = 0;
6243 static SYMBOL_CODE char_idx = 0;
6245 /* Hack -- for feature lighting */
6246 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6247 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6250 * Do visual mode command -- Change symbols
6252 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6253 int height, int width,
6254 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6255 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6257 static TERM_COLOR attr_old = 0;
6258 static SYMBOL_CODE char_old = 0;
6263 if (*visual_list_ptr)
6266 *cur_attr_ptr = attr_old;
6267 *cur_char_ptr = char_old;
6268 *visual_list_ptr = FALSE;
6276 if (*visual_list_ptr)
6279 *visual_list_ptr = FALSE;
6280 *need_redraw = TRUE;
6288 if (!*visual_list_ptr)
6290 *visual_list_ptr = TRUE;
6292 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6293 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6295 attr_old = *cur_attr_ptr;
6296 char_old = *cur_char_ptr;
6307 /* Set the visual */
6308 attr_idx = *cur_attr_ptr;
6309 char_idx = *cur_char_ptr;
6311 /* Hack -- for feature lighting */
6312 for (i = 0; i < F_LIT_MAX; i++)
6314 attr_idx_feat[i] = 0;
6315 char_idx_feat[i] = 0;
6322 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6325 *cur_attr_ptr = attr_idx;
6326 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6327 if (!*visual_list_ptr) *need_redraw = TRUE;
6333 *cur_char_ptr = char_idx;
6334 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6335 if (!*visual_list_ptr) *need_redraw = TRUE;
6341 if (*visual_list_ptr)
6344 int d = get_keymap_dir(ch);
6345 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6346 SYMBOL_CODE c = *cur_char_ptr;
6348 if (use_bigtile) eff_width = width / 2;
6349 else eff_width = width;
6351 /* Restrict direction */
6352 if ((a == 0) && (ddy[d] < 0)) d = 0;
6353 if ((c == 0) && (ddx[d] < 0)) d = 0;
6354 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6355 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6357 a += (TERM_COLOR)ddy[d];
6358 c += (SYMBOL_CODE)ddx[d];
6360 /* Force correct code for both ASCII character and tile */
6361 if (c & 0x80) a |= 0x80;
6363 /* Set the visual */
6368 /* Move the frame */
6369 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6370 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6371 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6372 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6378 /* Visual mode command is not used */
6384 * Display the monsters in a group.
6386 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6387 int mon_cur, int mon_top, bool visual_only)
6391 /* Display lines until done */
6392 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6396 /* Get the race index */
6397 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6399 /* Access the race */
6400 monster_race *r_ptr = &r_info[r_idx];
6402 /* Choose a color */
6403 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6405 /* Display the name */
6406 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6408 /* Hack -- visual_list mode */
6411 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6413 if (p_ptr->wizard || visual_only)
6415 c_prt(attr, format("%d", r_idx), row + i, 62);
6418 /* Erase chars before overwritten by the race letter */
6419 Term_erase(69, row + i, 255);
6421 /* Display symbol */
6422 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6427 if (!(r_ptr->flags1 & RF1_UNIQUE))
6428 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6430 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6431 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6435 /* Clear remaining lines */
6436 for (; i < per_page; i++)
6438 Term_erase(col, row + i, 255);
6444 * Display known monsters.
6446 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6450 IDX grp_cur, grp_top, old_grp_cur;
6451 IDX mon_cur, mon_top;
6452 IDX grp_cnt, grp_idx[100];
6460 bool visual_list = FALSE;
6461 TERM_COLOR attr_top = 0;
6469 Term_get_size(&wid, &hgt);
6471 browser_rows = hgt - 8;
6473 /* Allocate the "mon_idx" array */
6474 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6479 if (direct_r_idx < 0)
6481 mode = visual_only ? 0x03 : 0x01;
6483 /* Check every group */
6484 for (i = 0; monster_group_text[i] != NULL; i++)
6486 /* Measure the label */
6487 len = strlen(monster_group_text[i]);
6489 /* Save the maximum length */
6490 if (len > max) max = len;
6492 /* See if any monsters are known */
6493 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6495 /* Build a list of groups with known monsters */
6496 grp_idx[grp_cnt++] = i;
6504 mon_idx[0] = direct_r_idx;
6507 /* Terminate the list */
6510 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6511 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6514 /* Terminate the list */
6515 grp_idx[grp_cnt] = -1;
6518 grp_cur = grp_top = 0;
6519 mon_cur = mon_top = 0;
6524 mode = visual_only ? 0x02 : 0x00;
6529 monster_race *r_ptr;
6534 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6535 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6536 prt(_("名前", "Name"), 4, max + 3);
6537 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6538 prt(_("文字", "Sym"), 4, 67);
6539 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6541 for (i = 0; i < 78; i++)
6543 Term_putch(i, 5, TERM_WHITE, '=');
6546 if (direct_r_idx < 0)
6548 for (i = 0; i < browser_rows; i++)
6550 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6557 if (direct_r_idx < 0)
6559 /* Scroll group list */
6560 if (grp_cur < grp_top) grp_top = grp_cur;
6561 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6563 /* Display a list of monster groups */
6564 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6566 if (old_grp_cur != grp_cur)
6568 old_grp_cur = grp_cur;
6570 /* Get a list of monsters in the current group */
6571 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6574 /* Scroll monster list */
6575 while (mon_cur < mon_top)
6576 mon_top = MAX(0, mon_top - browser_rows/2);
6577 while (mon_cur >= mon_top + browser_rows)
6578 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6583 /* Display a list of monsters in the current group */
6584 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6590 /* Display a monster name */
6591 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6593 /* Display visual list below first monster */
6594 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6598 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6599 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6600 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6601 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6604 /* Get the current monster */
6605 r_ptr = &r_info[mon_idx[mon_cur]];
6609 /* Mega Hack -- track this monster race */
6610 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6616 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6620 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6624 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6629 /* Do visual mode command if needed */
6630 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))
6632 if (direct_r_idx >= 0)
6657 /* Recall on screen */
6658 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6660 screen_roff(mon_idx[mon_cur], 0);
6671 /* Move the cursor */
6672 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6679 /* Free the "mon_idx" array */
6680 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6685 * Display the objects in a group.
6687 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6688 int object_cur, int object_top, bool visual_only)
6692 /* Display lines until done */
6693 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6695 GAME_TEXT o_name[MAX_NLEN];
6698 object_kind *flavor_k_ptr;
6700 /* Get the object index */
6701 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6703 /* Access the object */
6704 object_kind *k_ptr = &k_info[k_idx];
6706 /* Choose a color */
6707 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6708 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6711 if (!visual_only && k_ptr->flavor)
6713 /* Appearance of this object is shuffled */
6714 flavor_k_ptr = &k_info[k_ptr->flavor];
6718 /* Appearance of this object is very normal */
6719 flavor_k_ptr = k_ptr;
6724 attr = ((i + object_top == object_cur) ? cursor : attr);
6726 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6729 strip_name(o_name, k_idx);
6734 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6737 /* Display the name */
6738 c_prt(attr, o_name, row + i, col);
6740 /* Hack -- visual_list mode */
6743 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);
6745 if (p_ptr->wizard || visual_only)
6747 c_prt(attr, format("%d", k_idx), row + i, 70);
6750 a = flavor_k_ptr->x_attr;
6751 c = flavor_k_ptr->x_char;
6753 /* Display symbol */
6754 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6757 /* Clear remaining lines */
6758 for (; i < per_page; i++)
6760 Term_erase(col, row + i, 255);
6765 * Describe fake object
6767 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6770 object_type object_type_body;
6771 o_ptr = &object_type_body;
6774 /* Create the artifact */
6775 object_prep(o_ptr, k_idx);
6777 /* It's fully know */
6778 o_ptr->ident |= IDENT_KNOWN;
6780 /* Track the object */
6781 /* object_actual_track(o_ptr); */
6783 /* Hack - mark as fake */
6784 /* term_obj_real = FALSE; */
6787 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6789 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6797 * Display known objects
6799 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6803 IDX grp_cur, grp_top, old_grp_cur;
6804 IDX object_old, object_cur, object_top;
6808 OBJECT_IDX *object_idx;
6814 bool visual_list = FALSE;
6815 TERM_COLOR attr_top = 0;
6823 Term_get_size(&wid, &hgt);
6825 browser_rows = hgt - 8;
6827 /* Allocate the "object_idx" array */
6828 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6833 if (direct_k_idx < 0)
6835 mode = visual_only ? 0x03 : 0x01;
6837 /* Check every group */
6838 for (i = 0; object_group_text[i] != NULL; i++)
6840 /* Measure the label */
6841 len = strlen(object_group_text[i]);
6843 /* Save the maximum length */
6844 if (len > max) max = len;
6846 /* See if any monsters are known */
6847 if (collect_objects(i, object_idx, mode))
6849 /* Build a list of groups with known monsters */
6850 grp_idx[grp_cnt++] = i;
6859 object_kind *k_ptr = &k_info[direct_k_idx];
6860 object_kind *flavor_k_ptr;
6862 if (!visual_only && k_ptr->flavor)
6864 /* Appearance of this object is shuffled */
6865 flavor_k_ptr = &k_info[k_ptr->flavor];
6869 /* Appearance of this object is very normal */
6870 flavor_k_ptr = k_ptr;
6873 object_idx[0] = direct_k_idx;
6874 object_old = direct_k_idx;
6877 /* Terminate the list */
6880 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6881 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6884 /* Terminate the list */
6885 grp_idx[grp_cnt] = -1;
6888 grp_cur = grp_top = 0;
6889 object_cur = object_top = 0;
6894 mode = visual_only ? 0x02 : 0x00;
6899 object_kind *k_ptr, *flavor_k_ptr;
6906 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6907 if (direct_k_idx < 0) prt("グループ", 4, 0);
6908 prt("名前", 4, max + 3);
6909 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6912 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6913 if (direct_k_idx < 0) prt("Group", 4, 0);
6914 prt("Name", 4, max + 3);
6915 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6919 for (i = 0; i < 78; i++)
6921 Term_putch(i, 5, TERM_WHITE, '=');
6924 if (direct_k_idx < 0)
6926 for (i = 0; i < browser_rows; i++)
6928 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6935 if (direct_k_idx < 0)
6937 /* Scroll group list */
6938 if (grp_cur < grp_top) grp_top = grp_cur;
6939 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6941 /* Display a list of object groups */
6942 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6944 if (old_grp_cur != grp_cur)
6946 old_grp_cur = grp_cur;
6948 /* Get a list of objects in the current group */
6949 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6952 /* Scroll object list */
6953 while (object_cur < object_top)
6954 object_top = MAX(0, object_top - browser_rows/2);
6955 while (object_cur >= object_top + browser_rows)
6956 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6961 /* Display a list of objects in the current group */
6962 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6966 object_top = object_cur;
6968 /* Display a list of objects in the current group */
6969 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6971 /* Display visual list below first object */
6972 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6975 /* Get the current object */
6976 k_ptr = &k_info[object_idx[object_cur]];
6978 if (!visual_only && k_ptr->flavor)
6980 /* Appearance of this object is shuffled */
6981 flavor_k_ptr = &k_info[k_ptr->flavor];
6985 /* Appearance of this object is very normal */
6986 flavor_k_ptr = k_ptr;
6991 prt(format("<方向>%s%s%s, ESC",
6992 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6993 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6994 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6997 prt(format("<dir>%s%s%s, ESC",
6998 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6999 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7000 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7006 /* Mega Hack -- track this object */
7007 if (object_cnt) object_kind_track(object_idx[object_cur]);
7009 /* The "current" object changed */
7010 if (object_old != object_idx[object_cur])
7014 /* Remember the "current" object */
7015 object_old = object_idx[object_cur];
7021 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7025 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7029 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7034 /* Do visual mode command if needed */
7035 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))
7037 if (direct_k_idx >= 0)
7062 /* Recall on screen */
7063 if (!visual_list && !visual_only && (grp_cnt > 0))
7065 desc_obj_fake(object_idx[object_cur]);
7073 /* Move the cursor */
7074 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7080 /* Free the "object_idx" array */
7081 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
7086 * Display the features in a group.
7088 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7089 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7091 int lit_col[F_LIT_MAX], i, j;
7092 int f_idx_col = use_bigtile ? 62 : 64;
7094 /* Correct columns 1 and 4 */
7095 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7096 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7097 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7099 /* Display lines until done */
7100 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7105 FEAT_IDX f_idx = feat_idx[feat_top + i];
7107 /* Access the index */
7108 feature_type *f_ptr = &f_info[f_idx];
7110 int row_i = row + i;
7112 /* Choose a color */
7113 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7115 /* Display the name */
7116 c_prt(attr, f_name + f_ptr->name, row_i, col);
7118 /* Hack -- visual_list mode */
7121 /* Display lighting level */
7122 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7124 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));
7126 if (p_ptr->wizard || visual_only)
7128 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7131 /* Display symbol */
7132 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);
7134 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7135 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7137 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7139 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7141 /* Mega-hack -- Use non-standard colour */
7142 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7144 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7148 /* Clear remaining lines */
7149 for (; i < per_page; i++)
7151 Term_erase(col, row + i, 255);
7157 * Interact with feature visuals.
7159 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7163 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7164 FEAT_IDX feat_cur, feat_top;
7166 FEAT_IDX grp_idx[100];
7170 TERM_LEN column = 0;
7174 bool visual_list = FALSE;
7175 TERM_COLOR attr_top = 0;
7178 TERM_LEN browser_rows;
7181 TERM_COLOR attr_old[F_LIT_MAX];
7182 SYMBOL_CODE char_old[F_LIT_MAX];
7183 TERM_COLOR *cur_attr_ptr;
7184 SYMBOL_CODE *cur_char_ptr;
7186 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7187 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7189 Term_get_size(&wid, &hgt);
7191 browser_rows = hgt - 8;
7193 /* Allocate the "feat_idx" array */
7194 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7199 if (direct_f_idx < 0)
7201 /* Check every group */
7202 for (i = 0; feature_group_text[i] != NULL; i++)
7204 /* Measure the label */
7205 len = strlen(feature_group_text[i]);
7207 /* Save the maximum length */
7208 if (len > max) max = len;
7210 /* See if any features are known */
7211 if (collect_features(i, feat_idx, 0x01))
7213 /* Build a list of groups with known features */
7214 grp_idx[grp_cnt++] = i;
7222 feature_type *f_ptr = &f_info[direct_f_idx];
7224 feat_idx[0] = direct_f_idx;
7227 /* Terminate the list */
7230 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7231 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7233 for (i = 0; i < F_LIT_MAX; i++)
7235 attr_old[i] = f_ptr->x_attr[i];
7236 char_old[i] = f_ptr->x_char[i];
7240 /* Terminate the list */
7241 grp_idx[grp_cnt] = -1;
7244 grp_cur = grp_top = 0;
7245 feat_cur = feat_top = 0;
7253 feature_type *f_ptr;
7259 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7260 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7261 prt(_("名前", "Name"), 4, max + 3);
7264 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7265 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7269 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7270 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7273 for (i = 0; i < 78; i++)
7275 Term_putch(i, 5, TERM_WHITE, '=');
7278 if (direct_f_idx < 0)
7280 for (i = 0; i < browser_rows; i++)
7282 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7289 if (direct_f_idx < 0)
7291 /* Scroll group list */
7292 if (grp_cur < grp_top) grp_top = grp_cur;
7293 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7295 /* Display a list of feature groups */
7296 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7298 if (old_grp_cur != grp_cur)
7300 old_grp_cur = grp_cur;
7302 /* Get a list of features in the current group */
7303 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7306 /* Scroll feature list */
7307 while (feat_cur < feat_top)
7308 feat_top = MAX(0, feat_top - browser_rows/2);
7309 while (feat_cur >= feat_top + browser_rows)
7310 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7315 /* Display a list of features in the current group */
7316 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7320 feat_top = feat_cur;
7322 /* Display a list of features in the current group */
7323 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7325 /* Display visual list below first object */
7326 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7330 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7331 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7332 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7335 /* Get the current feature */
7336 f_ptr = &f_info[feat_idx[feat_cur]];
7337 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7338 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7342 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7346 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7350 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7355 if (visual_list && ((ch == 'A') || (ch == 'a')))
7357 int prev_lighting_level = *lighting_level;
7361 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7362 else (*lighting_level)--;
7366 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7367 else (*lighting_level)++;
7370 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7371 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7373 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7374 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7379 else if ((ch == 'D') || (ch == 'd'))
7381 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7382 byte prev_x_char = f_ptr->x_char[*lighting_level];
7384 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7388 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7389 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7391 if (prev_x_char != f_ptr->x_char[*lighting_level])
7392 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7394 else *need_redraw = TRUE;
7399 /* Do visual mode command if needed */
7400 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))
7404 /* Restore previous visual settings */
7406 for (i = 0; i < F_LIT_MAX; i++)
7408 f_ptr->x_attr[i] = attr_old[i];
7409 f_ptr->x_char[i] = char_old[i];
7416 if (direct_f_idx >= 0) flag = TRUE;
7417 else *lighting_level = F_LIT_STANDARD;
7420 /* Preserve current visual settings */
7423 for (i = 0; i < F_LIT_MAX; i++)
7425 attr_old[i] = f_ptr->x_attr[i];
7426 char_old[i] = f_ptr->x_char[i];
7428 *lighting_level = F_LIT_STANDARD;
7435 for (i = 0; i < F_LIT_MAX; i++)
7437 attr_idx_feat[i] = f_ptr->x_attr[i];
7438 char_idx_feat[i] = f_ptr->x_char[i];
7447 /* Allow TERM_DARK text */
7448 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7450 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7451 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7469 /* Move the cursor */
7470 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7476 /* Free the "feat_idx" array */
7477 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7482 * List wanted monsters
7484 static void do_cmd_knowledge_kubi(void)
7489 GAME_TEXT file_name[1024];
7492 /* Open a new file */
7493 fff = my_fopen_temp(file_name, 1024);
7495 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7502 bool listed = FALSE;
7504 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7505 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7507 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7508 fprintf(fff, "----------------------------------------------\n");
7510 for (i = 0; i < MAX_KUBI; i++)
7512 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7514 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7522 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7527 /* Display the file contents */
7528 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7533 * List virtues & status
7535 static void do_cmd_knowledge_virtues(void)
7538 GAME_TEXT file_name[1024];
7540 /* Open a new file */
7541 fff = my_fopen_temp(file_name, 1024);
7543 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7550 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7555 /* Display the file contents */
7556 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7563 static void do_cmd_knowledge_dungeon(void)
7567 GAME_TEXT file_name[1024];
7570 /* Open a new file */
7571 fff = my_fopen_temp(file_name, 1024);
7573 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7580 for (i = 1; i < max_d_idx; i++)
7584 if (!d_info[i].maxdepth) continue;
7585 if (!max_dlv[i]) continue;
7586 if (d_info[i].final_guardian)
7588 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7590 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7592 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7597 /* Display the file contents */
7598 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7603 * List virtues & status
7606 static void do_cmd_knowledge_stat(void)
7610 GAME_TEXT file_name[1024];
7613 /* Open a new file */
7614 fff = my_fopen_temp(file_name, 1024);
7616 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7623 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7624 (2 * p_ptr->hitdie +
7625 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7627 if (p_ptr->knowledge & KNOW_HPRATE)
7628 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7629 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7631 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7632 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7634 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);
7635 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7642 /* Display the file contents */
7643 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7649 * Print all active quests
7651 static void do_cmd_knowledge_quests_current(FILE *fff)
7654 char rand_tmp_str[120] = "\0";
7655 GAME_TEXT name[MAX_NLEN];
7656 monster_race *r_ptr;
7658 int rand_level = 100;
7661 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7663 for (i = 1; i < max_q_idx; i++)
7665 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7666 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7667 (quest[i].status == QUEST_STATUS_COMPLETED))
7669 /* Set the quest number temporary */
7670 QUEST_IDX old_quest = p_ptr->inside_quest;
7673 /* Clear the text */
7674 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7675 quest_text_line = 0;
7677 p_ptr->inside_quest = i;
7679 /* Get the quest text */
7680 init_flags = INIT_SHOW_TEXT;
7682 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7684 /* Reset the old quest number */
7685 p_ptr->inside_quest = old_quest;
7687 /* No info from "silent" quests */
7688 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7692 if (quest[i].type != QUEST_TYPE_RANDOM)
7694 char note[80] = "\0";
7696 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7698 switch (quest[i].type)
7700 case QUEST_TYPE_KILL_LEVEL:
7701 case QUEST_TYPE_KILL_ANY_LEVEL:
7702 r_ptr = &r_info[quest[i].r_idx];
7703 strcpy(name, r_name + r_ptr->name);
7704 if (quest[i].max_num > 1)
7707 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7708 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7711 sprintf(note," - kill %d %s, have killed %d.",
7712 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7716 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7719 case QUEST_TYPE_FIND_ARTIFACT:
7722 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7724 object_type *q_ptr = &forge;
7725 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7726 object_prep(q_ptr, k_idx);
7727 q_ptr->name1 = quest[i].k_idx;
7728 q_ptr->ident = IDENT_STORE;
7729 object_desc(name, q_ptr, OD_NAME_ONLY);
7731 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7733 case QUEST_TYPE_FIND_EXIT:
7734 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7737 case QUEST_TYPE_KILL_NUMBER:
7739 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7740 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7742 sprintf(note," - Kill %d monsters, have killed %d.",
7743 (int)quest[i].max_num, (int)quest[i].cur_num);
7747 case QUEST_TYPE_KILL_ALL:
7748 case QUEST_TYPE_TOWER:
7749 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7754 /* Print the quest info */
7755 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7756 quest[i].name, (int)quest[i].level, note);
7758 fputs(tmp_str, fff);
7760 if (quest[i].status == QUEST_STATUS_COMPLETED)
7762 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7763 fputs(tmp_str, fff);
7769 while (quest_text[j][0] && j < 10)
7771 fprintf(fff, " %s\n", quest_text[j]);
7776 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7779 rand_level = quest[i].level;
7781 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7783 /* Print the quest info */
7784 r_ptr = &r_info[quest[i].r_idx];
7785 strcpy(name, r_name + r_ptr->name);
7787 if (quest[i].max_num > 1)
7790 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7791 quest[i].name, (int)quest[i].level,
7792 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7796 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7797 quest[i].name, (int)quest[i].level,
7798 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7803 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7804 quest[i].name, (int)quest[i].level, name);
7811 /* Print the current random quest */
7812 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7814 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7818 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7821 char playtime_str[16];
7822 quest_type* const q_ptr = &quest[q_idx];
7824 if (is_fixed_quest_idx(q_idx))
7826 /* Set the quest number temporary */
7827 IDX old_quest = p_ptr->inside_quest;
7829 p_ptr->inside_quest = q_idx;
7832 init_flags = INIT_NAME_ONLY;
7834 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7836 /* Reset the old quest number */
7837 p_ptr->inside_quest = old_quest;
7839 /* No info from "silent" quests */
7840 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7843 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7844 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7846 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7848 /* Print the quest info */
7849 if (q_ptr->complev == 0)
7852 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7853 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7854 r_name+r_info[q_ptr->r_idx].name,
7855 (int)q_ptr->level, playtime_str);
7860 _(" %-35s (%3d階) - レベル%2d - %s\n",
7861 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7862 r_name+r_info[q_ptr->r_idx].name,
7870 /* Print the quest info */
7872 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7873 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7874 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7877 fputs(tmp_str, fff);
7883 * Print all finished quests
7885 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7888 QUEST_IDX total = 0;
7890 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7891 for (i = 1; i < max_q_idx; i++)
7893 QUEST_IDX q_idx = quest_num[i];
7894 quest_type* const q_ptr = &quest[q_idx];
7896 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7901 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7906 * Print all failed quests
7908 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7911 QUEST_IDX total = 0;
7913 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7914 for (i = 1; i < max_q_idx; i++)
7916 QUEST_IDX q_idx = quest_num[i];
7917 quest_type* const q_ptr = &quest[q_idx];
7919 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7920 do_cmd_knowledge_quests_aux(fff, q_idx))
7925 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7930 * Print all random quests
7932 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7934 GAME_TEXT tmp_str[120];
7936 QUEST_IDX total = 0;
7938 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7939 for (i = 1; i < max_q_idx; i++)
7941 /* No info from "silent" quests */
7942 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7944 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7948 /* Print the quest info */
7949 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7950 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7951 fputs(tmp_str, fff);
7954 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7958 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7960 QUEST_IDX *q_num = (QUEST_IDX *)u;
7961 quest_type *qa = &quest[q_num[a]];
7962 quest_type *qb = &quest[q_num[b]];
7967 return (qa->comptime != qb->comptime) ?
7968 (qa->comptime < qb->comptime) :
7969 (qa->level <= qb->level);
7972 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
7974 QUEST_IDX *q_num = (QUEST_IDX *)u;
7981 q_num[a] = q_num[b];
7987 * Print quest status of all active quests
7989 static void do_cmd_knowledge_quests(void)
7992 GAME_TEXT file_name[1024];
7997 /* Open a new file */
7998 fff = my_fopen_temp(file_name, 1024);
8001 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8006 /* Allocate Memory */
8007 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8009 /* Sort by compete level */
8010 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8011 ang_sort_comp = ang_sort_comp_quest_num;
8012 ang_sort_swap = ang_sort_swap_quest_num;
8013 ang_sort(quest_num, &dummy, max_q_idx);
8015 /* Dump Quest Information */
8016 do_cmd_knowledge_quests_current(fff);
8018 do_cmd_knowledge_quests_completed(fff, quest_num);
8020 do_cmd_knowledge_quests_failed(fff, quest_num);
8024 do_cmd_knowledge_quests_wiz_random(fff);
8028 /* Display the file contents */
8029 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8033 C_KILL(quest_num, max_q_idx, QUEST_IDX);
8040 static void do_cmd_knowledge_home(void)
8045 GAME_TEXT file_name[1024];
8047 GAME_TEXT o_name[MAX_NLEN];
8048 concptr paren = ")";
8050 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
8052 /* Open a new file */
8053 fff = my_fopen_temp(file_name, 1024);
8055 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8062 /* Print all homes in the different towns */
8063 st_ptr = &town_info[1].store[STORE_HOME];
8065 /* Home -- if anything there */
8066 if (st_ptr->stock_num)
8071 /* Header with name of the town */
8072 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8074 /* Dump all available items */
8075 for (i = 0; i < st_ptr->stock_num; i++)
8078 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8079 object_desc(o_name, &st_ptr->stock[i], 0);
8080 if (strlen(o_name) <= 80-3)
8082 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8088 for (n = 0, t = o_name; n < 80-3; n++, t++)
8089 if(iskanji(*t)) {t++; n++;}
8090 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8092 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8093 fprintf(fff, " %.77s\n", o_name+n);
8096 object_desc(o_name, &st_ptr->stock[i], 0);
8097 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8102 /* Add an empty line */
8103 fprintf(fff, "\n\n");
8108 /* Display the file contents */
8109 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8115 * Check the status of "autopick"
8117 static void do_cmd_knowledge_autopick(void)
8121 GAME_TEXT file_name[1024];
8123 /* Open a new file */
8124 fff = my_fopen_temp(file_name, 1024);
8128 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8135 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8139 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8140 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8143 for (k = 0; k < max_autopick; k++)
8146 byte act = autopick_list[k].action;
8147 if (act & DONT_AUTOPICK)
8149 tmp = _("放置", "Leave");
8151 else if (act & DO_AUTODESTROY)
8153 tmp = _("破壊", "Destroy");
8155 else if (act & DO_AUTOPICK)
8157 tmp = _("拾う", "Pickup");
8161 tmp = _("確認", "Query");
8164 if (act & DO_DISPLAY)
8165 fprintf(fff, "%11s", format("[%s]", tmp));
8167 fprintf(fff, "%11s", format("(%s)", tmp));
8169 tmp = autopick_line_from_entry(&autopick_list[k]);
8170 fprintf(fff, " %s", tmp);
8175 /* Display the file contents */
8176 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8182 * Interact with "knowledge"
8184 void do_cmd_knowledge(void)
8187 bool need_redraw = FALSE;
8189 /* File type is "TEXT" */
8190 FILE_TYPE(FILE_TYPE_TEXT);
8193 /* Interact until done */
8198 /* Ask for a choice */
8199 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8200 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8202 /* Give some choices */
8206 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8207 prt("(2) 既知のアイテム の一覧", 7, 5);
8208 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8209 prt("(4) 既知のモンスター の一覧", 9, 5);
8210 prt("(5) 倒した敵の数 の一覧", 10, 5);
8211 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8212 prt("(7) 現在のペット の一覧", 12, 5);
8213 prt("(8) 我が家のアイテム の一覧", 13, 5);
8214 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8215 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8219 prt("(a) 自分に関する情報 の一覧", 6, 5);
8220 prt("(b) 突然変異 の一覧", 7, 5);
8221 prt("(c) 武器の経験値 の一覧", 8, 5);
8222 prt("(d) 魔法の経験値 の一覧", 9, 5);
8223 prt("(e) 技能の経験値 の一覧", 10, 5);
8224 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8225 prt("(g) 入ったダンジョン の一覧", 12, 5);
8226 prt("(h) 実行中のクエスト の一覧", 13, 5);
8227 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8232 prt("(1) Display known artifacts", 6, 5);
8233 prt("(2) Display known objects", 7, 5);
8234 prt("(3) Display remaining uniques", 8, 5);
8235 prt("(4) Display known monster", 9, 5);
8236 prt("(5) Display kill count", 10, 5);
8237 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8238 prt("(7) Display current pets", 12, 5);
8239 prt("(8) Display home inventory", 13, 5);
8240 prt("(9) Display *identified* equip.", 14, 5);
8241 prt("(0) Display terrain symbols.", 15, 5);
8245 prt("(a) Display about yourself", 6, 5);
8246 prt("(b) Display mutations", 7, 5);
8247 prt("(c) Display weapon proficiency", 8, 5);
8248 prt("(d) Display spell proficiency", 9, 5);
8249 prt("(e) Display misc. proficiency", 10, 5);
8250 prt("(f) Display virtues", 11, 5);
8251 prt("(g) Display dungeons", 12, 5);
8252 prt("(h) Display current quests", 13, 5);
8253 prt("(i) Display auto pick/destroy", 14, 5);
8257 prt(_("-続く-", "-more-"), 17, 8);
8258 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8259 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8260 /*prt("-) 前ページ", 21, 60);*/
8261 prt(_("コマンド:", "Command: "), 20, 0);
8264 if (i == ESCAPE) break;
8267 case ' ': /* Page change */
8271 case '1': /* Artifacts */
8272 do_cmd_knowledge_artifacts();
8274 case '2': /* Objects */
8275 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8277 case '3': /* Uniques */
8278 do_cmd_knowledge_uniques();
8280 case '4': /* Monsters */
8281 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8283 case '5': /* Kill count */
8284 do_cmd_knowledge_kill_count();
8286 case '6': /* wanted */
8287 if (!vanilla_town) do_cmd_knowledge_kubi();
8289 case '7': /* Pets */
8290 do_cmd_knowledge_pets();
8292 case '8': /* Home */
8293 do_cmd_knowledge_home();
8295 case '9': /* Resist list */
8296 do_cmd_knowledge_inven();
8298 case '0': /* Feature list */
8300 IDX lighting_level = F_LIT_STANDARD;
8301 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8305 case 'a': /* Max stat */
8306 do_cmd_knowledge_stat();
8308 case 'b': /* Mutations */
8309 do_cmd_knowledge_mutations();
8311 case 'c': /* weapon-exp */
8312 do_cmd_knowledge_weapon_exp();
8314 case 'd': /* spell-exp */
8315 do_cmd_knowledge_spell_exp();
8317 case 'e': /* skill-exp */
8318 do_cmd_knowledge_skill_exp();
8320 case 'f': /* Virtues */
8321 do_cmd_knowledge_virtues();
8323 case 'g': /* Dungeon */
8324 do_cmd_knowledge_dungeon();
8326 case 'h': /* Quests */
8327 do_cmd_knowledge_quests();
8329 case 'i': /* Autopick */
8330 do_cmd_knowledge_autopick();
8332 default: /* Unknown option */
8340 if (need_redraw) do_cmd_redraw();
8345 * Check on the status of an active quest
8347 void do_cmd_checkquest(void)
8349 /* File type is "TEXT" */
8350 FILE_TYPE(FILE_TYPE_TEXT);
8354 do_cmd_knowledge_quests();
8360 * Display the time and date
8362 void do_cmd_time(void)
8364 int day, hour, min, full, start, end, num;
8372 extract_day_hour_min(&day, &hour, &min);
8374 full = hour * 100 + min;
8381 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8383 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8384 else strcpy(day_buf, "*****");
8386 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8387 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8390 if (!randint0(10) || p_ptr->image)
8392 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8396 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8399 /* Open this file */
8400 fff = my_fopen(buf, "rt");
8404 /* Find this time */
8405 while (!my_fgets(fff, buf, sizeof(buf)))
8407 /* Ignore comments */
8408 if (!buf[0] || (buf[0] == '#')) continue;
8410 /* Ignore invalid lines */
8411 if (buf[1] != ':') continue;
8413 /* Process 'Start' */
8416 /* Extract the starting time */
8417 start = atoi(buf + 2);
8419 /* Assume valid for an hour */
8429 /* Extract the ending time */
8430 end = atoi(buf + 2);
8436 /* Ignore incorrect range */
8437 if ((start > full) || (full > end)) continue;
8439 /* Process 'Description' */
8444 /* Apply the randomizer */
8445 if (!randint0(num)) strcpy(desc, buf + 2);