3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
47 #include "cmd-spell.h"
50 #include "player-effects.h"
51 #include "player-status.h"
52 #include "player-skill.h"
59 #include "object-flavor.h"
60 #include "object-hook.h"
62 #include "monster-status.h"
64 #include "view-mainwindow.h"
65 #include "dungeon-file.h"
72 * Mark strings for auto dump
74 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
75 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
78 * Variables for auto dump
80 static FILE *auto_dump_stream;
81 static concptr auto_dump_mark;
82 static int auto_dump_line_num;
86 * @brief prf出力内容を消去する /
87 * Remove old lines automatically generated before.
88 * @param orig_file 消去を行うファイル名
90 static void remove_auto_dump(concptr orig_file)
92 FILE *tmp_fff, *orig_fff;
96 bool between_mark = FALSE;
99 long header_location = 0;
100 char header_mark_str[80];
101 char footer_mark_str[80];
104 /* Prepare a header/footer mark string */
105 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
106 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
108 mark_len = strlen(footer_mark_str);
110 /* Open an old dump file in read-only mode */
111 orig_fff = my_fopen(orig_file, "r");
113 /* If original file does not exist, nothing to do */
114 if (!orig_fff) return;
116 /* Open a new (temporary) file */
117 tmp_fff = my_fopen_temp(tmp_file, 1024);
121 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
126 /* Loop for every line */
130 if (my_fgets(orig_fff, buf, sizeof(buf)))
132 /* Read error: Assume End of File */
135 * Was looking for the footer, but not found.
137 * Since automatic dump might be edited by hand,
138 * it's dangerous to kill these lines.
139 * Seek back to the next line of the (pseudo) header,
144 fseek(orig_fff, header_location, SEEK_SET);
145 between_mark = FALSE;
149 /* Success -- End the loop */
156 /* We are looking for the header mark of automatic dump */
159 /* Is this line a header? */
160 if (!strcmp(buf, header_mark_str))
162 /* Memorise seek point of this line */
163 header_location = ftell(orig_fff);
165 /* Initialize counter for number of lines */
168 /* Look for the footer from now */
171 /* There are some changes */
178 /* Copy orginally lines */
179 fprintf(tmp_fff, "%s\n", buf);
183 /* We are looking for the footer mark of automatic dump */
186 /* Is this line a footer? */
187 if (!strncmp(buf, footer_mark_str, mark_len))
192 * Compare the number of lines
194 * If there is an inconsistency between
195 * actual number of lines and the
196 * number here, the automatic dump
197 * might be edited by hand. So it's
198 * dangerous to kill these lines.
199 * Seek back to the next line of the
200 * (pseudo) header, and read again.
202 if (!sscanf(buf + mark_len, " (%d)", &tmp)
205 fseek(orig_fff, header_location, SEEK_SET);
208 /* Look for another header */
209 between_mark = FALSE;
215 /* Ignore old line, and count number of lines */
225 /* If there are some changes, overwrite the original file with new one */
228 /* Copy contents of temporary file */
230 tmp_fff = my_fopen(tmp_file, "r");
231 orig_fff = my_fopen(orig_file, "w");
233 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
234 fprintf(orig_fff, "%s\n", buf);
240 /* Kill the temporary file */
248 * @brief prfファイルのフォーマットに従った内容を出力する /
249 * Dump a formatted line, using "vstrnfmt()".
252 static void auto_dump_printf(concptr fmt, ...)
259 /* Begin the Varargs Stuff */
262 /* Format the args, save the length */
263 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
265 /* End the Varargs Stuff */
268 /* Count number of lines */
269 for (p = buf; *p; p++)
271 if (*p == '\n') auto_dump_line_num++;
275 fprintf(auto_dump_stream, "%s", buf);
280 * @brief prfファイルをファイルオープンする /
281 * Open file to append auto dump.
283 * @param mark 出力するヘッダマーク
284 * @return ファイルポインタを取得できたらTRUEを返す
286 static bool open_auto_dump(concptr buf, concptr mark)
289 char header_mark_str[80];
291 /* Save the mark string */
292 auto_dump_mark = mark;
294 /* Prepare a header mark string */
295 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
297 /* Remove old macro dumps */
298 remove_auto_dump(buf);
300 /* Append to the file */
301 auto_dump_stream = my_fopen(buf, "a");
304 if (!auto_dump_stream) {
305 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
313 fprintf(auto_dump_stream, "%s\n", header_mark_str);
315 /* Initialize counter */
316 auto_dump_line_num = 0;
318 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
319 "# *Warning!* The lines below are an automatic dump.\n"));
320 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
321 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
327 * @brief prfファイルをファイルクローズする /
328 * Append foot part and close auto dump.
331 static void close_auto_dump(void)
333 char footer_mark_str[80];
335 /* Prepare a footer mark string */
336 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
338 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
339 "# *Warning!* The lines below are an automatic dump.\n"));
340 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
341 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
343 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
346 my_fclose(auto_dump_stream);
355 * @brief Return suffix of ordinal number
357 * @return pointer of suffix string.
359 concptr get_ordinal_number_suffix(int num)
361 num = ABS(num) % 100;
365 return (num == 11) ? "th" : "st";
367 return (num == 12) ? "th" : "nd";
369 return (num == 13) ? "th" : "rd";
378 * @brief 日記にメッセージを追加する /
379 * Take note to the diary.
380 * @param type 日記内容のID
381 * @param num 日記内容のIDに応じた数値
382 * @param note 日記内容のIDに応じた文字列参照ポインタ
385 errr do_cmd_write_nikki(int type, int num, concptr note)
389 GAME_TEXT file_name[MAX_NLEN];
391 concptr note_level = "";
392 bool do_level = TRUE;
393 char note_level_buf[40];
396 static bool disable_nikki = FALSE;
398 extract_day_hour_min(&day, &hour, &min);
400 if (disable_nikki) return(-1);
402 if (type == NIKKI_FIX_QUEST_C ||
403 type == NIKKI_FIX_QUEST_F ||
404 type == NIKKI_RAND_QUEST_C ||
405 type == NIKKI_RAND_QUEST_F ||
406 type == NIKKI_TO_QUEST)
410 old_quest = p_ptr->inside_quest;
411 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
413 /* Get the quest text */
414 init_flags = INIT_NAME_ONLY;
416 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
418 /* Reset the old quest number */
419 p_ptr->inside_quest = old_quest;
422 /* different filne name to avoid mixing */
423 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
425 /* Build the filename */
426 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
428 /* File type is "TEXT" */
429 FILE_TYPE(FILE_TYPE_TEXT);
431 fff = my_fopen(buf, "a");
436 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
442 q_idx = quest_number(current_floor_ptr->dun_level);
446 if (p_ptr->inside_arena)
447 note_level = _("アリーナ:", "Arane:");
448 else if (!current_floor_ptr->dun_level)
449 note_level = _("地上:", "Surface:");
450 else if (q_idx && (is_fixed_quest_idx(q_idx)
451 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
452 note_level = _("クエスト:", "Quest:");
456 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
458 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
460 note_level = note_level_buf;
468 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
469 else fputs(_("*****日目\n", "Day *****\n"), fff);
477 fprintf(fff, "%s\n",note);
481 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
486 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
489 case NIKKI_ART_SCROLL:
491 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
496 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
499 case NIKKI_FIX_QUEST_C:
501 if (quest[num].flags & QUEST_FLAG_SILENT) break;
502 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
503 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
506 case NIKKI_FIX_QUEST_F:
508 if (quest[num].flags & QUEST_FLAG_SILENT) break;
509 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
510 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
513 case NIKKI_RAND_QUEST_C:
515 GAME_TEXT name[MAX_NLEN];
516 strcpy(name, r_name+r_info[quest[num].r_idx].name);
517 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
518 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
521 case NIKKI_RAND_QUEST_F:
523 GAME_TEXT name[MAX_NLEN];
524 strcpy(name, r_name+r_info[quest[num].r_idx].name);
525 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
526 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
529 case NIKKI_MAXDEAPTH:
531 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
532 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
533 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
534 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
539 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
540 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
541 _(d_name + d_info[num].name, (int)max_dlv[num]),
542 _((int)max_dlv[num], d_name + d_info[num].name));
548 if (q_idx && (is_fixed_quest_idx(q_idx)
549 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
551 to = _("地上", "the surface");
555 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
556 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
558 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
564 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
565 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
566 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
568 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
573 if (quest[num].flags & QUEST_FLAG_SILENT) break;
574 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
575 hour, min, note_level, quest[num].name);
580 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
581 hour, min, note_level);
586 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
591 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
599 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
600 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
603 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
604 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
606 if (num == MAX_ARENA_MONS)
608 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
609 " won all fight to become a Chanpion.\n"));
616 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
622 if (!current_floor_ptr->dun_level)
623 to = _("地上", "the surface");
625 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
627 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
628 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
634 if (!current_floor_ptr->dun_level)
635 to = _("地上", "the surface");
637 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
639 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
640 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
645 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
648 case NIKKI_GAMESTART:
650 time_t ct = time((time_t*)0);
654 fprintf(fff, "%s %s",note, ctime(&ct));
657 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
660 case NIKKI_NAMED_PET:
662 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
665 case RECORD_NAMED_PET_NAME:
666 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
668 case RECORD_NAMED_PET_UNNAME:
669 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
671 case RECORD_NAMED_PET_DISMISS:
672 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
674 case RECORD_NAMED_PET_DEATH:
675 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
677 case RECORD_NAMED_PET_MOVED:
678 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
680 case RECORD_NAMED_PET_LOST_SIGHT:
681 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
683 case RECORD_NAMED_PET_DESTROY:
684 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
686 case RECORD_NAMED_PET_EARTHQUAKE:
687 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
689 case RECORD_NAMED_PET_GENOCIDE:
690 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
692 case RECORD_NAMED_PET_WIZ_ZAP:
693 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
695 case RECORD_NAMED_PET_TELE_LEVEL:
696 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
698 case RECORD_NAMED_PET_BLAST:
699 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
701 case RECORD_NAMED_PET_HEAL_LEPER:
702 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
704 case RECORD_NAMED_PET_COMPACT:
705 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
707 case RECORD_NAMED_PET_LOSE_PARENT:
708 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
719 case NIKKI_WIZARD_LOG:
720 fprintf(fff, "%s\n", note);
729 if (do_level) write_level = FALSE;
735 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
738 * @brief 日記のタイトル表記と内容出力 /
741 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
743 static void do_cmd_disp_nikki(void)
745 char nikki_title[256];
746 GAME_TEXT file_name[MAX_NLEN];
751 static const char subtitle[][30] = {"最強の肉体を求めて",
782 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
783 "Attack is the best form of defence.",
785 "An unexpected windfall",
786 "A drowning man will catch at a straw",
787 "Don't count your chickens before they are hatched.",
788 "It is no use crying over spilt milk.",
789 "Seeing is believing.",
790 "Strike the iron while it is hot.",
791 "I don't care what follows.",
792 "To dig a well to put out a house on fire.",
793 "Tomorrow is another day.",
794 "Easy come, easy go.",
795 "The more haste, the less speed.",
796 "Where there is life, there is hope.",
797 "There is no royal road to *WINNER*.",
798 "Danger past, God forgotten.",
799 "The best thing to do now is to run away.",
800 "Life is but an empty dream.",
801 "Dead men tell no tales.",
802 "A book that remains shut is but a block.",
803 "Misfortunes never come singly.",
804 "A little knowledge is a dangerous thing.",
805 "History repeats itself.",
806 "*WINNER* was not built in a day.",
807 "Ignorance is bliss.",
808 "To lose is to win?",
809 "No medicine can cure folly.",
810 "All good things come to an end.",
811 "M$ Empire strikes back.",
812 "To see is to believe",
814 "Quest of The World's Greatest Brain"};
816 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
818 /* Build the filename */
819 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
821 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
822 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
823 else if (IS_WIZARD_CLASS())
824 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
825 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
828 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
830 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
833 /* Display the file contents */
834 show_file(FALSE, buf, nikki_title, -1, 0);
838 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
841 static void do_cmd_bunshou(void)
844 char bunshou[80] = "\0";
846 if (get_string(_("内容: ", "diary note: "), tmp, 79))
848 strcpy(bunshou, tmp);
850 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
855 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
858 static void do_cmd_last_get(void)
863 if (record_o_name[0] == '\0') return;
865 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
866 if (!get_check(buf)) return;
868 turn_tmp = current_world_ptr->game_turn;
869 current_world_ptr->game_turn = record_turn;
870 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
871 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
872 current_world_ptr->game_turn = turn_tmp;
876 * @brief ファイル中の全日記記録を消去する /
879 static void do_cmd_erase_nikki(void)
881 GAME_TEXT file_name[MAX_NLEN];
885 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
886 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
888 /* Build the filename */
889 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
892 fff = my_fopen(buf, "w");
895 msg_format(_("記録を消去しました。", "deleted record."));
897 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
906 void do_cmd_nikki(void)
910 /* File type is "TEXT" */
911 FILE_TYPE(FILE_TYPE_TEXT);
914 /* Interact until done */
919 /* Ask for a choice */
920 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
922 /* Give some choices */
923 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
924 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
925 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
926 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
928 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
931 prt(_("コマンド:", "Command: "), 18, 0);
936 if (i == ESCAPE) break;
950 do_cmd_erase_nikki();
954 prepare_movie_hooks();
956 default: /* Unknown option */
966 * @brief 画面を再描画するコマンドのメインルーチン
967 * Hack -- redraw the screen
971 * This command performs various low level updates, clears all the "extra"
972 * windows, does a total redraw of the main window, and requests all of the
973 * interesting updates and redraws that I can think of.
975 * This command is also used to "instantiate" the results of the user
976 * selecting various things, such as graphics mode, so it must call
977 * the "TERM_XTRA_REACT" hook before redrawing the windows.
980 void do_cmd_redraw(void)
986 /* Hack -- react to changes */
987 Term_xtra(TERM_XTRA_REACT, 0);
989 /* Combine and Reorder the pack (later) */
990 p_ptr->update |= (PU_COMBINE | PU_REORDER);
991 p_ptr->update |= (PU_TORCH);
992 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
993 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
994 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
995 p_ptr->update |= (PU_MONSTERS);
997 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
999 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1000 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1006 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1009 /* Redraw every window */
1010 for (j = 0; j < 8; j++)
1013 if (!angband_term[j]) continue;
1016 Term_activate(angband_term[j]);
1025 * @brief 名前を変更するコマンドのメインルーチン
1026 * Hack -- change name
1029 void do_cmd_change_name(void)
1044 /* Display the player */
1045 display_player(mode);
1050 display_player(mode);
1055 Term_putstr(2, 23, -1, TERM_WHITE,
1056 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1058 Term_putstr(2, 23, -1, TERM_WHITE,
1059 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1067 if (c == ESCAPE) break;
1074 /* Process the player name */
1075 process_player_name(FALSE);
1081 sprintf(tmp, "%s.txt", player_base);
1082 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1084 if (tmp[0] && (tmp[0] != ' '))
1086 file_character(tmp);
1104 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1111 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1112 * Recall the most recent message
1115 void do_cmd_message_one(void)
1117 /* Recall one message */
1118 prt(format("> %s", message_str(0)), 0, 0);
1123 * @brief メッセージのログを表示するコマンドのメインルーチン
1124 * Recall the most recent message
1128 * Show previous messages to the user -BEN-
1130 * The screen format uses line 0 and 23 for headers and prompts,
1131 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1133 * This command shows you which commands you are viewing, and allows
1134 * you to "search" for strings in the recall.
1136 * Note that messages may be longer than 80 characters, but they are
1137 * displayed using "infinite" length, with a special sub-command to
1138 * "slide" the virtual display to the left or right.
1140 * Attempt to only hilite the matching portions of the string.
1143 void do_cmd_messages(int num_now)
1147 char shower_str[81];
1148 char finder_str[81];
1150 concptr shower = NULL;
1154 Term_get_size(&wid, &hgt);
1156 /* Number of message lines in a screen */
1157 num_lines = hgt - 4;
1160 strcpy(finder_str, "");
1163 strcpy(shower_str, "");
1165 /* Total messages */
1168 /* Start on first message */
1173 /* Process requests until done */
1179 /* Dump up to 20 lines of messages */
1180 for (j = 0; (j < num_lines) && (i + j < n); j++)
1182 concptr msg = message_str(i+j);
1184 /* Dump the messages, bottom to top */
1185 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1187 /* Hilite "shower" */
1188 if (shower && shower[0])
1192 /* Display matches */
1193 while ((str = my_strstr(str, shower)) != NULL)
1195 int len = strlen(shower);
1197 /* Display the match */
1198 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1206 /* Erase remaining lines */
1207 for (; j < num_lines; j++)
1209 Term_erase(0, num_lines + 1 - j, 255);
1212 /* Display header */
1214 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1215 i, i + j - 1, n), 0, 0);
1217 /* Display prompt (not very informative) */
1218 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1219 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1221 skey = inkey_special(TRUE);
1223 /* Exit on Escape */
1224 if (skey == ESCAPE) break;
1226 /* Hack -- Save the old index */
1231 /* Hack -- handle show */
1234 prt(_("強調: ", "Show: "), hgt - 1, 0);
1236 /* Get a "shower" string, or continue */
1237 strcpy(back_str, shower_str);
1238 if (askfor(shower_str, 80))
1241 shower = shower_str[0] ? shower_str : NULL;
1243 else strcpy(shower_str, back_str);
1247 /* Hack -- handle find */
1254 prt(_("検索: ", "Find: "), hgt - 1, 0);
1256 /* Get a "finder" string, or continue */
1257 strcpy(back_str, finder_str);
1258 if (!askfor(finder_str, 80))
1260 strcpy(finder_str, back_str);
1263 else if (!finder_str[0])
1265 shower = NULL; /* Stop showing */
1270 shower = finder_str;
1273 for (z = i + 1; z < n; z++)
1275 concptr msg = message_str(z);
1278 if (my_strstr(msg, finder_str))
1289 /* Recall 1 older message */
1291 /* Go to the oldest line */
1295 /* Recall 1 newer message */
1297 /* Go to the newest line */
1301 /* Recall 1 older message */
1306 /* Go older if legal */
1307 i = MIN(i + 1, n - num_lines);
1310 /* Recall 10 older messages */
1312 /* Go older if legal */
1313 i = MIN(i + 10, n - num_lines);
1316 /* Recall 20 older messages */
1321 /* Go older if legal */
1322 i = MIN(i + num_lines, n - num_lines);
1325 /* Recall 20 newer messages */
1329 /* Go newer (if able) */
1330 i = MAX(0, i - num_lines);
1333 /* Recall 10 newer messages */
1335 /* Go newer (if able) */
1339 /* Recall 1 newer messages */
1342 /* Go newer (if able) */
1347 /* Hack -- Error of some kind */
1355 * @brief チートオプションを変更するコマンドのメインルーチン
1356 * Interact with some options for cheating
1357 * @param info 表示メッセージ
1360 static void do_cmd_options_cheat(concptr info)
1363 int i, k = 0, n = CHEAT_MAX;
1367 /* Interact with the player */
1373 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1378 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1379 prt(" << 注意 >>", 11, 0);
1380 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1381 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1382 prt(" じらないようにして下さい。", 14, 0);
1384 /* Display the options */
1385 for (i = 0; i < n; i++)
1387 byte a = TERM_WHITE;
1389 /* Color current option */
1390 if (i == k) a = TERM_L_BLUE;
1392 /* Display the option text */
1393 sprintf(buf, "%-48s: %s (%s)",
1394 cheat_info[i].o_desc,
1395 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1396 cheat_info[i].o_text);
1397 c_prt(a, buf, i + 2, 0);
1400 /* Hilite current option */
1401 move_cursor(k + 2, 50);
1407 * HACK - Try to translate the key into a direction
1408 * to allow using the roguelike keys for navigation.
1410 dir = get_keymap_dir(ch);
1411 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1425 k = (n + k - 1) % n;
1443 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1444 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1445 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1446 (*cheat_info[k].o_var) = TRUE;
1455 (*cheat_info[k].o_var) = FALSE;
1462 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1463 /* Peruse the help file */
1464 (void)show_file(TRUE, buf, NULL, 0, 0);
1481 * @brief セーブ頻度ターンの次の値を返す
1482 * @param current 現在のセーブ頻度ターン値
1483 * @return 次のセーブ頻度ターン値
1485 static s16b toggle_frequency(s16b current)
1490 case 50: return 100;
1491 case 100: return 250;
1492 case 250: return 500;
1493 case 500: return 1000;
1494 case 1000: return 2500;
1495 case 2500: return 5000;
1496 case 5000: return 10000;
1497 case 10000: return 25000;
1504 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1505 * @param info 表示メッセージ
1508 static void do_cmd_options_autosave(concptr info)
1511 int i, k = 0, n = 2;
1516 /* Interact with the player */
1520 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1521 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1525 /* Display the options */
1526 for (i = 0; i < n; i++)
1528 byte a = TERM_WHITE;
1530 /* Color current option */
1531 if (i == k) a = TERM_L_BLUE;
1533 /* Display the option text */
1534 sprintf(buf, "%-48s: %s (%s)",
1535 autosave_info[i].o_desc,
1536 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1537 autosave_info[i].o_text);
1538 c_prt(a, buf, i + 2, 0);
1540 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1542 /* Hilite current option */
1543 move_cursor(k + 2, 50);
1559 k = (n + k - 1) % n;
1577 (*autosave_info[k].o_var) = TRUE;
1586 (*autosave_info[k].o_var) = FALSE;
1594 autosave_freq = toggle_frequency(autosave_freq);
1595 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1601 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1617 * @brief 標準オプションを変更するコマンドのサブルーチン /
1618 * Interact with some options
1619 * @param page オプションページ番号
1620 * @param info 表示メッセージ
1623 void do_cmd_options_aux(int page, concptr info)
1626 int i, k = 0, n = 0, l;
1629 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1630 (!p_ptr->wizard || !allow_debug_opts);
1633 /* Lookup the options */
1634 for (i = 0; i < 24; i++) opt[i] = 0;
1636 /* Scan the options */
1637 for (i = 0; option_info[i].o_desc; i++)
1639 /* Notice options on this "page" */
1640 if (option_info[i].o_page == page) opt[n++] = i;
1644 /* Interact with the player */
1650 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1651 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1654 /* HACK -- description for easy-auto-destroy options */
1655 if (page == OPT_PAGE_AUTODESTROY)
1656 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1657 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1659 /* Display the options */
1660 for (i = 0; i < n; i++)
1662 byte a = TERM_WHITE;
1664 /* Color current option */
1665 if (i == k) a = TERM_L_BLUE;
1667 /* Display the option text */
1668 sprintf(buf, "%-48s: %s (%.19s)",
1669 option_info[opt[i]].o_desc,
1670 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1671 option_info[opt[i]].o_text);
1672 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1673 else c_prt(a, buf, i + 2, 0);
1676 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1679 /* Hilite current option */
1680 move_cursor(k + 2 + l, 50);
1686 * HACK - Try to translate the key into a direction
1687 * to allow using the roguelike keys for navigation.
1689 dir = get_keymap_dir(ch);
1690 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1704 k = (n + k - 1) % n;
1721 if (browse_only) break;
1722 (*option_info[opt[k]].o_var) = TRUE;
1731 if (browse_only) break;
1732 (*option_info[opt[k]].o_var) = FALSE;
1740 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1746 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1747 /* Peruse the help file */
1748 (void)show_file(TRUE, buf, NULL, 0, 0);
1765 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1766 * Modify the "window" options
1769 static void do_cmd_options_win(void)
1779 /* Memorize old flags */
1780 for (j = 0; j < 8; j++)
1782 /* Acquire current flags */
1783 old_flag[j] = window_flag[j];
1792 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1794 /* Display the windows */
1795 for (j = 0; j < 8; j++)
1797 byte a = TERM_WHITE;
1799 concptr s = angband_term_name[j];
1802 if (j == x) a = TERM_L_BLUE;
1804 /* Window name, staggered, centered */
1805 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1808 /* Display the options */
1809 for (i = 0; i < 16; i++)
1811 byte a = TERM_WHITE;
1813 concptr str = window_flag_desc[i];
1816 if (i == y) a = TERM_L_BLUE;
1819 if (!str) str = _("(未使用)", "(Unused option)");
1822 Term_putstr(0, i + 5, -1, a, str);
1824 /* Display the windows */
1825 for (j = 0; j < 8; j++)
1831 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1834 if (window_flag[j] & (1L << i)) c = 'X';
1837 Term_putch(35 + j * 5, i + 5, a, c);
1842 Term_gotoxy(35 + x * 5, y + 5);
1860 for (j = 0; j < 8; j++)
1862 window_flag[j] &= ~(1L << y);
1866 for (i = 0; i < 16; i++)
1868 window_flag[x] &= ~(1L << i);
1881 window_flag[x] |= (1L << y);
1889 window_flag[x] &= ~(1L << y);
1895 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1903 d = get_keymap_dir(ch);
1905 x = (x + ddx[d] + 8) % 8;
1906 y = (y + ddy[d] + 16) % 16;
1913 /* Notice changes */
1914 for (j = 0; j < 8; j++)
1919 if (!angband_term[j]) continue;
1921 /* Ignore non-changes */
1922 if (window_flag[j] == old_flag[j]) continue;
1925 Term_activate(angband_term[j]);
1942 option_fields[OPT_NUM] =
1945 { '1', " キー入力 オプション", 3 },
1946 { '2', " マップ画面 オプション", 4 },
1947 { '3', " テキスト表示 オプション", 5 },
1948 { '4', " ゲームプレイ オプション", 6 },
1949 { '5', " 行動中止関係 オプション", 7 },
1950 { '6', " 簡易自動破壊 オプション", 8 },
1951 { 'r', " プレイ記録 オプション", 9 },
1953 { 'p', "自動拾いエディタ", 11 },
1954 { 'd', " 基本ウェイト量 ", 12 },
1955 { 'h', "低ヒットポイント", 13 },
1956 { 'm', " 低魔力色閾値 ", 14 },
1957 { 'a', " 自動セーブ オプション", 15 },
1958 { 'w', "ウインドウフラグ", 16 },
1960 { 'b', " 初期 オプション (参照のみ)", 18 },
1961 { 'c', " 詐欺 オプション", 19 },
1963 { '1', "Input Options", 3 },
1964 { '2', "Map Screen Options", 4 },
1965 { '3', "Text Display Options", 5 },
1966 { '4', "Game-Play Options", 6 },
1967 { '5', "Disturbance Options", 7 },
1968 { '6', "Easy Auto-Destroyer Options", 8 },
1969 { 'r', "Play record Options", 9 },
1971 { 'p', "Auto-picker/destroyer editor", 11 },
1972 { 'd', "Base Delay Factor", 12 },
1973 { 'h', "Hitpoint Warning", 13 },
1974 { 'm', "Mana Color Threshold", 14 },
1975 { 'a', "Autosave Options", 15 },
1976 { 'w', "Window Flags", 16 },
1978 { 'b', "Birth Options (Browse Only)", 18 },
1979 { 'c', "Cheat Options", 19 },
1985 * @brief 標準オプションを変更するコマンドのメインルーチン /
1986 * Set or unset various options.
1990 * The user must use the "Ctrl-R" command to "adapt" to changes
1991 * in any options which control "visual" aspects of the game.
1994 void do_cmd_options(void)
2006 /* Does not list cheat option when cheat option is off */
2007 if (!p_ptr->noscore && !allow_debug_opts) n--;
2010 /* Why are we here */
2011 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2015 /* Give some choices */
2016 for (i = 0; i < n; i++)
2018 byte a = TERM_WHITE;
2019 if (i == y) a = TERM_L_BLUE;
2020 Term_putstr(5, option_fields[i].row, -1, a,
2021 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2024 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2027 skey = inkey_special(TRUE);
2028 if (!(skey & SKEY_MASK)) k = (char)skey;
2032 if (k == ESCAPE) break;
2034 if (my_strchr("\n\r ", k))
2036 k = option_fields[y].key;
2040 for (i = 0; i < n; i++)
2042 if (tolower(k) == option_fields[i].key) break;
2045 /* Command is found */
2048 /* Hack -- browse help */
2049 if (k == '?') break;
2053 if (skey == SKEY_UP) d = 8;
2054 if (skey == SKEY_DOWN) d = 2;
2055 y = (y + ddy[d] + n) % n;
2060 if (k == ESCAPE) break;
2067 /* Process the general options */
2068 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2074 /* Process the general options */
2075 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2082 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2089 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2096 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2103 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2107 /* Play-record Options */
2112 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2121 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2122 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2123 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2127 /* Cheating Options */
2130 if (!p_ptr->noscore && !allow_debug_opts)
2132 /* Cheat options are not permitted */
2138 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2145 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2154 do_cmd_options_win();
2155 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2156 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2157 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2158 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2163 /* Auto-picker/destroyer editor */
2167 do_cmd_edit_autopick();
2171 /* Hack -- Delay Speed */
2177 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2179 /* Get a new value */
2182 int msec = delay_factor * delay_factor * delay_factor;
2183 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2184 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2186 if (k == ESCAPE) break;
2189 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2192 else if (isdigit(k)) delay_factor = D2I(k);
2199 /* Hack -- hitpoint warning factor */
2205 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2207 /* Get a new value */
2210 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2211 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2213 if (k == ESCAPE) break;
2216 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2219 else if (isdigit(k)) hitpoint_warn = D2I(k);
2226 /* Hack -- mana color factor */
2232 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2234 /* Get a new value */
2237 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2238 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2240 if (k == ESCAPE) break;
2243 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2246 else if (isdigit(k)) mana_warn = D2I(k);
2254 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2258 /* Unknown option */
2271 /* Hack - Redraw equippy chars */
2272 p_ptr->redraw |= (PR_EQUIPPY);
2278 * @brief prefファイルを選択して処理する /
2279 * Ask for a "user pref line" and process it
2282 * Allow absolute file names?
2284 void do_cmd_pref(void)
2291 /* Ask for a "user pref command" */
2292 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2294 /* Process that pref command */
2295 (void)process_pref_file_command(buf);
2299 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2302 void do_cmd_reload_autopick(void)
2304 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2305 /* Load the file with messages */
2306 autopick_load_pref(TRUE);
2312 * @brief マクロ情報をprefファイルに保存する /
2313 * @param fname ファイル名
2316 static errr macro_dump(concptr fname)
2318 static concptr mark = "Macro Dump";
2324 /* Build the filename */
2325 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2327 /* File type is "TEXT" */
2328 FILE_TYPE(FILE_TYPE_TEXT);
2330 /* Append to the file */
2331 if (!open_auto_dump(buf, mark)) return (-1);
2334 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2337 for (i = 0; i < macro__num; i++)
2339 /* Extract the action */
2340 ascii_to_text(buf, macro__act[i]);
2342 /* Dump the macro */
2343 auto_dump_printf("A:%s\n", buf);
2345 /* Extract the action */
2346 ascii_to_text(buf, macro__pat[i]);
2348 /* Dump normal macros */
2349 auto_dump_printf("P:%s\n", buf);
2352 auto_dump_printf("\n");
2364 * @brief マクロのトリガーキーを取得する /
2365 * Hack -- ask for a "trigger" (see below)
2366 * @param buf キー表記を保管するバッファ
2370 * Note the complex use of the "inkey()" function from "util.c".
2372 * Note that both "flush()" calls are extremely important.
2375 static void do_cmd_macro_aux(char *buf)
2383 /* Do not process macros */
2389 /* Read the pattern */
2395 /* Do not process macros */
2398 /* Do not wait for keys */
2401 /* Attempt to read a key */
2410 /* Convert the trigger */
2411 ascii_to_text(tmp, buf);
2413 /* Hack -- display the trigger */
2414 Term_addstr(-1, TERM_WHITE, tmp);
2420 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2421 * Hack -- ask for a keymap "trigger" (see below)
2422 * @param buf キー表記を取得するバッファ
2426 * Note that both "flush()" calls are extremely important. This may
2427 * no longer be true, since "util.c" is much simpler now.
2430 static void do_cmd_macro_aux_keymap(char *buf)
2440 /* Convert to ascii */
2441 ascii_to_text(tmp, buf);
2443 /* Hack -- display the trigger */
2444 Term_addstr(-1, TERM_WHITE, tmp);
2451 * @brief キーマップをprefファイルにダンプする /
2452 * Hack -- append all keymaps to the given file
2453 * @param fname ファイルネーム
2457 static errr keymap_dump(concptr fname)
2459 static concptr mark = "Keymap Dump";
2468 if (rogue_like_commands)
2470 mode = KEYMAP_MODE_ROGUE;
2476 mode = KEYMAP_MODE_ORIG;
2480 /* Build the filename */
2481 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2483 /* File type is "TEXT" */
2484 FILE_TYPE(FILE_TYPE_TEXT);
2486 /* Append to the file */
2487 if (!open_auto_dump(buf, mark)) return -1;
2490 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2493 for (i = 0; i < 256; i++)
2497 /* Loop up the keymap */
2498 act = keymap_act[mode][i];
2500 /* Skip empty keymaps */
2503 /* Encode the key */
2506 ascii_to_text(key, buf);
2508 /* Encode the action */
2509 ascii_to_text(buf, act);
2511 /* Dump the macro */
2512 auto_dump_printf("A:%s\n", buf);
2513 auto_dump_printf("C:%d:%s\n", mode, key);
2525 * @brief マクロを設定するコマンドのメインルーチン /
2526 * Interact with "macros"
2530 * Note that the macro "action" must be defined before the trigger.
2532 * Could use some helpful instructions on this page.
2535 void do_cmd_macros(void)
2547 if (rogue_like_commands)
2549 mode = KEYMAP_MODE_ROGUE;
2555 mode = KEYMAP_MODE_ORIG;
2558 /* File type is "TEXT" */
2559 FILE_TYPE(FILE_TYPE_TEXT);
2564 /* Process requests until done */
2568 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2570 /* Describe that action */
2571 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2573 /* Analyze the current action */
2574 ascii_to_text(buf, macro__buf);
2576 /* Display the current action */
2581 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2583 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2584 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2585 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2586 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2587 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2588 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2589 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2590 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2591 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2592 #endif /* ALLOW_MACROS */
2595 prt(_("コマンド: ", "Command: "), 16, 0);
2600 if (i == ESCAPE) break;
2602 /* Load a 'macro' file */
2608 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2611 prt(_("ファイル: ", "File: "), 18, 0);
2613 /* Default filename */
2614 sprintf(tmp, "%s.prf", player_base);
2616 /* Ask for a file */
2617 if (!askfor(tmp, 80)) continue;
2619 /* Process the given filename */
2620 err = process_pref_file(tmp);
2623 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2628 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2632 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2642 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2645 prt(_("ファイル: ", "File: "), 18, 0);
2647 /* Default filename */
2648 sprintf(tmp, "%s.prf", player_base);
2650 /* Ask for a file */
2651 if (!askfor(tmp, 80)) continue;
2653 /* Dump the macros */
2654 (void)macro_dump(tmp);
2657 msg_print(_("マクロを追加しました。", "Appended macros."));
2666 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2670 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2672 /* Get a macro trigger */
2673 do_cmd_macro_aux(buf);
2675 /* Acquire action */
2676 k = macro_find_exact(buf);
2682 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2688 /* Obtain the action */
2689 strcpy(macro__buf, macro__act[k]);
2691 /* Analyze the current action */
2692 ascii_to_text(buf, macro__buf);
2694 /* Display the current action */
2698 msg_print(_("マクロを確認しました。", "Found a macro."));
2702 /* Create a macro */
2706 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2709 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2711 /* Get a macro trigger */
2712 do_cmd_macro_aux(buf);
2718 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2719 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2722 prt(_("マクロ行動: ", "Action: "), 20, 0);
2724 /* Convert to text */
2725 ascii_to_text(tmp, macro__buf);
2727 /* Get an encoded action */
2728 if (askfor(tmp, 80))
2730 /* Convert to ascii */
2731 text_to_ascii(macro__buf, tmp);
2733 /* Link the macro */
2734 macro_add(buf, macro__buf);
2737 msg_print(_("マクロを追加しました。", "Added a macro."));
2741 /* Remove a macro */
2745 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2748 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2750 /* Get a macro trigger */
2751 do_cmd_macro_aux(buf);
2753 /* Link the macro */
2754 macro_add(buf, buf);
2757 msg_print(_("マクロを削除しました。", "Removed a macro."));
2764 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2767 prt(_("ファイル: ", "File: "), 18, 0);
2769 /* Default filename */
2770 sprintf(tmp, "%s.prf", player_base);
2772 /* Ask for a file */
2773 if (!askfor(tmp, 80)) continue;
2775 /* Dump the macros */
2776 (void)keymap_dump(tmp);
2779 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2782 /* Query a keymap */
2788 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2791 prt(_("押すキー: ", "Keypress: "), 18, 0);
2793 /* Get a keymap trigger */
2794 do_cmd_macro_aux_keymap(buf);
2796 /* Look up the keymap */
2797 act = keymap_act[mode][(byte)(buf[0])];
2803 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2809 /* Obtain the action */
2810 strcpy(macro__buf, act);
2812 /* Analyze the current action */
2813 ascii_to_text(buf, macro__buf);
2815 /* Display the current action */
2819 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2823 /* Create a keymap */
2827 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2830 prt(_("押すキー: ", "Keypress: "), 18, 0);
2832 /* Get a keymap trigger */
2833 do_cmd_macro_aux_keymap(buf);
2839 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2840 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2843 prt(_("行動: ", "Action: "), 20, 0);
2845 /* Convert to text */
2846 ascii_to_text(tmp, macro__buf);
2848 /* Get an encoded action */
2849 if (askfor(tmp, 80))
2851 /* Convert to ascii */
2852 text_to_ascii(macro__buf, tmp);
2854 /* Free old keymap */
2855 string_free(keymap_act[mode][(byte)(buf[0])]);
2857 /* Make new keymap */
2858 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2861 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2865 /* Remove a keymap */
2869 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2872 prt(_("押すキー: ", "Keypress: "), 18, 0);
2874 /* Get a keymap trigger */
2875 do_cmd_macro_aux_keymap(buf);
2877 /* Free old keymap */
2878 string_free(keymap_act[mode][(byte)(buf[0])]);
2880 /* Make new keymap */
2881 keymap_act[mode][(byte)(buf[0])] = NULL;
2884 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2887 /* Enter a new action */
2891 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2897 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2898 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2901 prt(_("マクロ行動: ", "Action: "), 20, 0);
2903 /* Hack -- limit the value */
2906 /* Get an encoded action */
2907 if (!askfor(buf, 80)) continue;
2909 /* Extract an action */
2910 text_to_ascii(macro__buf, buf);
2913 #endif /* ALLOW_MACROS */
2926 * @brief キャラクタ色の明暗表現
2928 static concptr lighting_level_str[F_LIT_MAX] =
2943 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2944 * @param i 指定対象となるキャラクタコード
2945 * @param num 指定されたビジュアルIDを返す参照ポインタ
2946 * @param max ビジュアルIDの最大数
2947 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2949 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2956 sprintf(str, "%d", *num);
2958 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2961 tmp = (IDX)strtol(str, NULL, 0);
2962 if (tmp >= 0 && tmp < max)
2965 else if (isupper(i))
2966 *num = (*num + max - 1) % max;
2968 *num = (*num + 1) % max;
2974 * @brief キャラクタの変更メニュー表示
2975 * @param choice_msg 選択メッセージ
2978 static void print_visuals_menu(concptr choice_msg)
2980 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2982 /* Give some choices */
2983 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2985 #ifdef ALLOW_VISUALS
2986 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2987 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2988 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2989 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2990 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2991 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2992 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2993 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2994 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2995 #endif /* ALLOW_VISUALS */
2997 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3000 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3003 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3004 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3005 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3008 * Interact with "visuals"
3010 void do_cmd_visuals(void)
3015 bool need_redraw = FALSE;
3016 concptr empty_symbol = "<< ? >>";
3018 if (use_bigtile) empty_symbol = "<< ?? >>";
3020 /* File type is "TEXT" */
3021 FILE_TYPE(FILE_TYPE_TEXT);
3024 /* Interact until done */
3029 /* Ask for a choice */
3030 print_visuals_menu(NULL);
3035 if (i == ESCAPE) break;
3039 /* Load a 'pref' file */
3042 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3045 prt(_("ファイル: ", "File: "), 17, 0);
3047 /* Default filename */
3048 sprintf(tmp, "%s.prf", player_base);
3051 if (!askfor(tmp, 70)) continue;
3053 /* Process the given filename */
3054 (void)process_pref_file(tmp);
3059 #ifdef ALLOW_VISUALS
3061 /* Dump monster attr/chars */
3064 static concptr mark = "Monster attr/chars";
3067 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3070 prt(_("ファイル: ", "File: "), 17, 0);
3072 /* Default filename */
3073 sprintf(tmp, "%s.prf", player_base);
3075 /* Get a filename */
3076 if (!askfor(tmp, 70)) continue;
3078 /* Build the filename */
3079 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3081 /* Append to the file */
3082 if (!open_auto_dump(buf, mark)) continue;
3085 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3088 for (i = 0; i < max_r_idx; i++)
3090 monster_race *r_ptr = &r_info[i];
3092 /* Skip non-entries */
3093 if (!r_ptr->name) continue;
3095 /* Dump a comment */
3096 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3098 /* Dump the monster attr/char info */
3099 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3100 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3106 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3111 /* Dump object attr/chars */
3114 static concptr mark = "Object attr/chars";
3115 KIND_OBJECT_IDX k_idx;
3118 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3121 prt(_("ファイル: ", "File: "), 17, 0);
3123 /* Default filename */
3124 sprintf(tmp, "%s.prf", player_base);
3126 /* Get a filename */
3127 if (!askfor(tmp, 70)) continue;
3129 /* Build the filename */
3130 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3132 /* Append to the file */
3133 if (!open_auto_dump(buf, mark)) continue;
3136 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3139 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3141 GAME_TEXT o_name[MAX_NLEN];
3142 object_kind *k_ptr = &k_info[k_idx];
3144 /* Skip non-entries */
3145 if (!k_ptr->name) continue;
3150 strip_name(o_name, k_idx);
3156 /* Prepare dummy object */
3157 object_prep(&forge, k_idx);
3159 /* Get un-shuffled flavor name */
3160 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3163 /* Dump a comment */
3164 auto_dump_printf("# %s\n", o_name);
3166 /* Dump the object attr/char info */
3167 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3168 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3174 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3179 /* Dump feature attr/chars */
3182 static concptr mark = "Feature attr/chars";
3185 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3188 prt(_("ファイル: ", "File: "), 17, 0);
3190 /* Default filename */
3191 sprintf(tmp, "%s.prf", player_base);
3193 /* Get a filename */
3194 if (!askfor(tmp, 70)) continue;
3196 /* Build the filename */
3197 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3199 /* Append to the file */
3200 if (!open_auto_dump(buf, mark)) continue;
3203 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3206 for (i = 0; i < max_f_idx; i++)
3208 feature_type *f_ptr = &f_info[i];
3210 /* Skip non-entries */
3211 if (!f_ptr->name) continue;
3213 /* Skip mimiccing features */
3214 if (f_ptr->mimic != i) continue;
3216 /* Dump a comment */
3217 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3219 /* Dump the feature attr/char info */
3220 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3221 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3222 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3223 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3229 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3234 /* Modify monster attr/chars (numeric operation) */
3237 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3238 static MONRACE_IDX r = 0;
3240 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3242 /* Hack -- query until done */
3245 monster_race *r_ptr = &r_info[r];
3249 TERM_COLOR da = r_ptr->d_attr;
3250 byte dc = r_ptr->d_char;
3251 TERM_COLOR ca = r_ptr->x_attr;
3252 byte cc = r_ptr->x_char;
3254 /* Label the object */
3255 Term_putstr(5, 17, -1, TERM_WHITE,
3256 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3258 /* Label the Default values */
3259 Term_putstr(10, 19, -1, TERM_WHITE,
3260 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3262 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3263 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3265 /* Label the Current values */
3266 Term_putstr(10, 20, -1, TERM_WHITE,
3267 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3269 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3270 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3273 Term_putstr(0, 22, -1, TERM_WHITE,
3274 _("コマンド (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): "));
3279 if (i == ESCAPE) break;
3281 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3282 else if (isupper(i)) c = 'a' + i - 'A';
3292 if (!cmd_visuals_aux(i, &r, max_r_idx))
3298 while (!r_info[r].name);
3302 t = (int)r_ptr->x_attr;
3303 (void)cmd_visuals_aux(i, &t, 256);
3304 r_ptr->x_attr = (byte)t;
3308 t = (int)r_ptr->x_char;
3309 (void)cmd_visuals_aux(i, &t, 256);
3310 r_ptr->x_char = (byte)t;
3314 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3316 print_visuals_menu(choice_msg);
3324 /* Modify object attr/chars (numeric operation) */
3327 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3329 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3331 /* Hack -- query until done */
3334 object_kind *k_ptr = &k_info[k];
3338 TERM_COLOR da = k_ptr->d_attr;
3339 SYMBOL_CODE dc = k_ptr->d_char;
3340 TERM_COLOR ca = k_ptr->x_attr;
3341 SYMBOL_CODE cc = k_ptr->x_char;
3343 /* Label the object */
3344 Term_putstr(5, 17, -1, TERM_WHITE,
3345 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3346 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3348 /* Label the Default values */
3349 Term_putstr(10, 19, -1, TERM_WHITE,
3350 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3352 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3353 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3355 /* Label the Current values */
3356 Term_putstr(10, 20, -1, TERM_WHITE,
3357 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3359 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3360 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3363 Term_putstr(0, 22, -1, TERM_WHITE,
3364 _("コマンド (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): "));
3369 if (i == ESCAPE) break;
3371 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3372 else if (isupper(i)) c = 'a' + i - 'A';
3382 if (!cmd_visuals_aux(i, &k, max_k_idx))
3388 while (!k_info[k].name);
3392 t = (int)k_ptr->x_attr;
3393 (void)cmd_visuals_aux(i, &t, 256);
3394 k_ptr->x_attr = (byte)t;
3398 t = (int)k_ptr->x_char;
3399 (void)cmd_visuals_aux(i, &t, 256);
3400 k_ptr->x_char = (byte)t;
3404 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3406 print_visuals_menu(choice_msg);
3414 /* Modify feature attr/chars (numeric operation) */
3417 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3419 static IDX lighting_level = F_LIT_STANDARD;
3420 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3422 /* Hack -- query until done */
3425 feature_type *f_ptr = &f_info[f];
3429 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3430 byte dc = f_ptr->d_char[lighting_level];
3431 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3432 byte cc = f_ptr->x_char[lighting_level];
3434 /* Label the object */
3436 Term_putstr(5, 17, -1, TERM_WHITE,
3437 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3438 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3440 /* Label the Default values */
3441 Term_putstr(10, 19, -1, TERM_WHITE,
3442 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3444 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3445 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3447 /* Label the Current values */
3449 Term_putstr(10, 20, -1, TERM_WHITE,
3450 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3452 Term_putstr(10, 20, -1, TERM_WHITE,
3453 format("Current attr/char = %3d / %3d", ca, cc));
3456 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3457 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3461 Term_putstr(0, 22, -1, TERM_WHITE,
3462 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3464 Term_putstr(0, 22, -1, TERM_WHITE,
3465 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3471 if (i == ESCAPE) break;
3473 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3474 else if (isupper(i)) c = 'a' + i - 'A';
3484 if (!cmd_visuals_aux(i, &f, max_f_idx))
3490 while (!f_info[f].name || (f_info[f].mimic != f));
3494 t = (int)f_ptr->x_attr[lighting_level];
3495 (void)cmd_visuals_aux(i, &t, 256);
3496 f_ptr->x_attr[lighting_level] = (byte)t;
3500 t = (int)f_ptr->x_char[lighting_level];
3501 (void)cmd_visuals_aux(i, &t, 256);
3502 f_ptr->x_char[lighting_level] = (byte)t;
3506 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3509 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3513 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3515 print_visuals_menu(choice_msg);
3523 /* Modify monster attr/chars (visual mode) */
3525 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3528 /* Modify object attr/chars (visual mode) */
3530 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3533 /* Modify feature attr/chars (visual mode) */
3536 IDX lighting_level = F_LIT_STANDARD;
3537 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3541 #endif /* ALLOW_VISUALS */
3549 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3553 /* Unknown option */
3563 if (need_redraw) do_cmd_redraw();
3568 * Interact with "colors"
3570 void do_cmd_colors(void)
3579 /* File type is "TEXT" */
3580 FILE_TYPE(FILE_TYPE_TEXT);
3585 /* Interact until done */
3590 /* Ask for a choice */
3591 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3593 /* Give some choices */
3594 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3597 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3598 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3602 prt(_("コマンド: ", "Command: "), 8, 0);
3606 if (i == ESCAPE) break;
3608 /* Load a 'pref' file */
3612 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3615 prt(_("ファイル: ", "File: "), 10, 0);
3618 sprintf(tmp, "%s.prf", player_base);
3621 if (!askfor(tmp, 70)) continue;
3623 /* Process the given filename */
3624 (void)process_pref_file(tmp);
3626 /* Mega-Hack -- react to changes */
3627 Term_xtra(TERM_XTRA_REACT, 0);
3629 /* Mega-Hack -- redraw */
3638 static concptr mark = "Colors";
3641 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3644 prt(_("ファイル: ", "File: "), 10, 0);
3646 /* Default filename */
3647 sprintf(tmp, "%s.prf", player_base);
3649 /* Get a filename */
3650 if (!askfor(tmp, 70)) continue;
3652 /* Build the filename */
3653 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3655 /* Append to the file */
3656 if (!open_auto_dump(buf, mark)) continue;
3659 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3662 for (i = 0; i < 256; i++)
3664 int kv = angband_color_table[i][0];
3665 int rv = angband_color_table[i][1];
3666 int gv = angband_color_table[i][2];
3667 int bv = angband_color_table[i][3];
3669 concptr name = _("未知", "unknown");
3671 /* Skip non-entries */
3672 if (!kv && !rv && !gv && !bv) continue;
3674 /* Extract the color name */
3675 if (i < 16) name = color_names[i];
3677 /* Dump a comment */
3678 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3680 /* Dump the monster attr/char info */
3681 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3688 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3697 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3699 /* Hack -- query until done */
3708 /* Exhibit the normal colors */
3709 for (j = 0; j < 16; j++)
3711 /* Exhibit this color */
3712 Term_putstr(j*4, 20, -1, a, "###");
3714 /* Exhibit all colors */
3715 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3718 /* Describe the color */
3719 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3721 /* Describe the color */
3722 Term_putstr(5, 10, -1, TERM_WHITE,
3723 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3725 /* Label the Current values */
3726 Term_putstr(5, 12, -1, TERM_WHITE,
3727 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3728 angband_color_table[a][0],
3729 angband_color_table[a][1],
3730 angband_color_table[a][2],
3731 angband_color_table[a][3]));
3734 Term_putstr(0, 14, -1, TERM_WHITE,
3735 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3740 if (i == ESCAPE) break;
3743 if (i == 'n') a = (byte)(a + 1);
3744 if (i == 'N') a = (byte)(a - 1);
3745 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3746 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3747 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3748 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3749 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3750 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3751 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3752 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3754 /* Hack -- react to changes */
3755 Term_xtra(TERM_XTRA_REACT, 0);
3757 /* Hack -- redraw */
3764 /* Unknown option */
3778 * Note something in the message recall
3780 void do_cmd_note(void)
3788 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3790 /* Ignore empty notes */
3791 if (!buf[0] || (buf[0] == ' ')) return;
3793 /* Add the note to the message recall */
3794 msg_format(_("メモ: %s", "Note: %s"), buf);
3799 * Mention the current version
3801 void do_cmd_version(void)
3803 #if FAKE_VER_EXTRA > 0
3804 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3805 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3807 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3808 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3815 * Array of feeling strings
3817 static concptr do_cmd_feeling_text[11] =
3819 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3820 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3821 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3822 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3823 _("とても悪い予感がする...", "You have a very bad feeling..."),
3824 _("悪い予感がする...", "You have a bad feeling..."),
3825 _("何か緊張する。", "You feel nervous."),
3826 _("少し不運な気がする...", "You feel your luck is turning..."),
3827 _("この場所は好きになれない。", "You don't like the look of this place."),
3828 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3829 _("なんて退屈なところだ...", "What a boring place...")
3832 static concptr do_cmd_feeling_text_combat[11] =
3834 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3835 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3836 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3837 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3838 _("とても悪い予感がする...", "You have a very bad feeling..."),
3839 _("悪い予感がする...", "You have a bad feeling..."),
3840 _("何か緊張する。", "You feel nervous."),
3841 _("少し不運な気がする...", "You feel your luck is turning..."),
3842 _("この場所は好きになれない。", "You don't like the look of this place."),
3843 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3844 _("なんて退屈なところだ...", "What a boring place...")
3847 static concptr do_cmd_feeling_text_lucky[11] =
3849 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3850 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3851 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3852 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3853 _("とても良い感じがする...", "You have a very good feeling..."),
3854 _("良い感じがする...", "You have a good feeling..."),
3855 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3856 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3857 _("見た感じ悪くはない...", "You like the look of this place..."),
3858 _("全然駄目ということはないが...", "This level can't be all bad..."),
3859 _("なんて退屈なところだ...", "What a boring place...")
3864 * Note that "feeling" is set to zero unless some time has passed.
3865 * Note that this is done when the level is GENERATED, not entered.
3867 void do_cmd_feeling(void)
3869 if (p_ptr->wild_mode) return;
3871 /* No useful feeling in quests */
3872 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3874 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3878 /* No useful feeling in town */
3879 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3881 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3883 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3888 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3893 /* No useful feeling in the wilderness */
3894 else if (!current_floor_ptr->dun_level)
3896 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3900 /* Display the feeling */
3901 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3902 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3903 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3904 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3905 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3907 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3913 * Description of each monster group.
3915 static concptr monster_group_text[] =
3918 "ユニーク", /* "Uniques" */
3919 "乗馬可能なモンスター", /* "Riding" */
3920 "賞金首", /* "Wanted */
3921 "アンバーの王族", /* "Ambertite" */
3950 /* "古代ドラゴン/ワイアーム", */
4011 /* "Ancient Dragon/Wyrm", */
4020 "Multi-Headed Reptile",
4025 "Reptile/Amphibian",
4026 "Spider/Scorpion/Tick",
4028 /* "Major Demon", */
4045 * Symbols of monsters in each group. Note the "Uniques" group
4046 * is handled differently.
4048 static concptr monster_group_char[] =
4105 "!$&()+./=>?[\\]`{|~",
4115 * Build a list of monster indexes in the given group. Return the number
4116 * of monsters in the group.
4118 * mode & 0x01 : check for non-empty group
4119 * mode & 0x02 : visual operation only
4121 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4127 /* Get a list of x_char in this group */
4128 concptr group_char = monster_group_char[grp_cur];
4130 /* XXX Hack -- Check if this is the "Uniques" group */
4131 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4133 /* XXX Hack -- Check if this is the "Riding" group */
4134 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4136 /* XXX Hack -- Check if this is the "Wanted" group */
4137 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4139 /* XXX Hack -- Check if this is the "Amberite" group */
4140 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4143 /* Check every race */
4144 for (i = 0; i < max_r_idx; i++)
4146 /* Access the race */
4147 monster_race *r_ptr = &r_info[i];
4149 /* Skip empty race */
4150 if (!r_ptr->name) continue ;
4152 /* Require known monsters */
4153 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4157 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4160 else if (grp_riding)
4162 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4165 else if (grp_wanted)
4167 bool wanted = FALSE;
4169 for (j = 0; j < MAX_KUBI; j++)
4171 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4172 (p_ptr->today_mon && p_ptr->today_mon == i))
4178 if (!wanted) continue;
4181 else if (grp_amberite)
4183 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4188 /* Check for race in the group */
4189 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4193 mon_idx[mon_cnt++] = i;
4195 /* XXX Hack -- Just checking for non-empty group */
4196 if (mode & 0x01) break;
4199 /* Terminate the list */
4200 mon_idx[mon_cnt] = -1;
4202 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4204 /* Return the number of races */
4210 * Description of each monster group.
4212 static concptr object_group_text[] =
4215 "キノコ", /* "Mushrooms" */
4216 "薬", /* "Potions" */
4217 "油つぼ", /* "Flasks" */
4218 "巻物", /* "Scrolls" */
4220 "アミュレット", /* "Amulets" */
4221 "笛", /* "Whistle" */
4222 "光源", /* "Lanterns" */
4223 "魔法棒", /* "Wands" */
4226 "カード", /* "Cards" */
4237 "刀剣類", /* "Swords" */
4238 "鈍器", /* "Blunt Weapons" */
4239 "長柄武器", /* "Polearms" */
4240 "採掘道具", /* "Diggers" */
4241 "飛び道具", /* "Bows" */
4245 "軽装鎧", /* "Soft Armor" */
4246 "重装鎧", /* "Hard Armor" */
4247 "ドラゴン鎧", /* "Dragon Armor" */
4248 "盾", /* "Shields" */
4249 "クローク", /* "Cloaks" */
4250 "籠手", /* "Gloves" */
4251 "ヘルメット", /* "Helms" */
4253 "ブーツ", /* "Boots" */
4306 * TVALs of items in each group
4308 static byte object_group_tval[] =
4349 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4357 * Build a list of object indexes in the given group. Return the number
4358 * of objects in the group.
4360 * mode & 0x01 : check for non-empty group
4361 * mode & 0x02 : visual operation only
4363 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4365 KIND_OBJECT_IDX i, object_cnt = 0;
4368 /* Get a list of x_char in this group */
4369 byte group_tval = object_group_tval[grp_cur];
4371 /* Check every object */
4372 for (i = 0; i < max_k_idx; i++)
4374 /* Access the object */
4375 object_kind *k_ptr = &k_info[i];
4377 /* Skip empty objects */
4378 if (!k_ptr->name) continue;
4382 /* Any objects will be displayed */
4388 /* Skip non-flavoured objects */
4389 if (!k_ptr->flavor) continue;
4391 /* Require objects ever seen */
4392 if (!k_ptr->aware) continue;
4395 /* Skip items with no distribution (special artifacts) */
4396 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4400 /* Check for objects in the group */
4401 if (TV_LIFE_BOOK == group_tval)
4403 /* Hack -- All spell books */
4404 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4406 /* Add the object */
4407 object_idx[object_cnt++] = i;
4411 else if (k_ptr->tval == group_tval)
4413 /* Add the object */
4414 object_idx[object_cnt++] = i;
4418 /* XXX Hack -- Just checking for non-empty group */
4419 if (mode & 0x01) break;
4422 /* Terminate the list */
4423 object_idx[object_cnt] = -1;
4425 /* Return the number of objects */
4431 * Description of each feature group.
4433 static concptr feature_group_text[] =
4441 * Build a list of feature indexes in the given group. Return the number
4442 * of features in the group.
4444 * mode & 0x01 : check for non-empty group
4446 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4449 FEAT_IDX feat_cnt = 0;
4451 /* Unused; There is a single group. */
4454 /* Check every feature */
4455 for (i = 0; i < max_f_idx; i++)
4457 feature_type *f_ptr = &f_info[i];
4459 /* Skip empty index */
4460 if (!f_ptr->name) continue;
4462 /* Skip mimiccing features */
4463 if (f_ptr->mimic != i) continue;
4466 feat_idx[feat_cnt++] = i;
4468 /* XXX Hack -- Just checking for non-empty group */
4469 if (mode & 0x01) break;
4472 /* Terminate the list */
4473 feat_idx[feat_cnt] = -1;
4475 /* Return the number of races */
4482 * Build a list of monster indexes in the given group. Return the number
4483 * of monsters in the group.
4485 static int collect_artifacts(int grp_cur, int object_idx[])
4487 int i, object_cnt = 0;
4489 /* Get a list of x_char in this group */
4490 byte group_tval = object_group_tval[grp_cur];
4492 /* Check every object */
4493 for (i = 0; i < max_a_idx; i++)
4495 /* Access the artifact */
4496 artifact_type *a_ptr = &a_info[i];
4498 /* Skip empty artifacts */
4499 if (!a_ptr->name) continue;
4501 /* Skip "uncreated" artifacts */
4502 if (!a_ptr->cur_num) continue;
4504 /* Check for race in the group */
4505 if (a_ptr->tval == group_tval)
4508 object_idx[object_cnt++] = i;
4512 /* Terminate the list */
4513 object_idx[object_cnt] = 0;
4515 /* Return the number of races */
4522 * Encode the screen colors
4524 static char hack[17] = "dwsorgbuDWvyRGBU";
4528 * Hack -- load a screen dump from a file
4530 void do_cmd_load_screen(void)
4535 SYMBOL_CODE c = ' ';
4541 Term_get_size(&wid, &hgt);
4543 /* Build the filename */
4544 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4546 /* Append to the file */
4547 fff = my_fopen(buf, "r");
4550 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4558 /* Load the screen */
4559 for (y = 0; okay; y++)
4561 /* Get a line of data including control code */
4562 if (!fgets(buf, 1024, fff)) okay = FALSE;
4564 /* Get the blank line */
4565 if (buf[0] == '\n' || buf[0] == '\0') break;
4567 /* Ignore too large screen image */
4568 if (y >= hgt) continue;
4571 for (x = 0; x < wid - 1; x++)
4574 if (buf[x] == '\n' || buf[x] == '\0') break;
4576 /* Put the attr/char */
4577 Term_draw(x, y, TERM_WHITE, buf[x]);
4581 /* Dump the screen */
4582 for (y = 0; okay; y++)
4584 /* Get a line of data including control code */
4585 if (!fgets(buf, 1024, fff)) okay = FALSE;
4587 /* Get the blank line */
4588 if (buf[0] == '\n' || buf[0] == '\0') break;
4590 /* Ignore too large screen image */
4591 if (y >= hgt) continue;
4594 for (x = 0; x < wid - 1; x++)
4597 if (buf[x] == '\n' || buf[x] == '\0') break;
4599 /* Get the attr/char */
4600 (void)(Term_what(x, y, &a, &c));
4602 /* Look up the attr */
4603 for (i = 0; i < 16; i++)
4605 /* Use attr matches */
4606 if (hack[i] == buf[x]) a = (byte_hack)i;
4609 /* Put the attr/char */
4610 Term_draw(x, y, a, c);
4615 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4626 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4627 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4630 #define IM_FLAG_STR _("*", "* ")
4631 #define HAS_FLAG_STR _("+", "+ ")
4632 #define NO_FLAG_STR _("・", ". ")
4634 #define print_im_or_res_flag(IM, RES) \
4636 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4637 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4640 #define print_flag(TR) \
4642 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4646 /* XTRA HACK RESLIST */
4647 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4649 GAME_TEXT o_name[MAX_NLEN];
4650 BIT_FLAGS flgs[TR_FLAG_SIZE];
4652 if (!o_ptr->k_idx) return;
4653 if (o_ptr->tval != tval) return;
4655 /* Identified items only */
4656 if (!object_is_known(o_ptr)) return;
4659 * HACK:Ring of Lordly protection and Dragon equipment
4660 * have random resistances.
4662 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4663 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4664 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4665 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4666 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4667 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4668 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4669 || object_is_artifact(o_ptr))
4672 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4674 while (o_name[i] && (i < 26))
4677 if (iskanji(o_name[i])) i++;
4686 o_name[i] = ' '; i++;
4691 fprintf(fff, "%s %s", where, o_name);
4693 if (!(o_ptr->ident & (IDENT_MENTAL)))
4695 fputs(_("-------不明--------------- -------不明---------\n",
4696 "-------unknown------------ -------unknown------\n"), fff);
4700 object_flags_known(o_ptr, flgs);
4702 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4703 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4704 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4705 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4706 print_flag(TR_RES_POIS);
4707 print_flag(TR_RES_LITE);
4708 print_flag(TR_RES_DARK);
4709 print_flag(TR_RES_SHARDS);
4710 print_flag(TR_RES_SOUND);
4711 print_flag(TR_RES_NETHER);
4712 print_flag(TR_RES_NEXUS);
4713 print_flag(TR_RES_CHAOS);
4714 print_flag(TR_RES_DISEN);
4718 print_flag(TR_RES_BLIND);
4719 print_flag(TR_RES_FEAR);
4720 print_flag(TR_RES_CONF);
4721 print_flag(TR_FREE_ACT);
4722 print_flag(TR_SEE_INVIS);
4723 print_flag(TR_HOLD_EXP);
4724 print_flag(TR_TELEPATHY);
4725 print_flag(TR_SLOW_DIGEST);
4726 print_flag(TR_REGEN);
4727 print_flag(TR_LEVITATION);
4735 fprintf(fff, "%s\n", inven_res_label);
4741 * Display *ID* ed weapons/armors's resistances
4743 static void do_cmd_knowledge_inven(void)
4746 GAME_TEXT file_name[1024];
4748 OBJECT_TYPE_VALUE tval;
4754 /* Open a new file */
4755 fff = my_fopen_temp(file_name, 1024);
4758 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4762 fprintf(fff, "%s\n", inven_res_label);
4764 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4768 for (; j < 9; j++) fputc('\n', fff);
4770 fprintf(fff, "%s\n", inven_res_label);
4772 strcpy(where, _("装", "E "));
4773 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4775 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4777 strcpy(where, _("持", "I "));
4778 for (i = 0; i < INVEN_PACK; i++)
4780 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4783 st_ptr = &town_info[1].store[STORE_HOME];
4784 strcpy(where, _("家", "H "));
4785 for (i = 0; i < st_ptr->stock_num; i++)
4787 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4792 /* Display the file contents */
4793 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4798 void do_cmd_save_screen_html_aux(char *filename, int message)
4803 TERM_COLOR a = 0, old_a = 0;
4817 concptr html_head[] = {
4818 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4822 concptr html_foot[] = {
4824 "</body>\n</html>\n",
4830 Term_get_size(&wid, &hgt);
4832 /* File type is "TEXT" */
4833 FILE_TYPE(FILE_TYPE_TEXT);
4835 /* Append to the file */
4836 fff = my_fopen(filename, "w");
4840 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4846 if (message) screen_save();
4848 /* Build the filename */
4849 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4850 tmpfff = my_fopen(buf, "r");
4852 for (i = 0; html_head[i]; i++)
4853 fputs(html_head[i], fff);
4857 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4859 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4863 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4865 fprintf(fff, "%s\n", buf);
4870 /* Dump the screen */
4871 for (y = 0; y < hgt; y++)
4878 for (x = 0; x < wid - 1; x++)
4882 /* Get the attr/char */
4883 (void)(Term_what(x, y, &a, &c));
4887 case '&': cc = "&"; break;
4888 case '<': cc = "<"; break;
4889 case '>': cc = ">"; break;
4891 case 0x1f: c = '.'; break;
4892 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4897 if ((y == 0 && x == 0) || a != old_a) {
4898 rv = angband_color_table[a][1];
4899 gv = angband_color_table[a][2];
4900 bv = angband_color_table[a][3];
4901 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4902 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4906 fprintf(fff, "%s", cc);
4908 fprintf(fff, "%c", c);
4911 fprintf(fff, "</font>");
4914 for (i = 0; html_foot[i]; i++)
4915 fputs(html_foot[i], fff);
4920 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4922 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4926 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4928 fprintf(fff, "%s\n", buf);
4939 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4947 * Hack -- save a screen dump to a file
4949 static void do_cmd_save_screen_html(void)
4951 char buf[1024], tmp[256] = "screen.html";
4953 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4956 /* Build the filename */
4957 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4961 do_cmd_save_screen_html_aux(buf, 1);
4966 * Redefinable "save_screen" action
4968 void (*screendump_aux)(void) = NULL;
4972 * Hack -- save a screen dump to a file
4974 void do_cmd_save_screen(void)
4976 bool old_use_graphics = use_graphics;
4977 bool html_dump = FALSE;
4981 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4985 if (c == 'Y' || c == 'y')
4987 else if (c == 'H' || c == 'h')
4999 Term_get_size(&wid, &hgt);
5001 if (old_use_graphics)
5003 use_graphics = FALSE;
5005 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5011 do_cmd_save_screen_html();
5015 /* Do we use a special screendump function ? */
5016 else if (screendump_aux)
5018 /* Dump the screen to a graphics file */
5019 (*screendump_aux)();
5021 else /* Dump the screen as text */
5025 SYMBOL_CODE c = ' ';
5029 /* Build the filename */
5030 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5032 /* File type is "TEXT" */
5033 FILE_TYPE(FILE_TYPE_TEXT);
5035 /* Append to the file */
5036 fff = my_fopen(buf, "w");
5040 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5048 /* Dump the screen */
5049 for (y = 0; y < hgt; y++)
5052 for (x = 0; x < wid - 1; x++)
5054 /* Get the attr/char */
5055 (void)(Term_what(x, y, &a, &c));
5065 fprintf(fff, "%s\n", buf);
5072 /* Dump the screen */
5073 for (y = 0; y < hgt; y++)
5076 for (x = 0; x < wid - 1; x++)
5078 /* Get the attr/char */
5079 (void)(Term_what(x, y, &a, &c));
5082 buf[x] = hack[a&0x0F];
5089 fprintf(fff, "%s\n", buf);
5096 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5101 if (old_use_graphics)
5103 use_graphics = TRUE;
5105 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5111 * Check the status of "artifacts"
5113 static void do_cmd_knowledge_artifacts(void)
5123 GAME_TEXT file_name[1024];
5124 GAME_TEXT base_name[MAX_NLEN];
5128 /* Open a new file */
5129 fff = my_fopen_temp(file_name, 1024);
5132 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5137 /* Allocate the "who" array */
5138 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5140 /* Allocate the "okay" array */
5141 C_MAKE(okay, max_a_idx, bool);
5143 /* Scan the artifacts */
5144 for (k = 0; k < max_a_idx; k++)
5146 artifact_type *a_ptr = &a_info[k];
5151 /* Skip "empty" artifacts */
5152 if (!a_ptr->name) continue;
5154 /* Skip "uncreated" artifacts */
5155 if (!a_ptr->cur_num) continue;
5161 /* Check the dungeon */
5162 for (y = 0; y < current_floor_ptr->height; y++)
5164 for (x = 0; x < current_floor_ptr->width; x++)
5166 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5168 OBJECT_IDX this_o_idx, next_o_idx = 0;
5170 /* Scan all objects in the grid */
5171 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5174 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5175 next_o_idx = o_ptr->next_o_idx;
5177 /* Ignore non-artifacts */
5178 if (!object_is_fixed_artifact(o_ptr)) continue;
5180 /* Ignore known items */
5181 if (object_is_known(o_ptr)) continue;
5183 /* Note the artifact */
5184 okay[o_ptr->name1] = FALSE;
5189 /* Check the p_ptr->inventory_list and equipment */
5190 for (i = 0; i < INVEN_TOTAL; i++)
5192 object_type *o_ptr = &p_ptr->inventory_list[i];
5194 /* Ignore non-objects */
5195 if (!o_ptr->k_idx) continue;
5197 /* Ignore non-artifacts */
5198 if (!object_is_fixed_artifact(o_ptr)) continue;
5200 /* Ignore known items */
5201 if (object_is_known(o_ptr)) continue;
5203 /* Note the artifact */
5204 okay[o_ptr->name1] = FALSE;
5207 for (k = 0; k < max_a_idx; k++)
5209 if (okay[k]) who[n++] = k;
5212 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5214 /* Scan the artifacts */
5215 for (k = 0; k < n; k++)
5217 artifact_type *a_ptr = &a_info[who[k]];
5218 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5220 /* Obtain the base object type */
5221 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5230 /* Create fake object */
5231 object_prep(q_ptr, z);
5233 /* Make it an artifact */
5234 q_ptr->name1 = (byte)who[k];
5236 /* Display as if known */
5237 q_ptr->ident |= IDENT_STORE;
5239 /* Describe the artifact */
5240 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5243 /* Hack -- Build the artifact name */
5244 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5247 /* Free the "who" array */
5248 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5250 /* Free the "okay" array */
5251 C_KILL(okay, max_a_idx, bool);
5254 /* Display the file contents */
5255 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5261 * Display known uniques
5262 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5264 static void do_cmd_knowledge_uniques(void)
5273 GAME_TEXT file_name[1024];
5276 int n_alive_surface = 0;
5277 int n_alive_over100 = 0;
5278 int n_alive_total = 0;
5281 for (i = 0; i < 10; i++) n_alive[i] = 0;
5283 /* Open a new file */
5284 fff = my_fopen_temp(file_name, 1024);
5288 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5293 /* Allocate the "who" array */
5294 C_MAKE(who, max_r_idx, MONRACE_IDX);
5296 /* Scan the monsters */
5297 for (i = 1; i < max_r_idx; i++)
5299 monster_race *r_ptr = &r_info[i];
5302 if (!r_ptr->name) continue;
5304 /* Require unique monsters */
5305 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5307 /* Only display "known" uniques */
5308 if (!cheat_know && !r_ptr->r_sights) continue;
5310 /* Only print rarity <= 100 uniques */
5311 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5313 /* Only "alive" uniques */
5314 if (r_ptr->max_num == 0) continue;
5318 lev = (r_ptr->level - 1) / 10;
5322 if (max_lev < lev) max_lev = lev;
5324 else n_alive_over100++;
5326 else n_alive_surface++;
5328 /* Collect "appropriate" monsters */
5332 /* Sort the array by dungeon depth of monsters */
5333 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5335 if (n_alive_surface)
5337 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5338 n_alive_total += n_alive_surface;
5340 for (i = 0; i <= max_lev; i++)
5342 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5343 n_alive_total += n_alive[i];
5345 if (n_alive_over100)
5347 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5348 n_alive_total += n_alive_over100;
5353 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5354 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5358 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5361 /* Scan the monster races */
5362 for (k = 0; k < n; k++)
5364 monster_race *r_ptr = &r_info[who[k]];
5366 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5369 /* Free the "who" array */
5370 C_KILL(who, max_r_idx, s16b);
5373 /* Display the file contents */
5374 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5380 * Display weapon-exp
5382 static void do_cmd_knowledge_weapon_exp(void)
5390 GAME_TEXT file_name[1024];
5393 /* Open a new file */
5394 fff = my_fopen_temp(file_name, 1024);
5396 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5401 for (i = 0; i < 5; i++)
5403 for (num = 0; num < 64; num++)
5405 for (j = 0; j < max_k_idx; j++)
5407 object_kind *k_ptr = &k_info[j];
5409 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5411 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5413 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5415 fprintf(fff, "%-25s ", tmp);
5416 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5417 else fprintf(fff, " ");
5418 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5419 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5428 /* Display the file contents */
5429 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5435 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5439 static void do_cmd_knowledge_spell_exp(void)
5446 const magic_type *s_ptr;
5448 GAME_TEXT file_name[1024];
5450 /* Open a new file */
5451 fff = my_fopen_temp(file_name, 1024);
5453 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5458 if (p_ptr->realm1 != REALM_NONE)
5460 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5461 for (i = 0; i < 32; i++)
5463 if (!is_magic(p_ptr->realm1))
5465 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5469 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5471 if (s_ptr->slevel >= 99) continue;
5472 spell_exp = p_ptr->spell_exp[i];
5473 exp_level = spell_exp_level(spell_exp);
5474 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5475 if (p_ptr->realm1 == REALM_HISSATSU)
5476 fprintf(fff, "[--]");
5479 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5480 else fprintf(fff, " ");
5481 fprintf(fff, "%s", exp_level_str[exp_level]);
5483 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5488 if (p_ptr->realm2 != REALM_NONE)
5490 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5491 for (i = 0; i < 32; i++)
5493 if (!is_magic(p_ptr->realm1))
5495 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5499 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5501 if (s_ptr->slevel >= 99) continue;
5503 spell_exp = p_ptr->spell_exp[i + 32];
5504 exp_level = spell_exp_level(spell_exp);
5505 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5506 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5507 else fprintf(fff, " ");
5508 fprintf(fff, "%s", exp_level_str[exp_level]);
5509 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5515 /* Display the file contents */
5516 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5522 * @brief スキル情報を表示するコマンドのメインルーチン /
5526 static void do_cmd_knowledge_skill_exp(void)
5528 int i = 0, skill_exp;
5532 char file_name[1024];
5533 char skill_name[GINOU_TEMPMAX][20] =
5535 _("マーシャルアーツ", "Martial Arts "),
5536 _("二刀流 ", "Dual Wielding "),
5537 _("乗馬 ", "Riding "),
5541 /* Open a new file */
5542 fff = my_fopen_temp(file_name, 1024);
5544 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5549 for (i = 0; i < GINOU_TEMPMAX; i++)
5551 skill_exp = p_ptr->skill_exp[i];
5552 fprintf(fff, "%-20s ", skill_name[i]);
5553 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5554 else fprintf(fff, " ");
5555 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5556 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5561 /* Display the file contents */
5562 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5568 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5569 * @param Name 変換したい文字列の参照ポインタ
5572 void plural_aux(char *Name)
5574 int NameLen = strlen(Name);
5576 if (my_strstr(Name, "Disembodied hand"))
5578 strcpy(Name, "Disembodied hands that strangled people");
5580 else if (my_strstr(Name, "Colour out of space"))
5582 strcpy(Name, "Colours out of space");
5584 else if (my_strstr(Name, "stairway to hell"))
5586 strcpy(Name, "stairways to hell");
5588 else if (my_strstr(Name, "Dweller on the threshold"))
5590 strcpy(Name, "Dwellers on the threshold");
5592 else if (my_strstr(Name, " of "))
5594 concptr aider = my_strstr(Name, " of ");
5605 if (dummy[i-1] == 's')
5607 strcpy(&(dummy[i]), "es");
5612 strcpy(&(dummy[i]), "s");
5615 strcpy(&(dummy[i+1]), aider);
5616 strcpy(Name, dummy);
5618 else if (my_strstr(Name, "coins"))
5621 strcpy(dummy, "piles of ");
5622 strcat(dummy, Name);
5623 strcpy(Name, dummy);
5626 else if (my_strstr(Name, "Manes"))
5630 else if (streq(&(Name[NameLen - 2]), "ey"))
5632 strcpy(&(Name[NameLen - 2]), "eys");
5634 else if (Name[NameLen - 1] == 'y')
5636 strcpy(&(Name[NameLen - 1]), "ies");
5638 else if (streq(&(Name[NameLen - 4]), "ouse"))
5640 strcpy(&(Name[NameLen - 4]), "ice");
5642 else if (streq(&(Name[NameLen - 2]), "us"))
5644 strcpy(&(Name[NameLen - 2]), "i");
5646 else if (streq(&(Name[NameLen - 6]), "kelman"))
5648 strcpy(&(Name[NameLen - 6]), "kelmen");
5650 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5652 strcpy(&(Name[NameLen - 8]), "wordsmen");
5654 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5656 strcpy(&(Name[NameLen - 7]), "oodsmen");
5658 else if (streq(&(Name[NameLen - 7]), "eastman"))
5660 strcpy(&(Name[NameLen - 7]), "eastmen");
5662 else if (streq(&(Name[NameLen - 8]), "izardman"))
5664 strcpy(&(Name[NameLen - 8]), "izardmen");
5666 else if (streq(&(Name[NameLen - 5]), "geist"))
5668 strcpy(&(Name[NameLen - 5]), "geister");
5670 else if (streq(&(Name[NameLen - 2]), "ex"))
5672 strcpy(&(Name[NameLen - 2]), "ices");
5674 else if (streq(&(Name[NameLen - 2]), "lf"))
5676 strcpy(&(Name[NameLen - 2]), "lves");
5678 else if (suffix(Name, "ch") ||
5679 suffix(Name, "sh") ||
5680 suffix(Name, "nx") ||
5681 suffix(Name, "s") ||
5684 strcpy(&(Name[NameLen]), "es");
5688 strcpy(&(Name[NameLen]), "s");
5693 * @brief 現在のペットを表示するコマンドのメインルーチン /
5694 * Display current pets
5697 static void do_cmd_knowledge_pets(void)
5701 monster_type *m_ptr;
5702 GAME_TEXT pet_name[MAX_NLEN];
5704 int show_upkeep = 0;
5705 GAME_TEXT file_name[1024];
5708 /* Open a new file */
5709 fff = my_fopen_temp(file_name, 1024);
5711 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5716 /* Process the monsters (backwards) */
5717 for (i = m_max - 1; i >= 1; i--)
5719 /* Access the monster */
5720 m_ptr = ¤t_floor_ptr->m_list[i];
5722 /* Ignore "dead" monsters */
5723 if (!monster_is_valid(m_ptr)) continue;
5725 /* Calculate "upkeep" for pets */
5729 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5730 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5734 show_upkeep = calculate_upkeep();
5736 fprintf(fff, "----------------------------------------------\n");
5738 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5740 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5742 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5747 /* Display the file contents */
5748 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5754 * @brief 現在のペットを表示するコマンドのメインルーチン /
5757 * @note the player ghosts are ignored.
5759 static void do_cmd_knowledge_kill_count(void)
5766 GAME_TEXT file_name[1024];
5771 /* Open a new file */
5772 fff = my_fopen_temp(file_name, 1024);
5775 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5780 /* Allocate the "who" array */
5781 C_MAKE(who, max_r_idx, MONRACE_IDX);
5784 /* Monsters slain */
5787 for (kk = 1; kk < max_r_idx; kk++)
5789 monster_race *r_ptr = &r_info[kk];
5791 if (r_ptr->flags1 & (RF1_UNIQUE))
5793 bool dead = (r_ptr->max_num == 0);
5802 MONSTER_NUMBER This = r_ptr->r_pkills;
5812 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5815 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5817 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5823 /* Scan the monsters */
5824 for (i = 1; i < max_r_idx; i++)
5826 monster_race *r_ptr = &r_info[i];
5828 /* Use that monster */
5829 if (r_ptr->name) who[n++] = i;
5832 /* Sort the array by dungeon depth of monsters */
5833 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5835 /* Scan the monster races */
5836 for (k = 0; k < n; k++)
5838 monster_race *r_ptr = &r_info[who[k]];
5840 if (r_ptr->flags1 & (RF1_UNIQUE))
5842 bool dead = (r_ptr->max_num == 0);
5846 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5852 MONSTER_NUMBER This = r_ptr->r_pkills;
5857 /* p,tは人と数える by ita */
5858 if (my_strchr("pt", r_ptr->d_char))
5859 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5861 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5865 if (my_strstr(r_name + r_ptr->name, "coins"))
5867 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5871 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5877 strcpy(ToPlural, (r_name + r_ptr->name));
5878 plural_aux(ToPlural);
5879 fprintf(fff, " %d %s\n", This, ToPlural);
5889 fprintf(fff,"----------------------------------------------\n");
5891 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5893 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5897 /* Free the "who" array */
5898 C_KILL(who, max_r_idx, s16b);
5901 /* Display the file contents */
5902 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5908 * @brief モンスター情報リスト中のグループを表示する /
5909 * Display the object groups.
5913 * @param per_page リストの表示行
5914 * @param grp_idx グループのID配列
5915 * @param group_text グループ名の文字列配列
5916 * @param grp_cur 現在の選択ID
5917 * @param grp_top 現在の選択リスト最上部ID
5920 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)
5924 /* Display lines until done */
5925 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5927 /* Get the group index */
5928 int grp = grp_idx[grp_top + i];
5930 /* Choose a color */
5931 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5933 /* Erase the entire line */
5934 Term_erase(col, row + i, wid);
5936 /* Display the group label */
5937 c_put_str(attr, group_text[grp], row + i, col);
5943 * Move the cursor in a browser window
5945 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5946 IDX *list_cur, int list_cnt)
5951 IDX list = *list_cur;
5953 /* Extract direction */
5956 /* Hack -- scroll up full screen */
5961 /* Hack -- scroll down full screen */
5966 d = get_keymap_dir(ch);
5971 /* Diagonals - hack */
5972 if ((ddx[d] > 0) && ddy[d])
5977 Term_get_size(&wid, &hgt);
5979 browser_rows = hgt - 8;
5981 /* Browse group list */
5986 /* Move up or down */
5987 grp += ddy[d] * (browser_rows - 1);
5990 if (grp >= grp_cnt) grp = grp_cnt - 1;
5991 if (grp < 0) grp = 0;
5992 if (grp != old_grp) list = 0;
5995 /* Browse sub-list list */
5998 /* Move up or down */
5999 list += ddy[d] * browser_rows;
6002 if (list >= list_cnt) list = list_cnt - 1;
6003 if (list < 0) list = 0;
6015 if (col < 0) col = 0;
6016 if (col > 1) col = 1;
6023 /* Browse group list */
6028 /* Move up or down */
6032 if (grp >= grp_cnt) grp = grp_cnt - 1;
6033 if (grp < 0) grp = 0;
6034 if (grp != old_grp) list = 0;
6037 /* Browse sub-list list */
6040 /* Move up or down */
6041 list += (IDX)ddy[d];
6044 if (list >= list_cnt) list = list_cnt - 1;
6045 if (list < 0) list = 0;
6056 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6060 /* Clear the display lines */
6061 for (i = 0; i < height; i++)
6063 Term_erase(col, row + i, width);
6066 /* Bigtile mode uses double width */
6067 if (use_bigtile) width /= 2;
6069 /* Display lines until done */
6070 for (i = 0; i < height; i++)
6072 /* Display columns until done */
6073 for (j = 0; j < width; j++)
6077 TERM_LEN x = col + j;
6078 TERM_LEN y = row + i;
6080 /* Bigtile mode uses double width */
6081 if (use_bigtile) x += j;
6086 /* Ignore illegal characters */
6087 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6088 (!use_graphics && ic > 0x7f))
6094 /* Force correct code for both ASCII character and tile */
6095 if (c & 0x80) a |= 0x80;
6097 /* Display symbol */
6098 Term_queue_bigchar(x, y, a, c, 0, 0);
6105 * Place the cursor at the collect position for visual mode
6107 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6109 int i = (a & 0x7f) - attr_top;
6110 int j = c - char_left;
6112 TERM_LEN x = col + j;
6113 TERM_LEN y = row + i;
6115 /* Bigtile mode uses double width */
6116 if (use_bigtile) x += j;
6118 /* Place the cursor */
6124 * Clipboard variables for copy&paste in visual mode
6126 static TERM_COLOR attr_idx = 0;
6127 static SYMBOL_CODE char_idx = 0;
6129 /* Hack -- for feature lighting */
6130 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6131 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6134 * Do visual mode command -- Change symbols
6136 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6137 int height, int width,
6138 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6139 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6141 static TERM_COLOR attr_old = 0;
6142 static SYMBOL_CODE char_old = 0;
6147 if (*visual_list_ptr)
6150 *cur_attr_ptr = attr_old;
6151 *cur_char_ptr = char_old;
6152 *visual_list_ptr = FALSE;
6160 if (*visual_list_ptr)
6163 *visual_list_ptr = FALSE;
6164 *need_redraw = TRUE;
6172 if (!*visual_list_ptr)
6174 *visual_list_ptr = TRUE;
6176 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6177 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6179 attr_old = *cur_attr_ptr;
6180 char_old = *cur_char_ptr;
6191 /* Set the visual */
6192 attr_idx = *cur_attr_ptr;
6193 char_idx = *cur_char_ptr;
6195 /* Hack -- for feature lighting */
6196 for (i = 0; i < F_LIT_MAX; i++)
6198 attr_idx_feat[i] = 0;
6199 char_idx_feat[i] = 0;
6206 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6209 *cur_attr_ptr = attr_idx;
6210 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6211 if (!*visual_list_ptr) *need_redraw = TRUE;
6217 *cur_char_ptr = char_idx;
6218 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6219 if (!*visual_list_ptr) *need_redraw = TRUE;
6225 if (*visual_list_ptr)
6228 int d = get_keymap_dir(ch);
6229 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6230 SYMBOL_CODE c = *cur_char_ptr;
6232 if (use_bigtile) eff_width = width / 2;
6233 else eff_width = width;
6235 /* Restrict direction */
6236 if ((a == 0) && (ddy[d] < 0)) d = 0;
6237 if ((c == 0) && (ddx[d] < 0)) d = 0;
6238 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6239 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6241 a += (TERM_COLOR)ddy[d];
6242 c += (SYMBOL_CODE)ddx[d];
6244 /* Force correct code for both ASCII character and tile */
6245 if (c & 0x80) a |= 0x80;
6247 /* Set the visual */
6252 /* Move the frame */
6253 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6254 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6255 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6256 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6262 /* Visual mode command is not used */
6268 * Display the monsters in a group.
6270 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6271 int mon_cur, int mon_top, bool visual_only)
6275 /* Display lines until done */
6276 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6280 /* Get the race index */
6281 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6283 /* Access the race */
6284 monster_race *r_ptr = &r_info[r_idx];
6286 /* Choose a color */
6287 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6289 /* Display the name */
6290 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6292 /* Hack -- visual_list mode */
6295 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6297 if (p_ptr->wizard || visual_only)
6299 c_prt(attr, format("%d", r_idx), row + i, 62);
6302 /* Erase chars before overwritten by the race letter */
6303 Term_erase(69, row + i, 255);
6305 /* Display symbol */
6306 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6311 if (!(r_ptr->flags1 & RF1_UNIQUE))
6312 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6314 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6315 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6319 /* Clear remaining lines */
6320 for (; i < per_page; i++)
6322 Term_erase(col, row + i, 255);
6328 * Display known monsters.
6330 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6334 IDX grp_cur, grp_top, old_grp_cur;
6335 IDX mon_cur, mon_top;
6336 IDX grp_cnt, grp_idx[100];
6344 bool visual_list = FALSE;
6345 TERM_COLOR attr_top = 0;
6353 Term_get_size(&wid, &hgt);
6355 browser_rows = hgt - 8;
6357 /* Allocate the "mon_idx" array */
6358 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6363 if (direct_r_idx < 0)
6365 mode = visual_only ? 0x03 : 0x01;
6367 /* Check every group */
6368 for (i = 0; monster_group_text[i] != NULL; i++)
6370 /* Measure the label */
6371 len = strlen(monster_group_text[i]);
6373 /* Save the maximum length */
6374 if (len > max) max = len;
6376 /* See if any monsters are known */
6377 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6379 /* Build a list of groups with known monsters */
6380 grp_idx[grp_cnt++] = i;
6388 mon_idx[0] = direct_r_idx;
6391 /* Terminate the list */
6394 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6395 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6398 /* Terminate the list */
6399 grp_idx[grp_cnt] = -1;
6402 grp_cur = grp_top = 0;
6403 mon_cur = mon_top = 0;
6408 mode = visual_only ? 0x02 : 0x00;
6413 monster_race *r_ptr;
6418 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6419 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6420 prt(_("名前", "Name"), 4, max + 3);
6421 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6422 prt(_("文字", "Sym"), 4, 67);
6423 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6425 for (i = 0; i < 78; i++)
6427 Term_putch(i, 5, TERM_WHITE, '=');
6430 if (direct_r_idx < 0)
6432 for (i = 0; i < browser_rows; i++)
6434 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6441 if (direct_r_idx < 0)
6443 /* Scroll group list */
6444 if (grp_cur < grp_top) grp_top = grp_cur;
6445 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6447 /* Display a list of monster groups */
6448 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6450 if (old_grp_cur != grp_cur)
6452 old_grp_cur = grp_cur;
6454 /* Get a list of monsters in the current group */
6455 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6458 /* Scroll monster list */
6459 while (mon_cur < mon_top)
6460 mon_top = MAX(0, mon_top - browser_rows/2);
6461 while (mon_cur >= mon_top + browser_rows)
6462 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6467 /* Display a list of monsters in the current group */
6468 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6474 /* Display a monster name */
6475 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6477 /* Display visual list below first monster */
6478 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6482 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6483 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6484 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6485 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6488 /* Get the current monster */
6489 r_ptr = &r_info[mon_idx[mon_cur]];
6493 /* Mega Hack -- track this monster race */
6494 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6500 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6504 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6508 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6513 /* Do visual mode command if needed */
6514 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))
6516 if (direct_r_idx >= 0)
6541 /* Recall on screen */
6542 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6544 screen_roff(mon_idx[mon_cur], 0);
6555 /* Move the cursor */
6556 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6563 /* Free the "mon_idx" array */
6564 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6569 * Display the objects in a group.
6571 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6572 int object_cur, int object_top, bool visual_only)
6576 /* Display lines until done */
6577 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6579 GAME_TEXT o_name[MAX_NLEN];
6582 object_kind *flavor_k_ptr;
6584 /* Get the object index */
6585 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6587 /* Access the object */
6588 object_kind *k_ptr = &k_info[k_idx];
6590 /* Choose a color */
6591 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6592 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6595 if (!visual_only && k_ptr->flavor)
6597 /* Appearance of this object is shuffled */
6598 flavor_k_ptr = &k_info[k_ptr->flavor];
6602 /* Appearance of this object is very normal */
6603 flavor_k_ptr = k_ptr;
6608 attr = ((i + object_top == object_cur) ? cursor : attr);
6610 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6613 strip_name(o_name, k_idx);
6618 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6621 /* Display the name */
6622 c_prt(attr, o_name, row + i, col);
6624 /* Hack -- visual_list mode */
6627 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);
6629 if (p_ptr->wizard || visual_only)
6631 c_prt(attr, format("%d", k_idx), row + i, 70);
6634 a = flavor_k_ptr->x_attr;
6635 c = flavor_k_ptr->x_char;
6637 /* Display symbol */
6638 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6641 /* Clear remaining lines */
6642 for (; i < per_page; i++)
6644 Term_erase(col, row + i, 255);
6649 * Describe fake object
6651 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6654 object_type object_type_body;
6655 o_ptr = &object_type_body;
6657 object_prep(o_ptr, k_idx);
6659 /* It's fully know */
6660 o_ptr->ident |= IDENT_KNOWN;
6662 /* Track the object */
6663 /* object_actual_track(o_ptr); */
6665 /* Hack - mark as fake */
6666 /* term_obj_real = FALSE; */
6669 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6671 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6679 * Display known objects
6681 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6685 IDX grp_cur, grp_top, old_grp_cur;
6686 IDX object_old, object_cur, object_top;
6690 OBJECT_IDX *object_idx;
6696 bool visual_list = FALSE;
6697 TERM_COLOR attr_top = 0;
6705 Term_get_size(&wid, &hgt);
6707 browser_rows = hgt - 8;
6709 /* Allocate the "object_idx" array */
6710 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6715 if (direct_k_idx < 0)
6717 mode = visual_only ? 0x03 : 0x01;
6719 /* Check every group */
6720 for (i = 0; object_group_text[i] != NULL; i++)
6722 /* Measure the label */
6723 len = strlen(object_group_text[i]);
6725 /* Save the maximum length */
6726 if (len > max) max = len;
6728 /* See if any monsters are known */
6729 if (collect_objects(i, object_idx, mode))
6731 /* Build a list of groups with known monsters */
6732 grp_idx[grp_cnt++] = i;
6741 object_kind *k_ptr = &k_info[direct_k_idx];
6742 object_kind *flavor_k_ptr;
6744 if (!visual_only && k_ptr->flavor)
6746 /* Appearance of this object is shuffled */
6747 flavor_k_ptr = &k_info[k_ptr->flavor];
6751 /* Appearance of this object is very normal */
6752 flavor_k_ptr = k_ptr;
6755 object_idx[0] = direct_k_idx;
6756 object_old = direct_k_idx;
6759 /* Terminate the list */
6762 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6763 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6766 /* Terminate the list */
6767 grp_idx[grp_cnt] = -1;
6770 grp_cur = grp_top = 0;
6771 object_cur = object_top = 0;
6776 mode = visual_only ? 0x02 : 0x00;
6781 object_kind *k_ptr, *flavor_k_ptr;
6788 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6789 if (direct_k_idx < 0) prt("グループ", 4, 0);
6790 prt("名前", 4, max + 3);
6791 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6794 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6795 if (direct_k_idx < 0) prt("Group", 4, 0);
6796 prt("Name", 4, max + 3);
6797 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6801 for (i = 0; i < 78; i++)
6803 Term_putch(i, 5, TERM_WHITE, '=');
6806 if (direct_k_idx < 0)
6808 for (i = 0; i < browser_rows; i++)
6810 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6817 if (direct_k_idx < 0)
6819 /* Scroll group list */
6820 if (grp_cur < grp_top) grp_top = grp_cur;
6821 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6823 /* Display a list of object groups */
6824 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6826 if (old_grp_cur != grp_cur)
6828 old_grp_cur = grp_cur;
6830 /* Get a list of objects in the current group */
6831 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6834 /* Scroll object list */
6835 while (object_cur < object_top)
6836 object_top = MAX(0, object_top - browser_rows/2);
6837 while (object_cur >= object_top + browser_rows)
6838 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6843 /* Display a list of objects in the current group */
6844 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6848 object_top = object_cur;
6850 /* Display a list of objects in the current group */
6851 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6853 /* Display visual list below first object */
6854 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6857 /* Get the current object */
6858 k_ptr = &k_info[object_idx[object_cur]];
6860 if (!visual_only && k_ptr->flavor)
6862 /* Appearance of this object is shuffled */
6863 flavor_k_ptr = &k_info[k_ptr->flavor];
6867 /* Appearance of this object is very normal */
6868 flavor_k_ptr = k_ptr;
6873 prt(format("<方向>%s%s%s, ESC",
6874 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6875 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6876 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6879 prt(format("<dir>%s%s%s, ESC",
6880 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6881 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6882 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6888 /* Mega Hack -- track this object */
6889 if (object_cnt) object_kind_track(object_idx[object_cur]);
6891 /* The "current" object changed */
6892 if (object_old != object_idx[object_cur])
6896 /* Remember the "current" object */
6897 object_old = object_idx[object_cur];
6903 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6907 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6911 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6916 /* Do visual mode command if needed */
6917 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))
6919 if (direct_k_idx >= 0)
6944 /* Recall on screen */
6945 if (!visual_list && !visual_only && (grp_cnt > 0))
6947 desc_obj_fake(object_idx[object_cur]);
6955 /* Move the cursor */
6956 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6962 /* Free the "object_idx" array */
6963 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6968 * Display the features in a group.
6970 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6971 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6973 int lit_col[F_LIT_MAX], i, j;
6974 int f_idx_col = use_bigtile ? 62 : 64;
6976 /* Correct columns 1 and 4 */
6977 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6978 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6979 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6981 /* Display lines until done */
6982 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6985 FEAT_IDX f_idx = feat_idx[feat_top + i];
6986 feature_type *f_ptr = &f_info[f_idx];
6987 int row_i = row + i;
6989 /* Choose a color */
6990 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
6992 /* Display the name */
6993 c_prt(attr, f_name + f_ptr->name, row_i, col);
6995 /* Hack -- visual_list mode */
6998 /* Display lighting level */
6999 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7001 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));
7003 if (p_ptr->wizard || visual_only)
7005 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7008 /* Display symbol */
7009 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);
7011 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7012 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7014 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7016 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7018 /* Mega-hack -- Use non-standard colour */
7019 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7021 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7025 /* Clear remaining lines */
7026 for (; i < per_page; i++)
7028 Term_erase(col, row + i, 255);
7034 * Interact with feature visuals.
7036 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7040 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7041 FEAT_IDX feat_cur, feat_top;
7043 FEAT_IDX grp_idx[100];
7047 TERM_LEN column = 0;
7051 bool visual_list = FALSE;
7052 TERM_COLOR attr_top = 0;
7055 TERM_LEN browser_rows;
7058 TERM_COLOR attr_old[F_LIT_MAX];
7059 SYMBOL_CODE char_old[F_LIT_MAX];
7060 TERM_COLOR *cur_attr_ptr;
7061 SYMBOL_CODE *cur_char_ptr;
7063 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7064 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7066 Term_get_size(&wid, &hgt);
7068 browser_rows = hgt - 8;
7070 /* Allocate the "feat_idx" array */
7071 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7076 if (direct_f_idx < 0)
7078 /* Check every group */
7079 for (i = 0; feature_group_text[i] != NULL; i++)
7081 /* Measure the label */
7082 len = strlen(feature_group_text[i]);
7084 /* Save the maximum length */
7085 if (len > max) max = len;
7087 /* See if any features are known */
7088 if (collect_features(i, feat_idx, 0x01))
7090 /* Build a list of groups with known features */
7091 grp_idx[grp_cnt++] = i;
7099 feature_type *f_ptr = &f_info[direct_f_idx];
7101 feat_idx[0] = direct_f_idx;
7104 /* Terminate the list */
7107 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7108 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7110 for (i = 0; i < F_LIT_MAX; i++)
7112 attr_old[i] = f_ptr->x_attr[i];
7113 char_old[i] = f_ptr->x_char[i];
7117 /* Terminate the list */
7118 grp_idx[grp_cnt] = -1;
7121 grp_cur = grp_top = 0;
7122 feat_cur = feat_top = 0;
7130 feature_type *f_ptr;
7136 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7137 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7138 prt(_("名前", "Name"), 4, max + 3);
7141 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7142 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7146 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7147 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7150 for (i = 0; i < 78; i++)
7152 Term_putch(i, 5, TERM_WHITE, '=');
7155 if (direct_f_idx < 0)
7157 for (i = 0; i < browser_rows; i++)
7159 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7166 if (direct_f_idx < 0)
7168 /* Scroll group list */
7169 if (grp_cur < grp_top) grp_top = grp_cur;
7170 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7172 /* Display a list of feature groups */
7173 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7175 if (old_grp_cur != grp_cur)
7177 old_grp_cur = grp_cur;
7179 /* Get a list of features in the current group */
7180 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7183 /* Scroll feature list */
7184 while (feat_cur < feat_top)
7185 feat_top = MAX(0, feat_top - browser_rows/2);
7186 while (feat_cur >= feat_top + browser_rows)
7187 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7192 /* Display a list of features in the current group */
7193 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7197 feat_top = feat_cur;
7199 /* Display a list of features in the current group */
7200 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7202 /* Display visual list below first object */
7203 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7207 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7208 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7209 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7212 /* Get the current feature */
7213 f_ptr = &f_info[feat_idx[feat_cur]];
7214 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7215 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7219 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7223 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7227 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7232 if (visual_list && ((ch == 'A') || (ch == 'a')))
7234 int prev_lighting_level = *lighting_level;
7238 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7239 else (*lighting_level)--;
7243 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7244 else (*lighting_level)++;
7247 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7248 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7250 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7251 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7256 else if ((ch == 'D') || (ch == 'd'))
7258 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7259 byte prev_x_char = f_ptr->x_char[*lighting_level];
7261 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7265 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7266 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7268 if (prev_x_char != f_ptr->x_char[*lighting_level])
7269 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7271 else *need_redraw = TRUE;
7276 /* Do visual mode command if needed */
7277 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))
7281 /* Restore previous visual settings */
7283 for (i = 0; i < F_LIT_MAX; i++)
7285 f_ptr->x_attr[i] = attr_old[i];
7286 f_ptr->x_char[i] = char_old[i];
7293 if (direct_f_idx >= 0) flag = TRUE;
7294 else *lighting_level = F_LIT_STANDARD;
7297 /* Preserve current visual settings */
7300 for (i = 0; i < F_LIT_MAX; i++)
7302 attr_old[i] = f_ptr->x_attr[i];
7303 char_old[i] = f_ptr->x_char[i];
7305 *lighting_level = F_LIT_STANDARD;
7312 for (i = 0; i < F_LIT_MAX; i++)
7314 attr_idx_feat[i] = f_ptr->x_attr[i];
7315 char_idx_feat[i] = f_ptr->x_char[i];
7324 /* Allow TERM_DARK text */
7325 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7327 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7328 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7346 /* Move the cursor */
7347 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7353 /* Free the "feat_idx" array */
7354 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7359 * List wanted monsters
7361 static void do_cmd_knowledge_kubi(void)
7366 GAME_TEXT file_name[1024];
7369 /* Open a new file */
7370 fff = my_fopen_temp(file_name, 1024);
7372 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7379 bool listed = FALSE;
7381 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7382 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7384 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7385 fprintf(fff, "----------------------------------------------\n");
7387 for (i = 0; i < MAX_KUBI; i++)
7389 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7391 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7399 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7404 /* Display the file contents */
7405 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7410 * List virtues & status
7412 static void do_cmd_knowledge_virtues(void)
7415 GAME_TEXT file_name[1024];
7417 /* Open a new file */
7418 fff = my_fopen_temp(file_name, 1024);
7420 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7427 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7432 /* Display the file contents */
7433 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7440 static void do_cmd_knowledge_dungeon(void)
7444 GAME_TEXT file_name[1024];
7447 /* Open a new file */
7448 fff = my_fopen_temp(file_name, 1024);
7450 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7457 for (i = 1; i < max_d_idx; i++)
7461 if (!d_info[i].maxdepth) continue;
7462 if (!max_dlv[i]) continue;
7463 if (d_info[i].final_guardian)
7465 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7467 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7469 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7474 /* Display the file contents */
7475 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7480 * List virtues & status
7483 static void do_cmd_knowledge_stat(void)
7487 GAME_TEXT file_name[1024];
7490 /* Open a new file */
7491 fff = my_fopen_temp(file_name, 1024);
7493 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7500 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7501 (2 * p_ptr->hitdie +
7502 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7504 if (p_ptr->knowledge & KNOW_HPRATE)
7505 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7506 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7508 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7509 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7511 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);
7512 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7519 /* Display the file contents */
7520 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7526 * Print all active quests
7528 static void do_cmd_knowledge_quests_current(FILE *fff)
7531 char rand_tmp_str[120] = "\0";
7532 GAME_TEXT name[MAX_NLEN];
7533 monster_race *r_ptr;
7535 int rand_level = 100;
7538 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7540 for (i = 1; i < max_q_idx; i++)
7542 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7543 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7544 (quest[i].status == QUEST_STATUS_COMPLETED))
7546 /* Set the quest number temporary */
7547 QUEST_IDX old_quest = p_ptr->inside_quest;
7550 /* Clear the text */
7551 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7552 quest_text_line = 0;
7554 p_ptr->inside_quest = i;
7556 /* Get the quest text */
7557 init_flags = INIT_SHOW_TEXT;
7559 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7561 /* Reset the old quest number */
7562 p_ptr->inside_quest = old_quest;
7564 /* No info from "silent" quests */
7565 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7569 if (quest[i].type != QUEST_TYPE_RANDOM)
7571 char note[80] = "\0";
7573 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7575 switch (quest[i].type)
7577 case QUEST_TYPE_KILL_LEVEL:
7578 case QUEST_TYPE_KILL_ANY_LEVEL:
7579 r_ptr = &r_info[quest[i].r_idx];
7580 strcpy(name, r_name + r_ptr->name);
7581 if (quest[i].max_num > 1)
7584 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7585 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7588 sprintf(note," - kill %d %s, have killed %d.",
7589 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7593 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7596 case QUEST_TYPE_FIND_ARTIFACT:
7599 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7601 object_type *q_ptr = &forge;
7602 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7603 object_prep(q_ptr, k_idx);
7604 q_ptr->name1 = quest[i].k_idx;
7605 q_ptr->ident = IDENT_STORE;
7606 object_desc(name, q_ptr, OD_NAME_ONLY);
7608 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7610 case QUEST_TYPE_FIND_EXIT:
7611 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7614 case QUEST_TYPE_KILL_NUMBER:
7616 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7617 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7619 sprintf(note," - Kill %d monsters, have killed %d.",
7620 (int)quest[i].max_num, (int)quest[i].cur_num);
7624 case QUEST_TYPE_KILL_ALL:
7625 case QUEST_TYPE_TOWER:
7626 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7631 /* Print the quest info */
7632 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7633 quest[i].name, (int)quest[i].level, note);
7635 fputs(tmp_str, fff);
7637 if (quest[i].status == QUEST_STATUS_COMPLETED)
7639 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7640 fputs(tmp_str, fff);
7646 while (quest_text[j][0] && j < 10)
7648 fprintf(fff, " %s\n", quest_text[j]);
7653 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7656 rand_level = quest[i].level;
7658 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7660 /* Print the quest info */
7661 r_ptr = &r_info[quest[i].r_idx];
7662 strcpy(name, r_name + r_ptr->name);
7664 if (quest[i].max_num > 1)
7667 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7668 quest[i].name, (int)quest[i].level,
7669 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7673 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7674 quest[i].name, (int)quest[i].level,
7675 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7680 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7681 quest[i].name, (int)quest[i].level, name);
7688 /* Print the current random quest */
7689 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7691 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7695 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7698 char playtime_str[16];
7699 quest_type* const q_ptr = &quest[q_idx];
7701 if (is_fixed_quest_idx(q_idx))
7703 /* Set the quest number temporary */
7704 IDX old_quest = p_ptr->inside_quest;
7706 p_ptr->inside_quest = q_idx;
7709 init_flags = INIT_NAME_ONLY;
7711 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7713 /* Reset the old quest number */
7714 p_ptr->inside_quest = old_quest;
7716 /* No info from "silent" quests */
7717 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7720 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7721 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7723 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7725 /* Print the quest info */
7726 if (q_ptr->complev == 0)
7729 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7730 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7731 r_name+r_info[q_ptr->r_idx].name,
7732 (int)q_ptr->level, playtime_str);
7737 _(" %-35s (%3d階) - レベル%2d - %s\n",
7738 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7739 r_name+r_info[q_ptr->r_idx].name,
7747 /* Print the quest info */
7749 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7750 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7751 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7754 fputs(tmp_str, fff);
7760 * Print all finished quests
7762 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7765 QUEST_IDX total = 0;
7767 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7768 for (i = 1; i < max_q_idx; i++)
7770 QUEST_IDX q_idx = quest_num[i];
7771 quest_type* const q_ptr = &quest[q_idx];
7773 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7778 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7783 * Print all failed quests
7785 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7788 QUEST_IDX total = 0;
7790 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7791 for (i = 1; i < max_q_idx; i++)
7793 QUEST_IDX q_idx = quest_num[i];
7794 quest_type* const q_ptr = &quest[q_idx];
7796 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7797 do_cmd_knowledge_quests_aux(fff, q_idx))
7802 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7807 * Print all random quests
7809 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7811 GAME_TEXT tmp_str[120];
7813 QUEST_IDX total = 0;
7815 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7816 for (i = 1; i < max_q_idx; i++)
7818 /* No info from "silent" quests */
7819 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7821 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7825 /* Print the quest info */
7826 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7827 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7828 fputs(tmp_str, fff);
7831 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7835 * Print quest status of all active quests
7837 static void do_cmd_knowledge_quests(void)
7840 GAME_TEXT file_name[1024];
7845 /* Open a new file */
7846 fff = my_fopen_temp(file_name, 1024);
7849 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7854 /* Allocate Memory */
7855 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7857 /* Sort by compete level */
7858 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7859 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7861 /* Dump Quest Information */
7862 do_cmd_knowledge_quests_current(fff);
7864 do_cmd_knowledge_quests_completed(fff, quest_num);
7866 do_cmd_knowledge_quests_failed(fff, quest_num);
7870 do_cmd_knowledge_quests_wiz_random(fff);
7874 /* Display the file contents */
7875 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7879 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7886 static void do_cmd_knowledge_home(void)
7891 GAME_TEXT file_name[1024];
7893 GAME_TEXT o_name[MAX_NLEN];
7894 concptr paren = ")";
7896 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7898 /* Open a new file */
7899 fff = my_fopen_temp(file_name, 1024);
7901 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7908 /* Print all homes in the different towns */
7909 st_ptr = &town_info[1].store[STORE_HOME];
7911 /* Home -- if anything there */
7912 if (st_ptr->stock_num)
7917 /* Header with name of the town */
7918 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7920 /* Dump all available items */
7921 for (i = 0; i < st_ptr->stock_num; i++)
7924 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7925 object_desc(o_name, &st_ptr->stock[i], 0);
7926 if (strlen(o_name) <= 80-3)
7928 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7934 for (n = 0, t = o_name; n < 80-3; n++, t++)
7935 if(iskanji(*t)) {t++; n++;}
7936 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7938 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7939 fprintf(fff, " %.77s\n", o_name+n);
7942 object_desc(o_name, &st_ptr->stock[i], 0);
7943 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7948 /* Add an empty line */
7949 fprintf(fff, "\n\n");
7954 /* Display the file contents */
7955 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7961 * Check the status of "autopick"
7963 static void do_cmd_knowledge_autopick(void)
7967 GAME_TEXT file_name[1024];
7969 /* Open a new file */
7970 fff = my_fopen_temp(file_name, 1024);
7974 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7981 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7985 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7986 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7989 for (k = 0; k < max_autopick; k++)
7992 byte act = autopick_list[k].action;
7993 if (act & DONT_AUTOPICK)
7995 tmp = _("放置", "Leave");
7997 else if (act & DO_AUTODESTROY)
7999 tmp = _("破壊", "Destroy");
8001 else if (act & DO_AUTOPICK)
8003 tmp = _("拾う", "Pickup");
8007 tmp = _("確認", "Query");
8010 if (act & DO_DISPLAY)
8011 fprintf(fff, "%11s", format("[%s]", tmp));
8013 fprintf(fff, "%11s", format("(%s)", tmp));
8015 tmp = autopick_line_from_entry(&autopick_list[k]);
8016 fprintf(fff, " %s", tmp);
8021 /* Display the file contents */
8022 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8028 * Interact with "knowledge"
8030 void do_cmd_knowledge(void)
8033 bool need_redraw = FALSE;
8035 /* File type is "TEXT" */
8036 FILE_TYPE(FILE_TYPE_TEXT);
8039 /* Interact until done */
8044 /* Ask for a choice */
8045 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8046 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8048 /* Give some choices */
8052 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8053 prt("(2) 既知のアイテム の一覧", 7, 5);
8054 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8055 prt("(4) 既知のモンスター の一覧", 9, 5);
8056 prt("(5) 倒した敵の数 の一覧", 10, 5);
8057 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8058 prt("(7) 現在のペット の一覧", 12, 5);
8059 prt("(8) 我が家のアイテム の一覧", 13, 5);
8060 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8061 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8065 prt("(a) 自分に関する情報 の一覧", 6, 5);
8066 prt("(b) 突然変異 の一覧", 7, 5);
8067 prt("(c) 武器の経験値 の一覧", 8, 5);
8068 prt("(d) 魔法の経験値 の一覧", 9, 5);
8069 prt("(e) 技能の経験値 の一覧", 10, 5);
8070 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8071 prt("(g) 入ったダンジョン の一覧", 12, 5);
8072 prt("(h) 実行中のクエスト の一覧", 13, 5);
8073 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8078 prt("(1) Display known artifacts", 6, 5);
8079 prt("(2) Display known objects", 7, 5);
8080 prt("(3) Display remaining uniques", 8, 5);
8081 prt("(4) Display known monster", 9, 5);
8082 prt("(5) Display kill count", 10, 5);
8083 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8084 prt("(7) Display current pets", 12, 5);
8085 prt("(8) Display home p_ptr->inventory_list", 13, 5);
8086 prt("(9) Display *identified* equip.", 14, 5);
8087 prt("(0) Display terrain symbols.", 15, 5);
8091 prt("(a) Display about yourself", 6, 5);
8092 prt("(b) Display mutations", 7, 5);
8093 prt("(c) Display weapon proficiency", 8, 5);
8094 prt("(d) Display spell proficiency", 9, 5);
8095 prt("(e) Display misc. proficiency", 10, 5);
8096 prt("(f) Display virtues", 11, 5);
8097 prt("(g) Display dungeons", 12, 5);
8098 prt("(h) Display current quests", 13, 5);
8099 prt("(i) Display auto pick/destroy", 14, 5);
8103 prt(_("-続く-", "-more-"), 17, 8);
8104 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8105 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8106 /*prt("-) 前ページ", 21, 60);*/
8107 prt(_("コマンド:", "Command: "), 20, 0);
8110 if (i == ESCAPE) break;
8113 case ' ': /* Page change */
8117 case '1': /* Artifacts */
8118 do_cmd_knowledge_artifacts();
8120 case '2': /* Objects */
8121 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8123 case '3': /* Uniques */
8124 do_cmd_knowledge_uniques();
8126 case '4': /* Monsters */
8127 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8129 case '5': /* Kill count */
8130 do_cmd_knowledge_kill_count();
8132 case '6': /* wanted */
8133 if (!vanilla_town) do_cmd_knowledge_kubi();
8135 case '7': /* Pets */
8136 do_cmd_knowledge_pets();
8138 case '8': /* Home */
8139 do_cmd_knowledge_home();
8141 case '9': /* Resist list */
8142 do_cmd_knowledge_inven();
8144 case '0': /* Feature list */
8146 IDX lighting_level = F_LIT_STANDARD;
8147 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8151 case 'a': /* Max stat */
8152 do_cmd_knowledge_stat();
8154 case 'b': /* Mutations */
8155 do_cmd_knowledge_mutations();
8157 case 'c': /* weapon-exp */
8158 do_cmd_knowledge_weapon_exp();
8160 case 'd': /* spell-exp */
8161 do_cmd_knowledge_spell_exp();
8163 case 'e': /* skill-exp */
8164 do_cmd_knowledge_skill_exp();
8166 case 'f': /* Virtues */
8167 do_cmd_knowledge_virtues();
8169 case 'g': /* Dungeon */
8170 do_cmd_knowledge_dungeon();
8172 case 'h': /* Quests */
8173 do_cmd_knowledge_quests();
8175 case 'i': /* Autopick */
8176 do_cmd_knowledge_autopick();
8178 default: /* Unknown option */
8186 if (need_redraw) do_cmd_redraw();
8191 * Check on the status of an active quest
8193 void do_cmd_checkquest(void)
8195 /* File type is "TEXT" */
8196 FILE_TYPE(FILE_TYPE_TEXT);
8200 do_cmd_knowledge_quests();
8206 * Display the time and date
8208 void do_cmd_time(void)
8210 int day, hour, min, full, start, end, num;
8218 extract_day_hour_min(&day, &hour, &min);
8220 full = hour * 100 + min;
8227 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8229 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8230 else strcpy(day_buf, "*****");
8232 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8233 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8236 if (!randint0(10) || p_ptr->image)
8238 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8242 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8245 /* Open this file */
8246 fff = my_fopen(buf, "rt");
8250 /* Find this time */
8251 while (!my_fgets(fff, buf, sizeof(buf)))
8253 /* Ignore comments */
8254 if (!buf[0] || (buf[0] == '#')) continue;
8256 /* Ignore invalid lines */
8257 if (buf[1] != ':') continue;
8259 /* Process 'Start' */
8262 /* Extract the starting time */
8263 start = atoi(buf + 2);
8265 /* Assume valid for an hour */
8275 /* Extract the ending time */
8276 end = atoi(buf + 2);
8282 /* Ignore incorrect range */
8283 if ((start > full) || (full > end)) continue;
8285 /* Process 'Description' */
8290 /* Apply the randomizer */
8291 if (!randint0(num)) strcpy(desc, buf + 2);