3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
45 #include "cmd-spell.h"
47 #include "player-effects.h"
48 #include "player-status.h"
55 #include "object-flavor.h"
56 #include "object-hook.h"
58 #include "monster-status.h"
60 #include "view-mainwindow.h"
61 #include "dungeon-file.h"
68 * Mark strings for auto dump
70 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
71 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
74 * Variables for auto dump
76 static FILE *auto_dump_stream;
77 static concptr auto_dump_mark;
78 static int auto_dump_line_num;
82 * @brief prf出力内容を消去する /
83 * Remove old lines automatically generated before.
84 * @param orig_file 消去を行うファイル名
86 static void remove_auto_dump(concptr orig_file)
88 FILE *tmp_fff, *orig_fff;
92 bool between_mark = FALSE;
95 long header_location = 0;
96 char header_mark_str[80];
97 char footer_mark_str[80];
100 /* Prepare a header/footer mark string */
101 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
102 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
104 mark_len = strlen(footer_mark_str);
106 /* Open an old dump file in read-only mode */
107 orig_fff = my_fopen(orig_file, "r");
109 /* If original file does not exist, nothing to do */
110 if (!orig_fff) return;
112 /* Open a new (temporary) file */
113 tmp_fff = my_fopen_temp(tmp_file, 1024);
117 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
122 /* Loop for every line */
126 if (my_fgets(orig_fff, buf, sizeof(buf)))
128 /* Read error: Assume End of File */
131 * Was looking for the footer, but not found.
133 * Since automatic dump might be edited by hand,
134 * it's dangerous to kill these lines.
135 * Seek back to the next line of the (pseudo) header,
140 fseek(orig_fff, header_location, SEEK_SET);
141 between_mark = FALSE;
145 /* Success -- End the loop */
152 /* We are looking for the header mark of automatic dump */
155 /* Is this line a header? */
156 if (!strcmp(buf, header_mark_str))
158 /* Memorise seek point of this line */
159 header_location = ftell(orig_fff);
161 /* Initialize counter for number of lines */
164 /* Look for the footer from now */
167 /* There are some changes */
174 /* Copy orginally lines */
175 fprintf(tmp_fff, "%s\n", buf);
179 /* We are looking for the footer mark of automatic dump */
182 /* Is this line a footer? */
183 if (!strncmp(buf, footer_mark_str, mark_len))
188 * Compare the number of lines
190 * If there is an inconsistency between
191 * actual number of lines and the
192 * number here, the automatic dump
193 * might be edited by hand. So it's
194 * dangerous to kill these lines.
195 * Seek back to the next line of the
196 * (pseudo) header, and read again.
198 if (!sscanf(buf + mark_len, " (%d)", &tmp)
201 fseek(orig_fff, header_location, SEEK_SET);
204 /* Look for another header */
205 between_mark = FALSE;
211 /* Ignore old line, and count number of lines */
221 /* If there are some changes, overwrite the original file with new one */
224 /* Copy contents of temporary file */
226 tmp_fff = my_fopen(tmp_file, "r");
227 orig_fff = my_fopen(orig_file, "w");
229 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
230 fprintf(orig_fff, "%s\n", buf);
236 /* Kill the temporary file */
244 * @brief prfファイルのフォーマットに従った内容を出力する /
245 * Dump a formatted line, using "vstrnfmt()".
248 static void auto_dump_printf(concptr fmt, ...)
255 /* Begin the Varargs Stuff */
258 /* Format the args, save the length */
259 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
261 /* End the Varargs Stuff */
264 /* Count number of lines */
265 for (p = buf; *p; p++)
267 if (*p == '\n') auto_dump_line_num++;
271 fprintf(auto_dump_stream, "%s", buf);
276 * @brief prfファイルをファイルオープンする /
277 * Open file to append auto dump.
279 * @param mark 出力するヘッダマーク
280 * @return ファイルポインタを取得できたらTRUEを返す
282 static bool open_auto_dump(concptr buf, concptr mark)
285 char header_mark_str[80];
287 /* Save the mark string */
288 auto_dump_mark = mark;
290 /* Prepare a header mark string */
291 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
293 /* Remove old macro dumps */
294 remove_auto_dump(buf);
296 /* Append to the file */
297 auto_dump_stream = my_fopen(buf, "a");
300 if (!auto_dump_stream) {
301 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
309 fprintf(auto_dump_stream, "%s\n", header_mark_str);
311 /* Initialize counter */
312 auto_dump_line_num = 0;
314 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
315 "# *Warning!* The lines below are an automatic dump.\n"));
316 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
317 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
323 * @brief prfファイルをファイルクローズする /
324 * Append foot part and close auto dump.
327 static void close_auto_dump(void)
329 char footer_mark_str[80];
331 /* Prepare a footer mark string */
332 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
334 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
335 "# *Warning!* The lines below are an automatic dump.\n"));
336 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
337 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
339 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
342 my_fclose(auto_dump_stream);
351 * @brief Return suffix of ordinal number
353 * @return pointer of suffix string.
355 concptr get_ordinal_number_suffix(int num)
357 num = ABS(num) % 100;
361 return (num == 11) ? "th" : "st";
363 return (num == 12) ? "th" : "nd";
365 return (num == 13) ? "th" : "rd";
374 * @brief 日記にメッセージを追加する /
375 * Take note to the diary.
376 * @param type 日記内容のID
377 * @param num 日記内容のIDに応じた数値
378 * @param note 日記内容のIDに応じた文字列参照ポインタ
381 errr do_cmd_write_nikki(int type, int num, concptr note)
385 GAME_TEXT file_name[MAX_NLEN];
387 concptr note_level = "";
388 bool do_level = TRUE;
389 char note_level_buf[40];
392 static bool disable_nikki = FALSE;
394 extract_day_hour_min(&day, &hour, &min);
396 if (disable_nikki) return(-1);
398 if (type == NIKKI_FIX_QUEST_C ||
399 type == NIKKI_FIX_QUEST_F ||
400 type == NIKKI_RAND_QUEST_C ||
401 type == NIKKI_RAND_QUEST_F ||
402 type == NIKKI_TO_QUEST)
406 old_quest = p_ptr->inside_quest;
407 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
409 /* Get the quest text */
410 init_flags = INIT_NAME_ONLY;
412 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
414 /* Reset the old quest number */
415 p_ptr->inside_quest = old_quest;
418 /* different filne name to avoid mixing */
419 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
421 /* Build the filename */
422 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
424 /* File type is "TEXT" */
425 FILE_TYPE(FILE_TYPE_TEXT);
427 fff = my_fopen(buf, "a");
432 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
438 q_idx = quest_number(current_floor_ptr->dun_level);
442 if (p_ptr->inside_arena)
443 note_level = _("アリーナ:", "Arane:");
444 else if (!current_floor_ptr->dun_level)
445 note_level = _("地上:", "Surface:");
446 else if (q_idx && (is_fixed_quest_idx(q_idx)
447 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
448 note_level = _("クエスト:", "Quest:");
452 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
454 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
456 note_level = note_level_buf;
464 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
465 else fputs(_("*****日目\n", "Day *****\n"), fff);
473 fprintf(fff, "%s\n",note);
477 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
482 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
485 case NIKKI_ART_SCROLL:
487 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
492 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
495 case NIKKI_FIX_QUEST_C:
497 if (quest[num].flags & QUEST_FLAG_SILENT) break;
498 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
499 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
502 case NIKKI_FIX_QUEST_F:
504 if (quest[num].flags & QUEST_FLAG_SILENT) break;
505 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
506 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
509 case NIKKI_RAND_QUEST_C:
511 GAME_TEXT name[MAX_NLEN];
512 strcpy(name, r_name+r_info[quest[num].r_idx].name);
513 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
514 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
517 case NIKKI_RAND_QUEST_F:
519 GAME_TEXT name[MAX_NLEN];
520 strcpy(name, r_name+r_info[quest[num].r_idx].name);
521 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
522 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
525 case NIKKI_MAXDEAPTH:
527 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
528 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
529 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
530 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
535 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
536 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
537 _(d_name + d_info[num].name, (int)max_dlv[num]),
538 _((int)max_dlv[num], d_name + d_info[num].name));
544 if (q_idx && (is_fixed_quest_idx(q_idx)
545 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
547 to = _("地上", "the surface");
551 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
552 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
554 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
560 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
561 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
562 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
564 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
569 if (quest[num].flags & QUEST_FLAG_SILENT) break;
570 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
571 hour, min, note_level, quest[num].name);
576 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
577 hour, min, note_level);
582 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
587 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
595 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
596 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
599 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
600 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
602 if (num == MAX_ARENA_MONS)
604 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
605 " won all fight to become a Chanpion.\n"));
612 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
618 if (!current_floor_ptr->dun_level)
619 to = _("地上", "the surface");
621 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
623 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
624 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
630 if (!current_floor_ptr->dun_level)
631 to = _("地上", "the surface");
633 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
635 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
636 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
641 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
644 case NIKKI_GAMESTART:
646 time_t ct = time((time_t*)0);
650 fprintf(fff, "%s %s",note, ctime(&ct));
653 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
656 case NIKKI_NAMED_PET:
658 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
661 case RECORD_NAMED_PET_NAME:
662 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
664 case RECORD_NAMED_PET_UNNAME:
665 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
667 case RECORD_NAMED_PET_DISMISS:
668 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
670 case RECORD_NAMED_PET_DEATH:
671 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
673 case RECORD_NAMED_PET_MOVED:
674 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
676 case RECORD_NAMED_PET_LOST_SIGHT:
677 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
679 case RECORD_NAMED_PET_DESTROY:
680 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
682 case RECORD_NAMED_PET_EARTHQUAKE:
683 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
685 case RECORD_NAMED_PET_GENOCIDE:
686 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
688 case RECORD_NAMED_PET_WIZ_ZAP:
689 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
691 case RECORD_NAMED_PET_TELE_LEVEL:
692 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
694 case RECORD_NAMED_PET_BLAST:
695 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
697 case RECORD_NAMED_PET_HEAL_LEPER:
698 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
700 case RECORD_NAMED_PET_COMPACT:
701 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
703 case RECORD_NAMED_PET_LOSE_PARENT:
704 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
715 case NIKKI_WIZARD_LOG:
716 fprintf(fff, "%s\n", note);
725 if (do_level) write_level = FALSE;
731 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
734 * @brief 日記のタイトル表記と内容出力 /
737 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
739 static void do_cmd_disp_nikki(void)
741 char nikki_title[256];
742 GAME_TEXT file_name[MAX_NLEN];
747 static const char subtitle[][30] = {"最強の肉体を求めて",
778 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
779 "Attack is the best form of defence.",
781 "An unexpected windfall",
782 "A drowning man will catch at a straw",
783 "Don't count your chickens before they are hatched.",
784 "It is no use crying over spilt milk.",
785 "Seeing is believing.",
786 "Strike the iron while it is hot.",
787 "I don't care what follows.",
788 "To dig a well to put out a house on fire.",
789 "Tomorrow is another day.",
790 "Easy come, easy go.",
791 "The more haste, the less speed.",
792 "Where there is life, there is hope.",
793 "There is no royal road to *WINNER*.",
794 "Danger past, God forgotten.",
795 "The best thing to do now is to run away.",
796 "Life is but an empty dream.",
797 "Dead men tell no tales.",
798 "A book that remains shut is but a block.",
799 "Misfortunes never come singly.",
800 "A little knowledge is a dangerous thing.",
801 "History repeats itself.",
802 "*WINNER* was not built in a day.",
803 "Ignorance is bliss.",
804 "To lose is to win?",
805 "No medicine can cure folly.",
806 "All good things come to an end.",
807 "M$ Empire strikes back.",
808 "To see is to believe",
810 "Quest of The World's Greatest Brain"};
812 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
814 /* Build the filename */
815 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
817 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
818 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
819 else if (IS_WIZARD_CLASS())
820 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
821 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
824 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
826 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
829 /* Display the file contents */
830 show_file(FALSE, buf, nikki_title, -1, 0);
834 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
837 static void do_cmd_bunshou(void)
840 char bunshou[80] = "\0";
842 if (get_string(_("内容: ", "diary note: "), tmp, 79))
844 strcpy(bunshou, tmp);
846 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
851 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
854 static void do_cmd_last_get(void)
859 if (record_o_name[0] == '\0') return;
861 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
862 if (!get_check(buf)) return;
864 turn_tmp = current_world_ptr->game_turn;
865 current_world_ptr->game_turn = record_turn;
866 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
867 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
868 current_world_ptr->game_turn = turn_tmp;
872 * @brief ファイル中の全日記記録を消去する /
875 static void do_cmd_erase_nikki(void)
877 GAME_TEXT file_name[MAX_NLEN];
881 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
882 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
884 /* Build the filename */
885 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
888 fff = my_fopen(buf, "w");
891 msg_format(_("記録を消去しました。", "deleted record."));
893 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
902 void do_cmd_nikki(void)
906 /* File type is "TEXT" */
907 FILE_TYPE(FILE_TYPE_TEXT);
910 /* Interact until done */
915 /* Ask for a choice */
916 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
918 /* Give some choices */
919 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
920 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
921 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
922 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
924 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
927 prt(_("コマンド:", "Command: "), 18, 0);
932 if (i == ESCAPE) break;
946 do_cmd_erase_nikki();
950 prepare_movie_hooks();
952 default: /* Unknown option */
962 * @brief 画面を再描画するコマンドのメインルーチン
963 * Hack -- redraw the screen
967 * This command performs various low level updates, clears all the "extra"
968 * windows, does a total redraw of the main window, and requests all of the
969 * interesting updates and redraws that I can think of.
971 * This command is also used to "instantiate" the results of the user
972 * selecting various things, such as graphics mode, so it must call
973 * the "TERM_XTRA_REACT" hook before redrawing the windows.
976 void do_cmd_redraw(void)
982 /* Hack -- react to changes */
983 Term_xtra(TERM_XTRA_REACT, 0);
985 /* Combine and Reorder the pack (later) */
986 p_ptr->update |= (PU_COMBINE | PU_REORDER);
987 p_ptr->update |= (PU_TORCH);
988 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
989 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
990 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
991 p_ptr->update |= (PU_MONSTERS);
993 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
995 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
996 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1002 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1005 /* Redraw every window */
1006 for (j = 0; j < 8; j++)
1009 if (!angband_term[j]) continue;
1012 Term_activate(angband_term[j]);
1021 * @brief 名前を変更するコマンドのメインルーチン
1022 * Hack -- change name
1025 void do_cmd_change_name(void)
1040 /* Display the player */
1041 display_player(mode);
1046 display_player(mode);
1051 Term_putstr(2, 23, -1, TERM_WHITE,
1052 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1054 Term_putstr(2, 23, -1, TERM_WHITE,
1055 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1063 if (c == ESCAPE) break;
1070 /* Process the player name */
1071 process_player_name(FALSE);
1077 sprintf(tmp, "%s.txt", player_base);
1078 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1080 if (tmp[0] && (tmp[0] != ' '))
1082 file_character(tmp);
1100 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1107 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1108 * Recall the most recent message
1111 void do_cmd_message_one(void)
1113 /* Recall one message */
1114 prt(format("> %s", message_str(0)), 0, 0);
1119 * @brief メッセージのログを表示するコマンドのメインルーチン
1120 * Recall the most recent message
1124 * Show previous messages to the user -BEN-
1126 * The screen format uses line 0 and 23 for headers and prompts,
1127 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1129 * This command shows you which commands you are viewing, and allows
1130 * you to "search" for strings in the recall.
1132 * Note that messages may be longer than 80 characters, but they are
1133 * displayed using "infinite" length, with a special sub-command to
1134 * "slide" the virtual display to the left or right.
1136 * Attempt to only hilite the matching portions of the string.
1139 void do_cmd_messages(int num_now)
1143 char shower_str[81];
1144 char finder_str[81];
1146 concptr shower = NULL;
1150 Term_get_size(&wid, &hgt);
1152 /* Number of message lines in a screen */
1153 num_lines = hgt - 4;
1156 strcpy(finder_str, "");
1159 strcpy(shower_str, "");
1161 /* Total messages */
1164 /* Start on first message */
1169 /* Process requests until done */
1175 /* Dump up to 20 lines of messages */
1176 for (j = 0; (j < num_lines) && (i + j < n); j++)
1178 concptr msg = message_str(i+j);
1180 /* Dump the messages, bottom to top */
1181 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1183 /* Hilite "shower" */
1184 if (shower && shower[0])
1188 /* Display matches */
1189 while ((str = my_strstr(str, shower)) != NULL)
1191 int len = strlen(shower);
1193 /* Display the match */
1194 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1202 /* Erase remaining lines */
1203 for (; j < num_lines; j++)
1205 Term_erase(0, num_lines + 1 - j, 255);
1208 /* Display header */
1210 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1211 i, i + j - 1, n), 0, 0);
1213 /* Display prompt (not very informative) */
1214 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1215 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1217 skey = inkey_special(TRUE);
1219 /* Exit on Escape */
1220 if (skey == ESCAPE) break;
1222 /* Hack -- Save the old index */
1227 /* Hack -- handle show */
1230 prt(_("強調: ", "Show: "), hgt - 1, 0);
1232 /* Get a "shower" string, or continue */
1233 strcpy(back_str, shower_str);
1234 if (askfor(shower_str, 80))
1237 shower = shower_str[0] ? shower_str : NULL;
1239 else strcpy(shower_str, back_str);
1243 /* Hack -- handle find */
1250 prt(_("検索: ", "Find: "), hgt - 1, 0);
1252 /* Get a "finder" string, or continue */
1253 strcpy(back_str, finder_str);
1254 if (!askfor(finder_str, 80))
1256 strcpy(finder_str, back_str);
1259 else if (!finder_str[0])
1261 shower = NULL; /* Stop showing */
1266 shower = finder_str;
1269 for (z = i + 1; z < n; z++)
1271 concptr msg = message_str(z);
1274 if (my_strstr(msg, finder_str))
1285 /* Recall 1 older message */
1287 /* Go to the oldest line */
1291 /* Recall 1 newer message */
1293 /* Go to the newest line */
1297 /* Recall 1 older message */
1302 /* Go older if legal */
1303 i = MIN(i + 1, n - num_lines);
1306 /* Recall 10 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + 10, n - num_lines);
1312 /* Recall 20 older messages */
1317 /* Go older if legal */
1318 i = MIN(i + num_lines, n - num_lines);
1321 /* Recall 20 newer messages */
1325 /* Go newer (if able) */
1326 i = MAX(0, i - num_lines);
1329 /* Recall 10 newer messages */
1331 /* Go newer (if able) */
1335 /* Recall 1 newer messages */
1338 /* Go newer (if able) */
1343 /* Hack -- Error of some kind */
1351 * @brief チートオプションを変更するコマンドのメインルーチン
1352 * Interact with some options for cheating
1353 * @param info 表示メッセージ
1356 static void do_cmd_options_cheat(concptr info)
1359 int i, k = 0, n = CHEAT_MAX;
1363 /* Interact with the player */
1369 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1374 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1375 prt(" << 注意 >>", 11, 0);
1376 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1377 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1378 prt(" じらないようにして下さい。", 14, 0);
1380 /* Display the options */
1381 for (i = 0; i < n; i++)
1383 byte a = TERM_WHITE;
1385 /* Color current option */
1386 if (i == k) a = TERM_L_BLUE;
1388 /* Display the option text */
1389 sprintf(buf, "%-48s: %s (%s)",
1390 cheat_info[i].o_desc,
1391 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1392 cheat_info[i].o_text);
1393 c_prt(a, buf, i + 2, 0);
1396 /* Hilite current option */
1397 move_cursor(k + 2, 50);
1403 * HACK - Try to translate the key into a direction
1404 * to allow using the roguelike keys for navigation.
1406 dir = get_keymap_dir(ch);
1407 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1421 k = (n + k - 1) % n;
1439 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1440 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1441 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1442 (*cheat_info[k].o_var) = TRUE;
1451 (*cheat_info[k].o_var) = FALSE;
1458 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1459 /* Peruse the help file */
1460 (void)show_file(TRUE, buf, NULL, 0, 0);
1477 * @brief セーブ頻度ターンの次の値を返す
1478 * @param current 現在のセーブ頻度ターン値
1479 * @return 次のセーブ頻度ターン値
1481 static s16b toggle_frequency(s16b current)
1486 case 50: return 100;
1487 case 100: return 250;
1488 case 250: return 500;
1489 case 500: return 1000;
1490 case 1000: return 2500;
1491 case 2500: return 5000;
1492 case 5000: return 10000;
1493 case 10000: return 25000;
1500 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1501 * @param info 表示メッセージ
1504 static void do_cmd_options_autosave(concptr info)
1507 int i, k = 0, n = 2;
1512 /* Interact with the player */
1516 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1517 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1521 /* Display the options */
1522 for (i = 0; i < n; i++)
1524 byte a = TERM_WHITE;
1526 /* Color current option */
1527 if (i == k) a = TERM_L_BLUE;
1529 /* Display the option text */
1530 sprintf(buf, "%-48s: %s (%s)",
1531 autosave_info[i].o_desc,
1532 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1533 autosave_info[i].o_text);
1534 c_prt(a, buf, i + 2, 0);
1536 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1538 /* Hilite current option */
1539 move_cursor(k + 2, 50);
1555 k = (n + k - 1) % n;
1573 (*autosave_info[k].o_var) = TRUE;
1582 (*autosave_info[k].o_var) = FALSE;
1590 autosave_freq = toggle_frequency(autosave_freq);
1591 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1597 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1613 * @brief 標準オプションを変更するコマンドのサブルーチン /
1614 * Interact with some options
1615 * @param page オプションページ番号
1616 * @param info 表示メッセージ
1619 void do_cmd_options_aux(int page, concptr info)
1622 int i, k = 0, n = 0, l;
1625 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1626 (!p_ptr->wizard || !allow_debug_opts);
1629 /* Lookup the options */
1630 for (i = 0; i < 24; i++) opt[i] = 0;
1632 /* Scan the options */
1633 for (i = 0; option_info[i].o_desc; i++)
1635 /* Notice options on this "page" */
1636 if (option_info[i].o_page == page) opt[n++] = i;
1640 /* Interact with the player */
1646 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1647 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1650 /* HACK -- description for easy-auto-destroy options */
1651 if (page == OPT_PAGE_AUTODESTROY)
1652 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1653 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1655 /* Display the options */
1656 for (i = 0; i < n; i++)
1658 byte a = TERM_WHITE;
1660 /* Color current option */
1661 if (i == k) a = TERM_L_BLUE;
1663 /* Display the option text */
1664 sprintf(buf, "%-48s: %s (%.19s)",
1665 option_info[opt[i]].o_desc,
1666 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1667 option_info[opt[i]].o_text);
1668 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1669 else c_prt(a, buf, i + 2, 0);
1672 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1675 /* Hilite current option */
1676 move_cursor(k + 2 + l, 50);
1682 * HACK - Try to translate the key into a direction
1683 * to allow using the roguelike keys for navigation.
1685 dir = get_keymap_dir(ch);
1686 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1700 k = (n + k - 1) % n;
1717 if (browse_only) break;
1718 (*option_info[opt[k]].o_var) = TRUE;
1727 if (browse_only) break;
1728 (*option_info[opt[k]].o_var) = FALSE;
1736 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1742 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1743 /* Peruse the help file */
1744 (void)show_file(TRUE, buf, NULL, 0, 0);
1761 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1762 * Modify the "window" options
1765 static void do_cmd_options_win(void)
1775 /* Memorize old flags */
1776 for (j = 0; j < 8; j++)
1778 /* Acquire current flags */
1779 old_flag[j] = window_flag[j];
1788 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1790 /* Display the windows */
1791 for (j = 0; j < 8; j++)
1793 byte a = TERM_WHITE;
1795 concptr s = angband_term_name[j];
1798 if (j == x) a = TERM_L_BLUE;
1800 /* Window name, staggered, centered */
1801 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1804 /* Display the options */
1805 for (i = 0; i < 16; i++)
1807 byte a = TERM_WHITE;
1809 concptr str = window_flag_desc[i];
1812 if (i == y) a = TERM_L_BLUE;
1815 if (!str) str = _("(未使用)", "(Unused option)");
1818 Term_putstr(0, i + 5, -1, a, str);
1820 /* Display the windows */
1821 for (j = 0; j < 8; j++)
1827 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1830 if (window_flag[j] & (1L << i)) c = 'X';
1833 Term_putch(35 + j * 5, i + 5, a, c);
1838 Term_gotoxy(35 + x * 5, y + 5);
1856 for (j = 0; j < 8; j++)
1858 window_flag[j] &= ~(1L << y);
1862 for (i = 0; i < 16; i++)
1864 window_flag[x] &= ~(1L << i);
1877 window_flag[x] |= (1L << y);
1885 window_flag[x] &= ~(1L << y);
1891 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1899 d = get_keymap_dir(ch);
1901 x = (x + ddx[d] + 8) % 8;
1902 y = (y + ddy[d] + 16) % 16;
1909 /* Notice changes */
1910 for (j = 0; j < 8; j++)
1915 if (!angband_term[j]) continue;
1917 /* Ignore non-changes */
1918 if (window_flag[j] == old_flag[j]) continue;
1921 Term_activate(angband_term[j]);
1938 option_fields[OPT_NUM] =
1941 { '1', " キー入力 オプション", 3 },
1942 { '2', " マップ画面 オプション", 4 },
1943 { '3', " テキスト表示 オプション", 5 },
1944 { '4', " ゲームプレイ オプション", 6 },
1945 { '5', " 行動中止関係 オプション", 7 },
1946 { '6', " 簡易自動破壊 オプション", 8 },
1947 { 'r', " プレイ記録 オプション", 9 },
1949 { 'p', "自動拾いエディタ", 11 },
1950 { 'd', " 基本ウェイト量 ", 12 },
1951 { 'h', "低ヒットポイント", 13 },
1952 { 'm', " 低魔力色閾値 ", 14 },
1953 { 'a', " 自動セーブ オプション", 15 },
1954 { 'w', "ウインドウフラグ", 16 },
1956 { 'b', " 初期 オプション (参照のみ)", 18 },
1957 { 'c', " 詐欺 オプション", 19 },
1959 { '1', "Input Options", 3 },
1960 { '2', "Map Screen Options", 4 },
1961 { '3', "Text Display Options", 5 },
1962 { '4', "Game-Play Options", 6 },
1963 { '5', "Disturbance Options", 7 },
1964 { '6', "Easy Auto-Destroyer Options", 8 },
1965 { 'r', "Play record Options", 9 },
1967 { 'p', "Auto-picker/destroyer editor", 11 },
1968 { 'd', "Base Delay Factor", 12 },
1969 { 'h', "Hitpoint Warning", 13 },
1970 { 'm', "Mana Color Threshold", 14 },
1971 { 'a', "Autosave Options", 15 },
1972 { 'w', "Window Flags", 16 },
1974 { 'b', "Birth Options (Browse Only)", 18 },
1975 { 'c', "Cheat Options", 19 },
1981 * @brief 標準オプションを変更するコマンドのメインルーチン /
1982 * Set or unset various options.
1986 * The user must use the "Ctrl-R" command to "adapt" to changes
1987 * in any options which control "visual" aspects of the game.
1990 void do_cmd_options(void)
2002 /* Does not list cheat option when cheat option is off */
2003 if (!p_ptr->noscore && !allow_debug_opts) n--;
2006 /* Why are we here */
2007 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2011 /* Give some choices */
2012 for (i = 0; i < n; i++)
2014 byte a = TERM_WHITE;
2015 if (i == y) a = TERM_L_BLUE;
2016 Term_putstr(5, option_fields[i].row, -1, a,
2017 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2020 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2023 skey = inkey_special(TRUE);
2024 if (!(skey & SKEY_MASK)) k = (char)skey;
2028 if (k == ESCAPE) break;
2030 if (my_strchr("\n\r ", k))
2032 k = option_fields[y].key;
2036 for (i = 0; i < n; i++)
2038 if (tolower(k) == option_fields[i].key) break;
2041 /* Command is found */
2044 /* Hack -- browse help */
2045 if (k == '?') break;
2049 if (skey == SKEY_UP) d = 8;
2050 if (skey == SKEY_DOWN) d = 2;
2051 y = (y + ddy[d] + n) % n;
2056 if (k == ESCAPE) break;
2063 /* Process the general options */
2064 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2070 /* Process the general options */
2071 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2078 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2085 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2092 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2099 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2103 /* Play-record Options */
2108 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2117 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2118 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2119 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2123 /* Cheating Options */
2126 if (!p_ptr->noscore && !allow_debug_opts)
2128 /* Cheat options are not permitted */
2134 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2141 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2150 do_cmd_options_win();
2151 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2152 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2153 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2154 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2159 /* Auto-picker/destroyer editor */
2163 do_cmd_edit_autopick();
2167 /* Hack -- Delay Speed */
2173 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2175 /* Get a new value */
2178 int msec = delay_factor * delay_factor * delay_factor;
2179 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2180 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2182 if (k == ESCAPE) break;
2185 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2188 else if (isdigit(k)) delay_factor = D2I(k);
2195 /* Hack -- hitpoint warning factor */
2201 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2203 /* Get a new value */
2206 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2207 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2209 if (k == ESCAPE) break;
2212 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2215 else if (isdigit(k)) hitpoint_warn = D2I(k);
2222 /* Hack -- mana color factor */
2228 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2230 /* Get a new value */
2233 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2234 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2236 if (k == ESCAPE) break;
2239 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2242 else if (isdigit(k)) mana_warn = D2I(k);
2250 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2254 /* Unknown option */
2267 /* Hack - Redraw equippy chars */
2268 p_ptr->redraw |= (PR_EQUIPPY);
2274 * @brief prefファイルを選択して処理する /
2275 * Ask for a "user pref line" and process it
2278 * Allow absolute file names?
2280 void do_cmd_pref(void)
2287 /* Ask for a "user pref command" */
2288 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2290 /* Process that pref command */
2291 (void)process_pref_file_command(buf);
2295 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2298 void do_cmd_reload_autopick(void)
2300 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2301 /* Load the file with messages */
2302 autopick_load_pref(TRUE);
2308 * @brief マクロ情報をprefファイルに保存する /
2309 * @param fname ファイル名
2312 static errr macro_dump(concptr fname)
2314 static concptr mark = "Macro Dump";
2320 /* Build the filename */
2321 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2323 /* File type is "TEXT" */
2324 FILE_TYPE(FILE_TYPE_TEXT);
2326 /* Append to the file */
2327 if (!open_auto_dump(buf, mark)) return (-1);
2330 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2333 for (i = 0; i < macro__num; i++)
2335 /* Extract the action */
2336 ascii_to_text(buf, macro__act[i]);
2338 /* Dump the macro */
2339 auto_dump_printf("A:%s\n", buf);
2341 /* Extract the action */
2342 ascii_to_text(buf, macro__pat[i]);
2344 /* Dump normal macros */
2345 auto_dump_printf("P:%s\n", buf);
2348 auto_dump_printf("\n");
2360 * @brief マクロのトリガーキーを取得する /
2361 * Hack -- ask for a "trigger" (see below)
2362 * @param buf キー表記を保管するバッファ
2366 * Note the complex use of the "inkey()" function from "util.c".
2368 * Note that both "flush()" calls are extremely important.
2371 static void do_cmd_macro_aux(char *buf)
2379 /* Do not process macros */
2385 /* Read the pattern */
2391 /* Do not process macros */
2394 /* Do not wait for keys */
2397 /* Attempt to read a key */
2406 /* Convert the trigger */
2407 ascii_to_text(tmp, buf);
2409 /* Hack -- display the trigger */
2410 Term_addstr(-1, TERM_WHITE, tmp);
2416 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2417 * Hack -- ask for a keymap "trigger" (see below)
2418 * @param buf キー表記を取得するバッファ
2422 * Note that both "flush()" calls are extremely important. This may
2423 * no longer be true, since "util.c" is much simpler now.
2426 static void do_cmd_macro_aux_keymap(char *buf)
2436 /* Convert to ascii */
2437 ascii_to_text(tmp, buf);
2439 /* Hack -- display the trigger */
2440 Term_addstr(-1, TERM_WHITE, tmp);
2447 * @brief キーマップをprefファイルにダンプする /
2448 * Hack -- append all keymaps to the given file
2449 * @param fname ファイルネーム
2453 static errr keymap_dump(concptr fname)
2455 static concptr mark = "Keymap Dump";
2464 if (rogue_like_commands)
2466 mode = KEYMAP_MODE_ROGUE;
2472 mode = KEYMAP_MODE_ORIG;
2476 /* Build the filename */
2477 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2479 /* File type is "TEXT" */
2480 FILE_TYPE(FILE_TYPE_TEXT);
2482 /* Append to the file */
2483 if (!open_auto_dump(buf, mark)) return -1;
2486 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2489 for (i = 0; i < 256; i++)
2493 /* Loop up the keymap */
2494 act = keymap_act[mode][i];
2496 /* Skip empty keymaps */
2499 /* Encode the key */
2502 ascii_to_text(key, buf);
2504 /* Encode the action */
2505 ascii_to_text(buf, act);
2507 /* Dump the macro */
2508 auto_dump_printf("A:%s\n", buf);
2509 auto_dump_printf("C:%d:%s\n", mode, key);
2521 * @brief マクロを設定するコマンドのメインルーチン /
2522 * Interact with "macros"
2526 * Note that the macro "action" must be defined before the trigger.
2528 * Could use some helpful instructions on this page.
2531 void do_cmd_macros(void)
2543 if (rogue_like_commands)
2545 mode = KEYMAP_MODE_ROGUE;
2551 mode = KEYMAP_MODE_ORIG;
2554 /* File type is "TEXT" */
2555 FILE_TYPE(FILE_TYPE_TEXT);
2560 /* Process requests until done */
2564 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2566 /* Describe that action */
2567 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2569 /* Analyze the current action */
2570 ascii_to_text(buf, macro__buf);
2572 /* Display the current action */
2577 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2579 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2580 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2581 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2582 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2583 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2584 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2585 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2586 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2587 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2588 #endif /* ALLOW_MACROS */
2591 prt(_("コマンド: ", "Command: "), 16, 0);
2596 if (i == ESCAPE) break;
2598 /* Load a 'macro' file */
2604 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2607 prt(_("ファイル: ", "File: "), 18, 0);
2609 /* Default filename */
2610 sprintf(tmp, "%s.prf", player_base);
2612 /* Ask for a file */
2613 if (!askfor(tmp, 80)) continue;
2615 /* Process the given filename */
2616 err = process_pref_file(tmp);
2619 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2624 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2628 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2638 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2641 prt(_("ファイル: ", "File: "), 18, 0);
2643 /* Default filename */
2644 sprintf(tmp, "%s.prf", player_base);
2646 /* Ask for a file */
2647 if (!askfor(tmp, 80)) continue;
2649 /* Dump the macros */
2650 (void)macro_dump(tmp);
2653 msg_print(_("マクロを追加しました。", "Appended macros."));
2662 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2666 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2668 /* Get a macro trigger */
2669 do_cmd_macro_aux(buf);
2671 /* Acquire action */
2672 k = macro_find_exact(buf);
2678 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2684 /* Obtain the action */
2685 strcpy(macro__buf, macro__act[k]);
2687 /* Analyze the current action */
2688 ascii_to_text(buf, macro__buf);
2690 /* Display the current action */
2694 msg_print(_("マクロを確認しました。", "Found a macro."));
2698 /* Create a macro */
2702 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2705 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2707 /* Get a macro trigger */
2708 do_cmd_macro_aux(buf);
2714 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2715 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2718 prt(_("マクロ行動: ", "Action: "), 20, 0);
2720 /* Convert to text */
2721 ascii_to_text(tmp, macro__buf);
2723 /* Get an encoded action */
2724 if (askfor(tmp, 80))
2726 /* Convert to ascii */
2727 text_to_ascii(macro__buf, tmp);
2729 /* Link the macro */
2730 macro_add(buf, macro__buf);
2733 msg_print(_("マクロを追加しました。", "Added a macro."));
2737 /* Remove a macro */
2741 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2744 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2746 /* Get a macro trigger */
2747 do_cmd_macro_aux(buf);
2749 /* Link the macro */
2750 macro_add(buf, buf);
2753 msg_print(_("マクロを削除しました。", "Removed a macro."));
2760 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2763 prt(_("ファイル: ", "File: "), 18, 0);
2765 /* Default filename */
2766 sprintf(tmp, "%s.prf", player_base);
2768 /* Ask for a file */
2769 if (!askfor(tmp, 80)) continue;
2771 /* Dump the macros */
2772 (void)keymap_dump(tmp);
2775 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2778 /* Query a keymap */
2784 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2787 prt(_("押すキー: ", "Keypress: "), 18, 0);
2789 /* Get a keymap trigger */
2790 do_cmd_macro_aux_keymap(buf);
2792 /* Look up the keymap */
2793 act = keymap_act[mode][(byte)(buf[0])];
2799 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2805 /* Obtain the action */
2806 strcpy(macro__buf, act);
2808 /* Analyze the current action */
2809 ascii_to_text(buf, macro__buf);
2811 /* Display the current action */
2815 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2819 /* Create a keymap */
2823 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2826 prt(_("押すキー: ", "Keypress: "), 18, 0);
2828 /* Get a keymap trigger */
2829 do_cmd_macro_aux_keymap(buf);
2835 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2836 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2839 prt(_("行動: ", "Action: "), 20, 0);
2841 /* Convert to text */
2842 ascii_to_text(tmp, macro__buf);
2844 /* Get an encoded action */
2845 if (askfor(tmp, 80))
2847 /* Convert to ascii */
2848 text_to_ascii(macro__buf, tmp);
2850 /* Free old keymap */
2851 string_free(keymap_act[mode][(byte)(buf[0])]);
2853 /* Make new keymap */
2854 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2857 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2861 /* Remove a keymap */
2865 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2868 prt(_("押すキー: ", "Keypress: "), 18, 0);
2870 /* Get a keymap trigger */
2871 do_cmd_macro_aux_keymap(buf);
2873 /* Free old keymap */
2874 string_free(keymap_act[mode][(byte)(buf[0])]);
2876 /* Make new keymap */
2877 keymap_act[mode][(byte)(buf[0])] = NULL;
2880 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2883 /* Enter a new action */
2887 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2893 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2894 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2897 prt(_("マクロ行動: ", "Action: "), 20, 0);
2899 /* Hack -- limit the value */
2902 /* Get an encoded action */
2903 if (!askfor(buf, 80)) continue;
2905 /* Extract an action */
2906 text_to_ascii(macro__buf, buf);
2909 #endif /* ALLOW_MACROS */
2922 * @brief キャラクタ色の明暗表現
2924 static concptr lighting_level_str[F_LIT_MAX] =
2939 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2940 * @param i 指定対象となるキャラクタコード
2941 * @param num 指定されたビジュアルIDを返す参照ポインタ
2942 * @param max ビジュアルIDの最大数
2943 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2945 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2952 sprintf(str, "%d", *num);
2954 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2957 tmp = (IDX)strtol(str, NULL, 0);
2958 if (tmp >= 0 && tmp < max)
2961 else if (isupper(i))
2962 *num = (*num + max - 1) % max;
2964 *num = (*num + 1) % max;
2970 * @brief キャラクタの変更メニュー表示
2971 * @param choice_msg 選択メッセージ
2974 static void print_visuals_menu(concptr choice_msg)
2976 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2978 /* Give some choices */
2979 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2981 #ifdef ALLOW_VISUALS
2982 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2983 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2984 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2985 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2986 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2987 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2988 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2989 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2990 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2991 #endif /* ALLOW_VISUALS */
2993 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2996 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2999 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3000 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3001 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3004 * Interact with "visuals"
3006 void do_cmd_visuals(void)
3011 bool need_redraw = FALSE;
3012 concptr empty_symbol = "<< ? >>";
3014 if (use_bigtile) empty_symbol = "<< ?? >>";
3016 /* File type is "TEXT" */
3017 FILE_TYPE(FILE_TYPE_TEXT);
3020 /* Interact until done */
3025 /* Ask for a choice */
3026 print_visuals_menu(NULL);
3031 if (i == ESCAPE) break;
3035 /* Load a 'pref' file */
3038 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3041 prt(_("ファイル: ", "File: "), 17, 0);
3043 /* Default filename */
3044 sprintf(tmp, "%s.prf", player_base);
3047 if (!askfor(tmp, 70)) continue;
3049 /* Process the given filename */
3050 (void)process_pref_file(tmp);
3055 #ifdef ALLOW_VISUALS
3057 /* Dump monster attr/chars */
3060 static concptr mark = "Monster attr/chars";
3063 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3066 prt(_("ファイル: ", "File: "), 17, 0);
3068 /* Default filename */
3069 sprintf(tmp, "%s.prf", player_base);
3071 /* Get a filename */
3072 if (!askfor(tmp, 70)) continue;
3074 /* Build the filename */
3075 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3077 /* Append to the file */
3078 if (!open_auto_dump(buf, mark)) continue;
3081 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3084 for (i = 0; i < max_r_idx; i++)
3086 monster_race *r_ptr = &r_info[i];
3088 /* Skip non-entries */
3089 if (!r_ptr->name) continue;
3091 /* Dump a comment */
3092 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3094 /* Dump the monster attr/char info */
3095 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3096 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3102 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3107 /* Dump object attr/chars */
3110 static concptr mark = "Object attr/chars";
3111 KIND_OBJECT_IDX k_idx;
3114 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3117 prt(_("ファイル: ", "File: "), 17, 0);
3119 /* Default filename */
3120 sprintf(tmp, "%s.prf", player_base);
3122 /* Get a filename */
3123 if (!askfor(tmp, 70)) continue;
3125 /* Build the filename */
3126 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3128 /* Append to the file */
3129 if (!open_auto_dump(buf, mark)) continue;
3132 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3135 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3137 GAME_TEXT o_name[MAX_NLEN];
3138 object_kind *k_ptr = &k_info[k_idx];
3140 /* Skip non-entries */
3141 if (!k_ptr->name) continue;
3146 strip_name(o_name, k_idx);
3152 /* Prepare dummy object */
3153 object_prep(&forge, k_idx);
3155 /* Get un-shuffled flavor name */
3156 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3159 /* Dump a comment */
3160 auto_dump_printf("# %s\n", o_name);
3162 /* Dump the object attr/char info */
3163 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3164 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3170 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3175 /* Dump feature attr/chars */
3178 static concptr mark = "Feature attr/chars";
3181 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3184 prt(_("ファイル: ", "File: "), 17, 0);
3186 /* Default filename */
3187 sprintf(tmp, "%s.prf", player_base);
3189 /* Get a filename */
3190 if (!askfor(tmp, 70)) continue;
3192 /* Build the filename */
3193 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3195 /* Append to the file */
3196 if (!open_auto_dump(buf, mark)) continue;
3199 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3202 for (i = 0; i < max_f_idx; i++)
3204 feature_type *f_ptr = &f_info[i];
3206 /* Skip non-entries */
3207 if (!f_ptr->name) continue;
3209 /* Skip mimiccing features */
3210 if (f_ptr->mimic != i) continue;
3212 /* Dump a comment */
3213 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3215 /* Dump the feature attr/char info */
3216 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3217 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3218 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3219 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3225 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3230 /* Modify monster attr/chars (numeric operation) */
3233 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3234 static MONRACE_IDX r = 0;
3236 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3238 /* Hack -- query until done */
3241 monster_race *r_ptr = &r_info[r];
3245 TERM_COLOR da = r_ptr->d_attr;
3246 byte dc = r_ptr->d_char;
3247 TERM_COLOR ca = r_ptr->x_attr;
3248 byte cc = r_ptr->x_char;
3250 /* Label the object */
3251 Term_putstr(5, 17, -1, TERM_WHITE,
3252 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3254 /* Label the Default values */
3255 Term_putstr(10, 19, -1, TERM_WHITE,
3256 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3258 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3259 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3261 /* Label the Current values */
3262 Term_putstr(10, 20, -1, TERM_WHITE,
3263 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3265 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3266 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3269 Term_putstr(0, 22, -1, TERM_WHITE,
3270 _("コマンド (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): "));
3275 if (i == ESCAPE) break;
3277 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3278 else if (isupper(i)) c = 'a' + i - 'A';
3288 if (!cmd_visuals_aux(i, &r, max_r_idx))
3294 while (!r_info[r].name);
3298 t = (int)r_ptr->x_attr;
3299 (void)cmd_visuals_aux(i, &t, 256);
3300 r_ptr->x_attr = (byte)t;
3304 t = (int)r_ptr->x_char;
3305 (void)cmd_visuals_aux(i, &t, 256);
3306 r_ptr->x_char = (byte)t;
3310 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3312 print_visuals_menu(choice_msg);
3320 /* Modify object attr/chars (numeric operation) */
3323 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3325 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3327 /* Hack -- query until done */
3330 object_kind *k_ptr = &k_info[k];
3334 TERM_COLOR da = k_ptr->d_attr;
3335 SYMBOL_CODE dc = k_ptr->d_char;
3336 TERM_COLOR ca = k_ptr->x_attr;
3337 SYMBOL_CODE cc = k_ptr->x_char;
3339 /* Label the object */
3340 Term_putstr(5, 17, -1, TERM_WHITE,
3341 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3342 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3344 /* Label the Default values */
3345 Term_putstr(10, 19, -1, TERM_WHITE,
3346 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3348 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3349 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3351 /* Label the Current values */
3352 Term_putstr(10, 20, -1, TERM_WHITE,
3353 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3355 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3356 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3359 Term_putstr(0, 22, -1, TERM_WHITE,
3360 _("コマンド (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): "));
3365 if (i == ESCAPE) break;
3367 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3368 else if (isupper(i)) c = 'a' + i - 'A';
3378 if (!cmd_visuals_aux(i, &k, max_k_idx))
3384 while (!k_info[k].name);
3388 t = (int)k_ptr->x_attr;
3389 (void)cmd_visuals_aux(i, &t, 256);
3390 k_ptr->x_attr = (byte)t;
3394 t = (int)k_ptr->x_char;
3395 (void)cmd_visuals_aux(i, &t, 256);
3396 k_ptr->x_char = (byte)t;
3400 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3402 print_visuals_menu(choice_msg);
3410 /* Modify feature attr/chars (numeric operation) */
3413 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3415 static IDX lighting_level = F_LIT_STANDARD;
3416 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3418 /* Hack -- query until done */
3421 feature_type *f_ptr = &f_info[f];
3425 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3426 byte dc = f_ptr->d_char[lighting_level];
3427 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3428 byte cc = f_ptr->x_char[lighting_level];
3430 /* Label the object */
3432 Term_putstr(5, 17, -1, TERM_WHITE,
3433 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3434 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3436 /* Label the Default values */
3437 Term_putstr(10, 19, -1, TERM_WHITE,
3438 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3440 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3441 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3443 /* Label the Current values */
3445 Term_putstr(10, 20, -1, TERM_WHITE,
3446 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3448 Term_putstr(10, 20, -1, TERM_WHITE,
3449 format("Current attr/char = %3d / %3d", ca, cc));
3452 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3453 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3457 Term_putstr(0, 22, -1, TERM_WHITE,
3458 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3460 Term_putstr(0, 22, -1, TERM_WHITE,
3461 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3467 if (i == ESCAPE) break;
3469 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3470 else if (isupper(i)) c = 'a' + i - 'A';
3480 if (!cmd_visuals_aux(i, &f, max_f_idx))
3486 while (!f_info[f].name || (f_info[f].mimic != f));
3490 t = (int)f_ptr->x_attr[lighting_level];
3491 (void)cmd_visuals_aux(i, &t, 256);
3492 f_ptr->x_attr[lighting_level] = (byte)t;
3496 t = (int)f_ptr->x_char[lighting_level];
3497 (void)cmd_visuals_aux(i, &t, 256);
3498 f_ptr->x_char[lighting_level] = (byte)t;
3502 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3505 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3509 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3511 print_visuals_menu(choice_msg);
3519 /* Modify monster attr/chars (visual mode) */
3521 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3524 /* Modify object attr/chars (visual mode) */
3526 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3529 /* Modify feature attr/chars (visual mode) */
3532 IDX lighting_level = F_LIT_STANDARD;
3533 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3537 #endif /* ALLOW_VISUALS */
3545 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3549 /* Unknown option */
3559 if (need_redraw) do_cmd_redraw();
3564 * Interact with "colors"
3566 void do_cmd_colors(void)
3575 /* File type is "TEXT" */
3576 FILE_TYPE(FILE_TYPE_TEXT);
3581 /* Interact until done */
3586 /* Ask for a choice */
3587 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3589 /* Give some choices */
3590 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3593 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3594 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3598 prt(_("コマンド: ", "Command: "), 8, 0);
3602 if (i == ESCAPE) break;
3604 /* Load a 'pref' file */
3608 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3611 prt(_("ファイル: ", "File: "), 10, 0);
3614 sprintf(tmp, "%s.prf", player_base);
3617 if (!askfor(tmp, 70)) continue;
3619 /* Process the given filename */
3620 (void)process_pref_file(tmp);
3622 /* Mega-Hack -- react to changes */
3623 Term_xtra(TERM_XTRA_REACT, 0);
3625 /* Mega-Hack -- redraw */
3634 static concptr mark = "Colors";
3637 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3640 prt(_("ファイル: ", "File: "), 10, 0);
3642 /* Default filename */
3643 sprintf(tmp, "%s.prf", player_base);
3645 /* Get a filename */
3646 if (!askfor(tmp, 70)) continue;
3648 /* Build the filename */
3649 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3651 /* Append to the file */
3652 if (!open_auto_dump(buf, mark)) continue;
3655 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3658 for (i = 0; i < 256; i++)
3660 int kv = angband_color_table[i][0];
3661 int rv = angband_color_table[i][1];
3662 int gv = angband_color_table[i][2];
3663 int bv = angband_color_table[i][3];
3665 concptr name = _("未知", "unknown");
3667 /* Skip non-entries */
3668 if (!kv && !rv && !gv && !bv) continue;
3670 /* Extract the color name */
3671 if (i < 16) name = color_names[i];
3673 /* Dump a comment */
3674 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3676 /* Dump the monster attr/char info */
3677 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3684 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3693 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3695 /* Hack -- query until done */
3704 /* Exhibit the normal colors */
3705 for (j = 0; j < 16; j++)
3707 /* Exhibit this color */
3708 Term_putstr(j*4, 20, -1, a, "###");
3710 /* Exhibit all colors */
3711 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3714 /* Describe the color */
3715 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3717 /* Describe the color */
3718 Term_putstr(5, 10, -1, TERM_WHITE,
3719 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3721 /* Label the Current values */
3722 Term_putstr(5, 12, -1, TERM_WHITE,
3723 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3724 angband_color_table[a][0],
3725 angband_color_table[a][1],
3726 angband_color_table[a][2],
3727 angband_color_table[a][3]));
3730 Term_putstr(0, 14, -1, TERM_WHITE,
3731 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3736 if (i == ESCAPE) break;
3739 if (i == 'n') a = (byte)(a + 1);
3740 if (i == 'N') a = (byte)(a - 1);
3741 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3742 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3743 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3744 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3745 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3746 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3747 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3748 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3750 /* Hack -- react to changes */
3751 Term_xtra(TERM_XTRA_REACT, 0);
3753 /* Hack -- redraw */
3760 /* Unknown option */
3774 * Note something in the message recall
3776 void do_cmd_note(void)
3784 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3786 /* Ignore empty notes */
3787 if (!buf[0] || (buf[0] == ' ')) return;
3789 /* Add the note to the message recall */
3790 msg_format(_("メモ: %s", "Note: %s"), buf);
3795 * Mention the current version
3797 void do_cmd_version(void)
3799 #if FAKE_VER_EXTRA > 0
3800 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3801 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3803 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3804 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3811 * Array of feeling strings
3813 static concptr do_cmd_feeling_text[11] =
3815 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3816 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3817 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3818 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3819 _("とても悪い予感がする...", "You have a very bad feeling..."),
3820 _("悪い予感がする...", "You have a bad feeling..."),
3821 _("何か緊張する。", "You feel nervous."),
3822 _("少し不運な気がする...", "You feel your luck is turning..."),
3823 _("この場所は好きになれない。", "You don't like the look of this place."),
3824 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3825 _("なんて退屈なところだ...", "What a boring place...")
3828 static concptr do_cmd_feeling_text_combat[11] =
3830 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3831 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3832 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3833 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3834 _("とても悪い予感がする...", "You have a very bad feeling..."),
3835 _("悪い予感がする...", "You have a bad feeling..."),
3836 _("何か緊張する。", "You feel nervous."),
3837 _("少し不運な気がする...", "You feel your luck is turning..."),
3838 _("この場所は好きになれない。", "You don't like the look of this place."),
3839 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3840 _("なんて退屈なところだ...", "What a boring place...")
3843 static concptr do_cmd_feeling_text_lucky[11] =
3845 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3846 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3847 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3848 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3849 _("とても良い感じがする...", "You have a very good feeling..."),
3850 _("良い感じがする...", "You have a good feeling..."),
3851 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3852 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3853 _("見た感じ悪くはない...", "You like the look of this place..."),
3854 _("全然駄目ということはないが...", "This level can't be all bad..."),
3855 _("なんて退屈なところだ...", "What a boring place...")
3860 * Note that "feeling" is set to zero unless some time has passed.
3861 * Note that this is done when the level is GENERATED, not entered.
3863 void do_cmd_feeling(void)
3865 if (p_ptr->wild_mode) return;
3867 /* No useful feeling in quests */
3868 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3870 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3874 /* No useful feeling in town */
3875 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3877 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3879 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3884 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3889 /* No useful feeling in the wilderness */
3890 else if (!current_floor_ptr->dun_level)
3892 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3896 /* Display the feeling */
3897 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3898 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3899 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3900 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3901 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3903 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3909 * Description of each monster group.
3911 static concptr monster_group_text[] =
3914 "ユニーク", /* "Uniques" */
3915 "乗馬可能なモンスター", /* "Riding" */
3916 "賞金首", /* "Wanted */
3917 "アンバーの王族", /* "Ambertite" */
3946 /* "古代ドラゴン/ワイアーム", */
4007 /* "Ancient Dragon/Wyrm", */
4016 "Multi-Headed Reptile",
4021 "Reptile/Amphibian",
4022 "Spider/Scorpion/Tick",
4024 /* "Major Demon", */
4041 * Symbols of monsters in each group. Note the "Uniques" group
4042 * is handled differently.
4044 static concptr monster_group_char[] =
4101 "!$&()+./=>?[\\]`{|~",
4111 * Build a list of monster indexes in the given group. Return the number
4112 * of monsters in the group.
4114 * mode & 0x01 : check for non-empty group
4115 * mode & 0x02 : visual operation only
4117 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4123 /* Get a list of x_char in this group */
4124 concptr group_char = monster_group_char[grp_cur];
4126 /* XXX Hack -- Check if this is the "Uniques" group */
4127 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4129 /* XXX Hack -- Check if this is the "Riding" group */
4130 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4132 /* XXX Hack -- Check if this is the "Wanted" group */
4133 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4135 /* XXX Hack -- Check if this is the "Amberite" group */
4136 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4139 /* Check every race */
4140 for (i = 0; i < max_r_idx; i++)
4142 /* Access the race */
4143 monster_race *r_ptr = &r_info[i];
4145 /* Skip empty race */
4146 if (!r_ptr->name) continue ;
4148 /* Require known monsters */
4149 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4153 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4156 else if (grp_riding)
4158 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4161 else if (grp_wanted)
4163 bool wanted = FALSE;
4165 for (j = 0; j < MAX_KUBI; j++)
4167 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4168 (p_ptr->today_mon && p_ptr->today_mon == i))
4174 if (!wanted) continue;
4177 else if (grp_amberite)
4179 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4184 /* Check for race in the group */
4185 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4189 mon_idx[mon_cnt++] = i;
4191 /* XXX Hack -- Just checking for non-empty group */
4192 if (mode & 0x01) break;
4195 /* Terminate the list */
4196 mon_idx[mon_cnt] = -1;
4198 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4200 /* Return the number of races */
4206 * Description of each monster group.
4208 static concptr object_group_text[] =
4211 "キノコ", /* "Mushrooms" */
4212 "薬", /* "Potions" */
4213 "油つぼ", /* "Flasks" */
4214 "巻物", /* "Scrolls" */
4216 "アミュレット", /* "Amulets" */
4217 "笛", /* "Whistle" */
4218 "光源", /* "Lanterns" */
4219 "魔法棒", /* "Wands" */
4222 "カード", /* "Cards" */
4233 "刀剣類", /* "Swords" */
4234 "鈍器", /* "Blunt Weapons" */
4235 "長柄武器", /* "Polearms" */
4236 "採掘道具", /* "Diggers" */
4237 "飛び道具", /* "Bows" */
4241 "軽装鎧", /* "Soft Armor" */
4242 "重装鎧", /* "Hard Armor" */
4243 "ドラゴン鎧", /* "Dragon Armor" */
4244 "盾", /* "Shields" */
4245 "クローク", /* "Cloaks" */
4246 "籠手", /* "Gloves" */
4247 "ヘルメット", /* "Helms" */
4249 "ブーツ", /* "Boots" */
4302 * TVALs of items in each group
4304 static byte object_group_tval[] =
4345 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4353 * Build a list of object indexes in the given group. Return the number
4354 * of objects in the group.
4356 * mode & 0x01 : check for non-empty group
4357 * mode & 0x02 : visual operation only
4359 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4361 KIND_OBJECT_IDX i, object_cnt = 0;
4364 /* Get a list of x_char in this group */
4365 byte group_tval = object_group_tval[grp_cur];
4367 /* Check every object */
4368 for (i = 0; i < max_k_idx; i++)
4370 /* Access the object */
4371 object_kind *k_ptr = &k_info[i];
4373 /* Skip empty objects */
4374 if (!k_ptr->name) continue;
4378 /* Any objects will be displayed */
4384 /* Skip non-flavoured objects */
4385 if (!k_ptr->flavor) continue;
4387 /* Require objects ever seen */
4388 if (!k_ptr->aware) continue;
4391 /* Skip items with no distribution (special artifacts) */
4392 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4396 /* Check for objects in the group */
4397 if (TV_LIFE_BOOK == group_tval)
4399 /* Hack -- All spell books */
4400 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4402 /* Add the object */
4403 object_idx[object_cnt++] = i;
4407 else if (k_ptr->tval == group_tval)
4409 /* Add the object */
4410 object_idx[object_cnt++] = i;
4414 /* XXX Hack -- Just checking for non-empty group */
4415 if (mode & 0x01) break;
4418 /* Terminate the list */
4419 object_idx[object_cnt] = -1;
4421 /* Return the number of objects */
4427 * Description of each feature group.
4429 static concptr feature_group_text[] =
4437 * Build a list of feature indexes in the given group. Return the number
4438 * of features in the group.
4440 * mode & 0x01 : check for non-empty group
4442 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4445 FEAT_IDX feat_cnt = 0;
4447 /* Unused; There is a single group. */
4450 /* Check every feature */
4451 for (i = 0; i < max_f_idx; i++)
4453 feature_type *f_ptr = &f_info[i];
4455 /* Skip empty index */
4456 if (!f_ptr->name) continue;
4458 /* Skip mimiccing features */
4459 if (f_ptr->mimic != i) continue;
4462 feat_idx[feat_cnt++] = i;
4464 /* XXX Hack -- Just checking for non-empty group */
4465 if (mode & 0x01) break;
4468 /* Terminate the list */
4469 feat_idx[feat_cnt] = -1;
4471 /* Return the number of races */
4478 * Build a list of monster indexes in the given group. Return the number
4479 * of monsters in the group.
4481 static int collect_artifacts(int grp_cur, int object_idx[])
4483 int i, object_cnt = 0;
4485 /* Get a list of x_char in this group */
4486 byte group_tval = object_group_tval[grp_cur];
4488 /* Check every object */
4489 for (i = 0; i < max_a_idx; i++)
4491 /* Access the artifact */
4492 artifact_type *a_ptr = &a_info[i];
4494 /* Skip empty artifacts */
4495 if (!a_ptr->name) continue;
4497 /* Skip "uncreated" artifacts */
4498 if (!a_ptr->cur_num) continue;
4500 /* Check for race in the group */
4501 if (a_ptr->tval == group_tval)
4504 object_idx[object_cnt++] = i;
4508 /* Terminate the list */
4509 object_idx[object_cnt] = 0;
4511 /* Return the number of races */
4518 * Encode the screen colors
4520 static char hack[17] = "dwsorgbuDWvyRGBU";
4524 * Hack -- load a screen dump from a file
4526 void do_cmd_load_screen(void)
4531 SYMBOL_CODE c = ' ';
4537 Term_get_size(&wid, &hgt);
4539 /* Build the filename */
4540 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4542 /* Append to the file */
4543 fff = my_fopen(buf, "r");
4546 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4554 /* Load the screen */
4555 for (y = 0; okay; y++)
4557 /* Get a line of data including control code */
4558 if (!fgets(buf, 1024, fff)) okay = FALSE;
4560 /* Get the blank line */
4561 if (buf[0] == '\n' || buf[0] == '\0') break;
4563 /* Ignore too large screen image */
4564 if (y >= hgt) continue;
4567 for (x = 0; x < wid - 1; x++)
4570 if (buf[x] == '\n' || buf[x] == '\0') break;
4572 /* Put the attr/char */
4573 Term_draw(x, y, TERM_WHITE, buf[x]);
4577 /* Dump the screen */
4578 for (y = 0; okay; y++)
4580 /* Get a line of data including control code */
4581 if (!fgets(buf, 1024, fff)) okay = FALSE;
4583 /* Get the blank line */
4584 if (buf[0] == '\n' || buf[0] == '\0') break;
4586 /* Ignore too large screen image */
4587 if (y >= hgt) continue;
4590 for (x = 0; x < wid - 1; x++)
4593 if (buf[x] == '\n' || buf[x] == '\0') break;
4595 /* Get the attr/char */
4596 (void)(Term_what(x, y, &a, &c));
4598 /* Look up the attr */
4599 for (i = 0; i < 16; i++)
4601 /* Use attr matches */
4602 if (hack[i] == buf[x]) a = (byte_hack)i;
4605 /* Put the attr/char */
4606 Term_draw(x, y, a, c);
4611 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4622 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4623 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4626 #define IM_FLAG_STR _("*", "* ")
4627 #define HAS_FLAG_STR _("+", "+ ")
4628 #define NO_FLAG_STR _("・", ". ")
4630 #define print_im_or_res_flag(IM, RES) \
4632 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4633 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4636 #define print_flag(TR) \
4638 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4642 /* XTRA HACK RESLIST */
4643 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4645 GAME_TEXT o_name[MAX_NLEN];
4646 BIT_FLAGS flgs[TR_FLAG_SIZE];
4648 if (!o_ptr->k_idx) return;
4649 if (o_ptr->tval != tval) return;
4651 /* Identified items only */
4652 if (!object_is_known(o_ptr)) return;
4655 * HACK:Ring of Lordly protection and Dragon equipment
4656 * have random resistances.
4658 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4659 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4660 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4661 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4662 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4663 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4664 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4665 || object_is_artifact(o_ptr))
4668 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4670 while (o_name[i] && (i < 26))
4673 if (iskanji(o_name[i])) i++;
4682 o_name[i] = ' '; i++;
4687 fprintf(fff, "%s %s", where, o_name);
4689 if (!(o_ptr->ident & (IDENT_MENTAL)))
4691 fputs(_("-------不明--------------- -------不明---------\n",
4692 "-------unknown------------ -------unknown------\n"), fff);
4696 object_flags_known(o_ptr, flgs);
4698 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4699 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4700 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4701 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4702 print_flag(TR_RES_POIS);
4703 print_flag(TR_RES_LITE);
4704 print_flag(TR_RES_DARK);
4705 print_flag(TR_RES_SHARDS);
4706 print_flag(TR_RES_SOUND);
4707 print_flag(TR_RES_NETHER);
4708 print_flag(TR_RES_NEXUS);
4709 print_flag(TR_RES_CHAOS);
4710 print_flag(TR_RES_DISEN);
4714 print_flag(TR_RES_BLIND);
4715 print_flag(TR_RES_FEAR);
4716 print_flag(TR_RES_CONF);
4717 print_flag(TR_FREE_ACT);
4718 print_flag(TR_SEE_INVIS);
4719 print_flag(TR_HOLD_EXP);
4720 print_flag(TR_TELEPATHY);
4721 print_flag(TR_SLOW_DIGEST);
4722 print_flag(TR_REGEN);
4723 print_flag(TR_LEVITATION);
4731 fprintf(fff, "%s\n", inven_res_label);
4737 * Display *ID* ed weapons/armors's resistances
4739 static void do_cmd_knowledge_inven(void)
4742 GAME_TEXT file_name[1024];
4744 OBJECT_TYPE_VALUE tval;
4750 /* Open a new file */
4751 fff = my_fopen_temp(file_name, 1024);
4754 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4758 fprintf(fff, "%s\n", inven_res_label);
4760 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4764 for (; j < 9; j++) fputc('\n', fff);
4766 fprintf(fff, "%s\n", inven_res_label);
4768 strcpy(where, _("装", "E "));
4769 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4771 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4773 strcpy(where, _("持", "I "));
4774 for (i = 0; i < INVEN_PACK; i++)
4776 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4779 st_ptr = &town_info[1].store[STORE_HOME];
4780 strcpy(where, _("家", "H "));
4781 for (i = 0; i < st_ptr->stock_num; i++)
4783 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4788 /* Display the file contents */
4789 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4794 void do_cmd_save_screen_html_aux(char *filename, int message)
4799 TERM_COLOR a = 0, old_a = 0;
4813 concptr html_head[] = {
4814 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4818 concptr html_foot[] = {
4820 "</body>\n</html>\n",
4826 Term_get_size(&wid, &hgt);
4828 /* File type is "TEXT" */
4829 FILE_TYPE(FILE_TYPE_TEXT);
4831 /* Append to the file */
4832 fff = my_fopen(filename, "w");
4836 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4842 if (message) screen_save();
4844 /* Build the filename */
4845 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4846 tmpfff = my_fopen(buf, "r");
4848 for (i = 0; html_head[i]; i++)
4849 fputs(html_head[i], fff);
4853 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4855 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4859 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4861 fprintf(fff, "%s\n", buf);
4866 /* Dump the screen */
4867 for (y = 0; y < hgt; y++)
4874 for (x = 0; x < wid - 1; x++)
4878 /* Get the attr/char */
4879 (void)(Term_what(x, y, &a, &c));
4883 case '&': cc = "&"; break;
4884 case '<': cc = "<"; break;
4885 case '>': cc = ">"; break;
4887 case 0x1f: c = '.'; break;
4888 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4893 if ((y == 0 && x == 0) || a != old_a) {
4894 rv = angband_color_table[a][1];
4895 gv = angband_color_table[a][2];
4896 bv = angband_color_table[a][3];
4897 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4898 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4902 fprintf(fff, "%s", cc);
4904 fprintf(fff, "%c", c);
4907 fprintf(fff, "</font>");
4910 for (i = 0; html_foot[i]; i++)
4911 fputs(html_foot[i], fff);
4916 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4918 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4922 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4924 fprintf(fff, "%s\n", buf);
4935 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4943 * Hack -- save a screen dump to a file
4945 static void do_cmd_save_screen_html(void)
4947 char buf[1024], tmp[256] = "screen.html";
4949 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4952 /* Build the filename */
4953 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4957 do_cmd_save_screen_html_aux(buf, 1);
4962 * Redefinable "save_screen" action
4964 void (*screendump_aux)(void) = NULL;
4968 * Hack -- save a screen dump to a file
4970 void do_cmd_save_screen(void)
4972 bool old_use_graphics = use_graphics;
4973 bool html_dump = FALSE;
4977 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4981 if (c == 'Y' || c == 'y')
4983 else if (c == 'H' || c == 'h')
4995 Term_get_size(&wid, &hgt);
4997 if (old_use_graphics)
4999 use_graphics = FALSE;
5001 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5007 do_cmd_save_screen_html();
5011 /* Do we use a special screendump function ? */
5012 else if (screendump_aux)
5014 /* Dump the screen to a graphics file */
5015 (*screendump_aux)();
5017 else /* Dump the screen as text */
5021 SYMBOL_CODE c = ' ';
5025 /* Build the filename */
5026 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5028 /* File type is "TEXT" */
5029 FILE_TYPE(FILE_TYPE_TEXT);
5031 /* Append to the file */
5032 fff = my_fopen(buf, "w");
5036 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5044 /* Dump the screen */
5045 for (y = 0; y < hgt; y++)
5048 for (x = 0; x < wid - 1; x++)
5050 /* Get the attr/char */
5051 (void)(Term_what(x, y, &a, &c));
5061 fprintf(fff, "%s\n", buf);
5068 /* Dump the screen */
5069 for (y = 0; y < hgt; y++)
5072 for (x = 0; x < wid - 1; x++)
5074 /* Get the attr/char */
5075 (void)(Term_what(x, y, &a, &c));
5078 buf[x] = hack[a&0x0F];
5085 fprintf(fff, "%s\n", buf);
5092 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5097 if (old_use_graphics)
5099 use_graphics = TRUE;
5101 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5107 * Check the status of "artifacts"
5109 static void do_cmd_knowledge_artifacts(void)
5119 GAME_TEXT file_name[1024];
5120 GAME_TEXT base_name[MAX_NLEN];
5124 /* Open a new file */
5125 fff = my_fopen_temp(file_name, 1024);
5128 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5133 /* Allocate the "who" array */
5134 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5136 /* Allocate the "okay" array */
5137 C_MAKE(okay, max_a_idx, bool);
5139 /* Scan the artifacts */
5140 for (k = 0; k < max_a_idx; k++)
5142 artifact_type *a_ptr = &a_info[k];
5147 /* Skip "empty" artifacts */
5148 if (!a_ptr->name) continue;
5150 /* Skip "uncreated" artifacts */
5151 if (!a_ptr->cur_num) continue;
5157 /* Check the dungeon */
5158 for (y = 0; y < current_floor_ptr->height; y++)
5160 for (x = 0; x < current_floor_ptr->width; x++)
5162 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5164 OBJECT_IDX this_o_idx, next_o_idx = 0;
5166 /* Scan all objects in the grid */
5167 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5170 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5171 next_o_idx = o_ptr->next_o_idx;
5173 /* Ignore non-artifacts */
5174 if (!object_is_fixed_artifact(o_ptr)) continue;
5176 /* Ignore known items */
5177 if (object_is_known(o_ptr)) continue;
5179 /* Note the artifact */
5180 okay[o_ptr->name1] = FALSE;
5185 /* Check the inventory and equipment */
5186 for (i = 0; i < INVEN_TOTAL; i++)
5188 object_type *o_ptr = &inventory[i];
5190 /* Ignore non-objects */
5191 if (!o_ptr->k_idx) continue;
5193 /* Ignore non-artifacts */
5194 if (!object_is_fixed_artifact(o_ptr)) continue;
5196 /* Ignore known items */
5197 if (object_is_known(o_ptr)) continue;
5199 /* Note the artifact */
5200 okay[o_ptr->name1] = FALSE;
5203 for (k = 0; k < max_a_idx; k++)
5205 if (okay[k]) who[n++] = k;
5208 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5210 /* Scan the artifacts */
5211 for (k = 0; k < n; k++)
5213 artifact_type *a_ptr = &a_info[who[k]];
5214 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5216 /* Obtain the base object type */
5217 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5226 /* Create fake object */
5227 object_prep(q_ptr, z);
5229 /* Make it an artifact */
5230 q_ptr->name1 = (byte)who[k];
5232 /* Display as if known */
5233 q_ptr->ident |= IDENT_STORE;
5235 /* Describe the artifact */
5236 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5239 /* Hack -- Build the artifact name */
5240 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5243 /* Free the "who" array */
5244 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5246 /* Free the "okay" array */
5247 C_KILL(okay, max_a_idx, bool);
5250 /* Display the file contents */
5251 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5257 * Display known uniques
5258 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5260 static void do_cmd_knowledge_uniques(void)
5269 GAME_TEXT file_name[1024];
5272 int n_alive_surface = 0;
5273 int n_alive_over100 = 0;
5274 int n_alive_total = 0;
5277 for (i = 0; i < 10; i++) n_alive[i] = 0;
5279 /* Open a new file */
5280 fff = my_fopen_temp(file_name, 1024);
5284 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5289 /* Allocate the "who" array */
5290 C_MAKE(who, max_r_idx, MONRACE_IDX);
5292 /* Scan the monsters */
5293 for (i = 1; i < max_r_idx; i++)
5295 monster_race *r_ptr = &r_info[i];
5298 if (!r_ptr->name) continue;
5300 /* Require unique monsters */
5301 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5303 /* Only display "known" uniques */
5304 if (!cheat_know && !r_ptr->r_sights) continue;
5306 /* Only print rarity <= 100 uniques */
5307 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5309 /* Only "alive" uniques */
5310 if (r_ptr->max_num == 0) continue;
5314 lev = (r_ptr->level - 1) / 10;
5318 if (max_lev < lev) max_lev = lev;
5320 else n_alive_over100++;
5322 else n_alive_surface++;
5324 /* Collect "appropriate" monsters */
5328 /* Sort the array by dungeon depth of monsters */
5329 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5331 if (n_alive_surface)
5333 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5334 n_alive_total += n_alive_surface;
5336 for (i = 0; i <= max_lev; i++)
5338 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5339 n_alive_total += n_alive[i];
5341 if (n_alive_over100)
5343 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5344 n_alive_total += n_alive_over100;
5349 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5350 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5354 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5357 /* Scan the monster races */
5358 for (k = 0; k < n; k++)
5360 monster_race *r_ptr = &r_info[who[k]];
5362 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5365 /* Free the "who" array */
5366 C_KILL(who, max_r_idx, s16b);
5369 /* Display the file contents */
5370 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5376 * Display weapon-exp
5378 static void do_cmd_knowledge_weapon_exp(void)
5386 GAME_TEXT file_name[1024];
5389 /* Open a new file */
5390 fff = my_fopen_temp(file_name, 1024);
5392 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5397 for (i = 0; i < 5; i++)
5399 for (num = 0; num < 64; num++)
5401 for (j = 0; j < max_k_idx; j++)
5403 object_kind *k_ptr = &k_info[j];
5405 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5407 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5409 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5411 fprintf(fff, "%-25s ", tmp);
5412 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5413 else fprintf(fff, " ");
5414 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5415 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5424 /* Display the file contents */
5425 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5431 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5435 static void do_cmd_knowledge_spell_exp(void)
5442 const magic_type *s_ptr;
5444 GAME_TEXT file_name[1024];
5446 /* Open a new file */
5447 fff = my_fopen_temp(file_name, 1024);
5449 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5454 if (p_ptr->realm1 != REALM_NONE)
5456 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5457 for (i = 0; i < 32; i++)
5459 if (!is_magic(p_ptr->realm1))
5461 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5465 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5467 if (s_ptr->slevel >= 99) continue;
5468 spell_exp = p_ptr->spell_exp[i];
5469 exp_level = spell_exp_level(spell_exp);
5470 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5471 if (p_ptr->realm1 == REALM_HISSATSU)
5472 fprintf(fff, "[--]");
5475 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5476 else fprintf(fff, " ");
5477 fprintf(fff, "%s", exp_level_str[exp_level]);
5479 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5484 if (p_ptr->realm2 != REALM_NONE)
5486 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5487 for (i = 0; i < 32; i++)
5489 if (!is_magic(p_ptr->realm1))
5491 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5495 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5497 if (s_ptr->slevel >= 99) continue;
5499 spell_exp = p_ptr->spell_exp[i + 32];
5500 exp_level = spell_exp_level(spell_exp);
5501 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5502 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5503 else fprintf(fff, " ");
5504 fprintf(fff, "%s", exp_level_str[exp_level]);
5505 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5511 /* Display the file contents */
5512 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5518 * @brief スキル情報を表示するコマンドのメインルーチン /
5522 static void do_cmd_knowledge_skill_exp(void)
5524 int i = 0, skill_exp;
5528 char file_name[1024];
5529 char skill_name[GINOU_TEMPMAX][20] =
5531 _("マーシャルアーツ", "Martial Arts "),
5532 _("二刀流 ", "Dual Wielding "),
5533 _("乗馬 ", "Riding "),
5537 /* Open a new file */
5538 fff = my_fopen_temp(file_name, 1024);
5540 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5545 for (i = 0; i < GINOU_TEMPMAX; i++)
5547 skill_exp = p_ptr->skill_exp[i];
5548 fprintf(fff, "%-20s ", skill_name[i]);
5549 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5550 else fprintf(fff, " ");
5551 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5552 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5557 /* Display the file contents */
5558 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5564 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5565 * @param Name 変換したい文字列の参照ポインタ
5568 void plural_aux(char *Name)
5570 int NameLen = strlen(Name);
5572 if (my_strstr(Name, "Disembodied hand"))
5574 strcpy(Name, "Disembodied hands that strangled people");
5576 else if (my_strstr(Name, "Colour out of space"))
5578 strcpy(Name, "Colours out of space");
5580 else if (my_strstr(Name, "stairway to hell"))
5582 strcpy(Name, "stairways to hell");
5584 else if (my_strstr(Name, "Dweller on the threshold"))
5586 strcpy(Name, "Dwellers on the threshold");
5588 else if (my_strstr(Name, " of "))
5590 concptr aider = my_strstr(Name, " of ");
5601 if (dummy[i-1] == 's')
5603 strcpy(&(dummy[i]), "es");
5608 strcpy(&(dummy[i]), "s");
5611 strcpy(&(dummy[i+1]), aider);
5612 strcpy(Name, dummy);
5614 else if (my_strstr(Name, "coins"))
5617 strcpy(dummy, "piles of ");
5618 strcat(dummy, Name);
5619 strcpy(Name, dummy);
5622 else if (my_strstr(Name, "Manes"))
5626 else if (streq(&(Name[NameLen - 2]), "ey"))
5628 strcpy(&(Name[NameLen - 2]), "eys");
5630 else if (Name[NameLen - 1] == 'y')
5632 strcpy(&(Name[NameLen - 1]), "ies");
5634 else if (streq(&(Name[NameLen - 4]), "ouse"))
5636 strcpy(&(Name[NameLen - 4]), "ice");
5638 else if (streq(&(Name[NameLen - 2]), "us"))
5640 strcpy(&(Name[NameLen - 2]), "i");
5642 else if (streq(&(Name[NameLen - 6]), "kelman"))
5644 strcpy(&(Name[NameLen - 6]), "kelmen");
5646 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5648 strcpy(&(Name[NameLen - 8]), "wordsmen");
5650 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5652 strcpy(&(Name[NameLen - 7]), "oodsmen");
5654 else if (streq(&(Name[NameLen - 7]), "eastman"))
5656 strcpy(&(Name[NameLen - 7]), "eastmen");
5658 else if (streq(&(Name[NameLen - 8]), "izardman"))
5660 strcpy(&(Name[NameLen - 8]), "izardmen");
5662 else if (streq(&(Name[NameLen - 5]), "geist"))
5664 strcpy(&(Name[NameLen - 5]), "geister");
5666 else if (streq(&(Name[NameLen - 2]), "ex"))
5668 strcpy(&(Name[NameLen - 2]), "ices");
5670 else if (streq(&(Name[NameLen - 2]), "lf"))
5672 strcpy(&(Name[NameLen - 2]), "lves");
5674 else if (suffix(Name, "ch") ||
5675 suffix(Name, "sh") ||
5676 suffix(Name, "nx") ||
5677 suffix(Name, "s") ||
5680 strcpy(&(Name[NameLen]), "es");
5684 strcpy(&(Name[NameLen]), "s");
5689 * @brief 現在のペットを表示するコマンドのメインルーチン /
5690 * Display current pets
5693 static void do_cmd_knowledge_pets(void)
5697 monster_type *m_ptr;
5698 GAME_TEXT pet_name[MAX_NLEN];
5700 int show_upkeep = 0;
5701 GAME_TEXT file_name[1024];
5704 /* Open a new file */
5705 fff = my_fopen_temp(file_name, 1024);
5707 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5712 /* Process the monsters (backwards) */
5713 for (i = m_max - 1; i >= 1; i--)
5715 /* Access the monster */
5716 m_ptr = ¤t_floor_ptr->m_list[i];
5718 /* Ignore "dead" monsters */
5719 if (!monster_is_valid(m_ptr)) continue;
5721 /* Calculate "upkeep" for pets */
5725 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5726 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5730 show_upkeep = calculate_upkeep();
5732 fprintf(fff, "----------------------------------------------\n");
5734 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5736 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5738 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5743 /* Display the file contents */
5744 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5750 * @brief 現在のペットを表示するコマンドのメインルーチン /
5753 * @note the player ghosts are ignored.
5755 static void do_cmd_knowledge_kill_count(void)
5762 GAME_TEXT file_name[1024];
5767 /* Open a new file */
5768 fff = my_fopen_temp(file_name, 1024);
5771 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5776 /* Allocate the "who" array */
5777 C_MAKE(who, max_r_idx, MONRACE_IDX);
5780 /* Monsters slain */
5783 for (kk = 1; kk < max_r_idx; kk++)
5785 monster_race *r_ptr = &r_info[kk];
5787 if (r_ptr->flags1 & (RF1_UNIQUE))
5789 bool dead = (r_ptr->max_num == 0);
5798 MONSTER_NUMBER This = r_ptr->r_pkills;
5808 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5811 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5813 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5819 /* Scan the monsters */
5820 for (i = 1; i < max_r_idx; i++)
5822 monster_race *r_ptr = &r_info[i];
5824 /* Use that monster */
5825 if (r_ptr->name) who[n++] = i;
5828 /* Sort the array by dungeon depth of monsters */
5829 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5831 /* Scan the monster races */
5832 for (k = 0; k < n; k++)
5834 monster_race *r_ptr = &r_info[who[k]];
5836 if (r_ptr->flags1 & (RF1_UNIQUE))
5838 bool dead = (r_ptr->max_num == 0);
5842 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5848 MONSTER_NUMBER This = r_ptr->r_pkills;
5853 /* p,tは人と数える by ita */
5854 if (my_strchr("pt", r_ptr->d_char))
5855 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5857 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5861 if (my_strstr(r_name + r_ptr->name, "coins"))
5863 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5867 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5873 strcpy(ToPlural, (r_name + r_ptr->name));
5874 plural_aux(ToPlural);
5875 fprintf(fff, " %d %s\n", This, ToPlural);
5885 fprintf(fff,"----------------------------------------------\n");
5887 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5889 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5893 /* Free the "who" array */
5894 C_KILL(who, max_r_idx, s16b);
5897 /* Display the file contents */
5898 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5904 * @brief モンスター情報リスト中のグループを表示する /
5905 * Display the object groups.
5909 * @param per_page リストの表示行
5910 * @param grp_idx グループのID配列
5911 * @param group_text グループ名の文字列配列
5912 * @param grp_cur 現在の選択ID
5913 * @param grp_top 現在の選択リスト最上部ID
5916 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)
5920 /* Display lines until done */
5921 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5923 /* Get the group index */
5924 int grp = grp_idx[grp_top + i];
5926 /* Choose a color */
5927 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5929 /* Erase the entire line */
5930 Term_erase(col, row + i, wid);
5932 /* Display the group label */
5933 c_put_str(attr, group_text[grp], row + i, col);
5939 * Move the cursor in a browser window
5941 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5942 IDX *list_cur, int list_cnt)
5947 IDX list = *list_cur;
5949 /* Extract direction */
5952 /* Hack -- scroll up full screen */
5957 /* Hack -- scroll down full screen */
5962 d = get_keymap_dir(ch);
5967 /* Diagonals - hack */
5968 if ((ddx[d] > 0) && ddy[d])
5973 Term_get_size(&wid, &hgt);
5975 browser_rows = hgt - 8;
5977 /* Browse group list */
5982 /* Move up or down */
5983 grp += ddy[d] * (browser_rows - 1);
5986 if (grp >= grp_cnt) grp = grp_cnt - 1;
5987 if (grp < 0) grp = 0;
5988 if (grp != old_grp) list = 0;
5991 /* Browse sub-list list */
5994 /* Move up or down */
5995 list += ddy[d] * browser_rows;
5998 if (list >= list_cnt) list = list_cnt - 1;
5999 if (list < 0) list = 0;
6011 if (col < 0) col = 0;
6012 if (col > 1) col = 1;
6019 /* Browse group list */
6024 /* Move up or down */
6028 if (grp >= grp_cnt) grp = grp_cnt - 1;
6029 if (grp < 0) grp = 0;
6030 if (grp != old_grp) list = 0;
6033 /* Browse sub-list list */
6036 /* Move up or down */
6037 list += (IDX)ddy[d];
6040 if (list >= list_cnt) list = list_cnt - 1;
6041 if (list < 0) list = 0;
6052 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6056 /* Clear the display lines */
6057 for (i = 0; i < height; i++)
6059 Term_erase(col, row + i, width);
6062 /* Bigtile mode uses double width */
6063 if (use_bigtile) width /= 2;
6065 /* Display lines until done */
6066 for (i = 0; i < height; i++)
6068 /* Display columns until done */
6069 for (j = 0; j < width; j++)
6073 TERM_LEN x = col + j;
6074 TERM_LEN y = row + i;
6076 /* Bigtile mode uses double width */
6077 if (use_bigtile) x += j;
6082 /* Ignore illegal characters */
6083 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6084 (!use_graphics && ic > 0x7f))
6090 /* Force correct code for both ASCII character and tile */
6091 if (c & 0x80) a |= 0x80;
6093 /* Display symbol */
6094 Term_queue_bigchar(x, y, a, c, 0, 0);
6101 * Place the cursor at the collect position for visual mode
6103 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6105 int i = (a & 0x7f) - attr_top;
6106 int j = c - char_left;
6108 TERM_LEN x = col + j;
6109 TERM_LEN y = row + i;
6111 /* Bigtile mode uses double width */
6112 if (use_bigtile) x += j;
6114 /* Place the cursor */
6120 * Clipboard variables for copy&paste in visual mode
6122 static TERM_COLOR attr_idx = 0;
6123 static SYMBOL_CODE char_idx = 0;
6125 /* Hack -- for feature lighting */
6126 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6127 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6130 * Do visual mode command -- Change symbols
6132 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6133 int height, int width,
6134 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6135 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6137 static TERM_COLOR attr_old = 0;
6138 static SYMBOL_CODE char_old = 0;
6143 if (*visual_list_ptr)
6146 *cur_attr_ptr = attr_old;
6147 *cur_char_ptr = char_old;
6148 *visual_list_ptr = FALSE;
6156 if (*visual_list_ptr)
6159 *visual_list_ptr = FALSE;
6160 *need_redraw = TRUE;
6168 if (!*visual_list_ptr)
6170 *visual_list_ptr = TRUE;
6172 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6173 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6175 attr_old = *cur_attr_ptr;
6176 char_old = *cur_char_ptr;
6187 /* Set the visual */
6188 attr_idx = *cur_attr_ptr;
6189 char_idx = *cur_char_ptr;
6191 /* Hack -- for feature lighting */
6192 for (i = 0; i < F_LIT_MAX; i++)
6194 attr_idx_feat[i] = 0;
6195 char_idx_feat[i] = 0;
6202 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6205 *cur_attr_ptr = attr_idx;
6206 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6207 if (!*visual_list_ptr) *need_redraw = TRUE;
6213 *cur_char_ptr = char_idx;
6214 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6215 if (!*visual_list_ptr) *need_redraw = TRUE;
6221 if (*visual_list_ptr)
6224 int d = get_keymap_dir(ch);
6225 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6226 SYMBOL_CODE c = *cur_char_ptr;
6228 if (use_bigtile) eff_width = width / 2;
6229 else eff_width = width;
6231 /* Restrict direction */
6232 if ((a == 0) && (ddy[d] < 0)) d = 0;
6233 if ((c == 0) && (ddx[d] < 0)) d = 0;
6234 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6235 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6237 a += (TERM_COLOR)ddy[d];
6238 c += (SYMBOL_CODE)ddx[d];
6240 /* Force correct code for both ASCII character and tile */
6241 if (c & 0x80) a |= 0x80;
6243 /* Set the visual */
6248 /* Move the frame */
6249 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6250 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6251 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6252 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6258 /* Visual mode command is not used */
6264 * Display the monsters in a group.
6266 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6267 int mon_cur, int mon_top, bool visual_only)
6271 /* Display lines until done */
6272 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6276 /* Get the race index */
6277 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6279 /* Access the race */
6280 monster_race *r_ptr = &r_info[r_idx];
6282 /* Choose a color */
6283 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6285 /* Display the name */
6286 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6288 /* Hack -- visual_list mode */
6291 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6293 if (p_ptr->wizard || visual_only)
6295 c_prt(attr, format("%d", r_idx), row + i, 62);
6298 /* Erase chars before overwritten by the race letter */
6299 Term_erase(69, row + i, 255);
6301 /* Display symbol */
6302 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6307 if (!(r_ptr->flags1 & RF1_UNIQUE))
6308 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6310 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6311 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6315 /* Clear remaining lines */
6316 for (; i < per_page; i++)
6318 Term_erase(col, row + i, 255);
6324 * Display known monsters.
6326 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6330 IDX grp_cur, grp_top, old_grp_cur;
6331 IDX mon_cur, mon_top;
6332 IDX grp_cnt, grp_idx[100];
6340 bool visual_list = FALSE;
6341 TERM_COLOR attr_top = 0;
6349 Term_get_size(&wid, &hgt);
6351 browser_rows = hgt - 8;
6353 /* Allocate the "mon_idx" array */
6354 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6359 if (direct_r_idx < 0)
6361 mode = visual_only ? 0x03 : 0x01;
6363 /* Check every group */
6364 for (i = 0; monster_group_text[i] != NULL; i++)
6366 /* Measure the label */
6367 len = strlen(monster_group_text[i]);
6369 /* Save the maximum length */
6370 if (len > max) max = len;
6372 /* See if any monsters are known */
6373 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6375 /* Build a list of groups with known monsters */
6376 grp_idx[grp_cnt++] = i;
6384 mon_idx[0] = direct_r_idx;
6387 /* Terminate the list */
6390 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6391 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6394 /* Terminate the list */
6395 grp_idx[grp_cnt] = -1;
6398 grp_cur = grp_top = 0;
6399 mon_cur = mon_top = 0;
6404 mode = visual_only ? 0x02 : 0x00;
6409 monster_race *r_ptr;
6414 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6415 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6416 prt(_("名前", "Name"), 4, max + 3);
6417 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6418 prt(_("文字", "Sym"), 4, 67);
6419 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6421 for (i = 0; i < 78; i++)
6423 Term_putch(i, 5, TERM_WHITE, '=');
6426 if (direct_r_idx < 0)
6428 for (i = 0; i < browser_rows; i++)
6430 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6437 if (direct_r_idx < 0)
6439 /* Scroll group list */
6440 if (grp_cur < grp_top) grp_top = grp_cur;
6441 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6443 /* Display a list of monster groups */
6444 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6446 if (old_grp_cur != grp_cur)
6448 old_grp_cur = grp_cur;
6450 /* Get a list of monsters in the current group */
6451 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6454 /* Scroll monster list */
6455 while (mon_cur < mon_top)
6456 mon_top = MAX(0, mon_top - browser_rows/2);
6457 while (mon_cur >= mon_top + browser_rows)
6458 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6463 /* Display a list of monsters in the current group */
6464 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6470 /* Display a monster name */
6471 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6473 /* Display visual list below first monster */
6474 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6478 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6479 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6480 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6481 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6484 /* Get the current monster */
6485 r_ptr = &r_info[mon_idx[mon_cur]];
6489 /* Mega Hack -- track this monster race */
6490 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6496 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6500 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6504 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6509 /* Do visual mode command if needed */
6510 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))
6512 if (direct_r_idx >= 0)
6537 /* Recall on screen */
6538 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6540 screen_roff(mon_idx[mon_cur], 0);
6551 /* Move the cursor */
6552 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6559 /* Free the "mon_idx" array */
6560 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6565 * Display the objects in a group.
6567 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6568 int object_cur, int object_top, bool visual_only)
6572 /* Display lines until done */
6573 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6575 GAME_TEXT o_name[MAX_NLEN];
6578 object_kind *flavor_k_ptr;
6580 /* Get the object index */
6581 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6583 /* Access the object */
6584 object_kind *k_ptr = &k_info[k_idx];
6586 /* Choose a color */
6587 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6588 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6591 if (!visual_only && k_ptr->flavor)
6593 /* Appearance of this object is shuffled */
6594 flavor_k_ptr = &k_info[k_ptr->flavor];
6598 /* Appearance of this object is very normal */
6599 flavor_k_ptr = k_ptr;
6604 attr = ((i + object_top == object_cur) ? cursor : attr);
6606 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6609 strip_name(o_name, k_idx);
6614 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6617 /* Display the name */
6618 c_prt(attr, o_name, row + i, col);
6620 /* Hack -- visual_list mode */
6623 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);
6625 if (p_ptr->wizard || visual_only)
6627 c_prt(attr, format("%d", k_idx), row + i, 70);
6630 a = flavor_k_ptr->x_attr;
6631 c = flavor_k_ptr->x_char;
6633 /* Display symbol */
6634 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6637 /* Clear remaining lines */
6638 for (; i < per_page; i++)
6640 Term_erase(col, row + i, 255);
6645 * Describe fake object
6647 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6650 object_type object_type_body;
6651 o_ptr = &object_type_body;
6653 object_prep(o_ptr, k_idx);
6655 /* It's fully know */
6656 o_ptr->ident |= IDENT_KNOWN;
6658 /* Track the object */
6659 /* object_actual_track(o_ptr); */
6661 /* Hack - mark as fake */
6662 /* term_obj_real = FALSE; */
6665 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6667 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6675 * Display known objects
6677 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6681 IDX grp_cur, grp_top, old_grp_cur;
6682 IDX object_old, object_cur, object_top;
6686 OBJECT_IDX *object_idx;
6692 bool visual_list = FALSE;
6693 TERM_COLOR attr_top = 0;
6701 Term_get_size(&wid, &hgt);
6703 browser_rows = hgt - 8;
6705 /* Allocate the "object_idx" array */
6706 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6711 if (direct_k_idx < 0)
6713 mode = visual_only ? 0x03 : 0x01;
6715 /* Check every group */
6716 for (i = 0; object_group_text[i] != NULL; i++)
6718 /* Measure the label */
6719 len = strlen(object_group_text[i]);
6721 /* Save the maximum length */
6722 if (len > max) max = len;
6724 /* See if any monsters are known */
6725 if (collect_objects(i, object_idx, mode))
6727 /* Build a list of groups with known monsters */
6728 grp_idx[grp_cnt++] = i;
6737 object_kind *k_ptr = &k_info[direct_k_idx];
6738 object_kind *flavor_k_ptr;
6740 if (!visual_only && k_ptr->flavor)
6742 /* Appearance of this object is shuffled */
6743 flavor_k_ptr = &k_info[k_ptr->flavor];
6747 /* Appearance of this object is very normal */
6748 flavor_k_ptr = k_ptr;
6751 object_idx[0] = direct_k_idx;
6752 object_old = direct_k_idx;
6755 /* Terminate the list */
6758 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6759 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6762 /* Terminate the list */
6763 grp_idx[grp_cnt] = -1;
6766 grp_cur = grp_top = 0;
6767 object_cur = object_top = 0;
6772 mode = visual_only ? 0x02 : 0x00;
6777 object_kind *k_ptr, *flavor_k_ptr;
6784 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6785 if (direct_k_idx < 0) prt("グループ", 4, 0);
6786 prt("名前", 4, max + 3);
6787 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6790 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6791 if (direct_k_idx < 0) prt("Group", 4, 0);
6792 prt("Name", 4, max + 3);
6793 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6797 for (i = 0; i < 78; i++)
6799 Term_putch(i, 5, TERM_WHITE, '=');
6802 if (direct_k_idx < 0)
6804 for (i = 0; i < browser_rows; i++)
6806 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6813 if (direct_k_idx < 0)
6815 /* Scroll group list */
6816 if (grp_cur < grp_top) grp_top = grp_cur;
6817 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6819 /* Display a list of object groups */
6820 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6822 if (old_grp_cur != grp_cur)
6824 old_grp_cur = grp_cur;
6826 /* Get a list of objects in the current group */
6827 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6830 /* Scroll object list */
6831 while (object_cur < object_top)
6832 object_top = MAX(0, object_top - browser_rows/2);
6833 while (object_cur >= object_top + browser_rows)
6834 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6839 /* Display a list of objects in the current group */
6840 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6844 object_top = object_cur;
6846 /* Display a list of objects in the current group */
6847 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6849 /* Display visual list below first object */
6850 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6853 /* Get the current object */
6854 k_ptr = &k_info[object_idx[object_cur]];
6856 if (!visual_only && k_ptr->flavor)
6858 /* Appearance of this object is shuffled */
6859 flavor_k_ptr = &k_info[k_ptr->flavor];
6863 /* Appearance of this object is very normal */
6864 flavor_k_ptr = k_ptr;
6869 prt(format("<方向>%s%s%s, ESC",
6870 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6871 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6872 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6875 prt(format("<dir>%s%s%s, ESC",
6876 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6877 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6878 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6884 /* Mega Hack -- track this object */
6885 if (object_cnt) object_kind_track(object_idx[object_cur]);
6887 /* The "current" object changed */
6888 if (object_old != object_idx[object_cur])
6892 /* Remember the "current" object */
6893 object_old = object_idx[object_cur];
6899 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6903 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6907 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6912 /* Do visual mode command if needed */
6913 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))
6915 if (direct_k_idx >= 0)
6940 /* Recall on screen */
6941 if (!visual_list && !visual_only && (grp_cnt > 0))
6943 desc_obj_fake(object_idx[object_cur]);
6951 /* Move the cursor */
6952 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6958 /* Free the "object_idx" array */
6959 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6964 * Display the features in a group.
6966 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6967 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6969 int lit_col[F_LIT_MAX], i, j;
6970 int f_idx_col = use_bigtile ? 62 : 64;
6972 /* Correct columns 1 and 4 */
6973 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6974 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6975 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6977 /* Display lines until done */
6978 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6981 FEAT_IDX f_idx = feat_idx[feat_top + i];
6982 feature_type *f_ptr = &f_info[f_idx];
6983 int row_i = row + i;
6985 /* Choose a color */
6986 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
6988 /* Display the name */
6989 c_prt(attr, f_name + f_ptr->name, row_i, col);
6991 /* Hack -- visual_list mode */
6994 /* Display lighting level */
6995 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
6997 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));
6999 if (p_ptr->wizard || visual_only)
7001 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7004 /* Display symbol */
7005 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);
7007 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7008 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7010 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7012 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7014 /* Mega-hack -- Use non-standard colour */
7015 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7017 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7021 /* Clear remaining lines */
7022 for (; i < per_page; i++)
7024 Term_erase(col, row + i, 255);
7030 * Interact with feature visuals.
7032 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7036 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7037 FEAT_IDX feat_cur, feat_top;
7039 FEAT_IDX grp_idx[100];
7043 TERM_LEN column = 0;
7047 bool visual_list = FALSE;
7048 TERM_COLOR attr_top = 0;
7051 TERM_LEN browser_rows;
7054 TERM_COLOR attr_old[F_LIT_MAX];
7055 SYMBOL_CODE char_old[F_LIT_MAX];
7056 TERM_COLOR *cur_attr_ptr;
7057 SYMBOL_CODE *cur_char_ptr;
7059 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7060 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7062 Term_get_size(&wid, &hgt);
7064 browser_rows = hgt - 8;
7066 /* Allocate the "feat_idx" array */
7067 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7072 if (direct_f_idx < 0)
7074 /* Check every group */
7075 for (i = 0; feature_group_text[i] != NULL; i++)
7077 /* Measure the label */
7078 len = strlen(feature_group_text[i]);
7080 /* Save the maximum length */
7081 if (len > max) max = len;
7083 /* See if any features are known */
7084 if (collect_features(i, feat_idx, 0x01))
7086 /* Build a list of groups with known features */
7087 grp_idx[grp_cnt++] = i;
7095 feature_type *f_ptr = &f_info[direct_f_idx];
7097 feat_idx[0] = direct_f_idx;
7100 /* Terminate the list */
7103 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7104 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7106 for (i = 0; i < F_LIT_MAX; i++)
7108 attr_old[i] = f_ptr->x_attr[i];
7109 char_old[i] = f_ptr->x_char[i];
7113 /* Terminate the list */
7114 grp_idx[grp_cnt] = -1;
7117 grp_cur = grp_top = 0;
7118 feat_cur = feat_top = 0;
7126 feature_type *f_ptr;
7132 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7133 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7134 prt(_("名前", "Name"), 4, max + 3);
7137 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7138 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7142 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7143 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7146 for (i = 0; i < 78; i++)
7148 Term_putch(i, 5, TERM_WHITE, '=');
7151 if (direct_f_idx < 0)
7153 for (i = 0; i < browser_rows; i++)
7155 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7162 if (direct_f_idx < 0)
7164 /* Scroll group list */
7165 if (grp_cur < grp_top) grp_top = grp_cur;
7166 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7168 /* Display a list of feature groups */
7169 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7171 if (old_grp_cur != grp_cur)
7173 old_grp_cur = grp_cur;
7175 /* Get a list of features in the current group */
7176 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7179 /* Scroll feature list */
7180 while (feat_cur < feat_top)
7181 feat_top = MAX(0, feat_top - browser_rows/2);
7182 while (feat_cur >= feat_top + browser_rows)
7183 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7188 /* Display a list of features in the current group */
7189 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7193 feat_top = feat_cur;
7195 /* Display a list of features in the current group */
7196 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7198 /* Display visual list below first object */
7199 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7203 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7204 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7205 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7208 /* Get the current feature */
7209 f_ptr = &f_info[feat_idx[feat_cur]];
7210 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7211 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7215 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7219 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7223 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7228 if (visual_list && ((ch == 'A') || (ch == 'a')))
7230 int prev_lighting_level = *lighting_level;
7234 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7235 else (*lighting_level)--;
7239 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7240 else (*lighting_level)++;
7243 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7244 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7246 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7247 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7252 else if ((ch == 'D') || (ch == 'd'))
7254 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7255 byte prev_x_char = f_ptr->x_char[*lighting_level];
7257 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7261 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7262 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7264 if (prev_x_char != f_ptr->x_char[*lighting_level])
7265 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7267 else *need_redraw = TRUE;
7272 /* Do visual mode command if needed */
7273 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))
7277 /* Restore previous visual settings */
7279 for (i = 0; i < F_LIT_MAX; i++)
7281 f_ptr->x_attr[i] = attr_old[i];
7282 f_ptr->x_char[i] = char_old[i];
7289 if (direct_f_idx >= 0) flag = TRUE;
7290 else *lighting_level = F_LIT_STANDARD;
7293 /* Preserve current visual settings */
7296 for (i = 0; i < F_LIT_MAX; i++)
7298 attr_old[i] = f_ptr->x_attr[i];
7299 char_old[i] = f_ptr->x_char[i];
7301 *lighting_level = F_LIT_STANDARD;
7308 for (i = 0; i < F_LIT_MAX; i++)
7310 attr_idx_feat[i] = f_ptr->x_attr[i];
7311 char_idx_feat[i] = f_ptr->x_char[i];
7320 /* Allow TERM_DARK text */
7321 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7323 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7324 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7342 /* Move the cursor */
7343 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7349 /* Free the "feat_idx" array */
7350 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7355 * List wanted monsters
7357 static void do_cmd_knowledge_kubi(void)
7362 GAME_TEXT file_name[1024];
7365 /* Open a new file */
7366 fff = my_fopen_temp(file_name, 1024);
7368 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7375 bool listed = FALSE;
7377 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7378 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7380 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7381 fprintf(fff, "----------------------------------------------\n");
7383 for (i = 0; i < MAX_KUBI; i++)
7385 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7387 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7395 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7400 /* Display the file contents */
7401 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7406 * List virtues & status
7408 static void do_cmd_knowledge_virtues(void)
7411 GAME_TEXT file_name[1024];
7413 /* Open a new file */
7414 fff = my_fopen_temp(file_name, 1024);
7416 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7423 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7428 /* Display the file contents */
7429 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7436 static void do_cmd_knowledge_dungeon(void)
7440 GAME_TEXT file_name[1024];
7443 /* Open a new file */
7444 fff = my_fopen_temp(file_name, 1024);
7446 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7453 for (i = 1; i < max_d_idx; i++)
7457 if (!d_info[i].maxdepth) continue;
7458 if (!max_dlv[i]) continue;
7459 if (d_info[i].final_guardian)
7461 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7463 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7465 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7470 /* Display the file contents */
7471 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7476 * List virtues & status
7479 static void do_cmd_knowledge_stat(void)
7483 GAME_TEXT file_name[1024];
7486 /* Open a new file */
7487 fff = my_fopen_temp(file_name, 1024);
7489 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7496 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7497 (2 * p_ptr->hitdie +
7498 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7500 if (p_ptr->knowledge & KNOW_HPRATE)
7501 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7502 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7504 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7505 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7507 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);
7508 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7515 /* Display the file contents */
7516 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7522 * Print all active quests
7524 static void do_cmd_knowledge_quests_current(FILE *fff)
7527 char rand_tmp_str[120] = "\0";
7528 GAME_TEXT name[MAX_NLEN];
7529 monster_race *r_ptr;
7531 int rand_level = 100;
7534 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7536 for (i = 1; i < max_q_idx; i++)
7538 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7539 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7540 (quest[i].status == QUEST_STATUS_COMPLETED))
7542 /* Set the quest number temporary */
7543 QUEST_IDX old_quest = p_ptr->inside_quest;
7546 /* Clear the text */
7547 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7548 quest_text_line = 0;
7550 p_ptr->inside_quest = i;
7552 /* Get the quest text */
7553 init_flags = INIT_SHOW_TEXT;
7555 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7557 /* Reset the old quest number */
7558 p_ptr->inside_quest = old_quest;
7560 /* No info from "silent" quests */
7561 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7565 if (quest[i].type != QUEST_TYPE_RANDOM)
7567 char note[80] = "\0";
7569 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7571 switch (quest[i].type)
7573 case QUEST_TYPE_KILL_LEVEL:
7574 case QUEST_TYPE_KILL_ANY_LEVEL:
7575 r_ptr = &r_info[quest[i].r_idx];
7576 strcpy(name, r_name + r_ptr->name);
7577 if (quest[i].max_num > 1)
7580 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7581 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7584 sprintf(note," - kill %d %s, have killed %d.",
7585 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7589 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7592 case QUEST_TYPE_FIND_ARTIFACT:
7595 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7597 object_type *q_ptr = &forge;
7598 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7599 object_prep(q_ptr, k_idx);
7600 q_ptr->name1 = quest[i].k_idx;
7601 q_ptr->ident = IDENT_STORE;
7602 object_desc(name, q_ptr, OD_NAME_ONLY);
7604 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7606 case QUEST_TYPE_FIND_EXIT:
7607 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7610 case QUEST_TYPE_KILL_NUMBER:
7612 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7613 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7615 sprintf(note," - Kill %d monsters, have killed %d.",
7616 (int)quest[i].max_num, (int)quest[i].cur_num);
7620 case QUEST_TYPE_KILL_ALL:
7621 case QUEST_TYPE_TOWER:
7622 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7627 /* Print the quest info */
7628 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7629 quest[i].name, (int)quest[i].level, note);
7631 fputs(tmp_str, fff);
7633 if (quest[i].status == QUEST_STATUS_COMPLETED)
7635 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7636 fputs(tmp_str, fff);
7642 while (quest_text[j][0] && j < 10)
7644 fprintf(fff, " %s\n", quest_text[j]);
7649 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7652 rand_level = quest[i].level;
7654 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7656 /* Print the quest info */
7657 r_ptr = &r_info[quest[i].r_idx];
7658 strcpy(name, r_name + r_ptr->name);
7660 if (quest[i].max_num > 1)
7663 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7664 quest[i].name, (int)quest[i].level,
7665 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7669 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7670 quest[i].name, (int)quest[i].level,
7671 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7676 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7677 quest[i].name, (int)quest[i].level, name);
7684 /* Print the current random quest */
7685 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7687 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7691 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7694 char playtime_str[16];
7695 quest_type* const q_ptr = &quest[q_idx];
7697 if (is_fixed_quest_idx(q_idx))
7699 /* Set the quest number temporary */
7700 IDX old_quest = p_ptr->inside_quest;
7702 p_ptr->inside_quest = q_idx;
7705 init_flags = INIT_NAME_ONLY;
7707 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7709 /* Reset the old quest number */
7710 p_ptr->inside_quest = old_quest;
7712 /* No info from "silent" quests */
7713 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7716 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7717 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7719 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7721 /* Print the quest info */
7722 if (q_ptr->complev == 0)
7725 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7726 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7727 r_name+r_info[q_ptr->r_idx].name,
7728 (int)q_ptr->level, playtime_str);
7733 _(" %-35s (%3d階) - レベル%2d - %s\n",
7734 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7735 r_name+r_info[q_ptr->r_idx].name,
7743 /* Print the quest info */
7745 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7746 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7747 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7750 fputs(tmp_str, fff);
7756 * Print all finished quests
7758 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7761 QUEST_IDX total = 0;
7763 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7764 for (i = 1; i < max_q_idx; i++)
7766 QUEST_IDX q_idx = quest_num[i];
7767 quest_type* const q_ptr = &quest[q_idx];
7769 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7774 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7779 * Print all failed quests
7781 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7784 QUEST_IDX total = 0;
7786 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7787 for (i = 1; i < max_q_idx; i++)
7789 QUEST_IDX q_idx = quest_num[i];
7790 quest_type* const q_ptr = &quest[q_idx];
7792 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7793 do_cmd_knowledge_quests_aux(fff, q_idx))
7798 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7803 * Print all random quests
7805 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7807 GAME_TEXT tmp_str[120];
7809 QUEST_IDX total = 0;
7811 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7812 for (i = 1; i < max_q_idx; i++)
7814 /* No info from "silent" quests */
7815 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7817 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7821 /* Print the quest info */
7822 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7823 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7824 fputs(tmp_str, fff);
7827 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7831 * Print quest status of all active quests
7833 static void do_cmd_knowledge_quests(void)
7836 GAME_TEXT file_name[1024];
7841 /* Open a new file */
7842 fff = my_fopen_temp(file_name, 1024);
7845 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7850 /* Allocate Memory */
7851 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7853 /* Sort by compete level */
7854 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7855 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7857 /* Dump Quest Information */
7858 do_cmd_knowledge_quests_current(fff);
7860 do_cmd_knowledge_quests_completed(fff, quest_num);
7862 do_cmd_knowledge_quests_failed(fff, quest_num);
7866 do_cmd_knowledge_quests_wiz_random(fff);
7870 /* Display the file contents */
7871 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7875 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7882 static void do_cmd_knowledge_home(void)
7887 GAME_TEXT file_name[1024];
7889 GAME_TEXT o_name[MAX_NLEN];
7890 concptr paren = ")";
7892 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7894 /* Open a new file */
7895 fff = my_fopen_temp(file_name, 1024);
7897 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7904 /* Print all homes in the different towns */
7905 st_ptr = &town_info[1].store[STORE_HOME];
7907 /* Home -- if anything there */
7908 if (st_ptr->stock_num)
7913 /* Header with name of the town */
7914 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7916 /* Dump all available items */
7917 for (i = 0; i < st_ptr->stock_num; i++)
7920 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7921 object_desc(o_name, &st_ptr->stock[i], 0);
7922 if (strlen(o_name) <= 80-3)
7924 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7930 for (n = 0, t = o_name; n < 80-3; n++, t++)
7931 if(iskanji(*t)) {t++; n++;}
7932 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7934 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7935 fprintf(fff, " %.77s\n", o_name+n);
7938 object_desc(o_name, &st_ptr->stock[i], 0);
7939 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7944 /* Add an empty line */
7945 fprintf(fff, "\n\n");
7950 /* Display the file contents */
7951 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7957 * Check the status of "autopick"
7959 static void do_cmd_knowledge_autopick(void)
7963 GAME_TEXT file_name[1024];
7965 /* Open a new file */
7966 fff = my_fopen_temp(file_name, 1024);
7970 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7977 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7981 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7982 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7985 for (k = 0; k < max_autopick; k++)
7988 byte act = autopick_list[k].action;
7989 if (act & DONT_AUTOPICK)
7991 tmp = _("放置", "Leave");
7993 else if (act & DO_AUTODESTROY)
7995 tmp = _("破壊", "Destroy");
7997 else if (act & DO_AUTOPICK)
7999 tmp = _("拾う", "Pickup");
8003 tmp = _("確認", "Query");
8006 if (act & DO_DISPLAY)
8007 fprintf(fff, "%11s", format("[%s]", tmp));
8009 fprintf(fff, "%11s", format("(%s)", tmp));
8011 tmp = autopick_line_from_entry(&autopick_list[k]);
8012 fprintf(fff, " %s", tmp);
8017 /* Display the file contents */
8018 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8024 * Interact with "knowledge"
8026 void do_cmd_knowledge(void)
8029 bool need_redraw = FALSE;
8031 /* File type is "TEXT" */
8032 FILE_TYPE(FILE_TYPE_TEXT);
8035 /* Interact until done */
8040 /* Ask for a choice */
8041 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8042 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8044 /* Give some choices */
8048 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8049 prt("(2) 既知のアイテム の一覧", 7, 5);
8050 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8051 prt("(4) 既知のモンスター の一覧", 9, 5);
8052 prt("(5) 倒した敵の数 の一覧", 10, 5);
8053 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8054 prt("(7) 現在のペット の一覧", 12, 5);
8055 prt("(8) 我が家のアイテム の一覧", 13, 5);
8056 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8057 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8061 prt("(a) 自分に関する情報 の一覧", 6, 5);
8062 prt("(b) 突然変異 の一覧", 7, 5);
8063 prt("(c) 武器の経験値 の一覧", 8, 5);
8064 prt("(d) 魔法の経験値 の一覧", 9, 5);
8065 prt("(e) 技能の経験値 の一覧", 10, 5);
8066 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8067 prt("(g) 入ったダンジョン の一覧", 12, 5);
8068 prt("(h) 実行中のクエスト の一覧", 13, 5);
8069 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8074 prt("(1) Display known artifacts", 6, 5);
8075 prt("(2) Display known objects", 7, 5);
8076 prt("(3) Display remaining uniques", 8, 5);
8077 prt("(4) Display known monster", 9, 5);
8078 prt("(5) Display kill count", 10, 5);
8079 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8080 prt("(7) Display current pets", 12, 5);
8081 prt("(8) Display home inventory", 13, 5);
8082 prt("(9) Display *identified* equip.", 14, 5);
8083 prt("(0) Display terrain symbols.", 15, 5);
8087 prt("(a) Display about yourself", 6, 5);
8088 prt("(b) Display mutations", 7, 5);
8089 prt("(c) Display weapon proficiency", 8, 5);
8090 prt("(d) Display spell proficiency", 9, 5);
8091 prt("(e) Display misc. proficiency", 10, 5);
8092 prt("(f) Display virtues", 11, 5);
8093 prt("(g) Display dungeons", 12, 5);
8094 prt("(h) Display current quests", 13, 5);
8095 prt("(i) Display auto pick/destroy", 14, 5);
8099 prt(_("-続く-", "-more-"), 17, 8);
8100 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8101 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8102 /*prt("-) 前ページ", 21, 60);*/
8103 prt(_("コマンド:", "Command: "), 20, 0);
8106 if (i == ESCAPE) break;
8109 case ' ': /* Page change */
8113 case '1': /* Artifacts */
8114 do_cmd_knowledge_artifacts();
8116 case '2': /* Objects */
8117 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8119 case '3': /* Uniques */
8120 do_cmd_knowledge_uniques();
8122 case '4': /* Monsters */
8123 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8125 case '5': /* Kill count */
8126 do_cmd_knowledge_kill_count();
8128 case '6': /* wanted */
8129 if (!vanilla_town) do_cmd_knowledge_kubi();
8131 case '7': /* Pets */
8132 do_cmd_knowledge_pets();
8134 case '8': /* Home */
8135 do_cmd_knowledge_home();
8137 case '9': /* Resist list */
8138 do_cmd_knowledge_inven();
8140 case '0': /* Feature list */
8142 IDX lighting_level = F_LIT_STANDARD;
8143 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8147 case 'a': /* Max stat */
8148 do_cmd_knowledge_stat();
8150 case 'b': /* Mutations */
8151 do_cmd_knowledge_mutations();
8153 case 'c': /* weapon-exp */
8154 do_cmd_knowledge_weapon_exp();
8156 case 'd': /* spell-exp */
8157 do_cmd_knowledge_spell_exp();
8159 case 'e': /* skill-exp */
8160 do_cmd_knowledge_skill_exp();
8162 case 'f': /* Virtues */
8163 do_cmd_knowledge_virtues();
8165 case 'g': /* Dungeon */
8166 do_cmd_knowledge_dungeon();
8168 case 'h': /* Quests */
8169 do_cmd_knowledge_quests();
8171 case 'i': /* Autopick */
8172 do_cmd_knowledge_autopick();
8174 default: /* Unknown option */
8182 if (need_redraw) do_cmd_redraw();
8187 * Check on the status of an active quest
8189 void do_cmd_checkquest(void)
8191 /* File type is "TEXT" */
8192 FILE_TYPE(FILE_TYPE_TEXT);
8196 do_cmd_knowledge_quests();
8202 * Display the time and date
8204 void do_cmd_time(void)
8206 int day, hour, min, full, start, end, num;
8214 extract_day_hour_min(&day, &hour, &min);
8216 full = hour * 100 + min;
8223 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8225 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8226 else strcpy(day_buf, "*****");
8228 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8229 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8232 if (!randint0(10) || p_ptr->image)
8234 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8238 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8241 /* Open this file */
8242 fff = my_fopen(buf, "rt");
8246 /* Find this time */
8247 while (!my_fgets(fff, buf, sizeof(buf)))
8249 /* Ignore comments */
8250 if (!buf[0] || (buf[0] == '#')) continue;
8252 /* Ignore invalid lines */
8253 if (buf[1] != ':') continue;
8255 /* Process 'Start' */
8258 /* Extract the starting time */
8259 start = atoi(buf + 2);
8261 /* Assume valid for an hour */
8271 /* Extract the ending time */
8272 end = atoi(buf + 2);
8278 /* Ignore incorrect range */
8279 if ((start > full) || (full > end)) continue;
8281 /* Process 'Description' */
8286 /* Apply the randomizer */
8287 if (!randint0(num)) strcpy(desc, buf + 2);