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.
47 #include "cmd-spell.h"
49 #include "player-effects.h"
50 #include "player-status.h"
51 #include "player-skill.h"
58 #include "object-flavor.h"
59 #include "object-hook.h"
61 #include "monster-status.h"
63 #include "view-mainwindow.h"
64 #include "dungeon-file.h"
71 * Mark strings for auto dump
73 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
74 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
77 * Variables for auto dump
79 static FILE *auto_dump_stream;
80 static concptr auto_dump_mark;
81 static int auto_dump_line_num;
85 * @brief prf出力内容を消去する /
86 * Remove old lines automatically generated before.
87 * @param orig_file 消去を行うファイル名
89 static void remove_auto_dump(concptr orig_file)
91 FILE *tmp_fff, *orig_fff;
95 bool between_mark = FALSE;
98 long header_location = 0;
99 char header_mark_str[80];
100 char footer_mark_str[80];
103 /* Prepare a header/footer mark string */
104 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
105 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
107 mark_len = strlen(footer_mark_str);
109 /* Open an old dump file in read-only mode */
110 orig_fff = my_fopen(orig_file, "r");
112 /* If original file does not exist, nothing to do */
113 if (!orig_fff) return;
115 /* Open a new (temporary) file */
116 tmp_fff = my_fopen_temp(tmp_file, 1024);
120 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
125 /* Loop for every line */
129 if (my_fgets(orig_fff, buf, sizeof(buf)))
131 /* Read error: Assume End of File */
134 * Was looking for the footer, but not found.
136 * Since automatic dump might be edited by hand,
137 * it's dangerous to kill these lines.
138 * Seek back to the next line of the (pseudo) header,
143 fseek(orig_fff, header_location, SEEK_SET);
144 between_mark = FALSE;
148 /* Success -- End the loop */
155 /* We are looking for the header mark of automatic dump */
158 /* Is this line a header? */
159 if (!strcmp(buf, header_mark_str))
161 /* Memorise seek point of this line */
162 header_location = ftell(orig_fff);
164 /* Initialize counter for number of lines */
167 /* Look for the footer from now */
170 /* There are some changes */
177 /* Copy orginally lines */
178 fprintf(tmp_fff, "%s\n", buf);
182 /* We are looking for the footer mark of automatic dump */
185 /* Is this line a footer? */
186 if (!strncmp(buf, footer_mark_str, mark_len))
191 * Compare the number of lines
193 * If there is an inconsistency between
194 * actual number of lines and the
195 * number here, the automatic dump
196 * might be edited by hand. So it's
197 * dangerous to kill these lines.
198 * Seek back to the next line of the
199 * (pseudo) header, and read again.
201 if (!sscanf(buf + mark_len, " (%d)", &tmp)
204 fseek(orig_fff, header_location, SEEK_SET);
207 /* Look for another header */
208 between_mark = FALSE;
214 /* Ignore old line, and count number of lines */
224 /* If there are some changes, overwrite the original file with new one */
227 /* Copy contents of temporary file */
229 tmp_fff = my_fopen(tmp_file, "r");
230 orig_fff = my_fopen(orig_file, "w");
232 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
233 fprintf(orig_fff, "%s\n", buf);
239 /* Kill the temporary file */
247 * @brief prfファイルのフォーマットに従った内容を出力する /
248 * Dump a formatted line, using "vstrnfmt()".
251 static void auto_dump_printf(concptr fmt, ...)
258 /* Begin the Varargs Stuff */
261 /* Format the args, save the length */
262 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
264 /* End the Varargs Stuff */
267 /* Count number of lines */
268 for (p = buf; *p; p++)
270 if (*p == '\n') auto_dump_line_num++;
274 fprintf(auto_dump_stream, "%s", buf);
279 * @brief prfファイルをファイルオープンする /
280 * Open file to append auto dump.
282 * @param mark 出力するヘッダマーク
283 * @return ファイルポインタを取得できたらTRUEを返す
285 static bool open_auto_dump(concptr buf, concptr mark)
288 char header_mark_str[80];
290 /* Save the mark string */
291 auto_dump_mark = mark;
293 /* Prepare a header mark string */
294 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
296 /* Remove old macro dumps */
297 remove_auto_dump(buf);
299 /* Append to the file */
300 auto_dump_stream = my_fopen(buf, "a");
303 if (!auto_dump_stream) {
304 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
312 fprintf(auto_dump_stream, "%s\n", header_mark_str);
314 /* Initialize counter */
315 auto_dump_line_num = 0;
317 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
318 "# *Warning!* The lines below are an automatic dump.\n"));
319 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
320 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
326 * @brief prfファイルをファイルクローズする /
327 * Append foot part and close auto dump.
330 static void close_auto_dump(void)
332 char footer_mark_str[80];
334 /* Prepare a footer mark string */
335 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
337 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
338 "# *Warning!* The lines below are an automatic dump.\n"));
339 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
340 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
342 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
345 my_fclose(auto_dump_stream);
354 * @brief Return suffix of ordinal number
356 * @return pointer of suffix string.
358 concptr get_ordinal_number_suffix(int num)
360 num = ABS(num) % 100;
364 return (num == 11) ? "th" : "st";
366 return (num == 12) ? "th" : "nd";
368 return (num == 13) ? "th" : "rd";
377 * @brief 日記にメッセージを追加する /
378 * Take note to the diary.
379 * @param type 日記内容のID
380 * @param num 日記内容のIDに応じた数値
381 * @param note 日記内容のIDに応じた文字列参照ポインタ
384 errr do_cmd_write_nikki(int type, int num, concptr note)
388 GAME_TEXT file_name[MAX_NLEN];
390 concptr note_level = "";
391 bool do_level = TRUE;
392 char note_level_buf[40];
395 static bool disable_nikki = FALSE;
397 extract_day_hour_min(&day, &hour, &min);
399 if (disable_nikki) return(-1);
401 if (type == NIKKI_FIX_QUEST_C ||
402 type == NIKKI_FIX_QUEST_F ||
403 type == NIKKI_RAND_QUEST_C ||
404 type == NIKKI_RAND_QUEST_F ||
405 type == NIKKI_TO_QUEST)
409 old_quest = p_ptr->inside_quest;
410 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
412 /* Get the quest text */
413 init_flags = INIT_NAME_ONLY;
415 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
417 /* Reset the old quest number */
418 p_ptr->inside_quest = old_quest;
421 /* different filne name to avoid mixing */
422 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
424 /* Build the filename */
425 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
427 /* File type is "TEXT" */
428 FILE_TYPE(FILE_TYPE_TEXT);
430 fff = my_fopen(buf, "a");
435 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
441 q_idx = quest_number(current_floor_ptr->dun_level);
445 if (p_ptr->inside_arena)
446 note_level = _("アリーナ:", "Arane:");
447 else if (!current_floor_ptr->dun_level)
448 note_level = _("地上:", "Surface:");
449 else if (q_idx && (is_fixed_quest_idx(q_idx)
450 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
451 note_level = _("クエスト:", "Quest:");
455 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
457 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
459 note_level = note_level_buf;
467 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
468 else fputs(_("*****日目\n", "Day *****\n"), fff);
476 fprintf(fff, "%s\n",note);
480 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
485 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
488 case NIKKI_ART_SCROLL:
490 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
495 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
498 case NIKKI_FIX_QUEST_C:
500 if (quest[num].flags & QUEST_FLAG_SILENT) break;
501 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
502 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
505 case NIKKI_FIX_QUEST_F:
507 if (quest[num].flags & QUEST_FLAG_SILENT) break;
508 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
509 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
512 case NIKKI_RAND_QUEST_C:
514 GAME_TEXT name[MAX_NLEN];
515 strcpy(name, r_name+r_info[quest[num].r_idx].name);
516 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
517 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
520 case NIKKI_RAND_QUEST_F:
522 GAME_TEXT name[MAX_NLEN];
523 strcpy(name, r_name+r_info[quest[num].r_idx].name);
524 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
525 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
528 case NIKKI_MAXDEAPTH:
530 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
531 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
532 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
533 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
538 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
539 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
540 _(d_name + d_info[num].name, (int)max_dlv[num]),
541 _((int)max_dlv[num], d_name + d_info[num].name));
547 if (q_idx && (is_fixed_quest_idx(q_idx)
548 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
550 to = _("地上", "the surface");
554 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
555 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
557 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
563 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
564 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
565 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
567 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
572 if (quest[num].flags & QUEST_FLAG_SILENT) break;
573 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
574 hour, min, note_level, quest[num].name);
579 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
580 hour, min, note_level);
585 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
590 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
598 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
599 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
602 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
603 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
605 if (num == MAX_ARENA_MONS)
607 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
608 " won all fight to become a Chanpion.\n"));
615 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
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 wizard-teleport to %s.\n"), hour, min, note_level, to);
633 if (!current_floor_ptr->dun_level)
634 to = _("地上", "the surface");
636 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
638 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
639 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
644 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
647 case NIKKI_GAMESTART:
649 time_t ct = time((time_t*)0);
653 fprintf(fff, "%s %s",note, ctime(&ct));
656 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
659 case NIKKI_NAMED_PET:
661 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
664 case RECORD_NAMED_PET_NAME:
665 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
667 case RECORD_NAMED_PET_UNNAME:
668 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
670 case RECORD_NAMED_PET_DISMISS:
671 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
673 case RECORD_NAMED_PET_DEATH:
674 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
676 case RECORD_NAMED_PET_MOVED:
677 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
679 case RECORD_NAMED_PET_LOST_SIGHT:
680 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
682 case RECORD_NAMED_PET_DESTROY:
683 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
685 case RECORD_NAMED_PET_EARTHQUAKE:
686 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
688 case RECORD_NAMED_PET_GENOCIDE:
689 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
691 case RECORD_NAMED_PET_WIZ_ZAP:
692 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
694 case RECORD_NAMED_PET_TELE_LEVEL:
695 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
697 case RECORD_NAMED_PET_BLAST:
698 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
700 case RECORD_NAMED_PET_HEAL_LEPER:
701 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
703 case RECORD_NAMED_PET_COMPACT:
704 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
706 case RECORD_NAMED_PET_LOSE_PARENT:
707 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
718 case NIKKI_WIZARD_LOG:
719 fprintf(fff, "%s\n", note);
728 if (do_level) write_level = FALSE;
734 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
737 * @brief 日記のタイトル表記と内容出力 /
740 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
742 static void do_cmd_disp_nikki(void)
744 char nikki_title[256];
745 GAME_TEXT file_name[MAX_NLEN];
750 static const char subtitle[][30] = {"最強の肉体を求めて",
781 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
782 "Attack is the best form of defence.",
784 "An unexpected windfall",
785 "A drowning man will catch at a straw",
786 "Don't count your chickens before they are hatched.",
787 "It is no use crying over spilt milk.",
788 "Seeing is believing.",
789 "Strike the iron while it is hot.",
790 "I don't care what follows.",
791 "To dig a well to put out a house on fire.",
792 "Tomorrow is another day.",
793 "Easy come, easy go.",
794 "The more haste, the less speed.",
795 "Where there is life, there is hope.",
796 "There is no royal road to *WINNER*.",
797 "Danger past, God forgotten.",
798 "The best thing to do now is to run away.",
799 "Life is but an empty dream.",
800 "Dead men tell no tales.",
801 "A book that remains shut is but a block.",
802 "Misfortunes never come singly.",
803 "A little knowledge is a dangerous thing.",
804 "History repeats itself.",
805 "*WINNER* was not built in a day.",
806 "Ignorance is bliss.",
807 "To lose is to win?",
808 "No medicine can cure folly.",
809 "All good things come to an end.",
810 "M$ Empire strikes back.",
811 "To see is to believe",
813 "Quest of The World's Greatest Brain"};
815 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
817 /* Build the filename */
818 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
820 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
821 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
822 else if (IS_WIZARD_CLASS())
823 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
824 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
827 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
829 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
832 /* Display the file contents */
833 show_file(FALSE, buf, nikki_title, -1, 0);
837 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
840 static void do_cmd_bunshou(void)
843 char bunshou[80] = "\0";
845 if (get_string(_("内容: ", "diary note: "), tmp, 79))
847 strcpy(bunshou, tmp);
849 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
854 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
857 static void do_cmd_last_get(void)
862 if (record_o_name[0] == '\0') return;
864 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
865 if (!get_check(buf)) return;
867 turn_tmp = current_world_ptr->game_turn;
868 current_world_ptr->game_turn = record_turn;
869 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
870 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
871 current_world_ptr->game_turn = turn_tmp;
875 * @brief ファイル中の全日記記録を消去する /
878 static void do_cmd_erase_nikki(void)
880 GAME_TEXT file_name[MAX_NLEN];
884 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
885 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
887 /* Build the filename */
888 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
891 fff = my_fopen(buf, "w");
894 msg_format(_("記録を消去しました。", "deleted record."));
896 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
905 void do_cmd_nikki(void)
909 /* File type is "TEXT" */
910 FILE_TYPE(FILE_TYPE_TEXT);
913 /* Interact until done */
918 /* Ask for a choice */
919 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
921 /* Give some choices */
922 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
923 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
924 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
925 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
927 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
930 prt(_("コマンド:", "Command: "), 18, 0);
935 if (i == ESCAPE) break;
949 do_cmd_erase_nikki();
953 prepare_movie_hooks();
955 default: /* Unknown option */
965 * @brief 画面を再描画するコマンドのメインルーチン
966 * Hack -- redraw the screen
970 * This command performs various low level updates, clears all the "extra"
971 * windows, does a total redraw of the main window, and requests all of the
972 * interesting updates and redraws that I can think of.
974 * This command is also used to "instantiate" the results of the user
975 * selecting various things, such as graphics mode, so it must call
976 * the "TERM_XTRA_REACT" hook before redrawing the windows.
979 void do_cmd_redraw(void)
985 /* Hack -- react to changes */
986 Term_xtra(TERM_XTRA_REACT, 0);
988 /* Combine and Reorder the pack (later) */
989 p_ptr->update |= (PU_COMBINE | PU_REORDER);
990 p_ptr->update |= (PU_TORCH);
991 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
992 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
993 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
994 p_ptr->update |= (PU_MONSTERS);
996 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
998 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
999 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1005 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1008 /* Redraw every window */
1009 for (j = 0; j < 8; j++)
1012 if (!angband_term[j]) continue;
1015 Term_activate(angband_term[j]);
1024 * @brief 名前を変更するコマンドのメインルーチン
1025 * Hack -- change name
1028 void do_cmd_change_name(void)
1043 /* Display the player */
1044 display_player(mode);
1049 display_player(mode);
1054 Term_putstr(2, 23, -1, TERM_WHITE,
1055 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1057 Term_putstr(2, 23, -1, TERM_WHITE,
1058 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1066 if (c == ESCAPE) break;
1073 /* Process the player name */
1074 process_player_name(FALSE);
1080 sprintf(tmp, "%s.txt", player_base);
1081 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1083 if (tmp[0] && (tmp[0] != ' '))
1085 file_character(tmp);
1103 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1110 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1111 * Recall the most recent message
1114 void do_cmd_message_one(void)
1116 /* Recall one message */
1117 prt(format("> %s", message_str(0)), 0, 0);
1122 * @brief メッセージのログを表示するコマンドのメインルーチン
1123 * Recall the most recent message
1127 * Show previous messages to the user -BEN-
1129 * The screen format uses line 0 and 23 for headers and prompts,
1130 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1132 * This command shows you which commands you are viewing, and allows
1133 * you to "search" for strings in the recall.
1135 * Note that messages may be longer than 80 characters, but they are
1136 * displayed using "infinite" length, with a special sub-command to
1137 * "slide" the virtual display to the left or right.
1139 * Attempt to only hilite the matching portions of the string.
1142 void do_cmd_messages(int num_now)
1146 char shower_str[81];
1147 char finder_str[81];
1149 concptr shower = NULL;
1153 Term_get_size(&wid, &hgt);
1155 /* Number of message lines in a screen */
1156 num_lines = hgt - 4;
1159 strcpy(finder_str, "");
1162 strcpy(shower_str, "");
1164 /* Total messages */
1167 /* Start on first message */
1172 /* Process requests until done */
1178 /* Dump up to 20 lines of messages */
1179 for (j = 0; (j < num_lines) && (i + j < n); j++)
1181 concptr msg = message_str(i+j);
1183 /* Dump the messages, bottom to top */
1184 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1186 /* Hilite "shower" */
1187 if (shower && shower[0])
1191 /* Display matches */
1192 while ((str = my_strstr(str, shower)) != NULL)
1194 int len = strlen(shower);
1196 /* Display the match */
1197 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1205 /* Erase remaining lines */
1206 for (; j < num_lines; j++)
1208 Term_erase(0, num_lines + 1 - j, 255);
1211 /* Display header */
1213 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1214 i, i + j - 1, n), 0, 0);
1216 /* Display prompt (not very informative) */
1217 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1218 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1220 skey = inkey_special(TRUE);
1222 /* Exit on Escape */
1223 if (skey == ESCAPE) break;
1225 /* Hack -- Save the old index */
1230 /* Hack -- handle show */
1233 prt(_("強調: ", "Show: "), hgt - 1, 0);
1235 /* Get a "shower" string, or continue */
1236 strcpy(back_str, shower_str);
1237 if (askfor(shower_str, 80))
1240 shower = shower_str[0] ? shower_str : NULL;
1242 else strcpy(shower_str, back_str);
1246 /* Hack -- handle find */
1253 prt(_("検索: ", "Find: "), hgt - 1, 0);
1255 /* Get a "finder" string, or continue */
1256 strcpy(back_str, finder_str);
1257 if (!askfor(finder_str, 80))
1259 strcpy(finder_str, back_str);
1262 else if (!finder_str[0])
1264 shower = NULL; /* Stop showing */
1269 shower = finder_str;
1272 for (z = i + 1; z < n; z++)
1274 concptr msg = message_str(z);
1277 if (my_strstr(msg, finder_str))
1288 /* Recall 1 older message */
1290 /* Go to the oldest line */
1294 /* Recall 1 newer message */
1296 /* Go to the newest line */
1300 /* Recall 1 older message */
1305 /* Go older if legal */
1306 i = MIN(i + 1, n - num_lines);
1309 /* Recall 10 older messages */
1311 /* Go older if legal */
1312 i = MIN(i + 10, n - num_lines);
1315 /* Recall 20 older messages */
1320 /* Go older if legal */
1321 i = MIN(i + num_lines, n - num_lines);
1324 /* Recall 20 newer messages */
1328 /* Go newer (if able) */
1329 i = MAX(0, i - num_lines);
1332 /* Recall 10 newer messages */
1334 /* Go newer (if able) */
1338 /* Recall 1 newer messages */
1341 /* Go newer (if able) */
1346 /* Hack -- Error of some kind */
1354 * @brief チートオプションを変更するコマンドのメインルーチン
1355 * Interact with some options for cheating
1356 * @param info 表示メッセージ
1359 static void do_cmd_options_cheat(concptr info)
1362 int i, k = 0, n = CHEAT_MAX;
1366 /* Interact with the player */
1372 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1377 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1378 prt(" << 注意 >>", 11, 0);
1379 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1380 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1381 prt(" じらないようにして下さい。", 14, 0);
1383 /* Display the options */
1384 for (i = 0; i < n; i++)
1386 byte a = TERM_WHITE;
1388 /* Color current option */
1389 if (i == k) a = TERM_L_BLUE;
1391 /* Display the option text */
1392 sprintf(buf, "%-48s: %s (%s)",
1393 cheat_info[i].o_desc,
1394 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1395 cheat_info[i].o_text);
1396 c_prt(a, buf, i + 2, 0);
1399 /* Hilite current option */
1400 move_cursor(k + 2, 50);
1406 * HACK - Try to translate the key into a direction
1407 * to allow using the roguelike keys for navigation.
1409 dir = get_keymap_dir(ch);
1410 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1424 k = (n + k - 1) % n;
1442 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1443 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1444 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1445 (*cheat_info[k].o_var) = TRUE;
1454 (*cheat_info[k].o_var) = FALSE;
1461 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1462 /* Peruse the help file */
1463 (void)show_file(TRUE, buf, NULL, 0, 0);
1480 * @brief セーブ頻度ターンの次の値を返す
1481 * @param current 現在のセーブ頻度ターン値
1482 * @return 次のセーブ頻度ターン値
1484 static s16b toggle_frequency(s16b current)
1489 case 50: return 100;
1490 case 100: return 250;
1491 case 250: return 500;
1492 case 500: return 1000;
1493 case 1000: return 2500;
1494 case 2500: return 5000;
1495 case 5000: return 10000;
1496 case 10000: return 25000;
1503 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1504 * @param info 表示メッセージ
1507 static void do_cmd_options_autosave(concptr info)
1510 int i, k = 0, n = 2;
1515 /* Interact with the player */
1519 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1520 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1524 /* Display the options */
1525 for (i = 0; i < n; i++)
1527 byte a = TERM_WHITE;
1529 /* Color current option */
1530 if (i == k) a = TERM_L_BLUE;
1532 /* Display the option text */
1533 sprintf(buf, "%-48s: %s (%s)",
1534 autosave_info[i].o_desc,
1535 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1536 autosave_info[i].o_text);
1537 c_prt(a, buf, i + 2, 0);
1539 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1541 /* Hilite current option */
1542 move_cursor(k + 2, 50);
1558 k = (n + k - 1) % n;
1576 (*autosave_info[k].o_var) = TRUE;
1585 (*autosave_info[k].o_var) = FALSE;
1593 autosave_freq = toggle_frequency(autosave_freq);
1594 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1600 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1616 * @brief 標準オプションを変更するコマンドのサブルーチン /
1617 * Interact with some options
1618 * @param page オプションページ番号
1619 * @param info 表示メッセージ
1622 void do_cmd_options_aux(int page, concptr info)
1625 int i, k = 0, n = 0, l;
1628 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1629 (!p_ptr->wizard || !allow_debug_opts);
1632 /* Lookup the options */
1633 for (i = 0; i < 24; i++) opt[i] = 0;
1635 /* Scan the options */
1636 for (i = 0; option_info[i].o_desc; i++)
1638 /* Notice options on this "page" */
1639 if (option_info[i].o_page == page) opt[n++] = i;
1643 /* Interact with the player */
1649 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1650 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1653 /* HACK -- description for easy-auto-destroy options */
1654 if (page == OPT_PAGE_AUTODESTROY)
1655 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1656 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1658 /* Display the options */
1659 for (i = 0; i < n; i++)
1661 byte a = TERM_WHITE;
1663 /* Color current option */
1664 if (i == k) a = TERM_L_BLUE;
1666 /* Display the option text */
1667 sprintf(buf, "%-48s: %s (%.19s)",
1668 option_info[opt[i]].o_desc,
1669 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1670 option_info[opt[i]].o_text);
1671 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1672 else c_prt(a, buf, i + 2, 0);
1675 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1678 /* Hilite current option */
1679 move_cursor(k + 2 + l, 50);
1685 * HACK - Try to translate the key into a direction
1686 * to allow using the roguelike keys for navigation.
1688 dir = get_keymap_dir(ch);
1689 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1703 k = (n + k - 1) % n;
1720 if (browse_only) break;
1721 (*option_info[opt[k]].o_var) = TRUE;
1730 if (browse_only) break;
1731 (*option_info[opt[k]].o_var) = FALSE;
1739 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1745 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1746 /* Peruse the help file */
1747 (void)show_file(TRUE, buf, NULL, 0, 0);
1764 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1765 * Modify the "window" options
1768 static void do_cmd_options_win(void)
1778 /* Memorize old flags */
1779 for (j = 0; j < 8; j++)
1781 /* Acquire current flags */
1782 old_flag[j] = window_flag[j];
1791 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1793 /* Display the windows */
1794 for (j = 0; j < 8; j++)
1796 byte a = TERM_WHITE;
1798 concptr s = angband_term_name[j];
1801 if (j == x) a = TERM_L_BLUE;
1803 /* Window name, staggered, centered */
1804 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1807 /* Display the options */
1808 for (i = 0; i < 16; i++)
1810 byte a = TERM_WHITE;
1812 concptr str = window_flag_desc[i];
1815 if (i == y) a = TERM_L_BLUE;
1818 if (!str) str = _("(未使用)", "(Unused option)");
1821 Term_putstr(0, i + 5, -1, a, str);
1823 /* Display the windows */
1824 for (j = 0; j < 8; j++)
1830 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1833 if (window_flag[j] & (1L << i)) c = 'X';
1836 Term_putch(35 + j * 5, i + 5, a, c);
1841 Term_gotoxy(35 + x * 5, y + 5);
1859 for (j = 0; j < 8; j++)
1861 window_flag[j] &= ~(1L << y);
1865 for (i = 0; i < 16; i++)
1867 window_flag[x] &= ~(1L << i);
1880 window_flag[x] |= (1L << y);
1888 window_flag[x] &= ~(1L << y);
1894 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1902 d = get_keymap_dir(ch);
1904 x = (x + ddx[d] + 8) % 8;
1905 y = (y + ddy[d] + 16) % 16;
1912 /* Notice changes */
1913 for (j = 0; j < 8; j++)
1918 if (!angband_term[j]) continue;
1920 /* Ignore non-changes */
1921 if (window_flag[j] == old_flag[j]) continue;
1924 Term_activate(angband_term[j]);
1941 option_fields[OPT_NUM] =
1944 { '1', " キー入力 オプション", 3 },
1945 { '2', " マップ画面 オプション", 4 },
1946 { '3', " テキスト表示 オプション", 5 },
1947 { '4', " ゲームプレイ オプション", 6 },
1948 { '5', " 行動中止関係 オプション", 7 },
1949 { '6', " 簡易自動破壊 オプション", 8 },
1950 { 'r', " プレイ記録 オプション", 9 },
1952 { 'p', "自動拾いエディタ", 11 },
1953 { 'd', " 基本ウェイト量 ", 12 },
1954 { 'h', "低ヒットポイント", 13 },
1955 { 'm', " 低魔力色閾値 ", 14 },
1956 { 'a', " 自動セーブ オプション", 15 },
1957 { 'w', "ウインドウフラグ", 16 },
1959 { 'b', " 初期 オプション (参照のみ)", 18 },
1960 { 'c', " 詐欺 オプション", 19 },
1962 { '1', "Input Options", 3 },
1963 { '2', "Map Screen Options", 4 },
1964 { '3', "Text Display Options", 5 },
1965 { '4', "Game-Play Options", 6 },
1966 { '5', "Disturbance Options", 7 },
1967 { '6', "Easy Auto-Destroyer Options", 8 },
1968 { 'r', "Play record Options", 9 },
1970 { 'p', "Auto-picker/destroyer editor", 11 },
1971 { 'd', "Base Delay Factor", 12 },
1972 { 'h', "Hitpoint Warning", 13 },
1973 { 'm', "Mana Color Threshold", 14 },
1974 { 'a', "Autosave Options", 15 },
1975 { 'w', "Window Flags", 16 },
1977 { 'b', "Birth Options (Browse Only)", 18 },
1978 { 'c', "Cheat Options", 19 },
1984 * @brief 標準オプションを変更するコマンドのメインルーチン /
1985 * Set or unset various options.
1989 * The user must use the "Ctrl-R" command to "adapt" to changes
1990 * in any options which control "visual" aspects of the game.
1993 void do_cmd_options(void)
2005 /* Does not list cheat option when cheat option is off */
2006 if (!p_ptr->noscore && !allow_debug_opts) n--;
2009 /* Why are we here */
2010 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2014 /* Give some choices */
2015 for (i = 0; i < n; i++)
2017 byte a = TERM_WHITE;
2018 if (i == y) a = TERM_L_BLUE;
2019 Term_putstr(5, option_fields[i].row, -1, a,
2020 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2023 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2026 skey = inkey_special(TRUE);
2027 if (!(skey & SKEY_MASK)) k = (char)skey;
2031 if (k == ESCAPE) break;
2033 if (my_strchr("\n\r ", k))
2035 k = option_fields[y].key;
2039 for (i = 0; i < n; i++)
2041 if (tolower(k) == option_fields[i].key) break;
2044 /* Command is found */
2047 /* Hack -- browse help */
2048 if (k == '?') break;
2052 if (skey == SKEY_UP) d = 8;
2053 if (skey == SKEY_DOWN) d = 2;
2054 y = (y + ddy[d] + n) % n;
2059 if (k == ESCAPE) break;
2066 /* Process the general options */
2067 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2073 /* Process the general options */
2074 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2081 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2088 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2095 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2102 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2106 /* Play-record Options */
2111 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2120 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2121 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2122 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2126 /* Cheating Options */
2129 if (!p_ptr->noscore && !allow_debug_opts)
2131 /* Cheat options are not permitted */
2137 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2144 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2153 do_cmd_options_win();
2154 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2155 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2156 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2157 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2162 /* Auto-picker/destroyer editor */
2166 do_cmd_edit_autopick();
2170 /* Hack -- Delay Speed */
2176 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2178 /* Get a new value */
2181 int msec = delay_factor * delay_factor * delay_factor;
2182 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2183 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2185 if (k == ESCAPE) break;
2188 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2191 else if (isdigit(k)) delay_factor = D2I(k);
2198 /* Hack -- hitpoint warning factor */
2204 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2206 /* Get a new value */
2209 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2210 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2212 if (k == ESCAPE) break;
2215 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2218 else if (isdigit(k)) hitpoint_warn = D2I(k);
2225 /* Hack -- mana color factor */
2231 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2233 /* Get a new value */
2236 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2237 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2239 if (k == ESCAPE) break;
2242 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2245 else if (isdigit(k)) mana_warn = D2I(k);
2253 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2257 /* Unknown option */
2270 /* Hack - Redraw equippy chars */
2271 p_ptr->redraw |= (PR_EQUIPPY);
2277 * @brief prefファイルを選択して処理する /
2278 * Ask for a "user pref line" and process it
2281 * Allow absolute file names?
2283 void do_cmd_pref(void)
2290 /* Ask for a "user pref command" */
2291 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2293 /* Process that pref command */
2294 (void)process_pref_file_command(buf);
2298 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2301 void do_cmd_reload_autopick(void)
2303 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2304 /* Load the file with messages */
2305 autopick_load_pref(TRUE);
2311 * @brief マクロ情報をprefファイルに保存する /
2312 * @param fname ファイル名
2315 static errr macro_dump(concptr fname)
2317 static concptr mark = "Macro Dump";
2323 /* Build the filename */
2324 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2326 /* File type is "TEXT" */
2327 FILE_TYPE(FILE_TYPE_TEXT);
2329 /* Append to the file */
2330 if (!open_auto_dump(buf, mark)) return (-1);
2333 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2336 for (i = 0; i < macro__num; i++)
2338 /* Extract the action */
2339 ascii_to_text(buf, macro__act[i]);
2341 /* Dump the macro */
2342 auto_dump_printf("A:%s\n", buf);
2344 /* Extract the action */
2345 ascii_to_text(buf, macro__pat[i]);
2347 /* Dump normal macros */
2348 auto_dump_printf("P:%s\n", buf);
2351 auto_dump_printf("\n");
2363 * @brief マクロのトリガーキーを取得する /
2364 * Hack -- ask for a "trigger" (see below)
2365 * @param buf キー表記を保管するバッファ
2369 * Note the complex use of the "inkey()" function from "util.c".
2371 * Note that both "flush()" calls are extremely important.
2374 static void do_cmd_macro_aux(char *buf)
2382 /* Do not process macros */
2388 /* Read the pattern */
2394 /* Do not process macros */
2397 /* Do not wait for keys */
2400 /* Attempt to read a key */
2409 /* Convert the trigger */
2410 ascii_to_text(tmp, buf);
2412 /* Hack -- display the trigger */
2413 Term_addstr(-1, TERM_WHITE, tmp);
2419 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2420 * Hack -- ask for a keymap "trigger" (see below)
2421 * @param buf キー表記を取得するバッファ
2425 * Note that both "flush()" calls are extremely important. This may
2426 * no longer be true, since "util.c" is much simpler now.
2429 static void do_cmd_macro_aux_keymap(char *buf)
2439 /* Convert to ascii */
2440 ascii_to_text(tmp, buf);
2442 /* Hack -- display the trigger */
2443 Term_addstr(-1, TERM_WHITE, tmp);
2450 * @brief キーマップをprefファイルにダンプする /
2451 * Hack -- append all keymaps to the given file
2452 * @param fname ファイルネーム
2456 static errr keymap_dump(concptr fname)
2458 static concptr mark = "Keymap Dump";
2467 if (rogue_like_commands)
2469 mode = KEYMAP_MODE_ROGUE;
2475 mode = KEYMAP_MODE_ORIG;
2479 /* Build the filename */
2480 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2482 /* File type is "TEXT" */
2483 FILE_TYPE(FILE_TYPE_TEXT);
2485 /* Append to the file */
2486 if (!open_auto_dump(buf, mark)) return -1;
2489 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2492 for (i = 0; i < 256; i++)
2496 /* Loop up the keymap */
2497 act = keymap_act[mode][i];
2499 /* Skip empty keymaps */
2502 /* Encode the key */
2505 ascii_to_text(key, buf);
2507 /* Encode the action */
2508 ascii_to_text(buf, act);
2510 /* Dump the macro */
2511 auto_dump_printf("A:%s\n", buf);
2512 auto_dump_printf("C:%d:%s\n", mode, key);
2524 * @brief マクロを設定するコマンドのメインルーチン /
2525 * Interact with "macros"
2529 * Note that the macro "action" must be defined before the trigger.
2531 * Could use some helpful instructions on this page.
2534 void do_cmd_macros(void)
2546 if (rogue_like_commands)
2548 mode = KEYMAP_MODE_ROGUE;
2554 mode = KEYMAP_MODE_ORIG;
2557 /* File type is "TEXT" */
2558 FILE_TYPE(FILE_TYPE_TEXT);
2563 /* Process requests until done */
2567 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2569 /* Describe that action */
2570 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2572 /* Analyze the current action */
2573 ascii_to_text(buf, macro__buf);
2575 /* Display the current action */
2580 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2582 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2583 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2584 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2585 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2586 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2587 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2588 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2589 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2590 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2591 #endif /* ALLOW_MACROS */
2594 prt(_("コマンド: ", "Command: "), 16, 0);
2599 if (i == ESCAPE) break;
2601 /* Load a 'macro' file */
2607 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2610 prt(_("ファイル: ", "File: "), 18, 0);
2612 /* Default filename */
2613 sprintf(tmp, "%s.prf", player_base);
2615 /* Ask for a file */
2616 if (!askfor(tmp, 80)) continue;
2618 /* Process the given filename */
2619 err = process_pref_file(tmp);
2622 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2627 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2631 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2641 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2644 prt(_("ファイル: ", "File: "), 18, 0);
2646 /* Default filename */
2647 sprintf(tmp, "%s.prf", player_base);
2649 /* Ask for a file */
2650 if (!askfor(tmp, 80)) continue;
2652 /* Dump the macros */
2653 (void)macro_dump(tmp);
2656 msg_print(_("マクロを追加しました。", "Appended macros."));
2665 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2669 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2671 /* Get a macro trigger */
2672 do_cmd_macro_aux(buf);
2674 /* Acquire action */
2675 k = macro_find_exact(buf);
2681 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2687 /* Obtain the action */
2688 strcpy(macro__buf, macro__act[k]);
2690 /* Analyze the current action */
2691 ascii_to_text(buf, macro__buf);
2693 /* Display the current action */
2697 msg_print(_("マクロを確認しました。", "Found a macro."));
2701 /* Create a macro */
2705 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2708 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2710 /* Get a macro trigger */
2711 do_cmd_macro_aux(buf);
2717 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2718 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2721 prt(_("マクロ行動: ", "Action: "), 20, 0);
2723 /* Convert to text */
2724 ascii_to_text(tmp, macro__buf);
2726 /* Get an encoded action */
2727 if (askfor(tmp, 80))
2729 /* Convert to ascii */
2730 text_to_ascii(macro__buf, tmp);
2732 /* Link the macro */
2733 macro_add(buf, macro__buf);
2736 msg_print(_("マクロを追加しました。", "Added a macro."));
2740 /* Remove a macro */
2744 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2747 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2749 /* Get a macro trigger */
2750 do_cmd_macro_aux(buf);
2752 /* Link the macro */
2753 macro_add(buf, buf);
2756 msg_print(_("マクロを削除しました。", "Removed a macro."));
2763 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2766 prt(_("ファイル: ", "File: "), 18, 0);
2768 /* Default filename */
2769 sprintf(tmp, "%s.prf", player_base);
2771 /* Ask for a file */
2772 if (!askfor(tmp, 80)) continue;
2774 /* Dump the macros */
2775 (void)keymap_dump(tmp);
2778 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2781 /* Query a keymap */
2787 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2790 prt(_("押すキー: ", "Keypress: "), 18, 0);
2792 /* Get a keymap trigger */
2793 do_cmd_macro_aux_keymap(buf);
2795 /* Look up the keymap */
2796 act = keymap_act[mode][(byte)(buf[0])];
2802 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2808 /* Obtain the action */
2809 strcpy(macro__buf, act);
2811 /* Analyze the current action */
2812 ascii_to_text(buf, macro__buf);
2814 /* Display the current action */
2818 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2822 /* Create a keymap */
2826 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2829 prt(_("押すキー: ", "Keypress: "), 18, 0);
2831 /* Get a keymap trigger */
2832 do_cmd_macro_aux_keymap(buf);
2838 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2839 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2842 prt(_("行動: ", "Action: "), 20, 0);
2844 /* Convert to text */
2845 ascii_to_text(tmp, macro__buf);
2847 /* Get an encoded action */
2848 if (askfor(tmp, 80))
2850 /* Convert to ascii */
2851 text_to_ascii(macro__buf, tmp);
2853 /* Free old keymap */
2854 string_free(keymap_act[mode][(byte)(buf[0])]);
2856 /* Make new keymap */
2857 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2860 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2864 /* Remove a keymap */
2868 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2871 prt(_("押すキー: ", "Keypress: "), 18, 0);
2873 /* Get a keymap trigger */
2874 do_cmd_macro_aux_keymap(buf);
2876 /* Free old keymap */
2877 string_free(keymap_act[mode][(byte)(buf[0])]);
2879 /* Make new keymap */
2880 keymap_act[mode][(byte)(buf[0])] = NULL;
2883 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2886 /* Enter a new action */
2890 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2896 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2897 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2900 prt(_("マクロ行動: ", "Action: "), 20, 0);
2902 /* Hack -- limit the value */
2905 /* Get an encoded action */
2906 if (!askfor(buf, 80)) continue;
2908 /* Extract an action */
2909 text_to_ascii(macro__buf, buf);
2912 #endif /* ALLOW_MACROS */
2925 * @brief キャラクタ色の明暗表現
2927 static concptr lighting_level_str[F_LIT_MAX] =
2942 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2943 * @param i 指定対象となるキャラクタコード
2944 * @param num 指定されたビジュアルIDを返す参照ポインタ
2945 * @param max ビジュアルIDの最大数
2946 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2948 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2955 sprintf(str, "%d", *num);
2957 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2960 tmp = (IDX)strtol(str, NULL, 0);
2961 if (tmp >= 0 && tmp < max)
2964 else if (isupper(i))
2965 *num = (*num + max - 1) % max;
2967 *num = (*num + 1) % max;
2973 * @brief キャラクタの変更メニュー表示
2974 * @param choice_msg 選択メッセージ
2977 static void print_visuals_menu(concptr choice_msg)
2979 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2981 /* Give some choices */
2982 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2984 #ifdef ALLOW_VISUALS
2985 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2986 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2987 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2988 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2989 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2990 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2991 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2992 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2993 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2994 #endif /* ALLOW_VISUALS */
2996 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2999 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3002 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3003 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3004 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3007 * Interact with "visuals"
3009 void do_cmd_visuals(void)
3014 bool need_redraw = FALSE;
3015 concptr empty_symbol = "<< ? >>";
3017 if (use_bigtile) empty_symbol = "<< ?? >>";
3019 /* File type is "TEXT" */
3020 FILE_TYPE(FILE_TYPE_TEXT);
3023 /* Interact until done */
3028 /* Ask for a choice */
3029 print_visuals_menu(NULL);
3034 if (i == ESCAPE) break;
3038 /* Load a 'pref' file */
3041 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3044 prt(_("ファイル: ", "File: "), 17, 0);
3046 /* Default filename */
3047 sprintf(tmp, "%s.prf", player_base);
3050 if (!askfor(tmp, 70)) continue;
3052 /* Process the given filename */
3053 (void)process_pref_file(tmp);
3058 #ifdef ALLOW_VISUALS
3060 /* Dump monster attr/chars */
3063 static concptr mark = "Monster attr/chars";
3066 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3069 prt(_("ファイル: ", "File: "), 17, 0);
3071 /* Default filename */
3072 sprintf(tmp, "%s.prf", player_base);
3074 /* Get a filename */
3075 if (!askfor(tmp, 70)) continue;
3077 /* Build the filename */
3078 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3080 /* Append to the file */
3081 if (!open_auto_dump(buf, mark)) continue;
3084 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3087 for (i = 0; i < max_r_idx; i++)
3089 monster_race *r_ptr = &r_info[i];
3091 /* Skip non-entries */
3092 if (!r_ptr->name) continue;
3094 /* Dump a comment */
3095 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3097 /* Dump the monster attr/char info */
3098 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3099 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3105 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3110 /* Dump object attr/chars */
3113 static concptr mark = "Object attr/chars";
3114 KIND_OBJECT_IDX k_idx;
3117 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3120 prt(_("ファイル: ", "File: "), 17, 0);
3122 /* Default filename */
3123 sprintf(tmp, "%s.prf", player_base);
3125 /* Get a filename */
3126 if (!askfor(tmp, 70)) continue;
3128 /* Build the filename */
3129 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3131 /* Append to the file */
3132 if (!open_auto_dump(buf, mark)) continue;
3135 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3138 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3140 GAME_TEXT o_name[MAX_NLEN];
3141 object_kind *k_ptr = &k_info[k_idx];
3143 /* Skip non-entries */
3144 if (!k_ptr->name) continue;
3149 strip_name(o_name, k_idx);
3155 /* Prepare dummy object */
3156 object_prep(&forge, k_idx);
3158 /* Get un-shuffled flavor name */
3159 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3162 /* Dump a comment */
3163 auto_dump_printf("# %s\n", o_name);
3165 /* Dump the object attr/char info */
3166 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3167 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3173 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3178 /* Dump feature attr/chars */
3181 static concptr mark = "Feature attr/chars";
3184 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3187 prt(_("ファイル: ", "File: "), 17, 0);
3189 /* Default filename */
3190 sprintf(tmp, "%s.prf", player_base);
3192 /* Get a filename */
3193 if (!askfor(tmp, 70)) continue;
3195 /* Build the filename */
3196 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3198 /* Append to the file */
3199 if (!open_auto_dump(buf, mark)) continue;
3202 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3205 for (i = 0; i < max_f_idx; i++)
3207 feature_type *f_ptr = &f_info[i];
3209 /* Skip non-entries */
3210 if (!f_ptr->name) continue;
3212 /* Skip mimiccing features */
3213 if (f_ptr->mimic != i) continue;
3215 /* Dump a comment */
3216 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3218 /* Dump the feature attr/char info */
3219 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3220 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3221 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3222 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3228 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3233 /* Modify monster attr/chars (numeric operation) */
3236 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3237 static MONRACE_IDX r = 0;
3239 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3241 /* Hack -- query until done */
3244 monster_race *r_ptr = &r_info[r];
3248 TERM_COLOR da = r_ptr->d_attr;
3249 byte dc = r_ptr->d_char;
3250 TERM_COLOR ca = r_ptr->x_attr;
3251 byte cc = r_ptr->x_char;
3253 /* Label the object */
3254 Term_putstr(5, 17, -1, TERM_WHITE,
3255 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3257 /* Label the Default values */
3258 Term_putstr(10, 19, -1, TERM_WHITE,
3259 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3261 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3262 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3264 /* Label the Current values */
3265 Term_putstr(10, 20, -1, TERM_WHITE,
3266 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3268 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3269 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3272 Term_putstr(0, 22, -1, TERM_WHITE,
3273 _("コマンド (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): "));
3278 if (i == ESCAPE) break;
3280 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3281 else if (isupper(i)) c = 'a' + i - 'A';
3291 if (!cmd_visuals_aux(i, &r, max_r_idx))
3297 while (!r_info[r].name);
3301 t = (int)r_ptr->x_attr;
3302 (void)cmd_visuals_aux(i, &t, 256);
3303 r_ptr->x_attr = (byte)t;
3307 t = (int)r_ptr->x_char;
3308 (void)cmd_visuals_aux(i, &t, 256);
3309 r_ptr->x_char = (byte)t;
3313 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3315 print_visuals_menu(choice_msg);
3323 /* Modify object attr/chars (numeric operation) */
3326 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3328 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3330 /* Hack -- query until done */
3333 object_kind *k_ptr = &k_info[k];
3337 TERM_COLOR da = k_ptr->d_attr;
3338 SYMBOL_CODE dc = k_ptr->d_char;
3339 TERM_COLOR ca = k_ptr->x_attr;
3340 SYMBOL_CODE cc = k_ptr->x_char;
3342 /* Label the object */
3343 Term_putstr(5, 17, -1, TERM_WHITE,
3344 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3345 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3347 /* Label the Default values */
3348 Term_putstr(10, 19, -1, TERM_WHITE,
3349 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3351 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3352 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3354 /* Label the Current values */
3355 Term_putstr(10, 20, -1, TERM_WHITE,
3356 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3358 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3359 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3362 Term_putstr(0, 22, -1, TERM_WHITE,
3363 _("コマンド (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): "));
3368 if (i == ESCAPE) break;
3370 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3371 else if (isupper(i)) c = 'a' + i - 'A';
3381 if (!cmd_visuals_aux(i, &k, max_k_idx))
3387 while (!k_info[k].name);
3391 t = (int)k_ptr->x_attr;
3392 (void)cmd_visuals_aux(i, &t, 256);
3393 k_ptr->x_attr = (byte)t;
3397 t = (int)k_ptr->x_char;
3398 (void)cmd_visuals_aux(i, &t, 256);
3399 k_ptr->x_char = (byte)t;
3403 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3405 print_visuals_menu(choice_msg);
3413 /* Modify feature attr/chars (numeric operation) */
3416 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3418 static IDX lighting_level = F_LIT_STANDARD;
3419 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3421 /* Hack -- query until done */
3424 feature_type *f_ptr = &f_info[f];
3428 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3429 byte dc = f_ptr->d_char[lighting_level];
3430 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3431 byte cc = f_ptr->x_char[lighting_level];
3433 /* Label the object */
3435 Term_putstr(5, 17, -1, TERM_WHITE,
3436 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3437 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3439 /* Label the Default values */
3440 Term_putstr(10, 19, -1, TERM_WHITE,
3441 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3443 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3444 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3446 /* Label the Current values */
3448 Term_putstr(10, 20, -1, TERM_WHITE,
3449 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3451 Term_putstr(10, 20, -1, TERM_WHITE,
3452 format("Current attr/char = %3d / %3d", ca, cc));
3455 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3456 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3460 Term_putstr(0, 22, -1, TERM_WHITE,
3461 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3463 Term_putstr(0, 22, -1, TERM_WHITE,
3464 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3470 if (i == ESCAPE) break;
3472 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3473 else if (isupper(i)) c = 'a' + i - 'A';
3483 if (!cmd_visuals_aux(i, &f, max_f_idx))
3489 while (!f_info[f].name || (f_info[f].mimic != f));
3493 t = (int)f_ptr->x_attr[lighting_level];
3494 (void)cmd_visuals_aux(i, &t, 256);
3495 f_ptr->x_attr[lighting_level] = (byte)t;
3499 t = (int)f_ptr->x_char[lighting_level];
3500 (void)cmd_visuals_aux(i, &t, 256);
3501 f_ptr->x_char[lighting_level] = (byte)t;
3505 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3508 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3512 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3514 print_visuals_menu(choice_msg);
3522 /* Modify monster attr/chars (visual mode) */
3524 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3527 /* Modify object attr/chars (visual mode) */
3529 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3532 /* Modify feature attr/chars (visual mode) */
3535 IDX lighting_level = F_LIT_STANDARD;
3536 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3540 #endif /* ALLOW_VISUALS */
3548 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3552 /* Unknown option */
3562 if (need_redraw) do_cmd_redraw();
3567 * Interact with "colors"
3569 void do_cmd_colors(void)
3578 /* File type is "TEXT" */
3579 FILE_TYPE(FILE_TYPE_TEXT);
3584 /* Interact until done */
3589 /* Ask for a choice */
3590 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3592 /* Give some choices */
3593 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3596 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3597 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3601 prt(_("コマンド: ", "Command: "), 8, 0);
3605 if (i == ESCAPE) break;
3607 /* Load a 'pref' file */
3611 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3614 prt(_("ファイル: ", "File: "), 10, 0);
3617 sprintf(tmp, "%s.prf", player_base);
3620 if (!askfor(tmp, 70)) continue;
3622 /* Process the given filename */
3623 (void)process_pref_file(tmp);
3625 /* Mega-Hack -- react to changes */
3626 Term_xtra(TERM_XTRA_REACT, 0);
3628 /* Mega-Hack -- redraw */
3637 static concptr mark = "Colors";
3640 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3643 prt(_("ファイル: ", "File: "), 10, 0);
3645 /* Default filename */
3646 sprintf(tmp, "%s.prf", player_base);
3648 /* Get a filename */
3649 if (!askfor(tmp, 70)) continue;
3651 /* Build the filename */
3652 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3654 /* Append to the file */
3655 if (!open_auto_dump(buf, mark)) continue;
3658 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3661 for (i = 0; i < 256; i++)
3663 int kv = angband_color_table[i][0];
3664 int rv = angband_color_table[i][1];
3665 int gv = angband_color_table[i][2];
3666 int bv = angband_color_table[i][3];
3668 concptr name = _("未知", "unknown");
3670 /* Skip non-entries */
3671 if (!kv && !rv && !gv && !bv) continue;
3673 /* Extract the color name */
3674 if (i < 16) name = color_names[i];
3676 /* Dump a comment */
3677 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3679 /* Dump the monster attr/char info */
3680 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3687 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3696 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3698 /* Hack -- query until done */
3707 /* Exhibit the normal colors */
3708 for (j = 0; j < 16; j++)
3710 /* Exhibit this color */
3711 Term_putstr(j*4, 20, -1, a, "###");
3713 /* Exhibit all colors */
3714 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3717 /* Describe the color */
3718 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3720 /* Describe the color */
3721 Term_putstr(5, 10, -1, TERM_WHITE,
3722 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3724 /* Label the Current values */
3725 Term_putstr(5, 12, -1, TERM_WHITE,
3726 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3727 angband_color_table[a][0],
3728 angband_color_table[a][1],
3729 angband_color_table[a][2],
3730 angband_color_table[a][3]));
3733 Term_putstr(0, 14, -1, TERM_WHITE,
3734 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3739 if (i == ESCAPE) break;
3742 if (i == 'n') a = (byte)(a + 1);
3743 if (i == 'N') a = (byte)(a - 1);
3744 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3745 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3746 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3747 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3748 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3749 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3750 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3751 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3753 /* Hack -- react to changes */
3754 Term_xtra(TERM_XTRA_REACT, 0);
3756 /* Hack -- redraw */
3763 /* Unknown option */
3777 * Note something in the message recall
3779 void do_cmd_note(void)
3787 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3789 /* Ignore empty notes */
3790 if (!buf[0] || (buf[0] == ' ')) return;
3792 /* Add the note to the message recall */
3793 msg_format(_("メモ: %s", "Note: %s"), buf);
3798 * Mention the current version
3800 void do_cmd_version(void)
3802 #if FAKE_VER_EXTRA > 0
3803 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3804 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3806 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3807 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3814 * Array of feeling strings
3816 static concptr do_cmd_feeling_text[11] =
3818 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3819 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3820 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3821 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3822 _("とても悪い予感がする...", "You have a very bad feeling..."),
3823 _("悪い予感がする...", "You have a bad feeling..."),
3824 _("何か緊張する。", "You feel nervous."),
3825 _("少し不運な気がする...", "You feel your luck is turning..."),
3826 _("この場所は好きになれない。", "You don't like the look of this place."),
3827 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3828 _("なんて退屈なところだ...", "What a boring place...")
3831 static concptr do_cmd_feeling_text_combat[11] =
3833 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3834 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3835 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3836 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3837 _("とても悪い予感がする...", "You have a very bad feeling..."),
3838 _("悪い予感がする...", "You have a bad feeling..."),
3839 _("何か緊張する。", "You feel nervous."),
3840 _("少し不運な気がする...", "You feel your luck is turning..."),
3841 _("この場所は好きになれない。", "You don't like the look of this place."),
3842 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3843 _("なんて退屈なところだ...", "What a boring place...")
3846 static concptr do_cmd_feeling_text_lucky[11] =
3848 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3849 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3850 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3851 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3852 _("とても良い感じがする...", "You have a very good feeling..."),
3853 _("良い感じがする...", "You have a good feeling..."),
3854 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3855 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3856 _("見た感じ悪くはない...", "You like the look of this place..."),
3857 _("全然駄目ということはないが...", "This level can't be all bad..."),
3858 _("なんて退屈なところだ...", "What a boring place...")
3863 * Note that "feeling" is set to zero unless some time has passed.
3864 * Note that this is done when the level is GENERATED, not entered.
3866 void do_cmd_feeling(void)
3868 if (p_ptr->wild_mode) return;
3870 /* No useful feeling in quests */
3871 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3873 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3877 /* No useful feeling in town */
3878 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3880 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3882 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3887 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3892 /* No useful feeling in the wilderness */
3893 else if (!current_floor_ptr->dun_level)
3895 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3899 /* Display the feeling */
3900 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3901 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3902 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3903 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3904 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3906 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3912 * Description of each monster group.
3914 static concptr monster_group_text[] =
3917 "ユニーク", /* "Uniques" */
3918 "乗馬可能なモンスター", /* "Riding" */
3919 "賞金首", /* "Wanted */
3920 "アンバーの王族", /* "Ambertite" */
3949 /* "古代ドラゴン/ワイアーム", */
4010 /* "Ancient Dragon/Wyrm", */
4019 "Multi-Headed Reptile",
4024 "Reptile/Amphibian",
4025 "Spider/Scorpion/Tick",
4027 /* "Major Demon", */
4044 * Symbols of monsters in each group. Note the "Uniques" group
4045 * is handled differently.
4047 static concptr monster_group_char[] =
4104 "!$&()+./=>?[\\]`{|~",
4114 * Build a list of monster indexes in the given group. Return the number
4115 * of monsters in the group.
4117 * mode & 0x01 : check for non-empty group
4118 * mode & 0x02 : visual operation only
4120 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4126 /* Get a list of x_char in this group */
4127 concptr group_char = monster_group_char[grp_cur];
4129 /* XXX Hack -- Check if this is the "Uniques" group */
4130 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4132 /* XXX Hack -- Check if this is the "Riding" group */
4133 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4135 /* XXX Hack -- Check if this is the "Wanted" group */
4136 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4138 /* XXX Hack -- Check if this is the "Amberite" group */
4139 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4142 /* Check every race */
4143 for (i = 0; i < max_r_idx; i++)
4145 /* Access the race */
4146 monster_race *r_ptr = &r_info[i];
4148 /* Skip empty race */
4149 if (!r_ptr->name) continue ;
4151 /* Require known monsters */
4152 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4156 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4159 else if (grp_riding)
4161 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4164 else if (grp_wanted)
4166 bool wanted = FALSE;
4168 for (j = 0; j < MAX_KUBI; j++)
4170 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4171 (p_ptr->today_mon && p_ptr->today_mon == i))
4177 if (!wanted) continue;
4180 else if (grp_amberite)
4182 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4187 /* Check for race in the group */
4188 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4192 mon_idx[mon_cnt++] = i;
4194 /* XXX Hack -- Just checking for non-empty group */
4195 if (mode & 0x01) break;
4198 /* Terminate the list */
4199 mon_idx[mon_cnt] = -1;
4201 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4203 /* Return the number of races */
4209 * Description of each monster group.
4211 static concptr object_group_text[] =
4214 "キノコ", /* "Mushrooms" */
4215 "薬", /* "Potions" */
4216 "油つぼ", /* "Flasks" */
4217 "巻物", /* "Scrolls" */
4219 "アミュレット", /* "Amulets" */
4220 "笛", /* "Whistle" */
4221 "光源", /* "Lanterns" */
4222 "魔法棒", /* "Wands" */
4225 "カード", /* "Cards" */
4236 "刀剣類", /* "Swords" */
4237 "鈍器", /* "Blunt Weapons" */
4238 "長柄武器", /* "Polearms" */
4239 "採掘道具", /* "Diggers" */
4240 "飛び道具", /* "Bows" */
4244 "軽装鎧", /* "Soft Armor" */
4245 "重装鎧", /* "Hard Armor" */
4246 "ドラゴン鎧", /* "Dragon Armor" */
4247 "盾", /* "Shields" */
4248 "クローク", /* "Cloaks" */
4249 "籠手", /* "Gloves" */
4250 "ヘルメット", /* "Helms" */
4252 "ブーツ", /* "Boots" */
4305 * TVALs of items in each group
4307 static byte object_group_tval[] =
4348 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4356 * Build a list of object indexes in the given group. Return the number
4357 * of objects in the group.
4359 * mode & 0x01 : check for non-empty group
4360 * mode & 0x02 : visual operation only
4362 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4364 KIND_OBJECT_IDX i, object_cnt = 0;
4367 /* Get a list of x_char in this group */
4368 byte group_tval = object_group_tval[grp_cur];
4370 /* Check every object */
4371 for (i = 0; i < max_k_idx; i++)
4373 /* Access the object */
4374 object_kind *k_ptr = &k_info[i];
4376 /* Skip empty objects */
4377 if (!k_ptr->name) continue;
4381 /* Any objects will be displayed */
4387 /* Skip non-flavoured objects */
4388 if (!k_ptr->flavor) continue;
4390 /* Require objects ever seen */
4391 if (!k_ptr->aware) continue;
4394 /* Skip items with no distribution (special artifacts) */
4395 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4399 /* Check for objects in the group */
4400 if (TV_LIFE_BOOK == group_tval)
4402 /* Hack -- All spell books */
4403 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4405 /* Add the object */
4406 object_idx[object_cnt++] = i;
4410 else if (k_ptr->tval == group_tval)
4412 /* Add the object */
4413 object_idx[object_cnt++] = i;
4417 /* XXX Hack -- Just checking for non-empty group */
4418 if (mode & 0x01) break;
4421 /* Terminate the list */
4422 object_idx[object_cnt] = -1;
4424 /* Return the number of objects */
4430 * Description of each feature group.
4432 static concptr feature_group_text[] =
4440 * Build a list of feature indexes in the given group. Return the number
4441 * of features in the group.
4443 * mode & 0x01 : check for non-empty group
4445 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4448 FEAT_IDX feat_cnt = 0;
4450 /* Unused; There is a single group. */
4453 /* Check every feature */
4454 for (i = 0; i < max_f_idx; i++)
4456 feature_type *f_ptr = &f_info[i];
4458 /* Skip empty index */
4459 if (!f_ptr->name) continue;
4461 /* Skip mimiccing features */
4462 if (f_ptr->mimic != i) continue;
4465 feat_idx[feat_cnt++] = i;
4467 /* XXX Hack -- Just checking for non-empty group */
4468 if (mode & 0x01) break;
4471 /* Terminate the list */
4472 feat_idx[feat_cnt] = -1;
4474 /* Return the number of races */
4481 * Build a list of monster indexes in the given group. Return the number
4482 * of monsters in the group.
4484 static int collect_artifacts(int grp_cur, int object_idx[])
4486 int i, object_cnt = 0;
4488 /* Get a list of x_char in this group */
4489 byte group_tval = object_group_tval[grp_cur];
4491 /* Check every object */
4492 for (i = 0; i < max_a_idx; i++)
4494 /* Access the artifact */
4495 artifact_type *a_ptr = &a_info[i];
4497 /* Skip empty artifacts */
4498 if (!a_ptr->name) continue;
4500 /* Skip "uncreated" artifacts */
4501 if (!a_ptr->cur_num) continue;
4503 /* Check for race in the group */
4504 if (a_ptr->tval == group_tval)
4507 object_idx[object_cnt++] = i;
4511 /* Terminate the list */
4512 object_idx[object_cnt] = 0;
4514 /* Return the number of races */
4521 * Encode the screen colors
4523 static char hack[17] = "dwsorgbuDWvyRGBU";
4527 * Hack -- load a screen dump from a file
4529 void do_cmd_load_screen(void)
4534 SYMBOL_CODE c = ' ';
4540 Term_get_size(&wid, &hgt);
4542 /* Build the filename */
4543 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4545 /* Append to the file */
4546 fff = my_fopen(buf, "r");
4549 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4557 /* Load the screen */
4558 for (y = 0; okay; y++)
4560 /* Get a line of data including control code */
4561 if (!fgets(buf, 1024, fff)) okay = FALSE;
4563 /* Get the blank line */
4564 if (buf[0] == '\n' || buf[0] == '\0') break;
4566 /* Ignore too large screen image */
4567 if (y >= hgt) continue;
4570 for (x = 0; x < wid - 1; x++)
4573 if (buf[x] == '\n' || buf[x] == '\0') break;
4575 /* Put the attr/char */
4576 Term_draw(x, y, TERM_WHITE, buf[x]);
4580 /* Dump the screen */
4581 for (y = 0; okay; y++)
4583 /* Get a line of data including control code */
4584 if (!fgets(buf, 1024, fff)) okay = FALSE;
4586 /* Get the blank line */
4587 if (buf[0] == '\n' || buf[0] == '\0') break;
4589 /* Ignore too large screen image */
4590 if (y >= hgt) continue;
4593 for (x = 0; x < wid - 1; x++)
4596 if (buf[x] == '\n' || buf[x] == '\0') break;
4598 /* Get the attr/char */
4599 (void)(Term_what(x, y, &a, &c));
4601 /* Look up the attr */
4602 for (i = 0; i < 16; i++)
4604 /* Use attr matches */
4605 if (hack[i] == buf[x]) a = (byte_hack)i;
4608 /* Put the attr/char */
4609 Term_draw(x, y, a, c);
4614 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4625 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4626 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4629 #define IM_FLAG_STR _("*", "* ")
4630 #define HAS_FLAG_STR _("+", "+ ")
4631 #define NO_FLAG_STR _("・", ". ")
4633 #define print_im_or_res_flag(IM, RES) \
4635 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4636 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4639 #define print_flag(TR) \
4641 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4645 /* XTRA HACK RESLIST */
4646 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4648 GAME_TEXT o_name[MAX_NLEN];
4649 BIT_FLAGS flgs[TR_FLAG_SIZE];
4651 if (!o_ptr->k_idx) return;
4652 if (o_ptr->tval != tval) return;
4654 /* Identified items only */
4655 if (!object_is_known(o_ptr)) return;
4658 * HACK:Ring of Lordly protection and Dragon equipment
4659 * have random resistances.
4661 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4662 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4663 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4664 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4665 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4666 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4667 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4668 || object_is_artifact(o_ptr))
4671 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4673 while (o_name[i] && (i < 26))
4676 if (iskanji(o_name[i])) i++;
4685 o_name[i] = ' '; i++;
4690 fprintf(fff, "%s %s", where, o_name);
4692 if (!(o_ptr->ident & (IDENT_MENTAL)))
4694 fputs(_("-------不明--------------- -------不明---------\n",
4695 "-------unknown------------ -------unknown------\n"), fff);
4699 object_flags_known(o_ptr, flgs);
4701 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4702 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4703 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4704 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4705 print_flag(TR_RES_POIS);
4706 print_flag(TR_RES_LITE);
4707 print_flag(TR_RES_DARK);
4708 print_flag(TR_RES_SHARDS);
4709 print_flag(TR_RES_SOUND);
4710 print_flag(TR_RES_NETHER);
4711 print_flag(TR_RES_NEXUS);
4712 print_flag(TR_RES_CHAOS);
4713 print_flag(TR_RES_DISEN);
4717 print_flag(TR_RES_BLIND);
4718 print_flag(TR_RES_FEAR);
4719 print_flag(TR_RES_CONF);
4720 print_flag(TR_FREE_ACT);
4721 print_flag(TR_SEE_INVIS);
4722 print_flag(TR_HOLD_EXP);
4723 print_flag(TR_TELEPATHY);
4724 print_flag(TR_SLOW_DIGEST);
4725 print_flag(TR_REGEN);
4726 print_flag(TR_LEVITATION);
4734 fprintf(fff, "%s\n", inven_res_label);
4740 * Display *ID* ed weapons/armors's resistances
4742 static void do_cmd_knowledge_inven(void)
4745 GAME_TEXT file_name[1024];
4747 OBJECT_TYPE_VALUE tval;
4753 /* Open a new file */
4754 fff = my_fopen_temp(file_name, 1024);
4757 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4761 fprintf(fff, "%s\n", inven_res_label);
4763 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4767 for (; j < 9; j++) fputc('\n', fff);
4769 fprintf(fff, "%s\n", inven_res_label);
4771 strcpy(where, _("装", "E "));
4772 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4774 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4776 strcpy(where, _("持", "I "));
4777 for (i = 0; i < INVEN_PACK; i++)
4779 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4782 st_ptr = &town_info[1].store[STORE_HOME];
4783 strcpy(where, _("家", "H "));
4784 for (i = 0; i < st_ptr->stock_num; i++)
4786 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4791 /* Display the file contents */
4792 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4797 void do_cmd_save_screen_html_aux(char *filename, int message)
4802 TERM_COLOR a = 0, old_a = 0;
4816 concptr html_head[] = {
4817 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4821 concptr html_foot[] = {
4823 "</body>\n</html>\n",
4829 Term_get_size(&wid, &hgt);
4831 /* File type is "TEXT" */
4832 FILE_TYPE(FILE_TYPE_TEXT);
4834 /* Append to the file */
4835 fff = my_fopen(filename, "w");
4839 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4845 if (message) screen_save();
4847 /* Build the filename */
4848 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4849 tmpfff = my_fopen(buf, "r");
4851 for (i = 0; html_head[i]; i++)
4852 fputs(html_head[i], fff);
4856 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4858 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4862 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4864 fprintf(fff, "%s\n", buf);
4869 /* Dump the screen */
4870 for (y = 0; y < hgt; y++)
4877 for (x = 0; x < wid - 1; x++)
4881 /* Get the attr/char */
4882 (void)(Term_what(x, y, &a, &c));
4886 case '&': cc = "&"; break;
4887 case '<': cc = "<"; break;
4888 case '>': cc = ">"; break;
4890 case 0x1f: c = '.'; break;
4891 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4896 if ((y == 0 && x == 0) || a != old_a) {
4897 rv = angband_color_table[a][1];
4898 gv = angband_color_table[a][2];
4899 bv = angband_color_table[a][3];
4900 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4901 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4905 fprintf(fff, "%s", cc);
4907 fprintf(fff, "%c", c);
4910 fprintf(fff, "</font>");
4913 for (i = 0; html_foot[i]; i++)
4914 fputs(html_foot[i], fff);
4919 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4921 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4925 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4927 fprintf(fff, "%s\n", buf);
4938 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4946 * Hack -- save a screen dump to a file
4948 static void do_cmd_save_screen_html(void)
4950 char buf[1024], tmp[256] = "screen.html";
4952 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4955 /* Build the filename */
4956 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4960 do_cmd_save_screen_html_aux(buf, 1);
4965 * Redefinable "save_screen" action
4967 void (*screendump_aux)(void) = NULL;
4971 * Hack -- save a screen dump to a file
4973 void do_cmd_save_screen(void)
4975 bool old_use_graphics = use_graphics;
4976 bool html_dump = FALSE;
4980 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4984 if (c == 'Y' || c == 'y')
4986 else if (c == 'H' || c == 'h')
4998 Term_get_size(&wid, &hgt);
5000 if (old_use_graphics)
5002 use_graphics = FALSE;
5004 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5010 do_cmd_save_screen_html();
5014 /* Do we use a special screendump function ? */
5015 else if (screendump_aux)
5017 /* Dump the screen to a graphics file */
5018 (*screendump_aux)();
5020 else /* Dump the screen as text */
5024 SYMBOL_CODE c = ' ';
5028 /* Build the filename */
5029 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5031 /* File type is "TEXT" */
5032 FILE_TYPE(FILE_TYPE_TEXT);
5034 /* Append to the file */
5035 fff = my_fopen(buf, "w");
5039 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5047 /* Dump the screen */
5048 for (y = 0; y < hgt; y++)
5051 for (x = 0; x < wid - 1; x++)
5053 /* Get the attr/char */
5054 (void)(Term_what(x, y, &a, &c));
5064 fprintf(fff, "%s\n", buf);
5071 /* Dump the screen */
5072 for (y = 0; y < hgt; y++)
5075 for (x = 0; x < wid - 1; x++)
5077 /* Get the attr/char */
5078 (void)(Term_what(x, y, &a, &c));
5081 buf[x] = hack[a&0x0F];
5088 fprintf(fff, "%s\n", buf);
5095 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5100 if (old_use_graphics)
5102 use_graphics = TRUE;
5104 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5110 * Check the status of "artifacts"
5112 static void do_cmd_knowledge_artifacts(void)
5122 GAME_TEXT file_name[1024];
5123 GAME_TEXT base_name[MAX_NLEN];
5127 /* Open a new file */
5128 fff = my_fopen_temp(file_name, 1024);
5131 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5136 /* Allocate the "who" array */
5137 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5139 /* Allocate the "okay" array */
5140 C_MAKE(okay, max_a_idx, bool);
5142 /* Scan the artifacts */
5143 for (k = 0; k < max_a_idx; k++)
5145 artifact_type *a_ptr = &a_info[k];
5150 /* Skip "empty" artifacts */
5151 if (!a_ptr->name) continue;
5153 /* Skip "uncreated" artifacts */
5154 if (!a_ptr->cur_num) continue;
5160 /* Check the dungeon */
5161 for (y = 0; y < current_floor_ptr->height; y++)
5163 for (x = 0; x < current_floor_ptr->width; x++)
5165 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5167 OBJECT_IDX this_o_idx, next_o_idx = 0;
5169 /* Scan all objects in the grid */
5170 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5173 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5174 next_o_idx = o_ptr->next_o_idx;
5176 /* Ignore non-artifacts */
5177 if (!object_is_fixed_artifact(o_ptr)) continue;
5179 /* Ignore known items */
5180 if (object_is_known(o_ptr)) continue;
5182 /* Note the artifact */
5183 okay[o_ptr->name1] = FALSE;
5188 /* Check the inventory and equipment */
5189 for (i = 0; i < INVEN_TOTAL; i++)
5191 object_type *o_ptr = &inventory[i];
5193 /* Ignore non-objects */
5194 if (!o_ptr->k_idx) continue;
5196 /* Ignore non-artifacts */
5197 if (!object_is_fixed_artifact(o_ptr)) continue;
5199 /* Ignore known items */
5200 if (object_is_known(o_ptr)) continue;
5202 /* Note the artifact */
5203 okay[o_ptr->name1] = FALSE;
5206 for (k = 0; k < max_a_idx; k++)
5208 if (okay[k]) who[n++] = k;
5211 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5213 /* Scan the artifacts */
5214 for (k = 0; k < n; k++)
5216 artifact_type *a_ptr = &a_info[who[k]];
5217 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5219 /* Obtain the base object type */
5220 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5229 /* Create fake object */
5230 object_prep(q_ptr, z);
5232 /* Make it an artifact */
5233 q_ptr->name1 = (byte)who[k];
5235 /* Display as if known */
5236 q_ptr->ident |= IDENT_STORE;
5238 /* Describe the artifact */
5239 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5242 /* Hack -- Build the artifact name */
5243 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5246 /* Free the "who" array */
5247 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5249 /* Free the "okay" array */
5250 C_KILL(okay, max_a_idx, bool);
5253 /* Display the file contents */
5254 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5260 * Display known uniques
5261 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5263 static void do_cmd_knowledge_uniques(void)
5272 GAME_TEXT file_name[1024];
5275 int n_alive_surface = 0;
5276 int n_alive_over100 = 0;
5277 int n_alive_total = 0;
5280 for (i = 0; i < 10; i++) n_alive[i] = 0;
5282 /* Open a new file */
5283 fff = my_fopen_temp(file_name, 1024);
5287 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5292 /* Allocate the "who" array */
5293 C_MAKE(who, max_r_idx, MONRACE_IDX);
5295 /* Scan the monsters */
5296 for (i = 1; i < max_r_idx; i++)
5298 monster_race *r_ptr = &r_info[i];
5301 if (!r_ptr->name) continue;
5303 /* Require unique monsters */
5304 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5306 /* Only display "known" uniques */
5307 if (!cheat_know && !r_ptr->r_sights) continue;
5309 /* Only print rarity <= 100 uniques */
5310 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5312 /* Only "alive" uniques */
5313 if (r_ptr->max_num == 0) continue;
5317 lev = (r_ptr->level - 1) / 10;
5321 if (max_lev < lev) max_lev = lev;
5323 else n_alive_over100++;
5325 else n_alive_surface++;
5327 /* Collect "appropriate" monsters */
5331 /* Sort the array by dungeon depth of monsters */
5332 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5334 if (n_alive_surface)
5336 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5337 n_alive_total += n_alive_surface;
5339 for (i = 0; i <= max_lev; i++)
5341 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5342 n_alive_total += n_alive[i];
5344 if (n_alive_over100)
5346 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5347 n_alive_total += n_alive_over100;
5352 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5353 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5357 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5360 /* Scan the monster races */
5361 for (k = 0; k < n; k++)
5363 monster_race *r_ptr = &r_info[who[k]];
5365 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5368 /* Free the "who" array */
5369 C_KILL(who, max_r_idx, s16b);
5372 /* Display the file contents */
5373 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5379 * Display weapon-exp
5381 static void do_cmd_knowledge_weapon_exp(void)
5389 GAME_TEXT file_name[1024];
5392 /* Open a new file */
5393 fff = my_fopen_temp(file_name, 1024);
5395 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5400 for (i = 0; i < 5; i++)
5402 for (num = 0; num < 64; num++)
5404 for (j = 0; j < max_k_idx; j++)
5406 object_kind *k_ptr = &k_info[j];
5408 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5410 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5412 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5414 fprintf(fff, "%-25s ", tmp);
5415 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5416 else fprintf(fff, " ");
5417 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5418 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5427 /* Display the file contents */
5428 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5434 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5438 static void do_cmd_knowledge_spell_exp(void)
5445 const magic_type *s_ptr;
5447 GAME_TEXT file_name[1024];
5449 /* Open a new file */
5450 fff = my_fopen_temp(file_name, 1024);
5452 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5457 if (p_ptr->realm1 != REALM_NONE)
5459 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5460 for (i = 0; i < 32; i++)
5462 if (!is_magic(p_ptr->realm1))
5464 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5468 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5470 if (s_ptr->slevel >= 99) continue;
5471 spell_exp = p_ptr->spell_exp[i];
5472 exp_level = spell_exp_level(spell_exp);
5473 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5474 if (p_ptr->realm1 == REALM_HISSATSU)
5475 fprintf(fff, "[--]");
5478 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5479 else fprintf(fff, " ");
5480 fprintf(fff, "%s", exp_level_str[exp_level]);
5482 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5487 if (p_ptr->realm2 != REALM_NONE)
5489 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5490 for (i = 0; i < 32; i++)
5492 if (!is_magic(p_ptr->realm1))
5494 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5498 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5500 if (s_ptr->slevel >= 99) continue;
5502 spell_exp = p_ptr->spell_exp[i + 32];
5503 exp_level = spell_exp_level(spell_exp);
5504 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5505 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5506 else fprintf(fff, " ");
5507 fprintf(fff, "%s", exp_level_str[exp_level]);
5508 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5514 /* Display the file contents */
5515 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5521 * @brief スキル情報を表示するコマンドのメインルーチン /
5525 static void do_cmd_knowledge_skill_exp(void)
5527 int i = 0, skill_exp;
5531 char file_name[1024];
5532 char skill_name[GINOU_TEMPMAX][20] =
5534 _("マーシャルアーツ", "Martial Arts "),
5535 _("二刀流 ", "Dual Wielding "),
5536 _("乗馬 ", "Riding "),
5540 /* Open a new file */
5541 fff = my_fopen_temp(file_name, 1024);
5543 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5548 for (i = 0; i < GINOU_TEMPMAX; i++)
5550 skill_exp = p_ptr->skill_exp[i];
5551 fprintf(fff, "%-20s ", skill_name[i]);
5552 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5553 else fprintf(fff, " ");
5554 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5555 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5560 /* Display the file contents */
5561 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5567 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5568 * @param Name 変換したい文字列の参照ポインタ
5571 void plural_aux(char *Name)
5573 int NameLen = strlen(Name);
5575 if (my_strstr(Name, "Disembodied hand"))
5577 strcpy(Name, "Disembodied hands that strangled people");
5579 else if (my_strstr(Name, "Colour out of space"))
5581 strcpy(Name, "Colours out of space");
5583 else if (my_strstr(Name, "stairway to hell"))
5585 strcpy(Name, "stairways to hell");
5587 else if (my_strstr(Name, "Dweller on the threshold"))
5589 strcpy(Name, "Dwellers on the threshold");
5591 else if (my_strstr(Name, " of "))
5593 concptr aider = my_strstr(Name, " of ");
5604 if (dummy[i-1] == 's')
5606 strcpy(&(dummy[i]), "es");
5611 strcpy(&(dummy[i]), "s");
5614 strcpy(&(dummy[i+1]), aider);
5615 strcpy(Name, dummy);
5617 else if (my_strstr(Name, "coins"))
5620 strcpy(dummy, "piles of ");
5621 strcat(dummy, Name);
5622 strcpy(Name, dummy);
5625 else if (my_strstr(Name, "Manes"))
5629 else if (streq(&(Name[NameLen - 2]), "ey"))
5631 strcpy(&(Name[NameLen - 2]), "eys");
5633 else if (Name[NameLen - 1] == 'y')
5635 strcpy(&(Name[NameLen - 1]), "ies");
5637 else if (streq(&(Name[NameLen - 4]), "ouse"))
5639 strcpy(&(Name[NameLen - 4]), "ice");
5641 else if (streq(&(Name[NameLen - 2]), "us"))
5643 strcpy(&(Name[NameLen - 2]), "i");
5645 else if (streq(&(Name[NameLen - 6]), "kelman"))
5647 strcpy(&(Name[NameLen - 6]), "kelmen");
5649 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5651 strcpy(&(Name[NameLen - 8]), "wordsmen");
5653 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5655 strcpy(&(Name[NameLen - 7]), "oodsmen");
5657 else if (streq(&(Name[NameLen - 7]), "eastman"))
5659 strcpy(&(Name[NameLen - 7]), "eastmen");
5661 else if (streq(&(Name[NameLen - 8]), "izardman"))
5663 strcpy(&(Name[NameLen - 8]), "izardmen");
5665 else if (streq(&(Name[NameLen - 5]), "geist"))
5667 strcpy(&(Name[NameLen - 5]), "geister");
5669 else if (streq(&(Name[NameLen - 2]), "ex"))
5671 strcpy(&(Name[NameLen - 2]), "ices");
5673 else if (streq(&(Name[NameLen - 2]), "lf"))
5675 strcpy(&(Name[NameLen - 2]), "lves");
5677 else if (suffix(Name, "ch") ||
5678 suffix(Name, "sh") ||
5679 suffix(Name, "nx") ||
5680 suffix(Name, "s") ||
5683 strcpy(&(Name[NameLen]), "es");
5687 strcpy(&(Name[NameLen]), "s");
5692 * @brief 現在のペットを表示するコマンドのメインルーチン /
5693 * Display current pets
5696 static void do_cmd_knowledge_pets(void)
5700 monster_type *m_ptr;
5701 GAME_TEXT pet_name[MAX_NLEN];
5703 int show_upkeep = 0;
5704 GAME_TEXT file_name[1024];
5707 /* Open a new file */
5708 fff = my_fopen_temp(file_name, 1024);
5710 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5715 /* Process the monsters (backwards) */
5716 for (i = m_max - 1; i >= 1; i--)
5718 /* Access the monster */
5719 m_ptr = ¤t_floor_ptr->m_list[i];
5721 /* Ignore "dead" monsters */
5722 if (!monster_is_valid(m_ptr)) continue;
5724 /* Calculate "upkeep" for pets */
5728 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5729 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5733 show_upkeep = calculate_upkeep();
5735 fprintf(fff, "----------------------------------------------\n");
5737 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5739 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5741 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5746 /* Display the file contents */
5747 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5753 * @brief 現在のペットを表示するコマンドのメインルーチン /
5756 * @note the player ghosts are ignored.
5758 static void do_cmd_knowledge_kill_count(void)
5765 GAME_TEXT file_name[1024];
5770 /* Open a new file */
5771 fff = my_fopen_temp(file_name, 1024);
5774 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5779 /* Allocate the "who" array */
5780 C_MAKE(who, max_r_idx, MONRACE_IDX);
5783 /* Monsters slain */
5786 for (kk = 1; kk < max_r_idx; kk++)
5788 monster_race *r_ptr = &r_info[kk];
5790 if (r_ptr->flags1 & (RF1_UNIQUE))
5792 bool dead = (r_ptr->max_num == 0);
5801 MONSTER_NUMBER This = r_ptr->r_pkills;
5811 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5814 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5816 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5822 /* Scan the monsters */
5823 for (i = 1; i < max_r_idx; i++)
5825 monster_race *r_ptr = &r_info[i];
5827 /* Use that monster */
5828 if (r_ptr->name) who[n++] = i;
5831 /* Sort the array by dungeon depth of monsters */
5832 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5834 /* Scan the monster races */
5835 for (k = 0; k < n; k++)
5837 monster_race *r_ptr = &r_info[who[k]];
5839 if (r_ptr->flags1 & (RF1_UNIQUE))
5841 bool dead = (r_ptr->max_num == 0);
5845 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5851 MONSTER_NUMBER This = r_ptr->r_pkills;
5856 /* p,tは人と数える by ita */
5857 if (my_strchr("pt", r_ptr->d_char))
5858 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5860 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5864 if (my_strstr(r_name + r_ptr->name, "coins"))
5866 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5870 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5876 strcpy(ToPlural, (r_name + r_ptr->name));
5877 plural_aux(ToPlural);
5878 fprintf(fff, " %d %s\n", This, ToPlural);
5888 fprintf(fff,"----------------------------------------------\n");
5890 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5892 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5896 /* Free the "who" array */
5897 C_KILL(who, max_r_idx, s16b);
5900 /* Display the file contents */
5901 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5907 * @brief モンスター情報リスト中のグループを表示する /
5908 * Display the object groups.
5912 * @param per_page リストの表示行
5913 * @param grp_idx グループのID配列
5914 * @param group_text グループ名の文字列配列
5915 * @param grp_cur 現在の選択ID
5916 * @param grp_top 現在の選択リスト最上部ID
5919 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)
5923 /* Display lines until done */
5924 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5926 /* Get the group index */
5927 int grp = grp_idx[grp_top + i];
5929 /* Choose a color */
5930 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5932 /* Erase the entire line */
5933 Term_erase(col, row + i, wid);
5935 /* Display the group label */
5936 c_put_str(attr, group_text[grp], row + i, col);
5942 * Move the cursor in a browser window
5944 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5945 IDX *list_cur, int list_cnt)
5950 IDX list = *list_cur;
5952 /* Extract direction */
5955 /* Hack -- scroll up full screen */
5960 /* Hack -- scroll down full screen */
5965 d = get_keymap_dir(ch);
5970 /* Diagonals - hack */
5971 if ((ddx[d] > 0) && ddy[d])
5976 Term_get_size(&wid, &hgt);
5978 browser_rows = hgt - 8;
5980 /* Browse group list */
5985 /* Move up or down */
5986 grp += ddy[d] * (browser_rows - 1);
5989 if (grp >= grp_cnt) grp = grp_cnt - 1;
5990 if (grp < 0) grp = 0;
5991 if (grp != old_grp) list = 0;
5994 /* Browse sub-list list */
5997 /* Move up or down */
5998 list += ddy[d] * browser_rows;
6001 if (list >= list_cnt) list = list_cnt - 1;
6002 if (list < 0) list = 0;
6014 if (col < 0) col = 0;
6015 if (col > 1) col = 1;
6022 /* Browse group list */
6027 /* Move up or down */
6031 if (grp >= grp_cnt) grp = grp_cnt - 1;
6032 if (grp < 0) grp = 0;
6033 if (grp != old_grp) list = 0;
6036 /* Browse sub-list list */
6039 /* Move up or down */
6040 list += (IDX)ddy[d];
6043 if (list >= list_cnt) list = list_cnt - 1;
6044 if (list < 0) list = 0;
6055 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6059 /* Clear the display lines */
6060 for (i = 0; i < height; i++)
6062 Term_erase(col, row + i, width);
6065 /* Bigtile mode uses double width */
6066 if (use_bigtile) width /= 2;
6068 /* Display lines until done */
6069 for (i = 0; i < height; i++)
6071 /* Display columns until done */
6072 for (j = 0; j < width; j++)
6076 TERM_LEN x = col + j;
6077 TERM_LEN y = row + i;
6079 /* Bigtile mode uses double width */
6080 if (use_bigtile) x += j;
6085 /* Ignore illegal characters */
6086 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6087 (!use_graphics && ic > 0x7f))
6093 /* Force correct code for both ASCII character and tile */
6094 if (c & 0x80) a |= 0x80;
6096 /* Display symbol */
6097 Term_queue_bigchar(x, y, a, c, 0, 0);
6104 * Place the cursor at the collect position for visual mode
6106 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6108 int i = (a & 0x7f) - attr_top;
6109 int j = c - char_left;
6111 TERM_LEN x = col + j;
6112 TERM_LEN y = row + i;
6114 /* Bigtile mode uses double width */
6115 if (use_bigtile) x += j;
6117 /* Place the cursor */
6123 * Clipboard variables for copy&paste in visual mode
6125 static TERM_COLOR attr_idx = 0;
6126 static SYMBOL_CODE char_idx = 0;
6128 /* Hack -- for feature lighting */
6129 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6130 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6133 * Do visual mode command -- Change symbols
6135 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6136 int height, int width,
6137 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6138 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6140 static TERM_COLOR attr_old = 0;
6141 static SYMBOL_CODE char_old = 0;
6146 if (*visual_list_ptr)
6149 *cur_attr_ptr = attr_old;
6150 *cur_char_ptr = char_old;
6151 *visual_list_ptr = FALSE;
6159 if (*visual_list_ptr)
6162 *visual_list_ptr = FALSE;
6163 *need_redraw = TRUE;
6171 if (!*visual_list_ptr)
6173 *visual_list_ptr = TRUE;
6175 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6176 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6178 attr_old = *cur_attr_ptr;
6179 char_old = *cur_char_ptr;
6190 /* Set the visual */
6191 attr_idx = *cur_attr_ptr;
6192 char_idx = *cur_char_ptr;
6194 /* Hack -- for feature lighting */
6195 for (i = 0; i < F_LIT_MAX; i++)
6197 attr_idx_feat[i] = 0;
6198 char_idx_feat[i] = 0;
6205 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6208 *cur_attr_ptr = attr_idx;
6209 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6210 if (!*visual_list_ptr) *need_redraw = TRUE;
6216 *cur_char_ptr = char_idx;
6217 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6218 if (!*visual_list_ptr) *need_redraw = TRUE;
6224 if (*visual_list_ptr)
6227 int d = get_keymap_dir(ch);
6228 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6229 SYMBOL_CODE c = *cur_char_ptr;
6231 if (use_bigtile) eff_width = width / 2;
6232 else eff_width = width;
6234 /* Restrict direction */
6235 if ((a == 0) && (ddy[d] < 0)) d = 0;
6236 if ((c == 0) && (ddx[d] < 0)) d = 0;
6237 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6238 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6240 a += (TERM_COLOR)ddy[d];
6241 c += (SYMBOL_CODE)ddx[d];
6243 /* Force correct code for both ASCII character and tile */
6244 if (c & 0x80) a |= 0x80;
6246 /* Set the visual */
6251 /* Move the frame */
6252 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6253 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6254 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6255 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6261 /* Visual mode command is not used */
6267 * Display the monsters in a group.
6269 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6270 int mon_cur, int mon_top, bool visual_only)
6274 /* Display lines until done */
6275 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6279 /* Get the race index */
6280 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6282 /* Access the race */
6283 monster_race *r_ptr = &r_info[r_idx];
6285 /* Choose a color */
6286 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6288 /* Display the name */
6289 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6291 /* Hack -- visual_list mode */
6294 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6296 if (p_ptr->wizard || visual_only)
6298 c_prt(attr, format("%d", r_idx), row + i, 62);
6301 /* Erase chars before overwritten by the race letter */
6302 Term_erase(69, row + i, 255);
6304 /* Display symbol */
6305 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6310 if (!(r_ptr->flags1 & RF1_UNIQUE))
6311 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6313 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6314 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6318 /* Clear remaining lines */
6319 for (; i < per_page; i++)
6321 Term_erase(col, row + i, 255);
6327 * Display known monsters.
6329 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6333 IDX grp_cur, grp_top, old_grp_cur;
6334 IDX mon_cur, mon_top;
6335 IDX grp_cnt, grp_idx[100];
6343 bool visual_list = FALSE;
6344 TERM_COLOR attr_top = 0;
6352 Term_get_size(&wid, &hgt);
6354 browser_rows = hgt - 8;
6356 /* Allocate the "mon_idx" array */
6357 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6362 if (direct_r_idx < 0)
6364 mode = visual_only ? 0x03 : 0x01;
6366 /* Check every group */
6367 for (i = 0; monster_group_text[i] != NULL; i++)
6369 /* Measure the label */
6370 len = strlen(monster_group_text[i]);
6372 /* Save the maximum length */
6373 if (len > max) max = len;
6375 /* See if any monsters are known */
6376 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6378 /* Build a list of groups with known monsters */
6379 grp_idx[grp_cnt++] = i;
6387 mon_idx[0] = direct_r_idx;
6390 /* Terminate the list */
6393 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6394 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6397 /* Terminate the list */
6398 grp_idx[grp_cnt] = -1;
6401 grp_cur = grp_top = 0;
6402 mon_cur = mon_top = 0;
6407 mode = visual_only ? 0x02 : 0x00;
6412 monster_race *r_ptr;
6417 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6418 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6419 prt(_("名前", "Name"), 4, max + 3);
6420 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6421 prt(_("文字", "Sym"), 4, 67);
6422 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6424 for (i = 0; i < 78; i++)
6426 Term_putch(i, 5, TERM_WHITE, '=');
6429 if (direct_r_idx < 0)
6431 for (i = 0; i < browser_rows; i++)
6433 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6440 if (direct_r_idx < 0)
6442 /* Scroll group list */
6443 if (grp_cur < grp_top) grp_top = grp_cur;
6444 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6446 /* Display a list of monster groups */
6447 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6449 if (old_grp_cur != grp_cur)
6451 old_grp_cur = grp_cur;
6453 /* Get a list of monsters in the current group */
6454 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6457 /* Scroll monster list */
6458 while (mon_cur < mon_top)
6459 mon_top = MAX(0, mon_top - browser_rows/2);
6460 while (mon_cur >= mon_top + browser_rows)
6461 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6466 /* Display a list of monsters in the current group */
6467 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6473 /* Display a monster name */
6474 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6476 /* Display visual list below first monster */
6477 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6481 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6482 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6483 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6484 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6487 /* Get the current monster */
6488 r_ptr = &r_info[mon_idx[mon_cur]];
6492 /* Mega Hack -- track this monster race */
6493 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6499 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6503 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6507 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6512 /* Do visual mode command if needed */
6513 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))
6515 if (direct_r_idx >= 0)
6540 /* Recall on screen */
6541 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6543 screen_roff(mon_idx[mon_cur], 0);
6554 /* Move the cursor */
6555 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6562 /* Free the "mon_idx" array */
6563 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6568 * Display the objects in a group.
6570 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6571 int object_cur, int object_top, bool visual_only)
6575 /* Display lines until done */
6576 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6578 GAME_TEXT o_name[MAX_NLEN];
6581 object_kind *flavor_k_ptr;
6583 /* Get the object index */
6584 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6586 /* Access the object */
6587 object_kind *k_ptr = &k_info[k_idx];
6589 /* Choose a color */
6590 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6591 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6594 if (!visual_only && k_ptr->flavor)
6596 /* Appearance of this object is shuffled */
6597 flavor_k_ptr = &k_info[k_ptr->flavor];
6601 /* Appearance of this object is very normal */
6602 flavor_k_ptr = k_ptr;
6607 attr = ((i + object_top == object_cur) ? cursor : attr);
6609 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6612 strip_name(o_name, k_idx);
6617 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6620 /* Display the name */
6621 c_prt(attr, o_name, row + i, col);
6623 /* Hack -- visual_list mode */
6626 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);
6628 if (p_ptr->wizard || visual_only)
6630 c_prt(attr, format("%d", k_idx), row + i, 70);
6633 a = flavor_k_ptr->x_attr;
6634 c = flavor_k_ptr->x_char;
6636 /* Display symbol */
6637 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6640 /* Clear remaining lines */
6641 for (; i < per_page; i++)
6643 Term_erase(col, row + i, 255);
6648 * Describe fake object
6650 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6653 object_type object_type_body;
6654 o_ptr = &object_type_body;
6656 object_prep(o_ptr, k_idx);
6658 /* It's fully know */
6659 o_ptr->ident |= IDENT_KNOWN;
6661 /* Track the object */
6662 /* object_actual_track(o_ptr); */
6664 /* Hack - mark as fake */
6665 /* term_obj_real = FALSE; */
6668 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6670 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6678 * Display known objects
6680 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6684 IDX grp_cur, grp_top, old_grp_cur;
6685 IDX object_old, object_cur, object_top;
6689 OBJECT_IDX *object_idx;
6695 bool visual_list = FALSE;
6696 TERM_COLOR attr_top = 0;
6704 Term_get_size(&wid, &hgt);
6706 browser_rows = hgt - 8;
6708 /* Allocate the "object_idx" array */
6709 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6714 if (direct_k_idx < 0)
6716 mode = visual_only ? 0x03 : 0x01;
6718 /* Check every group */
6719 for (i = 0; object_group_text[i] != NULL; i++)
6721 /* Measure the label */
6722 len = strlen(object_group_text[i]);
6724 /* Save the maximum length */
6725 if (len > max) max = len;
6727 /* See if any monsters are known */
6728 if (collect_objects(i, object_idx, mode))
6730 /* Build a list of groups with known monsters */
6731 grp_idx[grp_cnt++] = i;
6740 object_kind *k_ptr = &k_info[direct_k_idx];
6741 object_kind *flavor_k_ptr;
6743 if (!visual_only && k_ptr->flavor)
6745 /* Appearance of this object is shuffled */
6746 flavor_k_ptr = &k_info[k_ptr->flavor];
6750 /* Appearance of this object is very normal */
6751 flavor_k_ptr = k_ptr;
6754 object_idx[0] = direct_k_idx;
6755 object_old = direct_k_idx;
6758 /* Terminate the list */
6761 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6762 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6765 /* Terminate the list */
6766 grp_idx[grp_cnt] = -1;
6769 grp_cur = grp_top = 0;
6770 object_cur = object_top = 0;
6775 mode = visual_only ? 0x02 : 0x00;
6780 object_kind *k_ptr, *flavor_k_ptr;
6787 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6788 if (direct_k_idx < 0) prt("グループ", 4, 0);
6789 prt("名前", 4, max + 3);
6790 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6793 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6794 if (direct_k_idx < 0) prt("Group", 4, 0);
6795 prt("Name", 4, max + 3);
6796 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6800 for (i = 0; i < 78; i++)
6802 Term_putch(i, 5, TERM_WHITE, '=');
6805 if (direct_k_idx < 0)
6807 for (i = 0; i < browser_rows; i++)
6809 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6816 if (direct_k_idx < 0)
6818 /* Scroll group list */
6819 if (grp_cur < grp_top) grp_top = grp_cur;
6820 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6822 /* Display a list of object groups */
6823 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6825 if (old_grp_cur != grp_cur)
6827 old_grp_cur = grp_cur;
6829 /* Get a list of objects in the current group */
6830 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6833 /* Scroll object list */
6834 while (object_cur < object_top)
6835 object_top = MAX(0, object_top - browser_rows/2);
6836 while (object_cur >= object_top + browser_rows)
6837 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6842 /* Display a list of objects in the current group */
6843 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6847 object_top = object_cur;
6849 /* Display a list of objects in the current group */
6850 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6852 /* Display visual list below first object */
6853 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6856 /* Get the current object */
6857 k_ptr = &k_info[object_idx[object_cur]];
6859 if (!visual_only && k_ptr->flavor)
6861 /* Appearance of this object is shuffled */
6862 flavor_k_ptr = &k_info[k_ptr->flavor];
6866 /* Appearance of this object is very normal */
6867 flavor_k_ptr = k_ptr;
6872 prt(format("<方向>%s%s%s, ESC",
6873 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6874 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6875 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6878 prt(format("<dir>%s%s%s, ESC",
6879 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6880 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6881 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6887 /* Mega Hack -- track this object */
6888 if (object_cnt) object_kind_track(object_idx[object_cur]);
6890 /* The "current" object changed */
6891 if (object_old != object_idx[object_cur])
6895 /* Remember the "current" object */
6896 object_old = object_idx[object_cur];
6902 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6906 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6910 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6915 /* Do visual mode command if needed */
6916 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))
6918 if (direct_k_idx >= 0)
6943 /* Recall on screen */
6944 if (!visual_list && !visual_only && (grp_cnt > 0))
6946 desc_obj_fake(object_idx[object_cur]);
6954 /* Move the cursor */
6955 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6961 /* Free the "object_idx" array */
6962 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6967 * Display the features in a group.
6969 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6970 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6972 int lit_col[F_LIT_MAX], i, j;
6973 int f_idx_col = use_bigtile ? 62 : 64;
6975 /* Correct columns 1 and 4 */
6976 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6977 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6978 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6980 /* Display lines until done */
6981 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6984 FEAT_IDX f_idx = feat_idx[feat_top + i];
6985 feature_type *f_ptr = &f_info[f_idx];
6986 int row_i = row + i;
6988 /* Choose a color */
6989 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
6991 /* Display the name */
6992 c_prt(attr, f_name + f_ptr->name, row_i, col);
6994 /* Hack -- visual_list mode */
6997 /* Display lighting level */
6998 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7000 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));
7002 if (p_ptr->wizard || visual_only)
7004 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7007 /* Display symbol */
7008 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);
7010 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7011 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7013 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7015 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7017 /* Mega-hack -- Use non-standard colour */
7018 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7020 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7024 /* Clear remaining lines */
7025 for (; i < per_page; i++)
7027 Term_erase(col, row + i, 255);
7033 * Interact with feature visuals.
7035 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7039 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7040 FEAT_IDX feat_cur, feat_top;
7042 FEAT_IDX grp_idx[100];
7046 TERM_LEN column = 0;
7050 bool visual_list = FALSE;
7051 TERM_COLOR attr_top = 0;
7054 TERM_LEN browser_rows;
7057 TERM_COLOR attr_old[F_LIT_MAX];
7058 SYMBOL_CODE char_old[F_LIT_MAX];
7059 TERM_COLOR *cur_attr_ptr;
7060 SYMBOL_CODE *cur_char_ptr;
7062 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7063 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7065 Term_get_size(&wid, &hgt);
7067 browser_rows = hgt - 8;
7069 /* Allocate the "feat_idx" array */
7070 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7075 if (direct_f_idx < 0)
7077 /* Check every group */
7078 for (i = 0; feature_group_text[i] != NULL; i++)
7080 /* Measure the label */
7081 len = strlen(feature_group_text[i]);
7083 /* Save the maximum length */
7084 if (len > max) max = len;
7086 /* See if any features are known */
7087 if (collect_features(i, feat_idx, 0x01))
7089 /* Build a list of groups with known features */
7090 grp_idx[grp_cnt++] = i;
7098 feature_type *f_ptr = &f_info[direct_f_idx];
7100 feat_idx[0] = direct_f_idx;
7103 /* Terminate the list */
7106 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7107 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7109 for (i = 0; i < F_LIT_MAX; i++)
7111 attr_old[i] = f_ptr->x_attr[i];
7112 char_old[i] = f_ptr->x_char[i];
7116 /* Terminate the list */
7117 grp_idx[grp_cnt] = -1;
7120 grp_cur = grp_top = 0;
7121 feat_cur = feat_top = 0;
7129 feature_type *f_ptr;
7135 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7136 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7137 prt(_("名前", "Name"), 4, max + 3);
7140 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7141 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7145 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7146 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7149 for (i = 0; i < 78; i++)
7151 Term_putch(i, 5, TERM_WHITE, '=');
7154 if (direct_f_idx < 0)
7156 for (i = 0; i < browser_rows; i++)
7158 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7165 if (direct_f_idx < 0)
7167 /* Scroll group list */
7168 if (grp_cur < grp_top) grp_top = grp_cur;
7169 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7171 /* Display a list of feature groups */
7172 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7174 if (old_grp_cur != grp_cur)
7176 old_grp_cur = grp_cur;
7178 /* Get a list of features in the current group */
7179 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7182 /* Scroll feature list */
7183 while (feat_cur < feat_top)
7184 feat_top = MAX(0, feat_top - browser_rows/2);
7185 while (feat_cur >= feat_top + browser_rows)
7186 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7191 /* Display a list of features in the current group */
7192 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7196 feat_top = feat_cur;
7198 /* Display a list of features in the current group */
7199 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7201 /* Display visual list below first object */
7202 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7206 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7207 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7208 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7211 /* Get the current feature */
7212 f_ptr = &f_info[feat_idx[feat_cur]];
7213 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7214 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7218 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7222 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7226 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7231 if (visual_list && ((ch == 'A') || (ch == 'a')))
7233 int prev_lighting_level = *lighting_level;
7237 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7238 else (*lighting_level)--;
7242 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7243 else (*lighting_level)++;
7246 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7247 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7249 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7250 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7255 else if ((ch == 'D') || (ch == 'd'))
7257 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7258 byte prev_x_char = f_ptr->x_char[*lighting_level];
7260 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7264 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7265 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7267 if (prev_x_char != f_ptr->x_char[*lighting_level])
7268 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7270 else *need_redraw = TRUE;
7275 /* Do visual mode command if needed */
7276 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))
7280 /* Restore previous visual settings */
7282 for (i = 0; i < F_LIT_MAX; i++)
7284 f_ptr->x_attr[i] = attr_old[i];
7285 f_ptr->x_char[i] = char_old[i];
7292 if (direct_f_idx >= 0) flag = TRUE;
7293 else *lighting_level = F_LIT_STANDARD;
7296 /* Preserve current visual settings */
7299 for (i = 0; i < F_LIT_MAX; i++)
7301 attr_old[i] = f_ptr->x_attr[i];
7302 char_old[i] = f_ptr->x_char[i];
7304 *lighting_level = F_LIT_STANDARD;
7311 for (i = 0; i < F_LIT_MAX; i++)
7313 attr_idx_feat[i] = f_ptr->x_attr[i];
7314 char_idx_feat[i] = f_ptr->x_char[i];
7323 /* Allow TERM_DARK text */
7324 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7326 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7327 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7345 /* Move the cursor */
7346 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7352 /* Free the "feat_idx" array */
7353 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7358 * List wanted monsters
7360 static void do_cmd_knowledge_kubi(void)
7365 GAME_TEXT file_name[1024];
7368 /* Open a new file */
7369 fff = my_fopen_temp(file_name, 1024);
7371 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7378 bool listed = FALSE;
7380 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7381 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7383 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7384 fprintf(fff, "----------------------------------------------\n");
7386 for (i = 0; i < MAX_KUBI; i++)
7388 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7390 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7398 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7403 /* Display the file contents */
7404 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7409 * List virtues & status
7411 static void do_cmd_knowledge_virtues(void)
7414 GAME_TEXT file_name[1024];
7416 /* Open a new file */
7417 fff = my_fopen_temp(file_name, 1024);
7419 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7426 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7431 /* Display the file contents */
7432 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7439 static void do_cmd_knowledge_dungeon(void)
7443 GAME_TEXT file_name[1024];
7446 /* Open a new file */
7447 fff = my_fopen_temp(file_name, 1024);
7449 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7456 for (i = 1; i < max_d_idx; i++)
7460 if (!d_info[i].maxdepth) continue;
7461 if (!max_dlv[i]) continue;
7462 if (d_info[i].final_guardian)
7464 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7466 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7468 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7473 /* Display the file contents */
7474 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7479 * List virtues & status
7482 static void do_cmd_knowledge_stat(void)
7486 GAME_TEXT file_name[1024];
7489 /* Open a new file */
7490 fff = my_fopen_temp(file_name, 1024);
7492 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7499 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7500 (2 * p_ptr->hitdie +
7501 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7503 if (p_ptr->knowledge & KNOW_HPRATE)
7504 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7505 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7507 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7508 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7510 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);
7511 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7518 /* Display the file contents */
7519 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7525 * Print all active quests
7527 static void do_cmd_knowledge_quests_current(FILE *fff)
7530 char rand_tmp_str[120] = "\0";
7531 GAME_TEXT name[MAX_NLEN];
7532 monster_race *r_ptr;
7534 int rand_level = 100;
7537 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7539 for (i = 1; i < max_q_idx; i++)
7541 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7542 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7543 (quest[i].status == QUEST_STATUS_COMPLETED))
7545 /* Set the quest number temporary */
7546 QUEST_IDX old_quest = p_ptr->inside_quest;
7549 /* Clear the text */
7550 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7551 quest_text_line = 0;
7553 p_ptr->inside_quest = i;
7555 /* Get the quest text */
7556 init_flags = INIT_SHOW_TEXT;
7558 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7560 /* Reset the old quest number */
7561 p_ptr->inside_quest = old_quest;
7563 /* No info from "silent" quests */
7564 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7568 if (quest[i].type != QUEST_TYPE_RANDOM)
7570 char note[80] = "\0";
7572 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7574 switch (quest[i].type)
7576 case QUEST_TYPE_KILL_LEVEL:
7577 case QUEST_TYPE_KILL_ANY_LEVEL:
7578 r_ptr = &r_info[quest[i].r_idx];
7579 strcpy(name, r_name + r_ptr->name);
7580 if (quest[i].max_num > 1)
7583 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7584 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7587 sprintf(note," - kill %d %s, have killed %d.",
7588 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7592 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7595 case QUEST_TYPE_FIND_ARTIFACT:
7598 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7600 object_type *q_ptr = &forge;
7601 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7602 object_prep(q_ptr, k_idx);
7603 q_ptr->name1 = quest[i].k_idx;
7604 q_ptr->ident = IDENT_STORE;
7605 object_desc(name, q_ptr, OD_NAME_ONLY);
7607 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7609 case QUEST_TYPE_FIND_EXIT:
7610 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7613 case QUEST_TYPE_KILL_NUMBER:
7615 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7616 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7618 sprintf(note," - Kill %d monsters, have killed %d.",
7619 (int)quest[i].max_num, (int)quest[i].cur_num);
7623 case QUEST_TYPE_KILL_ALL:
7624 case QUEST_TYPE_TOWER:
7625 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7630 /* Print the quest info */
7631 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7632 quest[i].name, (int)quest[i].level, note);
7634 fputs(tmp_str, fff);
7636 if (quest[i].status == QUEST_STATUS_COMPLETED)
7638 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7639 fputs(tmp_str, fff);
7645 while (quest_text[j][0] && j < 10)
7647 fprintf(fff, " %s\n", quest_text[j]);
7652 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7655 rand_level = quest[i].level;
7657 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7659 /* Print the quest info */
7660 r_ptr = &r_info[quest[i].r_idx];
7661 strcpy(name, r_name + r_ptr->name);
7663 if (quest[i].max_num > 1)
7666 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7667 quest[i].name, (int)quest[i].level,
7668 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7672 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7673 quest[i].name, (int)quest[i].level,
7674 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7679 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7680 quest[i].name, (int)quest[i].level, name);
7687 /* Print the current random quest */
7688 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7690 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7694 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7697 char playtime_str[16];
7698 quest_type* const q_ptr = &quest[q_idx];
7700 if (is_fixed_quest_idx(q_idx))
7702 /* Set the quest number temporary */
7703 IDX old_quest = p_ptr->inside_quest;
7705 p_ptr->inside_quest = q_idx;
7708 init_flags = INIT_NAME_ONLY;
7710 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7712 /* Reset the old quest number */
7713 p_ptr->inside_quest = old_quest;
7715 /* No info from "silent" quests */
7716 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7719 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7720 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7722 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7724 /* Print the quest info */
7725 if (q_ptr->complev == 0)
7728 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7729 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7730 r_name+r_info[q_ptr->r_idx].name,
7731 (int)q_ptr->level, playtime_str);
7736 _(" %-35s (%3d階) - レベル%2d - %s\n",
7737 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7738 r_name+r_info[q_ptr->r_idx].name,
7746 /* Print the quest info */
7748 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7749 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7750 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7753 fputs(tmp_str, fff);
7759 * Print all finished quests
7761 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7764 QUEST_IDX total = 0;
7766 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7767 for (i = 1; i < max_q_idx; i++)
7769 QUEST_IDX q_idx = quest_num[i];
7770 quest_type* const q_ptr = &quest[q_idx];
7772 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7777 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7782 * Print all failed quests
7784 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7787 QUEST_IDX total = 0;
7789 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7790 for (i = 1; i < max_q_idx; i++)
7792 QUEST_IDX q_idx = quest_num[i];
7793 quest_type* const q_ptr = &quest[q_idx];
7795 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7796 do_cmd_knowledge_quests_aux(fff, q_idx))
7801 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7806 * Print all random quests
7808 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7810 GAME_TEXT tmp_str[120];
7812 QUEST_IDX total = 0;
7814 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7815 for (i = 1; i < max_q_idx; i++)
7817 /* No info from "silent" quests */
7818 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7820 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7824 /* Print the quest info */
7825 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7826 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7827 fputs(tmp_str, fff);
7830 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7834 * Print quest status of all active quests
7836 static void do_cmd_knowledge_quests(void)
7839 GAME_TEXT file_name[1024];
7844 /* Open a new file */
7845 fff = my_fopen_temp(file_name, 1024);
7848 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7853 /* Allocate Memory */
7854 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7856 /* Sort by compete level */
7857 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7858 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7860 /* Dump Quest Information */
7861 do_cmd_knowledge_quests_current(fff);
7863 do_cmd_knowledge_quests_completed(fff, quest_num);
7865 do_cmd_knowledge_quests_failed(fff, quest_num);
7869 do_cmd_knowledge_quests_wiz_random(fff);
7873 /* Display the file contents */
7874 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7878 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7885 static void do_cmd_knowledge_home(void)
7890 GAME_TEXT file_name[1024];
7892 GAME_TEXT o_name[MAX_NLEN];
7893 concptr paren = ")";
7895 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7897 /* Open a new file */
7898 fff = my_fopen_temp(file_name, 1024);
7900 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7907 /* Print all homes in the different towns */
7908 st_ptr = &town_info[1].store[STORE_HOME];
7910 /* Home -- if anything there */
7911 if (st_ptr->stock_num)
7916 /* Header with name of the town */
7917 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7919 /* Dump all available items */
7920 for (i = 0; i < st_ptr->stock_num; i++)
7923 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7924 object_desc(o_name, &st_ptr->stock[i], 0);
7925 if (strlen(o_name) <= 80-3)
7927 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7933 for (n = 0, t = o_name; n < 80-3; n++, t++)
7934 if(iskanji(*t)) {t++; n++;}
7935 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7937 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7938 fprintf(fff, " %.77s\n", o_name+n);
7941 object_desc(o_name, &st_ptr->stock[i], 0);
7942 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7947 /* Add an empty line */
7948 fprintf(fff, "\n\n");
7953 /* Display the file contents */
7954 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7960 * Check the status of "autopick"
7962 static void do_cmd_knowledge_autopick(void)
7966 GAME_TEXT file_name[1024];
7968 /* Open a new file */
7969 fff = my_fopen_temp(file_name, 1024);
7973 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7980 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7984 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7985 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7988 for (k = 0; k < max_autopick; k++)
7991 byte act = autopick_list[k].action;
7992 if (act & DONT_AUTOPICK)
7994 tmp = _("放置", "Leave");
7996 else if (act & DO_AUTODESTROY)
7998 tmp = _("破壊", "Destroy");
8000 else if (act & DO_AUTOPICK)
8002 tmp = _("拾う", "Pickup");
8006 tmp = _("確認", "Query");
8009 if (act & DO_DISPLAY)
8010 fprintf(fff, "%11s", format("[%s]", tmp));
8012 fprintf(fff, "%11s", format("(%s)", tmp));
8014 tmp = autopick_line_from_entry(&autopick_list[k]);
8015 fprintf(fff, " %s", tmp);
8020 /* Display the file contents */
8021 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8027 * Interact with "knowledge"
8029 void do_cmd_knowledge(void)
8032 bool need_redraw = FALSE;
8034 /* File type is "TEXT" */
8035 FILE_TYPE(FILE_TYPE_TEXT);
8038 /* Interact until done */
8043 /* Ask for a choice */
8044 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8045 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8047 /* Give some choices */
8051 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8052 prt("(2) 既知のアイテム の一覧", 7, 5);
8053 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8054 prt("(4) 既知のモンスター の一覧", 9, 5);
8055 prt("(5) 倒した敵の数 の一覧", 10, 5);
8056 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8057 prt("(7) 現在のペット の一覧", 12, 5);
8058 prt("(8) 我が家のアイテム の一覧", 13, 5);
8059 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8060 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8064 prt("(a) 自分に関する情報 の一覧", 6, 5);
8065 prt("(b) 突然変異 の一覧", 7, 5);
8066 prt("(c) 武器の経験値 の一覧", 8, 5);
8067 prt("(d) 魔法の経験値 の一覧", 9, 5);
8068 prt("(e) 技能の経験値 の一覧", 10, 5);
8069 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8070 prt("(g) 入ったダンジョン の一覧", 12, 5);
8071 prt("(h) 実行中のクエスト の一覧", 13, 5);
8072 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8077 prt("(1) Display known artifacts", 6, 5);
8078 prt("(2) Display known objects", 7, 5);
8079 prt("(3) Display remaining uniques", 8, 5);
8080 prt("(4) Display known monster", 9, 5);
8081 prt("(5) Display kill count", 10, 5);
8082 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8083 prt("(7) Display current pets", 12, 5);
8084 prt("(8) Display home inventory", 13, 5);
8085 prt("(9) Display *identified* equip.", 14, 5);
8086 prt("(0) Display terrain symbols.", 15, 5);
8090 prt("(a) Display about yourself", 6, 5);
8091 prt("(b) Display mutations", 7, 5);
8092 prt("(c) Display weapon proficiency", 8, 5);
8093 prt("(d) Display spell proficiency", 9, 5);
8094 prt("(e) Display misc. proficiency", 10, 5);
8095 prt("(f) Display virtues", 11, 5);
8096 prt("(g) Display dungeons", 12, 5);
8097 prt("(h) Display current quests", 13, 5);
8098 prt("(i) Display auto pick/destroy", 14, 5);
8102 prt(_("-続く-", "-more-"), 17, 8);
8103 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8104 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8105 /*prt("-) 前ページ", 21, 60);*/
8106 prt(_("コマンド:", "Command: "), 20, 0);
8109 if (i == ESCAPE) break;
8112 case ' ': /* Page change */
8116 case '1': /* Artifacts */
8117 do_cmd_knowledge_artifacts();
8119 case '2': /* Objects */
8120 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8122 case '3': /* Uniques */
8123 do_cmd_knowledge_uniques();
8125 case '4': /* Monsters */
8126 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8128 case '5': /* Kill count */
8129 do_cmd_knowledge_kill_count();
8131 case '6': /* wanted */
8132 if (!vanilla_town) do_cmd_knowledge_kubi();
8134 case '7': /* Pets */
8135 do_cmd_knowledge_pets();
8137 case '8': /* Home */
8138 do_cmd_knowledge_home();
8140 case '9': /* Resist list */
8141 do_cmd_knowledge_inven();
8143 case '0': /* Feature list */
8145 IDX lighting_level = F_LIT_STANDARD;
8146 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8150 case 'a': /* Max stat */
8151 do_cmd_knowledge_stat();
8153 case 'b': /* Mutations */
8154 do_cmd_knowledge_mutations();
8156 case 'c': /* weapon-exp */
8157 do_cmd_knowledge_weapon_exp();
8159 case 'd': /* spell-exp */
8160 do_cmd_knowledge_spell_exp();
8162 case 'e': /* skill-exp */
8163 do_cmd_knowledge_skill_exp();
8165 case 'f': /* Virtues */
8166 do_cmd_knowledge_virtues();
8168 case 'g': /* Dungeon */
8169 do_cmd_knowledge_dungeon();
8171 case 'h': /* Quests */
8172 do_cmd_knowledge_quests();
8174 case 'i': /* Autopick */
8175 do_cmd_knowledge_autopick();
8177 default: /* Unknown option */
8185 if (need_redraw) do_cmd_redraw();
8190 * Check on the status of an active quest
8192 void do_cmd_checkquest(void)
8194 /* File type is "TEXT" */
8195 FILE_TYPE(FILE_TYPE_TEXT);
8199 do_cmd_knowledge_quests();
8205 * Display the time and date
8207 void do_cmd_time(void)
8209 int day, hour, min, full, start, end, num;
8217 extract_day_hour_min(&day, &hour, &min);
8219 full = hour * 100 + min;
8226 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8228 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8229 else strcpy(day_buf, "*****");
8231 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8232 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8235 if (!randint0(10) || p_ptr->image)
8237 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8241 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8244 /* Open this file */
8245 fff = my_fopen(buf, "rt");
8249 /* Find this time */
8250 while (!my_fgets(fff, buf, sizeof(buf)))
8252 /* Ignore comments */
8253 if (!buf[0] || (buf[0] == '#')) continue;
8255 /* Ignore invalid lines */
8256 if (buf[1] != ':') continue;
8258 /* Process 'Start' */
8261 /* Extract the starting time */
8262 start = atoi(buf + 2);
8264 /* Assume valid for an hour */
8274 /* Extract the ending time */
8275 end = atoi(buf + 2);
8281 /* Ignore incorrect range */
8282 if ((start > full) || (full > end)) continue;
8284 /* Process 'Description' */
8289 /* Apply the randomizer */
8290 if (!randint0(num)) strcpy(desc, buf + 2);