3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
45 #include "player-status.h"
52 #include "object-hook.h"
54 #include "monster-status.h"
61 * Mark strings for auto dump
63 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
64 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
67 * Variables for auto dump
69 static FILE *auto_dump_stream;
70 static concptr auto_dump_mark;
71 static int auto_dump_line_num;
75 * @brief prf出力内容を消去する /
76 * Remove old lines automatically generated before.
77 * @param orig_file 消去を行うファイル名
79 static void remove_auto_dump(concptr orig_file)
81 FILE *tmp_fff, *orig_fff;
85 bool between_mark = FALSE;
88 long header_location = 0;
89 char header_mark_str[80];
90 char footer_mark_str[80];
93 /* Prepare a header/footer mark string */
94 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
95 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
97 mark_len = strlen(footer_mark_str);
99 /* Open an old dump file in read-only mode */
100 orig_fff = my_fopen(orig_file, "r");
102 /* If original file does not exist, nothing to do */
103 if (!orig_fff) return;
105 /* Open a new (temporary) file */
106 tmp_fff = my_fopen_temp(tmp_file, 1024);
110 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
115 /* Loop for every line */
119 if (my_fgets(orig_fff, buf, sizeof(buf)))
121 /* Read error: Assume End of File */
124 * Was looking for the footer, but not found.
126 * Since automatic dump might be edited by hand,
127 * it's dangerous to kill these lines.
128 * Seek back to the next line of the (pseudo) header,
133 fseek(orig_fff, header_location, SEEK_SET);
134 between_mark = FALSE;
138 /* Success -- End the loop */
145 /* We are looking for the header mark of automatic dump */
148 /* Is this line a header? */
149 if (!strcmp(buf, header_mark_str))
151 /* Memorise seek point of this line */
152 header_location = ftell(orig_fff);
154 /* Initialize counter for number of lines */
157 /* Look for the footer from now */
160 /* There are some changes */
167 /* Copy orginally lines */
168 fprintf(tmp_fff, "%s\n", buf);
172 /* We are looking for the footer mark of automatic dump */
175 /* Is this line a footer? */
176 if (!strncmp(buf, footer_mark_str, mark_len))
181 * Compare the number of lines
183 * If there is an inconsistency between
184 * actual number of lines and the
185 * number here, the automatic dump
186 * might be edited by hand. So it's
187 * dangerous to kill these lines.
188 * Seek back to the next line of the
189 * (pseudo) header, and read again.
191 if (!sscanf(buf + mark_len, " (%d)", &tmp)
194 fseek(orig_fff, header_location, SEEK_SET);
197 /* Look for another header */
198 between_mark = FALSE;
204 /* Ignore old line, and count number of lines */
214 /* If there are some changes, overwrite the original file with new one */
217 /* Copy contents of temporary file */
219 tmp_fff = my_fopen(tmp_file, "r");
220 orig_fff = my_fopen(orig_file, "w");
222 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
223 fprintf(orig_fff, "%s\n", buf);
229 /* Kill the temporary file */
237 * @brief prfファイルのフォーマットに従った内容を出力する /
238 * Dump a formatted line, using "vstrnfmt()".
241 static void auto_dump_printf(concptr fmt, ...)
248 /* Begin the Varargs Stuff */
251 /* Format the args, save the length */
252 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
254 /* End the Varargs Stuff */
257 /* Count number of lines */
258 for (p = buf; *p; p++)
260 if (*p == '\n') auto_dump_line_num++;
264 fprintf(auto_dump_stream, "%s", buf);
269 * @brief prfファイルをファイルオープンする /
270 * Open file to append auto dump.
272 * @param mark 出力するヘッダマーク
273 * @return ファイルポインタを取得できたらTRUEを返す
275 static bool open_auto_dump(concptr buf, concptr mark)
278 char header_mark_str[80];
280 /* Save the mark string */
281 auto_dump_mark = mark;
283 /* Prepare a header mark string */
284 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
286 /* Remove old macro dumps */
287 remove_auto_dump(buf);
289 /* Append to the file */
290 auto_dump_stream = my_fopen(buf, "a");
293 if (!auto_dump_stream) {
294 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
302 fprintf(auto_dump_stream, "%s\n", header_mark_str);
304 /* Initialize counter */
305 auto_dump_line_num = 0;
307 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
308 "# *Warning!* The lines below are an automatic dump.\n"));
309 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
310 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
316 * @brief prfファイルをファイルクローズする /
317 * Append foot part and close auto dump.
320 static void close_auto_dump(void)
322 char footer_mark_str[80];
324 /* Prepare a footer mark string */
325 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
327 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
328 "# *Warning!* The lines below are an automatic dump.\n"));
329 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
330 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
332 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
335 my_fclose(auto_dump_stream);
344 * @brief Return suffix of ordinal number
346 * @return pointer of suffix string.
348 concptr get_ordinal_number_suffix(int num)
350 num = ABS(num) % 100;
354 return (num == 11) ? "th" : "st";
356 return (num == 12) ? "th" : "nd";
358 return (num == 13) ? "th" : "rd";
367 * @brief 日記にメッセージを追加する /
368 * Take note to the diary.
369 * @param type 日記内容のID
370 * @param num 日記内容のIDに応じた数値
371 * @param note 日記内容のIDに応じた文字列参照ポインタ
374 errr do_cmd_write_nikki(int type, int num, concptr note)
378 GAME_TEXT file_name[MAX_NLEN];
380 concptr note_level = "";
381 bool do_level = TRUE;
382 char note_level_buf[40];
385 static bool disable_nikki = FALSE;
387 extract_day_hour_min(&day, &hour, &min);
389 if (disable_nikki) return(-1);
391 if (type == NIKKI_FIX_QUEST_C ||
392 type == NIKKI_FIX_QUEST_F ||
393 type == NIKKI_RAND_QUEST_C ||
394 type == NIKKI_RAND_QUEST_F ||
395 type == NIKKI_TO_QUEST)
399 old_quest = p_ptr->inside_quest;
400 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
402 /* Get the quest text */
403 init_flags = INIT_NAME_ONLY;
405 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
407 /* Reset the old quest number */
408 p_ptr->inside_quest = old_quest;
411 /* different filne name to avoid mixing */
412 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
414 /* Build the filename */
415 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
417 /* File type is "TEXT" */
418 FILE_TYPE(FILE_TYPE_TEXT);
420 fff = my_fopen(buf, "a");
425 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
431 q_idx = quest_number(current_floor_ptr->dun_level);
435 if (p_ptr->inside_arena)
436 note_level = _("アリーナ:", "Arena:");
437 else if (!current_floor_ptr->dun_level)
438 note_level = _("地上:", "Surface:");
439 else if (q_idx && (is_fixed_quest_idx(q_idx)
440 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
441 note_level = _("クエスト:", "Quest:");
445 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
447 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
449 note_level = note_level_buf;
457 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
458 else fputs(_("*****日目\n", "Day *****\n"), fff);
466 fprintf(fff, "%s\n",note);
470 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
475 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
478 case NIKKI_ART_SCROLL:
480 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
485 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
488 case NIKKI_FIX_QUEST_C:
490 if (quest[num].flags & QUEST_FLAG_SILENT) break;
491 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
492 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
495 case NIKKI_FIX_QUEST_F:
497 if (quest[num].flags & QUEST_FLAG_SILENT) break;
498 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
499 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
502 case NIKKI_RAND_QUEST_C:
504 GAME_TEXT name[MAX_NLEN];
505 strcpy(name, r_name+r_info[quest[num].r_idx].name);
506 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
507 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
510 case NIKKI_RAND_QUEST_F:
512 GAME_TEXT name[MAX_NLEN];
513 strcpy(name, r_name+r_info[quest[num].r_idx].name);
514 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
515 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
518 case NIKKI_MAXDEAPTH:
520 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
521 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
522 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
523 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
528 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
529 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
530 _(d_name + d_info[num].name, (int)max_dlv[num]),
531 _((int)max_dlv[num], d_name + d_info[num].name));
537 if (q_idx && (is_fixed_quest_idx(q_idx)
538 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
540 to = _("地上", "the surface");
544 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
545 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
547 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
553 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
554 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
555 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
557 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
562 if (quest[num].flags & QUEST_FLAG_SILENT) break;
563 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
564 hour, min, note_level, quest[num].name);
569 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s got out using teleport level.\n"),
570 hour, min, note_level);
575 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
580 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
588 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
589 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
592 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
593 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
595 if (num == MAX_ARENA_MONS)
597 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
598 " won all fights to become a Champion.\n"));
605 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
611 if (!current_floor_ptr->dun_level)
612 to = _("地上", "the surface");
614 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
616 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
617 " %2d:%02d %20s wizard-teleported to %s.\n"), hour, min, note_level, to);
623 if (!current_floor_ptr->dun_level)
624 to = _("地上", "the surface");
626 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
628 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
629 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
634 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
637 case NIKKI_GAMESTART:
639 time_t ct = time((time_t*)0);
643 fprintf(fff, "%s %s",note, ctime(&ct));
646 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
649 case NIKKI_NAMED_PET:
651 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
654 case RECORD_NAMED_PET_NAME:
655 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
657 case RECORD_NAMED_PET_UNNAME:
658 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
660 case RECORD_NAMED_PET_DISMISS:
661 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
663 case RECORD_NAMED_PET_DEATH:
664 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
666 case RECORD_NAMED_PET_MOVED:
667 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
669 case RECORD_NAMED_PET_LOST_SIGHT:
670 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
672 case RECORD_NAMED_PET_DESTROY:
673 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
675 case RECORD_NAMED_PET_EARTHQUAKE:
676 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
678 case RECORD_NAMED_PET_GENOCIDE:
679 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
681 case RECORD_NAMED_PET_WIZ_ZAP:
682 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
684 case RECORD_NAMED_PET_TELE_LEVEL:
685 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
687 case RECORD_NAMED_PET_BLAST:
688 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
690 case RECORD_NAMED_PET_HEAL_LEPER:
691 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
693 case RECORD_NAMED_PET_COMPACT:
694 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
696 case RECORD_NAMED_PET_LOSE_PARENT:
697 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
708 case NIKKI_WIZARD_LOG:
709 fprintf(fff, "%s\n", note);
718 if (do_level) write_level = FALSE;
724 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
727 * @brief 日記のタイトル表記と内容出力 /
730 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
732 static void do_cmd_disp_nikki(void)
734 char nikki_title[256];
735 GAME_TEXT file_name[MAX_NLEN];
740 static const char subtitle[][30] = {"最強の肉体を求めて",
771 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
772 "Attack is the best form of defence.",
774 "An unexpected windfall",
775 "A drowning man will catch at a straw",
776 "Don't count your chickens before they are hatched.",
777 "It is no use crying over spilt milk.",
778 "Seeing is believing.",
779 "Strike the iron while it is hot.",
780 "I don't care what follows.",
781 "To dig a well to put out a house on fire.",
782 "Tomorrow is another day.",
783 "Easy come, easy go.",
784 "The more haste, the less speed.",
785 "Where there is life, there is hope.",
786 "There is no royal road to *WINNER*.",
787 "Danger past, God forgotten.",
788 "The best thing to do now is to run away.",
789 "Life is but an empty dream.",
790 "Dead men tell no tales.",
791 "A book that remains shut is but a block.",
792 "Misfortunes never come singly.",
793 "A little knowledge is a dangerous thing.",
794 "History repeats itself.",
795 "*WINNER* was not built in a day.",
796 "Ignorance is bliss.",
797 "To lose is to win?",
798 "No medicine can cure folly.",
799 "All good things come to an end.",
800 "M$ Empire strikes back.",
801 "To see is to believe",
803 "Quest of The World's Greatest Brain"};
805 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
807 /* Build the filename */
808 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
810 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
811 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
812 else if (IS_WIZARD_CLASS())
813 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
814 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
817 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
819 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
822 /* Display the file contents */
823 show_file(FALSE, buf, nikki_title, -1, 0);
827 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
830 static void do_cmd_bunshou(void)
833 char bunshou[80] = "\0";
835 if (get_string(_("内容: ", "diary note: "), tmp, 79))
837 strcpy(bunshou, tmp);
839 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
844 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
847 static void do_cmd_last_get(void)
852 if (record_o_name[0] == '\0') return;
854 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
855 if (!get_check(buf)) return;
857 turn_tmp = current_world_ptr->game_turn;
858 current_world_ptr->game_turn = record_turn;
859 sprintf(buf,_("%sを手に入れた。", "discovered %s."), record_o_name);
860 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
861 current_world_ptr->game_turn = turn_tmp;
865 * @brief ファイル中の全日記記録を消去する /
868 static void do_cmd_erase_nikki(void)
870 GAME_TEXT file_name[MAX_NLEN];
874 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
875 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
877 /* Build the filename */
878 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
881 fff = my_fopen(buf, "w");
884 msg_format(_("記録を消去しました。", "deleted record."));
886 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
895 void do_cmd_nikki(void)
899 /* File type is "TEXT" */
900 FILE_TYPE(FILE_TYPE_TEXT);
903 /* Interact until done */
908 /* Ask for a choice */
909 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
911 /* Give some choices */
912 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
913 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
914 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
915 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
917 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
920 prt(_("コマンド:", "Command: "), 18, 0);
925 if (i == ESCAPE) break;
939 do_cmd_erase_nikki();
943 prepare_movie_hooks();
945 default: /* Unknown option */
955 * @brief 画面を再描画するコマンドのメインルーチン
956 * Hack -- redraw the screen
960 * This command performs various low level updates, clears all the "extra"
961 * windows, does a total redraw of the main window, and requests all of the
962 * interesting updates and redraws that I can think of.
964 * This command is also used to "instantiate" the results of the user
965 * selecting various things, such as graphics mode, so it must call
966 * the "TERM_XTRA_REACT" hook before redrawing the windows.
969 void do_cmd_redraw(void)
975 /* Hack -- react to changes */
976 Term_xtra(TERM_XTRA_REACT, 0);
978 /* Combine and Reorder the pack (later) */
979 p_ptr->update |= (PU_COMBINE | PU_REORDER);
980 p_ptr->update |= (PU_TORCH);
981 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
982 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
983 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
984 p_ptr->update |= (PU_MONSTERS);
986 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
988 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
989 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
995 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
998 /* Redraw every window */
999 for (j = 0; j < 8; j++)
1002 if (!angband_term[j]) continue;
1005 Term_activate(angband_term[j]);
1014 * @brief 名前を変更するコマンドのメインルーチン
1015 * Hack -- change name
1018 void do_cmd_change_name(void)
1033 /* Display the player */
1034 display_player(mode);
1039 display_player(mode);
1044 Term_putstr(2, 23, -1, TERM_WHITE,
1045 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1047 Term_putstr(2, 23, -1, TERM_WHITE,
1048 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1056 if (c == ESCAPE) break;
1063 /* Process the player name */
1064 process_player_name(FALSE);
1070 sprintf(tmp, "%s.txt", player_base);
1071 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1073 if (tmp[0] && (tmp[0] != ' '))
1075 file_character(tmp);
1093 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1100 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1101 * Recall the most recent message
1104 void do_cmd_message_one(void)
1106 /* Recall one message */
1107 prt(format("> %s", message_str(0)), 0, 0);
1112 * @brief メッセージのログを表示するコマンドのメインルーチン
1113 * Recall the most recent message
1117 * Show previous messages to the user -BEN-
1119 * The screen format uses line 0 and 23 for headers and prompts,
1120 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1122 * This command shows you which commands you are viewing, and allows
1123 * you to "search" for strings in the recall.
1125 * Note that messages may be longer than 80 characters, but they are
1126 * displayed using "infinite" length, with a special sub-command to
1127 * "slide" the virtual display to the left or right.
1129 * Attempt to only hilite the matching portions of the string.
1132 void do_cmd_messages(int num_now)
1136 char shower_str[81];
1137 char finder_str[81];
1139 concptr shower = NULL;
1143 Term_get_size(&wid, &hgt);
1145 /* Number of message lines in a screen */
1146 num_lines = hgt - 4;
1149 strcpy(finder_str, "");
1152 strcpy(shower_str, "");
1154 /* Total messages */
1157 /* Start on first message */
1162 /* Process requests until done */
1168 /* Dump up to 20 lines of messages */
1169 for (j = 0; (j < num_lines) && (i + j < n); j++)
1171 concptr msg = message_str(i+j);
1173 /* Dump the messages, bottom to top */
1174 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1176 /* Hilite "shower" */
1177 if (shower && shower[0])
1181 /* Display matches */
1182 while ((str = my_strstr(str, shower)) != NULL)
1184 int len = strlen(shower);
1186 /* Display the match */
1187 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1195 /* Erase remaining lines */
1196 for (; j < num_lines; j++)
1198 Term_erase(0, num_lines + 1 - j, 255);
1201 /* Display header */
1203 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1204 i, i + j - 1, n), 0, 0);
1206 /* Display prompt (not very informative) */
1207 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1208 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1210 skey = inkey_special(TRUE);
1212 /* Exit on Escape */
1213 if (skey == ESCAPE) break;
1215 /* Hack -- Save the old index */
1220 /* Hack -- handle show */
1223 prt(_("強調: ", "Show: "), hgt - 1, 0);
1225 /* Get a "shower" string, or continue */
1226 strcpy(back_str, shower_str);
1227 if (askfor(shower_str, 80))
1230 shower = shower_str[0] ? shower_str : NULL;
1232 else strcpy(shower_str, back_str);
1236 /* Hack -- handle find */
1243 prt(_("検索: ", "Find: "), hgt - 1, 0);
1245 /* Get a "finder" string, or continue */
1246 strcpy(back_str, finder_str);
1247 if (!askfor(finder_str, 80))
1249 strcpy(finder_str, back_str);
1252 else if (!finder_str[0])
1254 shower = NULL; /* Stop showing */
1259 shower = finder_str;
1262 for (z = i + 1; z < n; z++)
1264 concptr msg = message_str(z);
1267 if (my_strstr(msg, finder_str))
1278 /* Recall 1 older message */
1280 /* Go to the oldest line */
1284 /* Recall 1 newer message */
1286 /* Go to the newest line */
1290 /* Recall 1 older message */
1295 /* Go older if legal */
1296 i = MIN(i + 1, n - num_lines);
1299 /* Recall 10 older messages */
1301 /* Go older if legal */
1302 i = MIN(i + 10, n - num_lines);
1305 /* Recall 20 older messages */
1310 /* Go older if legal */
1311 i = MIN(i + num_lines, n - num_lines);
1314 /* Recall 20 newer messages */
1318 /* Go newer (if able) */
1319 i = MAX(0, i - num_lines);
1322 /* Recall 10 newer messages */
1324 /* Go newer (if able) */
1328 /* Recall 1 newer messages */
1331 /* Go newer (if able) */
1336 /* Hack -- Error of some kind */
1344 * @brief チートオプションを変更するコマンドのメインルーチン
1345 * Interact with some options for cheating
1346 * @param info 表示メッセージ
1349 static void do_cmd_options_cheat(concptr info)
1352 int i, k = 0, n = CHEAT_MAX;
1356 /* Interact with the player */
1362 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1367 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1368 prt(" << 注意 >>", 11, 0);
1369 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1370 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1371 prt(" じらないようにして下さい。", 14, 0);
1373 /* Display the options */
1374 for (i = 0; i < n; i++)
1376 byte a = TERM_WHITE;
1378 /* Color current option */
1379 if (i == k) a = TERM_L_BLUE;
1381 /* Display the option text */
1382 sprintf(buf, "%-48s: %s (%s)",
1383 cheat_info[i].o_desc,
1384 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1385 cheat_info[i].o_text);
1386 c_prt(a, buf, i + 2, 0);
1389 /* Hilite current option */
1390 move_cursor(k + 2, 50);
1396 * HACK - Try to translate the key into a direction
1397 * to allow using the roguelike keys for navigation.
1399 dir = get_keymap_dir(ch);
1400 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1414 k = (n + k - 1) % n;
1432 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1433 _("詐欺オプションをONにして、スコアを残せなくなった。", "gave up sending score to use cheating options."));
1434 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1435 (*cheat_info[k].o_var) = TRUE;
1444 (*cheat_info[k].o_var) = FALSE;
1451 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1452 /* Peruse the help file */
1453 (void)show_file(TRUE, buf, NULL, 0, 0);
1470 * @brief セーブ頻度ターンの次の値を返す
1471 * @param current 現在のセーブ頻度ターン値
1472 * @return 次のセーブ頻度ターン値
1474 static s16b toggle_frequency(s16b current)
1479 case 50: return 100;
1480 case 100: return 250;
1481 case 250: return 500;
1482 case 500: return 1000;
1483 case 1000: return 2500;
1484 case 2500: return 5000;
1485 case 5000: return 10000;
1486 case 10000: return 25000;
1493 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1494 * @param info 表示メッセージ
1497 static void do_cmd_options_autosave(concptr info)
1500 int i, k = 0, n = 2;
1505 /* Interact with the player */
1509 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1510 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1514 /* Display the options */
1515 for (i = 0; i < n; i++)
1517 byte a = TERM_WHITE;
1519 /* Color current option */
1520 if (i == k) a = TERM_L_BLUE;
1522 /* Display the option text */
1523 sprintf(buf, "%-48s: %s (%s)",
1524 autosave_info[i].o_desc,
1525 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1526 autosave_info[i].o_text);
1527 c_prt(a, buf, i + 2, 0);
1529 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1531 /* Hilite current option */
1532 move_cursor(k + 2, 50);
1548 k = (n + k - 1) % n;
1566 (*autosave_info[k].o_var) = TRUE;
1575 (*autosave_info[k].o_var) = FALSE;
1583 autosave_freq = toggle_frequency(autosave_freq);
1584 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1590 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1606 * @brief 標準オプションを変更するコマンドのサブルーチン /
1607 * Interact with some options
1608 * @param page オプションページ番号
1609 * @param info 表示メッセージ
1612 void do_cmd_options_aux(int page, concptr info)
1615 int i, k = 0, n = 0, l;
1618 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1619 (!p_ptr->wizard || !allow_debug_opts);
1622 /* Lookup the options */
1623 for (i = 0; i < 24; i++) opt[i] = 0;
1625 /* Scan the options */
1626 for (i = 0; option_info[i].o_desc; i++)
1628 /* Notice options on this "page" */
1629 if (option_info[i].o_page == page) opt[n++] = i;
1633 /* Interact with the player */
1639 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1640 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1643 /* HACK -- description for easy-auto-destroy options */
1644 if (page == OPT_PAGE_AUTODESTROY)
1645 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1646 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1648 /* Display the options */
1649 for (i = 0; i < n; i++)
1651 byte a = TERM_WHITE;
1653 /* Color current option */
1654 if (i == k) a = TERM_L_BLUE;
1656 /* Display the option text */
1657 sprintf(buf, "%-48s: %s (%.19s)",
1658 option_info[opt[i]].o_desc,
1659 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1660 option_info[opt[i]].o_text);
1661 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1662 else c_prt(a, buf, i + 2, 0);
1665 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1668 /* Hilite current option */
1669 move_cursor(k + 2 + l, 50);
1675 * HACK - Try to translate the key into a direction
1676 * to allow using the roguelike keys for navigation.
1678 dir = get_keymap_dir(ch);
1679 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1693 k = (n + k - 1) % n;
1710 if (browse_only) break;
1711 (*option_info[opt[k]].o_var) = TRUE;
1720 if (browse_only) break;
1721 (*option_info[opt[k]].o_var) = FALSE;
1729 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1735 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1736 /* Peruse the help file */
1737 (void)show_file(TRUE, buf, NULL, 0, 0);
1754 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1755 * Modify the "window" options
1758 static void do_cmd_options_win(void)
1768 /* Memorize old flags */
1769 for (j = 0; j < 8; j++)
1771 /* Acquire current flags */
1772 old_flag[j] = window_flag[j];
1781 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1783 /* Display the windows */
1784 for (j = 0; j < 8; j++)
1786 byte a = TERM_WHITE;
1788 concptr s = angband_term_name[j];
1791 if (j == x) a = TERM_L_BLUE;
1793 /* Window name, staggered, centered */
1794 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1797 /* Display the options */
1798 for (i = 0; i < 16; i++)
1800 byte a = TERM_WHITE;
1802 concptr str = window_flag_desc[i];
1805 if (i == y) a = TERM_L_BLUE;
1808 if (!str) str = _("(未使用)", "(Unused option)");
1811 Term_putstr(0, i + 5, -1, a, str);
1813 /* Display the windows */
1814 for (j = 0; j < 8; j++)
1820 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1823 if (window_flag[j] & (1L << i)) c = 'X';
1826 Term_putch(35 + j * 5, i + 5, a, c);
1831 Term_gotoxy(35 + x * 5, y + 5);
1849 for (j = 0; j < 8; j++)
1851 window_flag[j] &= ~(1L << y);
1855 for (i = 0; i < 16; i++)
1857 window_flag[x] &= ~(1L << i);
1870 window_flag[x] |= (1L << y);
1878 window_flag[x] &= ~(1L << y);
1884 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1892 d = get_keymap_dir(ch);
1894 x = (x + ddx[d] + 8) % 8;
1895 y = (y + ddy[d] + 16) % 16;
1902 /* Notice changes */
1903 for (j = 0; j < 8; j++)
1908 if (!angband_term[j]) continue;
1910 /* Ignore non-changes */
1911 if (window_flag[j] == old_flag[j]) continue;
1914 Term_activate(angband_term[j]);
1931 option_fields[OPT_NUM] =
1934 { '1', " キー入力 オプション", 3 },
1935 { '2', " マップ画面 オプション", 4 },
1936 { '3', " テキスト表示 オプション", 5 },
1937 { '4', " ゲームプレイ オプション", 6 },
1938 { '5', " 行動中止関係 オプション", 7 },
1939 { '6', " 簡易自動破壊 オプション", 8 },
1940 { 'r', " プレイ記録 オプション", 9 },
1942 { 'p', "自動拾いエディタ", 11 },
1943 { 'd', " 基本ウェイト量 ", 12 },
1944 { 'h', "低ヒットポイント", 13 },
1945 { 'm', " 低魔力色閾値 ", 14 },
1946 { 'a', " 自動セーブ オプション", 15 },
1947 { 'w', "ウインドウフラグ", 16 },
1949 { 'b', " 初期 オプション (参照のみ)", 18 },
1950 { 'c', " 詐欺 オプション", 19 },
1952 { '1', "Input Options", 3 },
1953 { '2', "Map Screen Options", 4 },
1954 { '3', "Text Display Options", 5 },
1955 { '4', "Game-Play Options", 6 },
1956 { '5', "Disturbance Options", 7 },
1957 { '6', "Easy Auto-Destroyer Options", 8 },
1958 { 'r', "Play record Options", 9 },
1960 { 'p', "Auto-picker/destroyer editor", 11 },
1961 { 'd', "Base Delay Factor", 12 },
1962 { 'h', "Hitpoint Warning", 13 },
1963 { 'm', "Mana Color Threshold", 14 },
1964 { 'a', "Autosave Options", 15 },
1965 { 'w', "Window Flags", 16 },
1967 { 'b', "Birth Options (Browse Only)", 18 },
1968 { 'c', "Cheat Options", 19 },
1974 * @brief 標準オプションを変更するコマンドのメインルーチン /
1975 * Set or unset various options.
1979 * The user must use the "Ctrl-R" command to "adapt" to changes
1980 * in any options which control "visual" aspects of the game.
1983 void do_cmd_options(void)
1995 /* Does not list cheat option when cheat option is off */
1996 if (!p_ptr->noscore && !allow_debug_opts) n--;
1999 /* Why are we here */
2000 prt(_("[ オプションの設定 ]", "Game options"), 1, 0);
2004 /* Give some choices */
2005 for (i = 0; i < n; i++)
2007 byte a = TERM_WHITE;
2008 if (i == y) a = TERM_L_BLUE;
2009 Term_putstr(5, option_fields[i].row, -1, a,
2010 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2013 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2016 skey = inkey_special(TRUE);
2017 if (!(skey & SKEY_MASK)) k = (char)skey;
2021 if (k == ESCAPE) break;
2023 if (my_strchr("\n\r ", k))
2025 k = option_fields[y].key;
2029 for (i = 0; i < n; i++)
2031 if (tolower(k) == option_fields[i].key) break;
2034 /* Command is found */
2037 /* Hack -- browse help */
2038 if (k == '?') break;
2042 if (skey == SKEY_UP) d = 8;
2043 if (skey == SKEY_DOWN) d = 2;
2044 y = (y + ddy[d] + n) % n;
2049 if (k == ESCAPE) break;
2056 /* Process the general options */
2057 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2063 /* Process the general options */
2064 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2071 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2078 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2085 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2092 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2096 /* Play-record Options */
2101 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2110 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2111 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2112 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2116 /* Cheating Options */
2119 if (!p_ptr->noscore && !allow_debug_opts)
2121 /* Cheat options are not permitted */
2127 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2134 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2143 do_cmd_options_win();
2144 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2145 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2146 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2147 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2152 /* Auto-picker/destroyer editor */
2156 do_cmd_edit_autopick();
2160 /* Hack -- Delay Speed */
2166 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2168 /* Get a new value */
2171 int msec = delay_factor * delay_factor * delay_factor;
2172 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2173 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2175 if (k == ESCAPE) break;
2178 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2181 else if (isdigit(k)) delay_factor = D2I(k);
2188 /* Hack -- hitpoint warning factor */
2194 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2196 /* Get a new value */
2199 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2200 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2202 if (k == ESCAPE) break;
2205 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2208 else if (isdigit(k)) hitpoint_warn = D2I(k);
2215 /* Hack -- mana color factor */
2221 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2223 /* Get a new value */
2226 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2227 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2229 if (k == ESCAPE) break;
2232 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2235 else if (isdigit(k)) mana_warn = D2I(k);
2243 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2247 /* Unknown option */
2260 /* Hack - Redraw equippy chars */
2261 p_ptr->redraw |= (PR_EQUIPPY);
2267 * @brief prefファイルを選択して処理する /
2268 * Ask for a "user pref line" and process it
2271 * Allow absolute file names?
2273 void do_cmd_pref(void)
2280 /* Ask for a "user pref command" */
2281 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2283 /* Process that pref command */
2284 (void)process_pref_file_command(buf);
2288 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2291 void do_cmd_reload_autopick(void)
2293 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2294 /* Load the file with messages */
2295 autopick_load_pref(TRUE);
2301 * @brief マクロ情報をprefファイルに保存する /
2302 * @param fname ファイル名
2305 static errr macro_dump(concptr fname)
2307 static concptr mark = "Macro Dump";
2313 /* Build the filename */
2314 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2316 /* File type is "TEXT" */
2317 FILE_TYPE(FILE_TYPE_TEXT);
2319 /* Append to the file */
2320 if (!open_auto_dump(buf, mark)) return (-1);
2323 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2326 for (i = 0; i < macro__num; i++)
2328 /* Extract the action */
2329 ascii_to_text(buf, macro__act[i]);
2331 /* Dump the macro */
2332 auto_dump_printf("A:%s\n", buf);
2334 /* Extract the action */
2335 ascii_to_text(buf, macro__pat[i]);
2337 /* Dump normal macros */
2338 auto_dump_printf("P:%s\n", buf);
2341 auto_dump_printf("\n");
2353 * @brief マクロのトリガーキーを取得する /
2354 * Hack -- ask for a "trigger" (see below)
2355 * @param buf キー表記を保管するバッファ
2359 * Note the complex use of the "inkey()" function from "util.c".
2361 * Note that both "flush()" calls are extremely important.
2364 static void do_cmd_macro_aux(char *buf)
2372 /* Do not process macros */
2378 /* Read the pattern */
2384 /* Do not process macros */
2387 /* Do not wait for keys */
2390 /* Attempt to read a key */
2399 /* Convert the trigger */
2400 ascii_to_text(tmp, buf);
2402 /* Hack -- display the trigger */
2403 Term_addstr(-1, TERM_WHITE, tmp);
2409 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2410 * Hack -- ask for a keymap "trigger" (see below)
2411 * @param buf キー表記を取得するバッファ
2415 * Note that both "flush()" calls are extremely important. This may
2416 * no longer be true, since "util.c" is much simpler now.
2419 static void do_cmd_macro_aux_keymap(char *buf)
2429 /* Convert to ascii */
2430 ascii_to_text(tmp, buf);
2432 /* Hack -- display the trigger */
2433 Term_addstr(-1, TERM_WHITE, tmp);
2440 * @brief キーマップをprefファイルにダンプする /
2441 * Hack -- append all keymaps to the given file
2442 * @param fname ファイルネーム
2446 static errr keymap_dump(concptr fname)
2448 static concptr mark = "Keymap Dump";
2457 if (rogue_like_commands)
2459 mode = KEYMAP_MODE_ROGUE;
2465 mode = KEYMAP_MODE_ORIG;
2469 /* Build the filename */
2470 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2472 /* File type is "TEXT" */
2473 FILE_TYPE(FILE_TYPE_TEXT);
2475 /* Append to the file */
2476 if (!open_auto_dump(buf, mark)) return -1;
2479 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2482 for (i = 0; i < 256; i++)
2486 /* Loop up the keymap */
2487 act = keymap_act[mode][i];
2489 /* Skip empty keymaps */
2492 /* Encode the key */
2495 ascii_to_text(key, buf);
2497 /* Encode the action */
2498 ascii_to_text(buf, act);
2500 /* Dump the macro */
2501 auto_dump_printf("A:%s\n", buf);
2502 auto_dump_printf("C:%d:%s\n", mode, key);
2514 * @brief マクロを設定するコマンドのメインルーチン /
2515 * Interact with "macros"
2519 * Note that the macro "action" must be defined before the trigger.
2521 * Could use some helpful instructions on this page.
2524 void do_cmd_macros(void)
2536 if (rogue_like_commands)
2538 mode = KEYMAP_MODE_ROGUE;
2544 mode = KEYMAP_MODE_ORIG;
2547 /* File type is "TEXT" */
2548 FILE_TYPE(FILE_TYPE_TEXT);
2553 /* Process requests until done */
2557 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2559 /* Describe that action */
2560 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2562 /* Analyze the current action */
2563 ascii_to_text(buf, macro__buf);
2565 /* Display the current action */
2570 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2572 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2573 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2574 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2575 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2576 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2577 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2578 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2579 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2580 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2581 #endif /* ALLOW_MACROS */
2584 prt(_("コマンド: ", "Command: "), 16, 0);
2589 if (i == ESCAPE) break;
2591 /* Load a 'macro' file */
2597 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2600 prt(_("ファイル: ", "File: "), 18, 0);
2602 /* Default filename */
2603 sprintf(tmp, "%s.prf", player_base);
2605 /* Ask for a file */
2606 if (!askfor(tmp, 80)) continue;
2608 /* Process the given filename */
2609 err = process_pref_file(tmp);
2612 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2617 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2621 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2631 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2634 prt(_("ファイル: ", "File: "), 18, 0);
2636 /* Default filename */
2637 sprintf(tmp, "%s.prf", player_base);
2639 /* Ask for a file */
2640 if (!askfor(tmp, 80)) continue;
2642 /* Dump the macros */
2643 (void)macro_dump(tmp);
2646 msg_print(_("マクロを追加しました。", "Appended macros."));
2655 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2659 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2661 /* Get a macro trigger */
2662 do_cmd_macro_aux(buf);
2664 /* Acquire action */
2665 k = macro_find_exact(buf);
2671 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2677 /* Obtain the action */
2678 strcpy(macro__buf, macro__act[k]);
2680 /* Analyze the current action */
2681 ascii_to_text(buf, macro__buf);
2683 /* Display the current action */
2687 msg_print(_("マクロを確認しました。", "Found a macro."));
2691 /* Create a macro */
2695 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2698 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2700 /* Get a macro trigger */
2701 do_cmd_macro_aux(buf);
2707 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2708 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2711 prt(_("マクロ行動: ", "Action: "), 20, 0);
2713 /* Convert to text */
2714 ascii_to_text(tmp, macro__buf);
2716 /* Get an encoded action */
2717 if (askfor(tmp, 80))
2719 /* Convert to ascii */
2720 text_to_ascii(macro__buf, tmp);
2722 /* Link the macro */
2723 macro_add(buf, macro__buf);
2726 msg_print(_("マクロを追加しました。", "Added a macro."));
2730 /* Remove a macro */
2734 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2737 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2739 /* Get a macro trigger */
2740 do_cmd_macro_aux(buf);
2742 /* Link the macro */
2743 macro_add(buf, buf);
2746 msg_print(_("マクロを削除しました。", "Removed a macro."));
2753 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2756 prt(_("ファイル: ", "File: "), 18, 0);
2758 /* Default filename */
2759 sprintf(tmp, "%s.prf", player_base);
2761 /* Ask for a file */
2762 if (!askfor(tmp, 80)) continue;
2764 /* Dump the macros */
2765 (void)keymap_dump(tmp);
2768 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2771 /* Query a keymap */
2777 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2780 prt(_("押すキー: ", "Keypress: "), 18, 0);
2782 /* Get a keymap trigger */
2783 do_cmd_macro_aux_keymap(buf);
2785 /* Look up the keymap */
2786 act = keymap_act[mode][(byte)(buf[0])];
2792 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2798 /* Obtain the action */
2799 strcpy(macro__buf, act);
2801 /* Analyze the current action */
2802 ascii_to_text(buf, macro__buf);
2804 /* Display the current action */
2808 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2812 /* Create a keymap */
2816 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2819 prt(_("押すキー: ", "Keypress: "), 18, 0);
2821 /* Get a keymap trigger */
2822 do_cmd_macro_aux_keymap(buf);
2828 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2829 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2832 prt(_("行動: ", "Action: "), 20, 0);
2834 /* Convert to text */
2835 ascii_to_text(tmp, macro__buf);
2837 /* Get an encoded action */
2838 if (askfor(tmp, 80))
2840 /* Convert to ascii */
2841 text_to_ascii(macro__buf, tmp);
2843 /* Free old keymap */
2844 string_free(keymap_act[mode][(byte)(buf[0])]);
2846 /* Make new keymap */
2847 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2850 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2854 /* Remove a keymap */
2858 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2861 prt(_("押すキー: ", "Keypress: "), 18, 0);
2863 /* Get a keymap trigger */
2864 do_cmd_macro_aux_keymap(buf);
2866 /* Free old keymap */
2867 string_free(keymap_act[mode][(byte)(buf[0])]);
2869 /* Make new keymap */
2870 keymap_act[mode][(byte)(buf[0])] = NULL;
2873 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2876 /* Enter a new action */
2880 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2886 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2887 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2890 prt(_("マクロ行動: ", "Action: "), 20, 0);
2892 /* Hack -- limit the value */
2895 /* Get an encoded action */
2896 if (!askfor(buf, 80)) continue;
2898 /* Extract an action */
2899 text_to_ascii(macro__buf, buf);
2902 #endif /* ALLOW_MACROS */
2915 * @brief キャラクタ色の明暗表現
2917 static concptr lighting_level_str[F_LIT_MAX] =
2932 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2933 * @param i 指定対象となるキャラクタコード
2934 * @param num 指定されたビジュアルIDを返す参照ポインタ
2935 * @param max ビジュアルIDの最大数
2936 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2938 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2945 sprintf(str, "%d", *num);
2947 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2950 tmp = (IDX)strtol(str, NULL, 0);
2951 if (tmp >= 0 && tmp < max)
2954 else if (isupper(i))
2955 *num = (*num + max - 1) % max;
2957 *num = (*num + 1) % max;
2963 * @brief キャラクタの変更メニュー表示
2964 * @param choice_msg 選択メッセージ
2967 static void print_visuals_menu(concptr choice_msg)
2969 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2971 /* Give some choices */
2972 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2974 #ifdef ALLOW_VISUALS
2975 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2976 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2977 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2978 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2979 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2980 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2981 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2982 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2983 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2984 #endif /* ALLOW_VISUALS */
2986 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2989 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2992 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2993 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2994 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2997 * Interact with "visuals"
2999 void do_cmd_visuals(void)
3004 bool need_redraw = FALSE;
3005 concptr empty_symbol = "<< ? >>";
3007 if (use_bigtile) empty_symbol = "<< ?? >>";
3009 /* File type is "TEXT" */
3010 FILE_TYPE(FILE_TYPE_TEXT);
3013 /* Interact until done */
3018 /* Ask for a choice */
3019 print_visuals_menu(NULL);
3024 if (i == ESCAPE) break;
3028 /* Load a 'pref' file */
3031 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3034 prt(_("ファイル: ", "File: "), 17, 0);
3036 /* Default filename */
3037 sprintf(tmp, "%s.prf", player_base);
3040 if (!askfor(tmp, 70)) continue;
3042 /* Process the given filename */
3043 (void)process_pref_file(tmp);
3048 #ifdef ALLOW_VISUALS
3050 /* Dump monster attr/chars */
3053 static concptr mark = "Monster attr/chars";
3056 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3059 prt(_("ファイル: ", "File: "), 17, 0);
3061 /* Default filename */
3062 sprintf(tmp, "%s.prf", player_base);
3064 /* Get a filename */
3065 if (!askfor(tmp, 70)) continue;
3067 /* Build the filename */
3068 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3070 /* Append to the file */
3071 if (!open_auto_dump(buf, mark)) continue;
3074 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3077 for (i = 0; i < max_r_idx; i++)
3079 monster_race *r_ptr = &r_info[i];
3081 /* Skip non-entries */
3082 if (!r_ptr->name) continue;
3084 /* Dump a comment */
3085 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3087 /* Dump the monster attr/char info */
3088 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3089 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3095 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3100 /* Dump object attr/chars */
3103 static concptr mark = "Object attr/chars";
3104 KIND_OBJECT_IDX k_idx;
3107 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3110 prt(_("ファイル: ", "File: "), 17, 0);
3112 /* Default filename */
3113 sprintf(tmp, "%s.prf", player_base);
3115 /* Get a filename */
3116 if (!askfor(tmp, 70)) continue;
3118 /* Build the filename */
3119 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3121 /* Append to the file */
3122 if (!open_auto_dump(buf, mark)) continue;
3125 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3128 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3130 GAME_TEXT o_name[MAX_NLEN];
3131 object_kind *k_ptr = &k_info[k_idx];
3133 /* Skip non-entries */
3134 if (!k_ptr->name) continue;
3139 strip_name(o_name, k_idx);
3145 /* Prepare dummy object */
3146 object_prep(&forge, k_idx);
3148 /* Get un-shuffled flavor name */
3149 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3152 /* Dump a comment */
3153 auto_dump_printf("# %s\n", o_name);
3155 /* Dump the object attr/char info */
3156 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3157 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3163 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3168 /* Dump feature attr/chars */
3171 static concptr mark = "Feature attr/chars";
3174 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3177 prt(_("ファイル: ", "File: "), 17, 0);
3179 /* Default filename */
3180 sprintf(tmp, "%s.prf", player_base);
3182 /* Get a filename */
3183 if (!askfor(tmp, 70)) continue;
3185 /* Build the filename */
3186 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3188 /* Append to the file */
3189 if (!open_auto_dump(buf, mark)) continue;
3192 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3195 for (i = 0; i < max_f_idx; i++)
3197 feature_type *f_ptr = &f_info[i];
3199 /* Skip non-entries */
3200 if (!f_ptr->name) continue;
3202 /* Skip mimiccing features */
3203 if (f_ptr->mimic != i) continue;
3205 /* Dump a comment */
3206 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3208 /* Dump the feature attr/char info */
3209 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3210 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3211 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3212 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3218 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3223 /* Modify monster attr/chars (numeric operation) */
3226 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3227 static MONRACE_IDX r = 0;
3229 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3231 /* Hack -- query until done */
3234 monster_race *r_ptr = &r_info[r];
3238 TERM_COLOR da = r_ptr->d_attr;
3239 byte dc = r_ptr->d_char;
3240 TERM_COLOR ca = r_ptr->x_attr;
3241 byte cc = r_ptr->x_char;
3243 /* Label the object */
3244 Term_putstr(5, 17, -1, TERM_WHITE,
3245 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3247 /* Label the Default values */
3248 Term_putstr(10, 19, -1, TERM_WHITE,
3249 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3251 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3252 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3254 /* Label the Current values */
3255 Term_putstr(10, 20, -1, TERM_WHITE,
3256 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3258 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3259 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3262 Term_putstr(0, 22, -1, TERM_WHITE,
3263 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3268 if (i == ESCAPE) break;
3270 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3271 else if (isupper(i)) c = 'a' + i - 'A';
3281 if (!cmd_visuals_aux(i, &r, max_r_idx))
3287 while (!r_info[r].name);
3291 t = (int)r_ptr->x_attr;
3292 (void)cmd_visuals_aux(i, &t, 256);
3293 r_ptr->x_attr = (byte)t;
3297 t = (int)r_ptr->x_char;
3298 (void)cmd_visuals_aux(i, &t, 256);
3299 r_ptr->x_char = (byte)t;
3303 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3305 print_visuals_menu(choice_msg);
3313 /* Modify object attr/chars (numeric operation) */
3316 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3318 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3320 /* Hack -- query until done */
3323 object_kind *k_ptr = &k_info[k];
3327 TERM_COLOR da = k_ptr->d_attr;
3328 SYMBOL_CODE dc = k_ptr->d_char;
3329 TERM_COLOR ca = k_ptr->x_attr;
3330 SYMBOL_CODE cc = k_ptr->x_char;
3332 /* Label the object */
3333 Term_putstr(5, 17, -1, TERM_WHITE,
3334 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3335 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3337 /* Label the Default values */
3338 Term_putstr(10, 19, -1, TERM_WHITE,
3339 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3341 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3342 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3344 /* Label the Current values */
3345 Term_putstr(10, 20, -1, TERM_WHITE,
3346 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3348 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3349 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3352 Term_putstr(0, 22, -1, TERM_WHITE,
3353 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3358 if (i == ESCAPE) break;
3360 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3361 else if (isupper(i)) c = 'a' + i - 'A';
3371 if (!cmd_visuals_aux(i, &k, max_k_idx))
3377 while (!k_info[k].name);
3381 t = (int)k_ptr->x_attr;
3382 (void)cmd_visuals_aux(i, &t, 256);
3383 k_ptr->x_attr = (byte)t;
3387 t = (int)k_ptr->x_char;
3388 (void)cmd_visuals_aux(i, &t, 256);
3389 k_ptr->x_char = (byte)t;
3393 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3395 print_visuals_menu(choice_msg);
3403 /* Modify feature attr/chars (numeric operation) */
3406 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3408 static IDX lighting_level = F_LIT_STANDARD;
3409 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3411 /* Hack -- query until done */
3414 feature_type *f_ptr = &f_info[f];
3418 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3419 byte dc = f_ptr->d_char[lighting_level];
3420 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3421 byte cc = f_ptr->x_char[lighting_level];
3423 /* Label the object */
3425 Term_putstr(5, 17, -1, TERM_WHITE,
3426 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3427 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3429 /* Label the Default values */
3430 Term_putstr(10, 19, -1, TERM_WHITE,
3431 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3433 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3434 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3436 /* Label the Current values */
3438 Term_putstr(10, 20, -1, TERM_WHITE,
3439 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3441 Term_putstr(10, 20, -1, TERM_WHITE,
3442 format("Current attr/char = %3d / %3d", ca, cc));
3445 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3446 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3450 Term_putstr(0, 22, -1, TERM_WHITE,
3451 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3453 Term_putstr(0, 22, -1, TERM_WHITE,
3454 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3460 if (i == ESCAPE) break;
3462 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3463 else if (isupper(i)) c = 'a' + i - 'A';
3473 if (!cmd_visuals_aux(i, &f, max_f_idx))
3479 while (!f_info[f].name || (f_info[f].mimic != f));
3483 t = (int)f_ptr->x_attr[lighting_level];
3484 (void)cmd_visuals_aux(i, &t, 256);
3485 f_ptr->x_attr[lighting_level] = (byte)t;
3489 t = (int)f_ptr->x_char[lighting_level];
3490 (void)cmd_visuals_aux(i, &t, 256);
3491 f_ptr->x_char[lighting_level] = (byte)t;
3495 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3498 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3502 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3504 print_visuals_menu(choice_msg);
3512 /* Modify monster attr/chars (visual mode) */
3514 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3517 /* Modify object attr/chars (visual mode) */
3519 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3522 /* Modify feature attr/chars (visual mode) */
3525 IDX lighting_level = F_LIT_STANDARD;
3526 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3530 #endif /* ALLOW_VISUALS */
3538 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3542 /* Unknown option */
3552 if (need_redraw) do_cmd_redraw();
3557 * Interact with "colors"
3559 void do_cmd_colors(void)
3568 /* File type is "TEXT" */
3569 FILE_TYPE(FILE_TYPE_TEXT);
3574 /* Interact until done */
3579 /* Ask for a choice */
3580 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3582 /* Give some choices */
3583 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3586 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3587 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3591 prt(_("コマンド: ", "Command: "), 8, 0);
3595 if (i == ESCAPE) break;
3597 /* Load a 'pref' file */
3601 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3604 prt(_("ファイル: ", "File: "), 10, 0);
3607 sprintf(tmp, "%s.prf", player_base);
3610 if (!askfor(tmp, 70)) continue;
3612 /* Process the given filename */
3613 (void)process_pref_file(tmp);
3615 /* Mega-Hack -- react to changes */
3616 Term_xtra(TERM_XTRA_REACT, 0);
3618 /* Mega-Hack -- redraw */
3627 static concptr mark = "Colors";
3630 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3633 prt(_("ファイル: ", "File: "), 10, 0);
3635 /* Default filename */
3636 sprintf(tmp, "%s.prf", player_base);
3638 /* Get a filename */
3639 if (!askfor(tmp, 70)) continue;
3641 /* Build the filename */
3642 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3644 /* Append to the file */
3645 if (!open_auto_dump(buf, mark)) continue;
3648 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3651 for (i = 0; i < 256; i++)
3653 int kv = angband_color_table[i][0];
3654 int rv = angband_color_table[i][1];
3655 int gv = angband_color_table[i][2];
3656 int bv = angband_color_table[i][3];
3658 concptr name = _("未知", "unknown");
3660 /* Skip non-entries */
3661 if (!kv && !rv && !gv && !bv) continue;
3663 /* Extract the color name */
3664 if (i < 16) name = color_names[i];
3666 /* Dump a comment */
3667 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3669 /* Dump the monster attr/char info */
3670 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3677 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3686 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3688 /* Hack -- query until done */
3697 /* Exhibit the normal colors */
3698 for (j = 0; j < 16; j++)
3700 /* Exhibit this color */
3701 Term_putstr(j*4, 20, -1, a, "###");
3703 /* Exhibit all colors */
3704 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3707 /* Describe the color */
3708 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3710 /* Describe the color */
3711 Term_putstr(5, 10, -1, TERM_WHITE,
3712 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3714 /* Label the Current values */
3715 Term_putstr(5, 12, -1, TERM_WHITE,
3716 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3717 angband_color_table[a][0],
3718 angband_color_table[a][1],
3719 angband_color_table[a][2],
3720 angband_color_table[a][3]));
3723 Term_putstr(0, 14, -1, TERM_WHITE,
3724 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3729 if (i == ESCAPE) break;
3732 if (i == 'n') a = (byte)(a + 1);
3733 if (i == 'N') a = (byte)(a - 1);
3734 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3735 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3736 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3737 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3738 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3739 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3740 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3741 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3743 /* Hack -- react to changes */
3744 Term_xtra(TERM_XTRA_REACT, 0);
3746 /* Hack -- redraw */
3753 /* Unknown option */
3767 * Note something in the message recall
3769 void do_cmd_note(void)
3777 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3779 /* Ignore empty notes */
3780 if (!buf[0] || (buf[0] == ' ')) return;
3782 /* Add the note to the message recall */
3783 msg_format(_("メモ: %s", "Note: %s"), buf);
3788 * Mention the current version
3790 void do_cmd_version(void)
3792 #if FAKE_VER_EXTRA > 0
3793 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3794 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3796 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3797 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3804 * Array of feeling strings
3806 static concptr do_cmd_feeling_text[11] =
3808 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3809 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3810 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3811 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3812 _("とても悪い予感がする...", "You have a very bad feeling..."),
3813 _("悪い予感がする...", "You have a bad feeling..."),
3814 _("何か緊張する。", "You feel nervous."),
3815 _("少し不運な気がする...", "You feel your luck is turning..."),
3816 _("この場所は好きになれない。", "You don't like the look of this place."),
3817 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3818 _("なんて退屈なところだ...", "What a boring place...")
3821 static concptr do_cmd_feeling_text_combat[11] =
3823 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3824 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3825 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3826 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3827 _("とても悪い予感がする...", "You have a very bad feeling..."),
3828 _("悪い予感がする...", "You have a bad feeling..."),
3829 _("何か緊張する。", "You feel nervous."),
3830 _("少し不運な気がする...", "You feel your luck is turning..."),
3831 _("この場所は好きになれない。", "You don't like the look of this place."),
3832 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3833 _("なんて退屈なところだ...", "What a boring place...")
3836 static concptr do_cmd_feeling_text_lucky[11] =
3838 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3839 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3840 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3841 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3842 _("とても良い感じがする...", "You have a very good feeling..."),
3843 _("良い感じがする...", "You have a good feeling..."),
3844 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3845 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3846 _("見た感じ悪くはない...", "You like the look of this place..."),
3847 _("全然駄目ということはないが...", "This level can't be all bad..."),
3848 _("なんて退屈なところだ...", "What a boring place...")
3853 * Note that "feeling" is set to zero unless some time has passed.
3854 * Note that this is done when the level is GENERATED, not entered.
3856 void do_cmd_feeling(void)
3858 if (p_ptr->wild_mode) return;
3860 /* No useful feeling in quests */
3861 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3863 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3867 /* No useful feeling in town */
3868 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3870 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3872 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3877 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3882 /* No useful feeling in the wilderness */
3883 else if (!current_floor_ptr->dun_level)
3885 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3889 /* Display the feeling */
3890 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3891 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3892 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3893 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3894 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3896 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3902 * Description of each monster group.
3904 static concptr monster_group_text[] =
3907 "ユニーク", /* "Uniques" */
3908 "乗馬可能なモンスター", /* "Riding" */
3909 "賞金首", /* "Wanted */
3910 "アンバーの王族", /* "Amberite" */
3939 /* "古代ドラゴン/ワイアーム", */
4000 /* "Ancient Dragon/Wyrm", */
4009 "Multi-Headed Reptile",
4014 "Reptile/Amphibian",
4015 "Spider/Scorpion/Tick",
4017 /* "Major Demon", */
4034 * Symbols of monsters in each group. Note the "Uniques" group
4035 * is handled differently.
4037 static concptr monster_group_char[] =
4094 "!$&()+./=>?[\\]`{|~",
4104 * Build a list of monster indexes in the given group. Return the number
4105 * of monsters in the group.
4107 * mode & 0x01 : check for non-empty group
4108 * mode & 0x02 : visual operation only
4110 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4116 /* Get a list of x_char in this group */
4117 concptr group_char = monster_group_char[grp_cur];
4119 /* XXX Hack -- Check if this is the "Uniques" group */
4120 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4122 /* XXX Hack -- Check if this is the "Riding" group */
4123 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4125 /* XXX Hack -- Check if this is the "Wanted" group */
4126 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4128 /* XXX Hack -- Check if this is the "Amberite" group */
4129 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4132 /* Check every race */
4133 for (i = 0; i < max_r_idx; i++)
4135 /* Access the race */
4136 monster_race *r_ptr = &r_info[i];
4138 /* Skip empty race */
4139 if (!r_ptr->name) continue ;
4141 /* Require known monsters */
4142 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4146 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4149 else if (grp_riding)
4151 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4154 else if (grp_wanted)
4156 bool wanted = FALSE;
4158 for (j = 0; j < MAX_KUBI; j++)
4160 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4161 (p_ptr->today_mon && p_ptr->today_mon == i))
4167 if (!wanted) continue;
4170 else if (grp_amberite)
4172 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4177 /* Check for race in the group */
4178 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4182 mon_idx[mon_cnt++] = i;
4184 /* XXX Hack -- Just checking for non-empty group */
4185 if (mode & 0x01) break;
4188 /* Terminate the list */
4189 mon_idx[mon_cnt] = -1;
4191 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4193 /* Return the number of races */
4199 * Description of each monster group.
4201 static concptr object_group_text[] =
4204 "キノコ", /* "Mushrooms" */
4205 "薬", /* "Potions" */
4206 "油つぼ", /* "Flasks" */
4207 "巻物", /* "Scrolls" */
4209 "アミュレット", /* "Amulets" */
4210 "笛", /* "Whistle" */
4211 "光源", /* "Lanterns" */
4212 "魔法棒", /* "Wands" */
4215 "カード", /* "Cards" */
4226 "刀剣類", /* "Swords" */
4227 "鈍器", /* "Blunt Weapons" */
4228 "長柄武器", /* "Polearms" */
4229 "採掘道具", /* "Diggers" */
4230 "飛び道具", /* "Bows" */
4234 "軽装鎧", /* "Soft Armor" */
4235 "重装鎧", /* "Hard Armor" */
4236 "ドラゴン鎧", /* "Dragon Armor" */
4237 "盾", /* "Shields" */
4238 "クローク", /* "Cloaks" */
4239 "籠手", /* "Gloves" */
4240 "ヘルメット", /* "Helms" */
4242 "ブーツ", /* "Boots" */
4295 * TVALs of items in each group
4297 static byte object_group_tval[] =
4338 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4346 * Build a list of object indexes in the given group. Return the number
4347 * of objects in the group.
4349 * mode & 0x01 : check for non-empty group
4350 * mode & 0x02 : visual operation only
4352 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4354 KIND_OBJECT_IDX i, object_cnt = 0;
4357 /* Get a list of x_char in this group */
4358 byte group_tval = object_group_tval[grp_cur];
4360 /* Check every object */
4361 for (i = 0; i < max_k_idx; i++)
4363 /* Access the object */
4364 object_kind *k_ptr = &k_info[i];
4366 /* Skip empty objects */
4367 if (!k_ptr->name) continue;
4371 /* Any objects will be displayed */
4377 /* Skip non-flavoured objects */
4378 if (!k_ptr->flavor) continue;
4380 /* Require objects ever seen */
4381 if (!k_ptr->aware) continue;
4384 /* Skip items with no distribution (special artifacts) */
4385 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4389 /* Check for objects in the group */
4390 if (TV_LIFE_BOOK == group_tval)
4392 /* Hack -- All spell books */
4393 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4395 /* Add the object */
4396 object_idx[object_cnt++] = i;
4400 else if (k_ptr->tval == group_tval)
4402 /* Add the object */
4403 object_idx[object_cnt++] = i;
4407 /* XXX Hack -- Just checking for non-empty group */
4408 if (mode & 0x01) break;
4411 /* Terminate the list */
4412 object_idx[object_cnt] = -1;
4414 /* Return the number of objects */
4420 * Description of each feature group.
4422 static concptr feature_group_text[] =
4430 * Build a list of feature indexes in the given group. Return the number
4431 * of features in the group.
4433 * mode & 0x01 : check for non-empty group
4435 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4438 FEAT_IDX feat_cnt = 0;
4440 /* Unused; There is a single group. */
4443 /* Check every feature */
4444 for (i = 0; i < max_f_idx; i++)
4446 feature_type *f_ptr = &f_info[i];
4448 /* Skip empty index */
4449 if (!f_ptr->name) continue;
4451 /* Skip mimiccing features */
4452 if (f_ptr->mimic != i) continue;
4455 feat_idx[feat_cnt++] = i;
4457 /* XXX Hack -- Just checking for non-empty group */
4458 if (mode & 0x01) break;
4461 /* Terminate the list */
4462 feat_idx[feat_cnt] = -1;
4464 /* Return the number of races */
4471 * Build a list of monster indexes in the given group. Return the number
4472 * of monsters in the group.
4474 static int collect_artifacts(int grp_cur, int object_idx[])
4476 int i, object_cnt = 0;
4478 /* Get a list of x_char in this group */
4479 byte group_tval = object_group_tval[grp_cur];
4481 /* Check every object */
4482 for (i = 0; i < max_a_idx; i++)
4484 /* Access the artifact */
4485 artifact_type *a_ptr = &a_info[i];
4487 /* Skip empty artifacts */
4488 if (!a_ptr->name) continue;
4490 /* Skip "uncreated" artifacts */
4491 if (!a_ptr->cur_num) continue;
4493 /* Check for race in the group */
4494 if (a_ptr->tval == group_tval)
4497 object_idx[object_cnt++] = i;
4501 /* Terminate the list */
4502 object_idx[object_cnt] = 0;
4504 /* Return the number of races */
4511 * Encode the screen colors
4513 static char hack[17] = "dwsorgbuDWvyRGBU";
4517 * Hack -- load a screen dump from a file
4519 void do_cmd_load_screen(void)
4524 SYMBOL_CODE c = ' ';
4530 Term_get_size(&wid, &hgt);
4532 /* Build the filename */
4533 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4535 /* Append to the file */
4536 fff = my_fopen(buf, "r");
4539 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4547 /* Load the screen */
4548 for (y = 0; okay; y++)
4550 /* Get a line of data including control code */
4551 if (!fgets(buf, 1024, fff)) okay = FALSE;
4553 /* Get the blank line */
4554 if (buf[0] == '\n' || buf[0] == '\0') break;
4556 /* Ignore too large screen image */
4557 if (y >= hgt) continue;
4560 for (x = 0; x < wid - 1; x++)
4563 if (buf[x] == '\n' || buf[x] == '\0') break;
4565 /* Put the attr/char */
4566 Term_draw(x, y, TERM_WHITE, buf[x]);
4570 /* Dump the screen */
4571 for (y = 0; okay; y++)
4573 /* Get a line of data including control code */
4574 if (!fgets(buf, 1024, fff)) okay = FALSE;
4576 /* Get the blank line */
4577 if (buf[0] == '\n' || buf[0] == '\0') break;
4579 /* Ignore too large screen image */
4580 if (y >= hgt) continue;
4583 for (x = 0; x < wid - 1; x++)
4586 if (buf[x] == '\n' || buf[x] == '\0') break;
4588 /* Get the attr/char */
4589 (void)(Term_what(x, y, &a, &c));
4591 /* Look up the attr */
4592 for (i = 0; i < 16; i++)
4594 /* Use attr matches */
4595 if (hack[i] == buf[x]) a = (byte_hack)i;
4598 /* Put the attr/char */
4599 Term_draw(x, y, a, c);
4604 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4615 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4616 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4619 #define IM_FLAG_STR _("*", "* ")
4620 #define HAS_FLAG_STR _("+", "+ ")
4621 #define NO_FLAG_STR _("・", ". ")
4623 #define print_im_or_res_flag(IM, RES) \
4625 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4626 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4629 #define print_flag(TR) \
4631 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4635 /* XTRA HACK RESLIST */
4636 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4638 GAME_TEXT o_name[MAX_NLEN];
4639 BIT_FLAGS flgs[TR_FLAG_SIZE];
4641 if (!o_ptr->k_idx) return;
4642 if (o_ptr->tval != tval) return;
4644 /* Identified items only */
4645 if (!object_is_known(o_ptr)) return;
4648 * HACK:Ring of Lordly protection and Dragon equipment
4649 * have random resistances.
4651 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4652 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4653 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4654 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4655 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4656 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4657 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4658 || object_is_artifact(o_ptr))
4661 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4663 while (o_name[i] && (i < 26))
4666 if (iskanji(o_name[i])) i++;
4675 o_name[i] = ' '; i++;
4680 fprintf(fff, "%s %s", where, o_name);
4682 if (!(o_ptr->ident & (IDENT_MENTAL)))
4684 fputs(_("-------不明--------------- -------不明---------\n",
4685 "-------unknown------------ -------unknown------\n"), fff);
4689 object_flags_known(o_ptr, flgs);
4691 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4692 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4693 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4694 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4695 print_flag(TR_RES_POIS);
4696 print_flag(TR_RES_LITE);
4697 print_flag(TR_RES_DARK);
4698 print_flag(TR_RES_SHARDS);
4699 print_flag(TR_RES_SOUND);
4700 print_flag(TR_RES_NETHER);
4701 print_flag(TR_RES_NEXUS);
4702 print_flag(TR_RES_CHAOS);
4703 print_flag(TR_RES_DISEN);
4707 print_flag(TR_RES_BLIND);
4708 print_flag(TR_RES_FEAR);
4709 print_flag(TR_RES_CONF);
4710 print_flag(TR_FREE_ACT);
4711 print_flag(TR_SEE_INVIS);
4712 print_flag(TR_HOLD_EXP);
4713 print_flag(TR_TELEPATHY);
4714 print_flag(TR_SLOW_DIGEST);
4715 print_flag(TR_REGEN);
4716 print_flag(TR_LEVITATION);
4724 fprintf(fff, "%s\n", inven_res_label);
4730 * Display *ID* ed weapons/armors's resistances
4732 static void do_cmd_knowledge_inven(void)
4735 GAME_TEXT file_name[1024];
4737 OBJECT_TYPE_VALUE tval;
4743 /* Open a new file */
4744 fff = my_fopen_temp(file_name, 1024);
4747 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4751 fprintf(fff, "%s\n", inven_res_label);
4753 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4757 for (; j < 9; j++) fputc('\n', fff);
4759 fprintf(fff, "%s\n", inven_res_label);
4761 strcpy(where, _("装", "E "));
4762 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4764 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4766 strcpy(where, _("持", "I "));
4767 for (i = 0; i < INVEN_PACK; i++)
4769 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4772 st_ptr = &town_info[1].store[STORE_HOME];
4773 strcpy(where, _("家", "H "));
4774 for (i = 0; i < st_ptr->stock_num; i++)
4776 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4781 /* Display the file contents */
4782 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4787 void do_cmd_save_screen_html_aux(char *filename, int message)
4792 TERM_COLOR a = 0, old_a = 0;
4806 concptr html_head[] = {
4807 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4811 concptr html_foot[] = {
4813 "</body>\n</html>\n",
4819 Term_get_size(&wid, &hgt);
4821 /* File type is "TEXT" */
4822 FILE_TYPE(FILE_TYPE_TEXT);
4824 /* Append to the file */
4825 fff = my_fopen(filename, "w");
4829 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4835 if (message) screen_save();
4837 /* Build the filename */
4838 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4839 tmpfff = my_fopen(buf, "r");
4841 for (i = 0; html_head[i]; i++)
4842 fputs(html_head[i], fff);
4846 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4848 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4852 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4854 fprintf(fff, "%s\n", buf);
4859 /* Dump the screen */
4860 for (y = 0; y < hgt; y++)
4867 for (x = 0; x < wid - 1; x++)
4871 /* Get the attr/char */
4872 (void)(Term_what(x, y, &a, &c));
4876 case '&': cc = "&"; break;
4877 case '<': cc = "<"; break;
4878 case '>': cc = ">"; break;
4880 case 0x1f: c = '.'; break;
4881 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4886 if ((y == 0 && x == 0) || a != old_a) {
4887 rv = angband_color_table[a][1];
4888 gv = angband_color_table[a][2];
4889 bv = angband_color_table[a][3];
4890 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4891 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4895 fprintf(fff, "%s", cc);
4897 fprintf(fff, "%c", c);
4900 fprintf(fff, "</font>");
4903 for (i = 0; html_foot[i]; i++)
4904 fputs(html_foot[i], fff);
4909 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4911 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4915 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4917 fprintf(fff, "%s\n", buf);
4928 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4936 * Hack -- save a screen dump to a file
4938 static void do_cmd_save_screen_html(void)
4940 char buf[1024], tmp[256] = "screen.html";
4942 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4945 /* Build the filename */
4946 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4950 do_cmd_save_screen_html_aux(buf, 1);
4955 * Redefinable "save_screen" action
4957 void (*screendump_aux)(void) = NULL;
4961 * Hack -- save a screen dump to a file
4963 void do_cmd_save_screen(void)
4965 bool old_use_graphics = use_graphics;
4966 bool html_dump = FALSE;
4970 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4974 if (c == 'Y' || c == 'y')
4976 else if (c == 'H' || c == 'h')
4988 Term_get_size(&wid, &hgt);
4990 if (old_use_graphics)
4992 use_graphics = FALSE;
4994 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5000 do_cmd_save_screen_html();
5004 /* Do we use a special screendump function ? */
5005 else if (screendump_aux)
5007 /* Dump the screen to a graphics file */
5008 (*screendump_aux)();
5010 else /* Dump the screen as text */
5014 SYMBOL_CODE c = ' ';
5018 /* Build the filename */
5019 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5021 /* File type is "TEXT" */
5022 FILE_TYPE(FILE_TYPE_TEXT);
5024 /* Append to the file */
5025 fff = my_fopen(buf, "w");
5029 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5037 /* Dump the screen */
5038 for (y = 0; y < hgt; y++)
5041 for (x = 0; x < wid - 1; x++)
5043 /* Get the attr/char */
5044 (void)(Term_what(x, y, &a, &c));
5054 fprintf(fff, "%s\n", buf);
5061 /* Dump the screen */
5062 for (y = 0; y < hgt; y++)
5065 for (x = 0; x < wid - 1; x++)
5067 /* Get the attr/char */
5068 (void)(Term_what(x, y, &a, &c));
5071 buf[x] = hack[a&0x0F];
5078 fprintf(fff, "%s\n", buf);
5085 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5090 if (old_use_graphics)
5092 use_graphics = TRUE;
5094 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5100 * Check the status of "artifacts"
5102 static void do_cmd_knowledge_artifacts(void)
5112 GAME_TEXT file_name[1024];
5113 GAME_TEXT base_name[MAX_NLEN];
5117 /* Open a new file */
5118 fff = my_fopen_temp(file_name, 1024);
5121 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5126 /* Allocate the "who" array */
5127 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5129 /* Allocate the "okay" array */
5130 C_MAKE(okay, max_a_idx, bool);
5132 /* Scan the artifacts */
5133 for (k = 0; k < max_a_idx; k++)
5135 artifact_type *a_ptr = &a_info[k];
5140 /* Skip "empty" artifacts */
5141 if (!a_ptr->name) continue;
5143 /* Skip "uncreated" artifacts */
5144 if (!a_ptr->cur_num) continue;
5150 /* Check the dungeon */
5151 for (y = 0; y < current_floor_ptr->height; y++)
5153 for (x = 0; x < current_floor_ptr->width; x++)
5155 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5157 OBJECT_IDX this_o_idx, next_o_idx = 0;
5159 /* Scan all objects in the grid */
5160 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5163 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5164 next_o_idx = o_ptr->next_o_idx;
5166 /* Ignore non-artifacts */
5167 if (!object_is_fixed_artifact(o_ptr)) continue;
5169 /* Ignore known items */
5170 if (object_is_known(o_ptr)) continue;
5172 /* Note the artifact */
5173 okay[o_ptr->name1] = FALSE;
5178 /* Check the inventory and equipment */
5179 for (i = 0; i < INVEN_TOTAL; i++)
5181 object_type *o_ptr = &inventory[i];
5183 /* Ignore non-objects */
5184 if (!o_ptr->k_idx) continue;
5186 /* Ignore non-artifacts */
5187 if (!object_is_fixed_artifact(o_ptr)) continue;
5189 /* Ignore known items */
5190 if (object_is_known(o_ptr)) continue;
5192 /* Note the artifact */
5193 okay[o_ptr->name1] = FALSE;
5196 for (k = 0; k < max_a_idx; k++)
5198 if (okay[k]) who[n++] = k;
5201 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5203 /* Scan the artifacts */
5204 for (k = 0; k < n; k++)
5206 artifact_type *a_ptr = &a_info[who[k]];
5207 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5209 /* Obtain the base object type */
5210 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5219 /* Create fake object */
5220 object_prep(q_ptr, z);
5222 /* Make it an artifact */
5223 q_ptr->name1 = (byte)who[k];
5225 /* Display as if known */
5226 q_ptr->ident |= IDENT_STORE;
5228 /* Describe the artifact */
5229 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5232 /* Hack -- Build the artifact name */
5233 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5236 /* Free the "who" array */
5237 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5239 /* Free the "okay" array */
5240 C_KILL(okay, max_a_idx, bool);
5243 /* Display the file contents */
5244 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5250 * Display known uniques
5251 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5253 static void do_cmd_knowledge_uniques(void)
5262 GAME_TEXT file_name[1024];
5265 int n_alive_surface = 0;
5266 int n_alive_over100 = 0;
5267 int n_alive_total = 0;
5270 for (i = 0; i < 10; i++) n_alive[i] = 0;
5272 /* Open a new file */
5273 fff = my_fopen_temp(file_name, 1024);
5277 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5282 /* Allocate the "who" array */
5283 C_MAKE(who, max_r_idx, MONRACE_IDX);
5285 /* Scan the monsters */
5286 for (i = 1; i < max_r_idx; i++)
5288 monster_race *r_ptr = &r_info[i];
5291 if (!r_ptr->name) continue;
5293 /* Require unique monsters */
5294 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5296 /* Only display "known" uniques */
5297 if (!cheat_know && !r_ptr->r_sights) continue;
5299 /* Only print rarity <= 100 uniques */
5300 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5302 /* Only "alive" uniques */
5303 if (r_ptr->max_num == 0) continue;
5307 lev = (r_ptr->level - 1) / 10;
5311 if (max_lev < lev) max_lev = lev;
5313 else n_alive_over100++;
5315 else n_alive_surface++;
5317 /* Collect "appropriate" monsters */
5321 /* Sort the array by dungeon depth of monsters */
5322 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5324 if (n_alive_surface)
5326 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5327 n_alive_total += n_alive_surface;
5329 for (i = 0; i <= max_lev; i++)
5331 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5332 n_alive_total += n_alive[i];
5334 if (n_alive_over100)
5336 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5337 n_alive_total += n_alive_over100;
5342 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5343 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5347 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5350 /* Scan the monster races */
5351 for (k = 0; k < n; k++)
5353 monster_race *r_ptr = &r_info[who[k]];
5355 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5358 /* Free the "who" array */
5359 C_KILL(who, max_r_idx, s16b);
5362 /* Display the file contents */
5363 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5369 * Display weapon-exp
5371 static void do_cmd_knowledge_weapon_exp(void)
5379 GAME_TEXT file_name[1024];
5382 /* Open a new file */
5383 fff = my_fopen_temp(file_name, 1024);
5385 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5390 for (i = 0; i < 5; i++)
5392 for (num = 0; num < 64; num++)
5394 for (j = 0; j < max_k_idx; j++)
5396 object_kind *k_ptr = &k_info[j];
5398 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5400 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5402 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5404 fprintf(fff, "%-25s ", tmp);
5405 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5406 else fprintf(fff, " ");
5407 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5408 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5417 /* Display the file contents */
5418 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5424 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5428 static void do_cmd_knowledge_spell_exp(void)
5435 const magic_type *s_ptr;
5437 GAME_TEXT file_name[1024];
5439 /* Open a new file */
5440 fff = my_fopen_temp(file_name, 1024);
5442 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5447 if (p_ptr->realm1 != REALM_NONE)
5449 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5450 for (i = 0; i < 32; i++)
5452 if (!is_magic(p_ptr->realm1))
5454 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5458 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5460 if (s_ptr->slevel >= 99) continue;
5461 spell_exp = p_ptr->spell_exp[i];
5462 exp_level = spell_exp_level(spell_exp);
5463 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5464 if (p_ptr->realm1 == REALM_HISSATSU)
5465 fprintf(fff, "[--]");
5468 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5469 else fprintf(fff, " ");
5470 fprintf(fff, "%s", exp_level_str[exp_level]);
5472 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5477 if (p_ptr->realm2 != REALM_NONE)
5479 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5480 for (i = 0; i < 32; i++)
5482 if (!is_magic(p_ptr->realm1))
5484 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5488 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5490 if (s_ptr->slevel >= 99) continue;
5492 spell_exp = p_ptr->spell_exp[i + 32];
5493 exp_level = spell_exp_level(spell_exp);
5494 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5495 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5496 else fprintf(fff, " ");
5497 fprintf(fff, "%s", exp_level_str[exp_level]);
5498 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5504 /* Display the file contents */
5505 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5511 * @brief スキル情報を表示するコマンドのメインルーチン /
5515 static void do_cmd_knowledge_skill_exp(void)
5517 int i = 0, skill_exp;
5521 char file_name[1024];
5522 char skill_name[GINOU_TEMPMAX][20] =
5524 _("マーシャルアーツ", "Martial Arts "),
5525 _("二刀流 ", "Dual Wielding "),
5526 _("乗馬 ", "Riding "),
5530 /* Open a new file */
5531 fff = my_fopen_temp(file_name, 1024);
5533 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5538 for (i = 0; i < GINOU_TEMPMAX; i++)
5540 skill_exp = p_ptr->skill_exp[i];
5541 fprintf(fff, "%-20s ", skill_name[i]);
5542 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5543 else fprintf(fff, " ");
5544 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5545 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5550 /* Display the file contents */
5551 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5557 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5558 * @param Name 変換したい文字列の参照ポインタ
5561 void plural_aux(char *Name)
5563 int NameLen = strlen(Name);
5565 if (my_strstr(Name, "Disembodied hand"))
5567 strcpy(Name, "Disembodied hands that strangled people");
5569 else if (my_strstr(Name, "Colour out of space"))
5571 strcpy(Name, "Colours out of space");
5573 else if (my_strstr(Name, "stairway to hell"))
5575 strcpy(Name, "stairways to hell");
5577 else if (my_strstr(Name, "Dweller on the threshold"))
5579 strcpy(Name, "Dwellers on the threshold");
5581 else if (my_strstr(Name, " of "))
5583 concptr aider = my_strstr(Name, " of ");
5594 if (dummy[i-1] == 's')
5596 strcpy(&(dummy[i]), "es");
5601 strcpy(&(dummy[i]), "s");
5604 strcpy(&(dummy[i+1]), aider);
5605 strcpy(Name, dummy);
5607 else if (my_strstr(Name, "coins"))
5610 strcpy(dummy, "piles of ");
5611 strcat(dummy, Name);
5612 strcpy(Name, dummy);
5615 else if (my_strstr(Name, "Manes"))
5619 else if (streq(&(Name[NameLen - 2]), "ey"))
5621 strcpy(&(Name[NameLen - 2]), "eys");
5623 else if (Name[NameLen - 1] == 'y')
5625 strcpy(&(Name[NameLen - 1]), "ies");
5627 else if (streq(&(Name[NameLen - 4]), "ouse"))
5629 strcpy(&(Name[NameLen - 4]), "ice");
5631 else if (streq(&(Name[NameLen - 2]), "us"))
5633 strcpy(&(Name[NameLen - 2]), "i");
5635 else if (streq(&(Name[NameLen - 6]), "kelman"))
5637 strcpy(&(Name[NameLen - 6]), "kelmen");
5639 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5641 strcpy(&(Name[NameLen - 8]), "wordsmen");
5643 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5645 strcpy(&(Name[NameLen - 7]), "oodsmen");
5647 else if (streq(&(Name[NameLen - 7]), "eastman"))
5649 strcpy(&(Name[NameLen - 7]), "eastmen");
5651 else if (streq(&(Name[NameLen - 8]), "izardman"))
5653 strcpy(&(Name[NameLen - 8]), "izardmen");
5655 else if (streq(&(Name[NameLen - 5]), "geist"))
5657 strcpy(&(Name[NameLen - 5]), "geister");
5659 else if (streq(&(Name[NameLen - 2]), "ex"))
5661 strcpy(&(Name[NameLen - 2]), "ices");
5663 else if (streq(&(Name[NameLen - 2]), "lf"))
5665 strcpy(&(Name[NameLen - 2]), "lves");
5667 else if (suffix(Name, "ch") ||
5668 suffix(Name, "sh") ||
5669 suffix(Name, "nx") ||
5670 suffix(Name, "s") ||
5673 strcpy(&(Name[NameLen]), "es");
5677 strcpy(&(Name[NameLen]), "s");
5682 * @brief 現在のペットを表示するコマンドのメインルーチン /
5683 * Display current pets
5686 static void do_cmd_knowledge_pets(void)
5690 monster_type *m_ptr;
5691 GAME_TEXT pet_name[MAX_NLEN];
5693 int show_upkeep = 0;
5694 GAME_TEXT file_name[1024];
5697 /* Open a new file */
5698 fff = my_fopen_temp(file_name, 1024);
5700 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5705 /* Process the monsters (backwards) */
5706 for (i = m_max - 1; i >= 1; i--)
5708 /* Access the monster */
5709 m_ptr = ¤t_floor_ptr->m_list[i];
5711 /* Ignore "dead" monsters */
5712 if (!monster_is_valid(m_ptr)) continue;
5714 /* Calculate "upkeep" for pets */
5718 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5719 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5723 show_upkeep = calculate_upkeep();
5725 fprintf(fff, "----------------------------------------------\n");
5727 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5729 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5731 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5736 /* Display the file contents */
5737 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5743 * @brief 現在のペットを表示するコマンドのメインルーチン /
5746 * @note the player ghosts are ignored.
5748 static void do_cmd_knowledge_kill_count(void)
5755 GAME_TEXT file_name[1024];
5760 /* Open a new file */
5761 fff = my_fopen_temp(file_name, 1024);
5764 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5769 /* Allocate the "who" array */
5770 C_MAKE(who, max_r_idx, MONRACE_IDX);
5773 /* Monsters slain */
5776 for (kk = 1; kk < max_r_idx; kk++)
5778 monster_race *r_ptr = &r_info[kk];
5780 if (r_ptr->flags1 & (RF1_UNIQUE))
5782 bool dead = (r_ptr->max_num == 0);
5791 MONSTER_NUMBER This = r_ptr->r_pkills;
5801 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5804 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5806 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5812 /* Scan the monsters */
5813 for (i = 1; i < max_r_idx; i++)
5815 monster_race *r_ptr = &r_info[i];
5817 /* Use that monster */
5818 if (r_ptr->name) who[n++] = i;
5821 /* Sort the array by dungeon depth of monsters */
5822 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5824 /* Scan the monster races */
5825 for (k = 0; k < n; k++)
5827 monster_race *r_ptr = &r_info[who[k]];
5829 if (r_ptr->flags1 & (RF1_UNIQUE))
5831 bool dead = (r_ptr->max_num == 0);
5835 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5841 MONSTER_NUMBER This = r_ptr->r_pkills;
5846 /* p,tは人と数える by ita */
5847 if (my_strchr("pt", r_ptr->d_char))
5848 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5850 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5854 if (my_strstr(r_name + r_ptr->name, "coins"))
5856 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5860 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5866 strcpy(ToPlural, (r_name + r_ptr->name));
5867 plural_aux(ToPlural);
5868 fprintf(fff, " %d %s\n", This, ToPlural);
5878 fprintf(fff,"----------------------------------------------\n");
5880 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5882 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5886 /* Free the "who" array */
5887 C_KILL(who, max_r_idx, s16b);
5890 /* Display the file contents */
5891 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5897 * @brief モンスター情報リスト中のグループを表示する /
5898 * Display the object groups.
5902 * @param per_page リストの表示行
5903 * @param grp_idx グループのID配列
5904 * @param group_text グループ名の文字列配列
5905 * @param grp_cur 現在の選択ID
5906 * @param grp_top 現在の選択リスト最上部ID
5909 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)
5913 /* Display lines until done */
5914 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5916 /* Get the group index */
5917 int grp = grp_idx[grp_top + i];
5919 /* Choose a color */
5920 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5922 /* Erase the entire line */
5923 Term_erase(col, row + i, wid);
5925 /* Display the group label */
5926 c_put_str(attr, group_text[grp], row + i, col);
5932 * Move the cursor in a browser window
5934 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5935 IDX *list_cur, int list_cnt)
5940 IDX list = *list_cur;
5942 /* Extract direction */
5945 /* Hack -- scroll up full screen */
5950 /* Hack -- scroll down full screen */
5955 d = get_keymap_dir(ch);
5960 /* Diagonals - hack */
5961 if ((ddx[d] > 0) && ddy[d])
5966 Term_get_size(&wid, &hgt);
5968 browser_rows = hgt - 8;
5970 /* Browse group list */
5975 /* Move up or down */
5976 grp += ddy[d] * (browser_rows - 1);
5979 if (grp >= grp_cnt) grp = grp_cnt - 1;
5980 if (grp < 0) grp = 0;
5981 if (grp != old_grp) list = 0;
5984 /* Browse sub-list list */
5987 /* Move up or down */
5988 list += ddy[d] * browser_rows;
5991 if (list >= list_cnt) list = list_cnt - 1;
5992 if (list < 0) list = 0;
6004 if (col < 0) col = 0;
6005 if (col > 1) col = 1;
6012 /* Browse group list */
6017 /* Move up or down */
6021 if (grp >= grp_cnt) grp = grp_cnt - 1;
6022 if (grp < 0) grp = 0;
6023 if (grp != old_grp) list = 0;
6026 /* Browse sub-list list */
6029 /* Move up or down */
6030 list += (IDX)ddy[d];
6033 if (list >= list_cnt) list = list_cnt - 1;
6034 if (list < 0) list = 0;
6045 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6049 /* Clear the display lines */
6050 for (i = 0; i < height; i++)
6052 Term_erase(col, row + i, width);
6055 /* Bigtile mode uses double width */
6056 if (use_bigtile) width /= 2;
6058 /* Display lines until done */
6059 for (i = 0; i < height; i++)
6061 /* Display columns until done */
6062 for (j = 0; j < width; j++)
6066 TERM_LEN x = col + j;
6067 TERM_LEN y = row + i;
6069 /* Bigtile mode uses double width */
6070 if (use_bigtile) x += j;
6075 /* Ignore illegal characters */
6076 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6077 (!use_graphics && ic > 0x7f))
6083 /* Force correct code for both ASCII character and tile */
6084 if (c & 0x80) a |= 0x80;
6086 /* Display symbol */
6087 Term_queue_bigchar(x, y, a, c, 0, 0);
6094 * Place the cursor at the collect position for visual mode
6096 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6098 int i = (a & 0x7f) - attr_top;
6099 int j = c - char_left;
6101 TERM_LEN x = col + j;
6102 TERM_LEN y = row + i;
6104 /* Bigtile mode uses double width */
6105 if (use_bigtile) x += j;
6107 /* Place the cursor */
6113 * Clipboard variables for copy&paste in visual mode
6115 static TERM_COLOR attr_idx = 0;
6116 static SYMBOL_CODE char_idx = 0;
6118 /* Hack -- for feature lighting */
6119 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6120 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6123 * Do visual mode command -- Change symbols
6125 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6126 int height, int width,
6127 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6128 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6130 static TERM_COLOR attr_old = 0;
6131 static SYMBOL_CODE char_old = 0;
6136 if (*visual_list_ptr)
6139 *cur_attr_ptr = attr_old;
6140 *cur_char_ptr = char_old;
6141 *visual_list_ptr = FALSE;
6149 if (*visual_list_ptr)
6152 *visual_list_ptr = FALSE;
6153 *need_redraw = TRUE;
6161 if (!*visual_list_ptr)
6163 *visual_list_ptr = TRUE;
6165 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6166 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6168 attr_old = *cur_attr_ptr;
6169 char_old = *cur_char_ptr;
6180 /* Set the visual */
6181 attr_idx = *cur_attr_ptr;
6182 char_idx = *cur_char_ptr;
6184 /* Hack -- for feature lighting */
6185 for (i = 0; i < F_LIT_MAX; i++)
6187 attr_idx_feat[i] = 0;
6188 char_idx_feat[i] = 0;
6195 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6198 *cur_attr_ptr = attr_idx;
6199 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6200 if (!*visual_list_ptr) *need_redraw = TRUE;
6206 *cur_char_ptr = char_idx;
6207 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6208 if (!*visual_list_ptr) *need_redraw = TRUE;
6214 if (*visual_list_ptr)
6217 int d = get_keymap_dir(ch);
6218 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6219 SYMBOL_CODE c = *cur_char_ptr;
6221 if (use_bigtile) eff_width = width / 2;
6222 else eff_width = width;
6224 /* Restrict direction */
6225 if ((a == 0) && (ddy[d] < 0)) d = 0;
6226 if ((c == 0) && (ddx[d] < 0)) d = 0;
6227 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6228 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6230 a += (TERM_COLOR)ddy[d];
6231 c += (SYMBOL_CODE)ddx[d];
6233 /* Force correct code for both ASCII character and tile */
6234 if (c & 0x80) a |= 0x80;
6236 /* Set the visual */
6241 /* Move the frame */
6242 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6243 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6244 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6245 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6251 /* Visual mode command is not used */
6257 * Display the monsters in a group.
6259 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6260 int mon_cur, int mon_top, bool visual_only)
6264 /* Display lines until done */
6265 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6269 /* Get the race index */
6270 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6272 /* Access the race */
6273 monster_race *r_ptr = &r_info[r_idx];
6275 /* Choose a color */
6276 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6278 /* Display the name */
6279 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6281 /* Hack -- visual_list mode */
6284 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6286 if (p_ptr->wizard || visual_only)
6288 c_prt(attr, format("%d", r_idx), row + i, 62);
6291 /* Erase chars before overwritten by the race letter */
6292 Term_erase(69, row + i, 255);
6294 /* Display symbol */
6295 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6300 if (!(r_ptr->flags1 & RF1_UNIQUE))
6301 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6303 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6304 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6308 /* Clear remaining lines */
6309 for (; i < per_page; i++)
6311 Term_erase(col, row + i, 255);
6317 * Display known monsters.
6319 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6323 IDX grp_cur, grp_top, old_grp_cur;
6324 IDX mon_cur, mon_top;
6325 IDX grp_cnt, grp_idx[100];
6333 bool visual_list = FALSE;
6334 TERM_COLOR attr_top = 0;
6342 Term_get_size(&wid, &hgt);
6344 browser_rows = hgt - 8;
6346 /* Allocate the "mon_idx" array */
6347 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6352 if (direct_r_idx < 0)
6354 mode = visual_only ? 0x03 : 0x01;
6356 /* Check every group */
6357 for (i = 0; monster_group_text[i] != NULL; i++)
6359 /* Measure the label */
6360 len = strlen(monster_group_text[i]);
6362 /* Save the maximum length */
6363 if (len > max) max = len;
6365 /* See if any monsters are known */
6366 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6368 /* Build a list of groups with known monsters */
6369 grp_idx[grp_cnt++] = i;
6377 mon_idx[0] = direct_r_idx;
6380 /* Terminate the list */
6383 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6384 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6387 /* Terminate the list */
6388 grp_idx[grp_cnt] = -1;
6391 grp_cur = grp_top = 0;
6392 mon_cur = mon_top = 0;
6397 mode = visual_only ? 0x02 : 0x00;
6402 monster_race *r_ptr;
6407 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6408 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6409 prt(_("名前", "Name"), 4, max + 3);
6410 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6411 prt(_("文字", "Sym"), 4, 67);
6412 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6414 for (i = 0; i < 78; i++)
6416 Term_putch(i, 5, TERM_WHITE, '=');
6419 if (direct_r_idx < 0)
6421 for (i = 0; i < browser_rows; i++)
6423 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6430 if (direct_r_idx < 0)
6432 /* Scroll group list */
6433 if (grp_cur < grp_top) grp_top = grp_cur;
6434 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6436 /* Display a list of monster groups */
6437 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6439 if (old_grp_cur != grp_cur)
6441 old_grp_cur = grp_cur;
6443 /* Get a list of monsters in the current group */
6444 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6447 /* Scroll monster list */
6448 while (mon_cur < mon_top)
6449 mon_top = MAX(0, mon_top - browser_rows/2);
6450 while (mon_cur >= mon_top + browser_rows)
6451 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6456 /* Display a list of monsters in the current group */
6457 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6463 /* Display a monster name */
6464 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6466 /* Display visual list below first monster */
6467 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6471 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6472 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6473 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6474 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6477 /* Get the current monster */
6478 r_ptr = &r_info[mon_idx[mon_cur]];
6482 /* Mega Hack -- track this monster race */
6483 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6489 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6493 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6497 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6502 /* Do visual mode command if needed */
6503 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))
6505 if (direct_r_idx >= 0)
6530 /* Recall on screen */
6531 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6533 screen_roff(mon_idx[mon_cur], 0);
6544 /* Move the cursor */
6545 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6552 /* Free the "mon_idx" array */
6553 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6558 * Display the objects in a group.
6560 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6561 int object_cur, int object_top, bool visual_only)
6565 /* Display lines until done */
6566 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6568 GAME_TEXT o_name[MAX_NLEN];
6571 object_kind *flavor_k_ptr;
6573 /* Get the object index */
6574 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6576 /* Access the object */
6577 object_kind *k_ptr = &k_info[k_idx];
6579 /* Choose a color */
6580 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6581 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6584 if (!visual_only && k_ptr->flavor)
6586 /* Appearance of this object is shuffled */
6587 flavor_k_ptr = &k_info[k_ptr->flavor];
6591 /* Appearance of this object is very normal */
6592 flavor_k_ptr = k_ptr;
6597 attr = ((i + object_top == object_cur) ? cursor : attr);
6599 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6602 strip_name(o_name, k_idx);
6607 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6610 /* Display the name */
6611 c_prt(attr, o_name, row + i, col);
6613 /* Hack -- visual_list mode */
6616 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);
6618 if (p_ptr->wizard || visual_only)
6620 c_prt(attr, format("%d", k_idx), row + i, 70);
6623 a = flavor_k_ptr->x_attr;
6624 c = flavor_k_ptr->x_char;
6626 /* Display symbol */
6627 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6630 /* Clear remaining lines */
6631 for (; i < per_page; i++)
6633 Term_erase(col, row + i, 255);
6638 * Describe fake object
6640 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6643 object_type object_type_body;
6644 o_ptr = &object_type_body;
6647 /* Create the artifact */
6648 object_prep(o_ptr, k_idx);
6650 /* It's fully know */
6651 o_ptr->ident |= IDENT_KNOWN;
6653 /* Track the object */
6654 /* object_actual_track(o_ptr); */
6656 /* Hack - mark as fake */
6657 /* term_obj_real = FALSE; */
6660 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6662 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6670 * Display known objects
6672 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6676 IDX grp_cur, grp_top, old_grp_cur;
6677 IDX object_old, object_cur, object_top;
6681 OBJECT_IDX *object_idx;
6687 bool visual_list = FALSE;
6688 TERM_COLOR attr_top = 0;
6696 Term_get_size(&wid, &hgt);
6698 browser_rows = hgt - 8;
6700 /* Allocate the "object_idx" array */
6701 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6706 if (direct_k_idx < 0)
6708 mode = visual_only ? 0x03 : 0x01;
6710 /* Check every group */
6711 for (i = 0; object_group_text[i] != NULL; i++)
6713 /* Measure the label */
6714 len = strlen(object_group_text[i]);
6716 /* Save the maximum length */
6717 if (len > max) max = len;
6719 /* See if any monsters are known */
6720 if (collect_objects(i, object_idx, mode))
6722 /* Build a list of groups with known monsters */
6723 grp_idx[grp_cnt++] = i;
6732 object_kind *k_ptr = &k_info[direct_k_idx];
6733 object_kind *flavor_k_ptr;
6735 if (!visual_only && k_ptr->flavor)
6737 /* Appearance of this object is shuffled */
6738 flavor_k_ptr = &k_info[k_ptr->flavor];
6742 /* Appearance of this object is very normal */
6743 flavor_k_ptr = k_ptr;
6746 object_idx[0] = direct_k_idx;
6747 object_old = direct_k_idx;
6750 /* Terminate the list */
6753 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6754 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6757 /* Terminate the list */
6758 grp_idx[grp_cnt] = -1;
6761 grp_cur = grp_top = 0;
6762 object_cur = object_top = 0;
6767 mode = visual_only ? 0x02 : 0x00;
6772 object_kind *k_ptr, *flavor_k_ptr;
6779 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6780 if (direct_k_idx < 0) prt("グループ", 4, 0);
6781 prt("名前", 4, max + 3);
6782 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6785 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6786 if (direct_k_idx < 0) prt("Group", 4, 0);
6787 prt("Name", 4, max + 3);
6788 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6792 for (i = 0; i < 78; i++)
6794 Term_putch(i, 5, TERM_WHITE, '=');
6797 if (direct_k_idx < 0)
6799 for (i = 0; i < browser_rows; i++)
6801 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6808 if (direct_k_idx < 0)
6810 /* Scroll group list */
6811 if (grp_cur < grp_top) grp_top = grp_cur;
6812 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6814 /* Display a list of object groups */
6815 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6817 if (old_grp_cur != grp_cur)
6819 old_grp_cur = grp_cur;
6821 /* Get a list of objects in the current group */
6822 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6825 /* Scroll object list */
6826 while (object_cur < object_top)
6827 object_top = MAX(0, object_top - browser_rows/2);
6828 while (object_cur >= object_top + browser_rows)
6829 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6834 /* Display a list of objects in the current group */
6835 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6839 object_top = object_cur;
6841 /* Display a list of objects in the current group */
6842 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6844 /* Display visual list below first object */
6845 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6848 /* Get the current object */
6849 k_ptr = &k_info[object_idx[object_cur]];
6851 if (!visual_only && k_ptr->flavor)
6853 /* Appearance of this object is shuffled */
6854 flavor_k_ptr = &k_info[k_ptr->flavor];
6858 /* Appearance of this object is very normal */
6859 flavor_k_ptr = k_ptr;
6864 prt(format("<方向>%s%s%s, ESC",
6865 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6866 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6867 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6870 prt(format("<dir>%s%s%s, ESC",
6871 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6872 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6873 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6879 /* Mega Hack -- track this object */
6880 if (object_cnt) object_kind_track(object_idx[object_cur]);
6882 /* The "current" object changed */
6883 if (object_old != object_idx[object_cur])
6887 /* Remember the "current" object */
6888 object_old = object_idx[object_cur];
6894 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6898 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6902 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6907 /* Do visual mode command if needed */
6908 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))
6910 if (direct_k_idx >= 0)
6935 /* Recall on screen */
6936 if (!visual_list && !visual_only && (grp_cnt > 0))
6938 desc_obj_fake(object_idx[object_cur]);
6946 /* Move the cursor */
6947 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6953 /* Free the "object_idx" array */
6954 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6959 * Display the features in a group.
6961 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6962 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6964 int lit_col[F_LIT_MAX], i, j;
6965 int f_idx_col = use_bigtile ? 62 : 64;
6967 /* Correct columns 1 and 4 */
6968 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6969 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6970 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6972 /* Display lines until done */
6973 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6976 FEAT_IDX f_idx = feat_idx[feat_top + i];
6977 feature_type *f_ptr = &f_info[f_idx];
6978 int row_i = row + i;
6980 /* Choose a color */
6981 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
6983 /* Display the name */
6984 c_prt(attr, f_name + f_ptr->name, row_i, col);
6986 /* Hack -- visual_list mode */
6989 /* Display lighting level */
6990 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
6992 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));
6994 if (p_ptr->wizard || visual_only)
6996 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
6999 /* Display symbol */
7000 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);
7002 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7003 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7005 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7007 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7009 /* Mega-hack -- Use non-standard colour */
7010 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7012 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7016 /* Clear remaining lines */
7017 for (; i < per_page; i++)
7019 Term_erase(col, row + i, 255);
7025 * Interact with feature visuals.
7027 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7031 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7032 FEAT_IDX feat_cur, feat_top;
7034 FEAT_IDX grp_idx[100];
7038 TERM_LEN column = 0;
7042 bool visual_list = FALSE;
7043 TERM_COLOR attr_top = 0;
7046 TERM_LEN browser_rows;
7049 TERM_COLOR attr_old[F_LIT_MAX];
7050 SYMBOL_CODE char_old[F_LIT_MAX];
7051 TERM_COLOR *cur_attr_ptr;
7052 SYMBOL_CODE *cur_char_ptr;
7054 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7055 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7057 Term_get_size(&wid, &hgt);
7059 browser_rows = hgt - 8;
7061 /* Allocate the "feat_idx" array */
7062 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7067 if (direct_f_idx < 0)
7069 /* Check every group */
7070 for (i = 0; feature_group_text[i] != NULL; i++)
7072 /* Measure the label */
7073 len = strlen(feature_group_text[i]);
7075 /* Save the maximum length */
7076 if (len > max) max = len;
7078 /* See if any features are known */
7079 if (collect_features(i, feat_idx, 0x01))
7081 /* Build a list of groups with known features */
7082 grp_idx[grp_cnt++] = i;
7090 feature_type *f_ptr = &f_info[direct_f_idx];
7092 feat_idx[0] = direct_f_idx;
7095 /* Terminate the list */
7098 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7099 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7101 for (i = 0; i < F_LIT_MAX; i++)
7103 attr_old[i] = f_ptr->x_attr[i];
7104 char_old[i] = f_ptr->x_char[i];
7108 /* Terminate the list */
7109 grp_idx[grp_cnt] = -1;
7112 grp_cur = grp_top = 0;
7113 feat_cur = feat_top = 0;
7121 feature_type *f_ptr;
7127 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7128 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7129 prt(_("名前", "Name"), 4, max + 3);
7132 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7133 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7137 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7138 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7141 for (i = 0; i < 78; i++)
7143 Term_putch(i, 5, TERM_WHITE, '=');
7146 if (direct_f_idx < 0)
7148 for (i = 0; i < browser_rows; i++)
7150 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7157 if (direct_f_idx < 0)
7159 /* Scroll group list */
7160 if (grp_cur < grp_top) grp_top = grp_cur;
7161 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7163 /* Display a list of feature groups */
7164 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7166 if (old_grp_cur != grp_cur)
7168 old_grp_cur = grp_cur;
7170 /* Get a list of features in the current group */
7171 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7174 /* Scroll feature list */
7175 while (feat_cur < feat_top)
7176 feat_top = MAX(0, feat_top - browser_rows/2);
7177 while (feat_cur >= feat_top + browser_rows)
7178 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7183 /* Display a list of features in the current group */
7184 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7188 feat_top = feat_cur;
7190 /* Display a list of features in the current group */
7191 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7193 /* Display visual list below first object */
7194 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7198 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7199 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7200 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7203 /* Get the current feature */
7204 f_ptr = &f_info[feat_idx[feat_cur]];
7205 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7206 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7210 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7214 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7218 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7223 if (visual_list && ((ch == 'A') || (ch == 'a')))
7225 int prev_lighting_level = *lighting_level;
7229 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7230 else (*lighting_level)--;
7234 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7235 else (*lighting_level)++;
7238 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7239 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7241 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7242 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7247 else if ((ch == 'D') || (ch == 'd'))
7249 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7250 byte prev_x_char = f_ptr->x_char[*lighting_level];
7252 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7256 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7257 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7259 if (prev_x_char != f_ptr->x_char[*lighting_level])
7260 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7262 else *need_redraw = TRUE;
7267 /* Do visual mode command if needed */
7268 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))
7272 /* Restore previous visual settings */
7274 for (i = 0; i < F_LIT_MAX; i++)
7276 f_ptr->x_attr[i] = attr_old[i];
7277 f_ptr->x_char[i] = char_old[i];
7284 if (direct_f_idx >= 0) flag = TRUE;
7285 else *lighting_level = F_LIT_STANDARD;
7288 /* Preserve current visual settings */
7291 for (i = 0; i < F_LIT_MAX; i++)
7293 attr_old[i] = f_ptr->x_attr[i];
7294 char_old[i] = f_ptr->x_char[i];
7296 *lighting_level = F_LIT_STANDARD;
7303 for (i = 0; i < F_LIT_MAX; i++)
7305 attr_idx_feat[i] = f_ptr->x_attr[i];
7306 char_idx_feat[i] = f_ptr->x_char[i];
7315 /* Allow TERM_DARK text */
7316 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7318 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7319 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7337 /* Move the cursor */
7338 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7344 /* Free the "feat_idx" array */
7345 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7350 * List wanted monsters
7352 static void do_cmd_knowledge_kubi(void)
7357 GAME_TEXT file_name[1024];
7360 /* Open a new file */
7361 fff = my_fopen_temp(file_name, 1024);
7363 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7370 bool listed = FALSE;
7372 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
7373 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7375 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7376 fprintf(fff, "----------------------------------------------\n");
7378 for (i = 0; i < MAX_KUBI; i++)
7380 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7382 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7390 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monsters."));
7395 /* Display the file contents */
7396 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7401 * List virtues & status
7403 static void do_cmd_knowledge_virtues(void)
7406 GAME_TEXT file_name[1024];
7408 /* Open a new file */
7409 fff = my_fopen_temp(file_name, 1024);
7411 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7418 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment());
7423 /* Display the file contents */
7424 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7431 static void do_cmd_knowledge_dungeon(void)
7435 GAME_TEXT file_name[1024];
7438 /* Open a new file */
7439 fff = my_fopen_temp(file_name, 1024);
7441 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7448 for (i = 1; i < max_d_idx; i++)
7452 if (!d_info[i].maxdepth) continue;
7453 if (!max_dlv[i]) continue;
7454 if (d_info[i].final_guardian)
7456 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7458 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7460 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7465 /* Display the file contents */
7466 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7471 * List virtues & status
7474 static void do_cmd_knowledge_stat(void)
7478 GAME_TEXT file_name[1024];
7481 /* Open a new file */
7482 fff = my_fopen_temp(file_name, 1024);
7484 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7491 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7492 (2 * p_ptr->hitdie +
7493 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7495 if (p_ptr->knowledge & KNOW_HPRATE)
7496 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7497 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7499 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7500 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7502 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);
7503 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7510 /* Display the file contents */
7511 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7517 * Print all active quests
7519 static void do_cmd_knowledge_quests_current(FILE *fff)
7522 char rand_tmp_str[120] = "\0";
7523 GAME_TEXT name[MAX_NLEN];
7524 monster_race *r_ptr;
7526 int rand_level = 100;
7529 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7531 for (i = 1; i < max_q_idx; i++)
7533 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7534 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7535 (quest[i].status == QUEST_STATUS_COMPLETED))
7537 /* Set the quest number temporary */
7538 QUEST_IDX old_quest = p_ptr->inside_quest;
7541 /* Clear the text */
7542 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7543 quest_text_line = 0;
7545 p_ptr->inside_quest = i;
7547 /* Get the quest text */
7548 init_flags = INIT_SHOW_TEXT;
7550 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7552 /* Reset the old quest number */
7553 p_ptr->inside_quest = old_quest;
7555 /* No info from "silent" quests */
7556 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7560 if (quest[i].type != QUEST_TYPE_RANDOM)
7562 char note[80] = "\0";
7564 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7566 switch (quest[i].type)
7568 case QUEST_TYPE_KILL_LEVEL:
7569 case QUEST_TYPE_KILL_ANY_LEVEL:
7570 r_ptr = &r_info[quest[i].r_idx];
7571 strcpy(name, r_name + r_ptr->name);
7572 if (quest[i].max_num > 1)
7575 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7576 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7579 sprintf(note," - kill %d %s, have killed %d.",
7580 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7584 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7587 case QUEST_TYPE_FIND_ARTIFACT:
7590 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7592 object_type *q_ptr = &forge;
7593 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7594 object_prep(q_ptr, k_idx);
7595 q_ptr->name1 = quest[i].k_idx;
7596 q_ptr->ident = IDENT_STORE;
7597 object_desc(name, q_ptr, OD_NAME_ONLY);
7599 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find %s."), name);
7601 case QUEST_TYPE_FIND_EXIT:
7602 sprintf(note,_(" - 出口に到達する。", " - Reach exit."));
7605 case QUEST_TYPE_KILL_NUMBER:
7607 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7608 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7610 sprintf(note," - Kill %d monsters, have killed %d.",
7611 (int)quest[i].max_num, (int)quest[i].cur_num);
7615 case QUEST_TYPE_KILL_ALL:
7616 case QUEST_TYPE_TOWER:
7617 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7622 /* Print the quest info */
7623 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7624 quest[i].name, (int)quest[i].level, note);
7626 fputs(tmp_str, fff);
7628 if (quest[i].status == QUEST_STATUS_COMPLETED)
7630 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7631 fputs(tmp_str, fff);
7637 while (quest_text[j][0] && j < 10)
7639 fprintf(fff, " %s\n", quest_text[j]);
7644 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7647 rand_level = quest[i].level;
7649 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7651 /* Print the quest info */
7652 r_ptr = &r_info[quest[i].r_idx];
7653 strcpy(name, r_name + r_ptr->name);
7655 if (quest[i].max_num > 1)
7658 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7659 quest[i].name, (int)quest[i].level,
7660 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7664 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7665 quest[i].name, (int)quest[i].level,
7666 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7671 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7672 quest[i].name, (int)quest[i].level, name);
7679 /* Print the current random quest */
7680 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7682 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7686 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7689 char playtime_str[16];
7690 quest_type* const q_ptr = &quest[q_idx];
7692 if (is_fixed_quest_idx(q_idx))
7694 /* Set the quest number temporary */
7695 IDX old_quest = p_ptr->inside_quest;
7697 p_ptr->inside_quest = q_idx;
7700 init_flags = INIT_NAME_ONLY;
7702 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7704 /* Reset the old quest number */
7705 p_ptr->inside_quest = old_quest;
7707 /* No info from "silent" quests */
7708 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7711 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7712 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7714 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7716 /* Print the quest info */
7717 if (q_ptr->complev == 0)
7720 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7721 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7722 r_name+r_info[q_ptr->r_idx].name,
7723 (int)q_ptr->level, playtime_str);
7728 _(" %-35s (%3d階) - レベル%2d - %s\n",
7729 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7730 r_name+r_info[q_ptr->r_idx].name,
7738 /* Print the quest info */
7740 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7741 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7742 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7745 fputs(tmp_str, fff);
7751 * Print all finished quests
7753 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7756 QUEST_IDX total = 0;
7758 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7759 for (i = 1; i < max_q_idx; i++)
7761 QUEST_IDX q_idx = quest_num[i];
7762 quest_type* const q_ptr = &quest[q_idx];
7764 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7769 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7774 * Print all failed quests
7776 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7779 QUEST_IDX total = 0;
7781 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7782 for (i = 1; i < max_q_idx; i++)
7784 QUEST_IDX q_idx = quest_num[i];
7785 quest_type* const q_ptr = &quest[q_idx];
7787 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7788 do_cmd_knowledge_quests_aux(fff, q_idx))
7793 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7798 * Print all random quests
7800 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7802 GAME_TEXT tmp_str[120];
7804 QUEST_IDX total = 0;
7806 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7807 for (i = 1; i < max_q_idx; i++)
7809 /* No info from "silent" quests */
7810 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7812 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7816 /* Print the quest info */
7817 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7818 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7819 fputs(tmp_str, fff);
7822 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7826 * Print quest status of all active quests
7828 static void do_cmd_knowledge_quests(void)
7831 GAME_TEXT file_name[1024];
7836 /* Open a new file */
7837 fff = my_fopen_temp(file_name, 1024);
7840 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7845 /* Allocate Memory */
7846 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7848 /* Sort by compete level */
7849 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7850 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7852 /* Dump Quest Information */
7853 do_cmd_knowledge_quests_current(fff);
7855 do_cmd_knowledge_quests_completed(fff, quest_num);
7857 do_cmd_knowledge_quests_failed(fff, quest_num);
7861 do_cmd_knowledge_quests_wiz_random(fff);
7865 /* Display the file contents */
7866 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7870 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7877 static void do_cmd_knowledge_home(void)
7882 GAME_TEXT file_name[1024];
7884 GAME_TEXT o_name[MAX_NLEN];
7885 concptr paren = ")";
7887 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7889 /* Open a new file */
7890 fff = my_fopen_temp(file_name, 1024);
7892 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7899 /* Print all homes in the different towns */
7900 st_ptr = &town_info[1].store[STORE_HOME];
7902 /* Home -- if anything there */
7903 if (st_ptr->stock_num)
7908 /* Header with name of the town */
7909 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7911 /* Dump all available items */
7912 for (i = 0; i < st_ptr->stock_num; i++)
7915 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7916 object_desc(o_name, &st_ptr->stock[i], 0);
7917 if (strlen(o_name) <= 80-3)
7919 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7925 for (n = 0, t = o_name; n < 80-3; n++, t++)
7926 if(iskanji(*t)) {t++; n++;}
7927 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7929 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7930 fprintf(fff, " %.77s\n", o_name+n);
7933 object_desc(o_name, &st_ptr->stock[i], 0);
7934 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7939 /* Add an empty line */
7940 fprintf(fff, "\n\n");
7945 /* Display the file contents */
7946 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7952 * Check the status of "autopick"
7954 static void do_cmd_knowledge_autopick(void)
7958 GAME_TEXT file_name[1024];
7960 /* Open a new file */
7961 fff = my_fopen_temp(file_name, 1024);
7965 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7972 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7976 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7977 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7980 for (k = 0; k < max_autopick; k++)
7983 byte act = autopick_list[k].action;
7984 if (act & DONT_AUTOPICK)
7986 tmp = _("放置", "Leave");
7988 else if (act & DO_AUTODESTROY)
7990 tmp = _("破壊", "Destroy");
7992 else if (act & DO_AUTOPICK)
7994 tmp = _("拾う", "Pickup");
7998 tmp = _("確認", "Query");
8001 if (act & DO_DISPLAY)
8002 fprintf(fff, "%11s", format("[%s]", tmp));
8004 fprintf(fff, "%11s", format("(%s)", tmp));
8006 tmp = autopick_line_from_entry(&autopick_list[k]);
8007 fprintf(fff, " %s", tmp);
8012 /* Display the file contents */
8013 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8019 * Interact with "knowledge"
8021 void do_cmd_knowledge(void)
8024 bool need_redraw = FALSE;
8026 /* File type is "TEXT" */
8027 FILE_TYPE(FILE_TYPE_TEXT);
8030 /* Interact until done */
8035 /* Ask for a choice */
8036 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8037 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8039 /* Give some choices */
8043 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8044 prt("(2) 既知のアイテム の一覧", 7, 5);
8045 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8046 prt("(4) 既知のモンスター の一覧", 9, 5);
8047 prt("(5) 倒した敵の数 の一覧", 10, 5);
8048 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8049 prt("(7) 現在のペット の一覧", 12, 5);
8050 prt("(8) 我が家のアイテム の一覧", 13, 5);
8051 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8052 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8056 prt("(a) 自分に関する情報 の一覧", 6, 5);
8057 prt("(b) 突然変異 の一覧", 7, 5);
8058 prt("(c) 武器の経験値 の一覧", 8, 5);
8059 prt("(d) 魔法の経験値 の一覧", 9, 5);
8060 prt("(e) 技能の経験値 の一覧", 10, 5);
8061 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8062 prt("(g) 入ったダンジョン の一覧", 12, 5);
8063 prt("(h) 実行中のクエスト の一覧", 13, 5);
8064 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8069 prt("(1) Display known artifacts", 6, 5);
8070 prt("(2) Display known objects", 7, 5);
8071 prt("(3) Display remaining uniques", 8, 5);
8072 prt("(4) Display known monster", 9, 5);
8073 prt("(5) Display kill count", 10, 5);
8074 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8075 prt("(7) Display current pets", 12, 5);
8076 prt("(8) Display home inventory", 13, 5);
8077 prt("(9) Display *identified* equip.", 14, 5);
8078 prt("(0) Display terrain symbols.", 15, 5);
8082 prt("(a) Display about yourself", 6, 5);
8083 prt("(b) Display mutations", 7, 5);
8084 prt("(c) Display weapon proficiency", 8, 5);
8085 prt("(d) Display spell proficiency", 9, 5);
8086 prt("(e) Display misc. proficiency", 10, 5);
8087 prt("(f) Display virtues", 11, 5);
8088 prt("(g) Display dungeons", 12, 5);
8089 prt("(h) Display current quests", 13, 5);
8090 prt("(i) Display auto pick/destroy", 14, 5);
8094 prt(_("-続く-", "-more-"), 17, 8);
8095 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8096 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8097 /*prt("-) 前ページ", 21, 60);*/
8098 prt(_("コマンド:", "Command: "), 20, 0);
8101 if (i == ESCAPE) break;
8104 case ' ': /* Page change */
8108 case '1': /* Artifacts */
8109 do_cmd_knowledge_artifacts();
8111 case '2': /* Objects */
8112 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8114 case '3': /* Uniques */
8115 do_cmd_knowledge_uniques();
8117 case '4': /* Monsters */
8118 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8120 case '5': /* Kill count */
8121 do_cmd_knowledge_kill_count();
8123 case '6': /* wanted */
8124 if (!vanilla_town) do_cmd_knowledge_kubi();
8126 case '7': /* Pets */
8127 do_cmd_knowledge_pets();
8129 case '8': /* Home */
8130 do_cmd_knowledge_home();
8132 case '9': /* Resist list */
8133 do_cmd_knowledge_inven();
8135 case '0': /* Feature list */
8137 IDX lighting_level = F_LIT_STANDARD;
8138 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8142 case 'a': /* Max stat */
8143 do_cmd_knowledge_stat();
8145 case 'b': /* Mutations */
8146 do_cmd_knowledge_mutations();
8148 case 'c': /* weapon-exp */
8149 do_cmd_knowledge_weapon_exp();
8151 case 'd': /* spell-exp */
8152 do_cmd_knowledge_spell_exp();
8154 case 'e': /* skill-exp */
8155 do_cmd_knowledge_skill_exp();
8157 case 'f': /* Virtues */
8158 do_cmd_knowledge_virtues();
8160 case 'g': /* Dungeon */
8161 do_cmd_knowledge_dungeon();
8163 case 'h': /* Quests */
8164 do_cmd_knowledge_quests();
8166 case 'i': /* Autopick */
8167 do_cmd_knowledge_autopick();
8169 default: /* Unknown option */
8177 if (need_redraw) do_cmd_redraw();
8182 * Check on the status of an active quest
8184 void do_cmd_checkquest(void)
8186 /* File type is "TEXT" */
8187 FILE_TYPE(FILE_TYPE_TEXT);
8191 do_cmd_knowledge_quests();
8197 * Display the time and date
8199 void do_cmd_time(void)
8201 int day, hour, min, full, start, end, num;
8209 extract_day_hour_min(&day, &hour, &min);
8211 full = hour * 100 + min;
8218 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8220 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8221 else strcpy(day_buf, "*****");
8223 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8224 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8227 if (!randint0(10) || p_ptr->image)
8229 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8233 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8236 /* Open this file */
8237 fff = my_fopen(buf, "rt");
8241 /* Find this time */
8242 while (!my_fgets(fff, buf, sizeof(buf)))
8244 /* Ignore comments */
8245 if (!buf[0] || (buf[0] == '#')) continue;
8247 /* Ignore invalid lines */
8248 if (buf[1] != ':') continue;
8250 /* Process 'Start' */
8253 /* Extract the starting time */
8254 start = atoi(buf + 2);
8256 /* Assume valid for an hour */
8266 /* Extract the ending time */
8267 end = atoi(buf + 2);
8273 /* Ignore incorrect range */
8274 if ((start > full) || (full > end)) continue;
8276 /* Process 'Description' */
8281 /* Apply the randomizer */
8282 if (!randint0(num)) strcpy(desc, buf + 2);