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.
48 #include "cmd-spell.h"
51 #include "player-effects.h"
52 #include "player-status.h"
53 #include "player-skill.h"
54 #include "player-personality.h"
61 #include "object-flavor.h"
62 #include "object-hook.h"
64 #include "monster-status.h"
66 #include "view-mainwindow.h"
67 #include "dungeon-file.h"
69 #include "player-class.h"
70 #include "player-move.h"
72 #include "objectkind.h"
73 #include "floor-town.h"
79 * Mark strings for auto dump
81 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
82 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
85 * Variables for auto dump
87 static FILE *auto_dump_stream;
88 static concptr auto_dump_mark;
89 static int auto_dump_line_num;
93 * @brief prf出力内容を消去する /
94 * Remove old lines automatically generated before.
95 * @param orig_file 消去を行うファイル名
97 static void remove_auto_dump(concptr orig_file)
99 FILE *tmp_fff, *orig_fff;
103 bool between_mark = FALSE;
104 bool changed = FALSE;
106 long header_location = 0;
107 char header_mark_str[80];
108 char footer_mark_str[80];
111 /* Prepare a header/footer mark string */
112 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
113 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
115 mark_len = strlen(footer_mark_str);
117 /* Open an old dump file in read-only mode */
118 orig_fff = my_fopen(orig_file, "r");
120 /* If original file does not exist, nothing to do */
121 if (!orig_fff) return;
123 /* Open a new (temporary) file */
124 tmp_fff = my_fopen_temp(tmp_file, 1024);
128 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
133 /* Loop for every line */
137 if (my_fgets(orig_fff, buf, sizeof(buf)))
139 /* Read error: Assume End of File */
142 * Was looking for the footer, but not found.
144 * Since automatic dump might be edited by hand,
145 * it's dangerous to kill these lines.
146 * Seek back to the next line of the (pseudo) header,
151 fseek(orig_fff, header_location, SEEK_SET);
152 between_mark = FALSE;
156 /* Success -- End the loop */
163 /* We are looking for the header mark of automatic dump */
166 /* Is this line a header? */
167 if (!strcmp(buf, header_mark_str))
169 /* Memorise seek point of this line */
170 header_location = ftell(orig_fff);
172 /* Initialize counter for number of lines */
175 /* Look for the footer from now */
178 /* There are some changes */
185 /* Copy orginally lines */
186 fprintf(tmp_fff, "%s\n", buf);
190 /* We are looking for the footer mark of automatic dump */
193 /* Is this line a footer? */
194 if (!strncmp(buf, footer_mark_str, mark_len))
199 * Compare the number of lines
201 * If there is an inconsistency between
202 * actual number of lines and the
203 * number here, the automatic dump
204 * might be edited by hand. So it's
205 * dangerous to kill these lines.
206 * Seek back to the next line of the
207 * (pseudo) header, and read again.
209 if (!sscanf(buf + mark_len, " (%d)", &tmp)
212 fseek(orig_fff, header_location, SEEK_SET);
215 /* Look for another header */
216 between_mark = FALSE;
222 /* Ignore old line, and count number of lines */
232 /* If there are some changes, overwrite the original file with new one */
235 /* Copy contents of temporary file */
237 tmp_fff = my_fopen(tmp_file, "r");
238 orig_fff = my_fopen(orig_file, "w");
240 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
241 fprintf(orig_fff, "%s\n", buf);
247 /* Kill the temporary file */
255 * @brief prfファイルのフォーマットに従った内容を出力する /
256 * Dump a formatted line, using "vstrnfmt()".
259 static void auto_dump_printf(concptr fmt, ...)
266 /* Begin the Varargs Stuff */
269 /* Format the args, save the length */
270 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
272 /* End the Varargs Stuff */
275 /* Count number of lines */
276 for (p = buf; *p; p++)
278 if (*p == '\n') auto_dump_line_num++;
282 fprintf(auto_dump_stream, "%s", buf);
287 * @brief prfファイルをファイルオープンする /
288 * Open file to append auto dump.
290 * @param mark 出力するヘッダマーク
291 * @return ファイルポインタを取得できたらTRUEを返す
293 static bool open_auto_dump(concptr buf, concptr mark)
296 char header_mark_str[80];
298 /* Save the mark string */
299 auto_dump_mark = mark;
301 /* Prepare a header mark string */
302 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
304 /* Remove old macro dumps */
305 remove_auto_dump(buf);
307 /* Append to the file */
308 auto_dump_stream = my_fopen(buf, "a");
311 if (!auto_dump_stream) {
312 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
320 fprintf(auto_dump_stream, "%s\n", header_mark_str);
322 /* Initialize counter */
323 auto_dump_line_num = 0;
325 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
326 "# *Warning!* The lines below are an automatic dump.\n"));
327 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
328 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
334 * @brief prfファイルをファイルクローズする /
335 * Append foot part and close auto dump.
338 static void close_auto_dump(void)
340 char footer_mark_str[80];
342 /* Prepare a footer mark string */
343 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
345 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
346 "# *Warning!* The lines below are an automatic dump.\n"));
347 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
348 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
350 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
353 my_fclose(auto_dump_stream);
362 * @brief Return suffix of ordinal number
364 * @return pointer of suffix string.
366 concptr get_ordinal_number_suffix(int num)
368 num = ABS(num) % 100;
372 return (num == 11) ? "th" : "st";
374 return (num == 12) ? "th" : "nd";
376 return (num == 13) ? "th" : "rd";
385 * @brief 日記にメッセージを追加する /
386 * Take note to the diary.
387 * @param type 日記内容のID
388 * @param num 日記内容のIDに応じた数値
389 * @param note 日記内容のIDに応じた文字列参照ポインタ
392 errr do_cmd_write_nikki(int type, int num, concptr note)
396 GAME_TEXT file_name[MAX_NLEN];
398 concptr note_level = "";
399 bool do_level = TRUE;
400 char note_level_buf[40];
403 static bool disable_nikki = FALSE;
405 extract_day_hour_min(&day, &hour, &min);
407 if (disable_nikki) return(-1);
409 if (type == NIKKI_FIX_QUEST_C ||
410 type == NIKKI_FIX_QUEST_F ||
411 type == NIKKI_RAND_QUEST_C ||
412 type == NIKKI_RAND_QUEST_F ||
413 type == NIKKI_TO_QUEST)
417 old_quest = p_ptr->inside_quest;
418 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
420 /* Get the quest text */
421 init_flags = INIT_NAME_ONLY;
423 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
425 /* Reset the old quest number */
426 p_ptr->inside_quest = old_quest;
429 /* different filne name to avoid mixing */
430 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
432 /* Build the filename */
433 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
435 /* File type is "TEXT" */
436 FILE_TYPE(FILE_TYPE_TEXT);
438 fff = my_fopen(buf, "a");
443 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
449 q_idx = quest_number(current_floor_ptr->dun_level);
453 if (p_ptr->inside_arena)
454 note_level = _("アリーナ:", "Arane:");
455 else if (!current_floor_ptr->dun_level)
456 note_level = _("地上:", "Surface:");
457 else if (q_idx && (is_fixed_quest_idx(q_idx)
458 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
459 note_level = _("クエスト:", "Quest:");
463 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
465 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
467 note_level = note_level_buf;
475 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
476 else fputs(_("*****日目\n", "Day *****\n"), fff);
484 fprintf(fff, "%s\n",note);
488 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
493 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
496 case NIKKI_ART_SCROLL:
498 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
503 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
506 case NIKKI_FIX_QUEST_C:
508 if (quest[num].flags & QUEST_FLAG_SILENT) break;
509 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
510 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
513 case NIKKI_FIX_QUEST_F:
515 if (quest[num].flags & QUEST_FLAG_SILENT) break;
516 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
517 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
520 case NIKKI_RAND_QUEST_C:
522 GAME_TEXT name[MAX_NLEN];
523 strcpy(name, r_name+r_info[quest[num].r_idx].name);
524 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
525 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
528 case NIKKI_RAND_QUEST_F:
530 GAME_TEXT name[MAX_NLEN];
531 strcpy(name, r_name+r_info[quest[num].r_idx].name);
532 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
533 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
536 case NIKKI_MAXDEAPTH:
538 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
539 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
540 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
541 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
546 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
547 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
548 _(d_name + d_info[num].name, (int)max_dlv[num]),
549 _((int)max_dlv[num], d_name + d_info[num].name));
555 if (q_idx && (is_fixed_quest_idx(q_idx)
556 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
558 to = _("地上", "the surface");
562 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
563 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
565 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
571 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
572 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
573 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
575 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
580 if (quest[num].flags & QUEST_FLAG_SILENT) break;
581 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
582 hour, min, note_level, quest[num].name);
587 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
588 hour, min, note_level);
593 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
598 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
606 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
607 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
610 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
611 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
613 if (num == MAX_ARENA_MONS)
615 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
616 " won all fight to become a Chanpion.\n"));
623 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
629 if (!current_floor_ptr->dun_level)
630 to = _("地上", "the surface");
632 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
634 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
635 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
641 if (!current_floor_ptr->dun_level)
642 to = _("地上", "the surface");
644 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
646 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
647 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
652 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
655 case NIKKI_GAMESTART:
657 time_t ct = time((time_t*)0);
661 fprintf(fff, "%s %s",note, ctime(&ct));
664 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
667 case NIKKI_NAMED_PET:
669 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
672 case RECORD_NAMED_PET_NAME:
673 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
675 case RECORD_NAMED_PET_UNNAME:
676 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
678 case RECORD_NAMED_PET_DISMISS:
679 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
681 case RECORD_NAMED_PET_DEATH:
682 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
684 case RECORD_NAMED_PET_MOVED:
685 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
687 case RECORD_NAMED_PET_LOST_SIGHT:
688 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
690 case RECORD_NAMED_PET_DESTROY:
691 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
693 case RECORD_NAMED_PET_EARTHQUAKE:
694 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
696 case RECORD_NAMED_PET_GENOCIDE:
697 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
699 case RECORD_NAMED_PET_WIZ_ZAP:
700 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
702 case RECORD_NAMED_PET_TELE_LEVEL:
703 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
705 case RECORD_NAMED_PET_BLAST:
706 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
708 case RECORD_NAMED_PET_HEAL_LEPER:
709 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
711 case RECORD_NAMED_PET_COMPACT:
712 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
714 case RECORD_NAMED_PET_LOSE_PARENT:
715 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
726 case NIKKI_WIZARD_LOG:
727 fprintf(fff, "%s\n", note);
736 if (do_level) write_level = FALSE;
742 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
745 * @brief 日記のタイトル表記と内容出力 /
748 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
750 static void do_cmd_disp_nikki(void)
752 char nikki_title[256];
753 GAME_TEXT file_name[MAX_NLEN];
758 static const char subtitle[][30] = {"最強の肉体を求めて",
789 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
790 "Attack is the best form of defence.",
792 "An unexpected windfall",
793 "A drowning man will catch at a straw",
794 "Don't count your chickens before they are hatched.",
795 "It is no use crying over spilt milk.",
796 "Seeing is believing.",
797 "Strike the iron while it is hot.",
798 "I don't care what follows.",
799 "To dig a well to put out a house on fire.",
800 "Tomorrow is another day.",
801 "Easy come, easy go.",
802 "The more haste, the less speed.",
803 "Where there is life, there is hope.",
804 "There is no royal road to *WINNER*.",
805 "Danger past, God forgotten.",
806 "The best thing to do now is to run away.",
807 "Life is but an empty dream.",
808 "Dead men tell no tales.",
809 "A book that remains shut is but a block.",
810 "Misfortunes never come singly.",
811 "A little knowledge is a dangerous thing.",
812 "History repeats itself.",
813 "*WINNER* was not built in a day.",
814 "Ignorance is bliss.",
815 "To lose is to win?",
816 "No medicine can cure folly.",
817 "All good things come to an end.",
818 "M$ Empire strikes back.",
819 "To see is to believe",
821 "Quest of The World's Greatest Brain"};
823 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
825 /* Build the filename */
826 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
828 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
829 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
830 else if (IS_WIZARD_CLASS())
831 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
832 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
835 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
837 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
840 /* Display the file contents */
841 show_file(FALSE, buf, nikki_title, -1, 0);
845 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
848 static void do_cmd_bunshou(void)
851 char bunshou[80] = "\0";
853 if (get_string(_("内容: ", "diary note: "), tmp, 79))
855 strcpy(bunshou, tmp);
857 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
862 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
865 static void do_cmd_last_get(void)
870 if (record_o_name[0] == '\0') return;
872 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
873 if (!get_check(buf)) return;
875 turn_tmp = current_world_ptr->game_turn;
876 current_world_ptr->game_turn = record_turn;
877 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
878 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
879 current_world_ptr->game_turn = turn_tmp;
883 * @brief ファイル中の全日記記録を消去する /
886 static void do_cmd_erase_nikki(void)
888 GAME_TEXT file_name[MAX_NLEN];
892 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
893 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
895 /* Build the filename */
896 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
899 fff = my_fopen(buf, "w");
902 msg_format(_("記録を消去しました。", "deleted record."));
904 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
913 void do_cmd_nikki(void)
917 /* File type is "TEXT" */
918 FILE_TYPE(FILE_TYPE_TEXT);
921 /* Interact until done */
926 /* Ask for a choice */
927 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
929 /* Give some choices */
930 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
931 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
932 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
933 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
935 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
938 prt(_("コマンド:", "Command: "), 18, 0);
943 if (i == ESCAPE) break;
957 do_cmd_erase_nikki();
961 prepare_movie_hooks();
963 default: /* Unknown option */
973 * @brief 画面を再描画するコマンドのメインルーチン
974 * Hack -- redraw the screen
978 * This command performs various low level updates, clears all the "extra"
979 * windows, does a total redraw of the main window, and requests all of the
980 * interesting updates and redraws that I can think of.
982 * This command is also used to "instantiate" the results of the user
983 * selecting various things, such as graphics mode, so it must call
984 * the "TERM_XTRA_REACT" hook before redrawing the windows.
987 void do_cmd_redraw(void)
993 /* Hack -- react to changes */
994 Term_xtra(TERM_XTRA_REACT, 0);
996 /* Combine and Reorder the pack (later) */
997 p_ptr->update |= (PU_COMBINE | PU_REORDER);
998 p_ptr->update |= (PU_TORCH);
999 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1000 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1001 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1002 p_ptr->update |= (PU_MONSTERS);
1004 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1006 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1007 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1013 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1016 /* Redraw every window */
1017 for (j = 0; j < 8; j++)
1020 if (!angband_term[j]) continue;
1023 Term_activate(angband_term[j]);
1032 * @brief 名前を変更するコマンドのメインルーチン
1033 * Hack -- change name
1036 void do_cmd_change_name(void)
1051 /* Display the player */
1052 display_player(mode);
1057 display_player(mode);
1062 Term_putstr(2, 23, -1, TERM_WHITE,
1063 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1065 Term_putstr(2, 23, -1, TERM_WHITE,
1066 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1074 if (c == ESCAPE) break;
1081 /* Process the player name */
1082 process_player_name(FALSE);
1088 sprintf(tmp, "%s.txt", player_base);
1089 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1091 if (tmp[0] && (tmp[0] != ' '))
1093 file_character(tmp);
1111 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1118 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1119 * Recall the most recent message
1122 void do_cmd_message_one(void)
1124 /* Recall one message */
1125 prt(format("> %s", message_str(0)), 0, 0);
1130 * @brief メッセージのログを表示するコマンドのメインルーチン
1131 * Recall the most recent message
1135 * Show previous messages to the user -BEN-
1137 * The screen format uses line 0 and 23 for headers and prompts,
1138 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1140 * This command shows you which commands you are viewing, and allows
1141 * you to "search" for strings in the recall.
1143 * Note that messages may be longer than 80 characters, but they are
1144 * displayed using "infinite" length, with a special sub-command to
1145 * "slide" the virtual display to the left or right.
1147 * Attempt to only hilite the matching portions of the string.
1150 void do_cmd_messages(int num_now)
1154 char shower_str[81];
1155 char finder_str[81];
1157 concptr shower = NULL;
1161 Term_get_size(&wid, &hgt);
1163 /* Number of message lines in a screen */
1164 num_lines = hgt - 4;
1167 strcpy(finder_str, "");
1170 strcpy(shower_str, "");
1172 /* Total messages */
1175 /* Start on first message */
1180 /* Process requests until done */
1186 /* Dump up to 20 lines of messages */
1187 for (j = 0; (j < num_lines) && (i + j < n); j++)
1189 concptr msg = message_str(i+j);
1191 /* Dump the messages, bottom to top */
1192 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1194 /* Hilite "shower" */
1195 if (shower && shower[0])
1199 /* Display matches */
1200 while ((str = my_strstr(str, shower)) != NULL)
1202 int len = strlen(shower);
1204 /* Display the match */
1205 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1213 /* Erase remaining lines */
1214 for (; j < num_lines; j++)
1216 Term_erase(0, num_lines + 1 - j, 255);
1219 /* Display header */
1221 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1222 i, i + j - 1, n), 0, 0);
1224 /* Display prompt (not very informative) */
1225 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1226 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1228 skey = inkey_special(TRUE);
1230 /* Exit on Escape */
1231 if (skey == ESCAPE) break;
1233 /* Hack -- Save the old index */
1238 /* Hack -- handle show */
1241 prt(_("強調: ", "Show: "), hgt - 1, 0);
1243 /* Get a "shower" string, or continue */
1244 strcpy(back_str, shower_str);
1245 if (askfor(shower_str, 80))
1248 shower = shower_str[0] ? shower_str : NULL;
1250 else strcpy(shower_str, back_str);
1254 /* Hack -- handle find */
1261 prt(_("検索: ", "Find: "), hgt - 1, 0);
1263 /* Get a "finder" string, or continue */
1264 strcpy(back_str, finder_str);
1265 if (!askfor(finder_str, 80))
1267 strcpy(finder_str, back_str);
1270 else if (!finder_str[0])
1272 shower = NULL; /* Stop showing */
1277 shower = finder_str;
1280 for (z = i + 1; z < n; z++)
1282 concptr msg = message_str(z);
1285 if (my_strstr(msg, finder_str))
1296 /* Recall 1 older message */
1298 /* Go to the oldest line */
1302 /* Recall 1 newer message */
1304 /* Go to the newest line */
1308 /* Recall 1 older message */
1313 /* Go older if legal */
1314 i = MIN(i + 1, n - num_lines);
1317 /* Recall 10 older messages */
1319 /* Go older if legal */
1320 i = MIN(i + 10, n - num_lines);
1323 /* Recall 20 older messages */
1328 /* Go older if legal */
1329 i = MIN(i + num_lines, n - num_lines);
1332 /* Recall 20 newer messages */
1336 /* Go newer (if able) */
1337 i = MAX(0, i - num_lines);
1340 /* Recall 10 newer messages */
1342 /* Go newer (if able) */
1346 /* Recall 1 newer messages */
1349 /* Go newer (if able) */
1354 /* Hack -- Error of some kind */
1362 * @brief チートオプションを変更するコマンドのメインルーチン
1363 * Interact with some options for cheating
1364 * @param info 表示メッセージ
1367 static void do_cmd_options_cheat(concptr info)
1370 int i, k = 0, n = CHEAT_MAX;
1374 /* Interact with the player */
1380 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1385 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1386 prt(" << 注意 >>", 11, 0);
1387 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1388 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1389 prt(" じらないようにして下さい。", 14, 0);
1391 /* Display the options */
1392 for (i = 0; i < n; i++)
1394 byte a = TERM_WHITE;
1396 /* Color current option */
1397 if (i == k) a = TERM_L_BLUE;
1399 /* Display the option text */
1400 sprintf(buf, "%-48s: %s (%s)",
1401 cheat_info[i].o_desc,
1402 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1403 cheat_info[i].o_text);
1404 c_prt(a, buf, i + 2, 0);
1407 /* Hilite current option */
1408 move_cursor(k + 2, 50);
1414 * HACK - Try to translate the key into a direction
1415 * to allow using the roguelike keys for navigation.
1417 dir = get_keymap_dir(ch);
1418 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1432 k = (n + k - 1) % n;
1450 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1451 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1452 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1453 (*cheat_info[k].o_var) = TRUE;
1462 (*cheat_info[k].o_var) = FALSE;
1469 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1470 /* Peruse the help file */
1471 (void)show_file(TRUE, buf, NULL, 0, 0);
1488 * @brief セーブ頻度ターンの次の値を返す
1489 * @param current 現在のセーブ頻度ターン値
1490 * @return 次のセーブ頻度ターン値
1492 static s16b toggle_frequency(s16b current)
1497 case 50: return 100;
1498 case 100: return 250;
1499 case 250: return 500;
1500 case 500: return 1000;
1501 case 1000: return 2500;
1502 case 2500: return 5000;
1503 case 5000: return 10000;
1504 case 10000: return 25000;
1511 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1512 * @param info 表示メッセージ
1515 static void do_cmd_options_autosave(concptr info)
1518 int i, k = 0, n = 2;
1523 /* Interact with the player */
1527 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1528 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1532 /* Display the options */
1533 for (i = 0; i < n; i++)
1535 byte a = TERM_WHITE;
1537 /* Color current option */
1538 if (i == k) a = TERM_L_BLUE;
1540 /* Display the option text */
1541 sprintf(buf, "%-48s: %s (%s)",
1542 autosave_info[i].o_desc,
1543 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1544 autosave_info[i].o_text);
1545 c_prt(a, buf, i + 2, 0);
1547 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1549 /* Hilite current option */
1550 move_cursor(k + 2, 50);
1566 k = (n + k - 1) % n;
1584 (*autosave_info[k].o_var) = TRUE;
1593 (*autosave_info[k].o_var) = FALSE;
1601 autosave_freq = toggle_frequency(autosave_freq);
1602 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1608 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1624 * @brief 標準オプションを変更するコマンドのサブルーチン /
1625 * Interact with some options
1626 * @param page オプションページ番号
1627 * @param info 表示メッセージ
1630 void do_cmd_options_aux(int page, concptr info)
1633 int i, k = 0, n = 0, l;
1636 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1637 (!p_ptr->wizard || !allow_debug_opts);
1640 /* Lookup the options */
1641 for (i = 0; i < 24; i++) opt[i] = 0;
1643 /* Scan the options */
1644 for (i = 0; option_info[i].o_desc; i++)
1646 /* Notice options on this "page" */
1647 if (option_info[i].o_page == page) opt[n++] = i;
1651 /* Interact with the player */
1657 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1658 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1661 /* HACK -- description for easy-auto-destroy options */
1662 if (page == OPT_PAGE_AUTODESTROY)
1663 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1664 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1666 /* Display the options */
1667 for (i = 0; i < n; i++)
1669 byte a = TERM_WHITE;
1671 /* Color current option */
1672 if (i == k) a = TERM_L_BLUE;
1674 /* Display the option text */
1675 sprintf(buf, "%-48s: %s (%.19s)",
1676 option_info[opt[i]].o_desc,
1677 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1678 option_info[opt[i]].o_text);
1679 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1680 else c_prt(a, buf, i + 2, 0);
1683 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1686 /* Hilite current option */
1687 move_cursor(k + 2 + l, 50);
1693 * HACK - Try to translate the key into a direction
1694 * to allow using the roguelike keys for navigation.
1696 dir = get_keymap_dir(ch);
1697 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1711 k = (n + k - 1) % n;
1728 if (browse_only) break;
1729 (*option_info[opt[k]].o_var) = TRUE;
1738 if (browse_only) break;
1739 (*option_info[opt[k]].o_var) = FALSE;
1747 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1753 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1754 /* Peruse the help file */
1755 (void)show_file(TRUE, buf, NULL, 0, 0);
1772 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1773 * Modify the "window" options
1776 static void do_cmd_options_win(void)
1786 /* Memorize old flags */
1787 for (j = 0; j < 8; j++)
1789 /* Acquire current flags */
1790 old_flag[j] = window_flag[j];
1799 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1801 /* Display the windows */
1802 for (j = 0; j < 8; j++)
1804 byte a = TERM_WHITE;
1806 concptr s = angband_term_name[j];
1809 if (j == x) a = TERM_L_BLUE;
1811 /* Window name, staggered, centered */
1812 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1815 /* Display the options */
1816 for (i = 0; i < 16; i++)
1818 byte a = TERM_WHITE;
1820 concptr str = window_flag_desc[i];
1823 if (i == y) a = TERM_L_BLUE;
1826 if (!str) str = _("(未使用)", "(Unused option)");
1829 Term_putstr(0, i + 5, -1, a, str);
1831 /* Display the windows */
1832 for (j = 0; j < 8; j++)
1838 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1841 if (window_flag[j] & (1L << i)) c = 'X';
1844 Term_putch(35 + j * 5, i + 5, a, c);
1849 Term_gotoxy(35 + x * 5, y + 5);
1867 for (j = 0; j < 8; j++)
1869 window_flag[j] &= ~(1L << y);
1873 for (i = 0; i < 16; i++)
1875 window_flag[x] &= ~(1L << i);
1888 window_flag[x] |= (1L << y);
1896 window_flag[x] &= ~(1L << y);
1902 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1910 d = get_keymap_dir(ch);
1912 x = (x + ddx[d] + 8) % 8;
1913 y = (y + ddy[d] + 16) % 16;
1920 /* Notice changes */
1921 for (j = 0; j < 8; j++)
1926 if (!angband_term[j]) continue;
1928 /* Ignore non-changes */
1929 if (window_flag[j] == old_flag[j]) continue;
1932 Term_activate(angband_term[j]);
1949 option_fields[OPT_NUM] =
1952 { '1', " キー入力 オプション", 3 },
1953 { '2', " マップ画面 オプション", 4 },
1954 { '3', " テキスト表示 オプション", 5 },
1955 { '4', " ゲームプレイ オプション", 6 },
1956 { '5', " 行動中止関係 オプション", 7 },
1957 { '6', " 簡易自動破壊 オプション", 8 },
1958 { 'r', " プレイ記録 オプション", 9 },
1960 { 'p', "自動拾いエディタ", 11 },
1961 { 'd', " 基本ウェイト量 ", 12 },
1962 { 'h', "低ヒットポイント", 13 },
1963 { 'm', " 低魔力色閾値 ", 14 },
1964 { 'a', " 自動セーブ オプション", 15 },
1965 { 'w', "ウインドウフラグ", 16 },
1967 { 'b', " 初期 オプション (参照のみ)", 18 },
1968 { 'c', " 詐欺 オプション", 19 },
1970 { '1', "Input Options", 3 },
1971 { '2', "Map Screen Options", 4 },
1972 { '3', "Text Display Options", 5 },
1973 { '4', "Game-Play Options", 6 },
1974 { '5', "Disturbance Options", 7 },
1975 { '6', "Easy Auto-Destroyer Options", 8 },
1976 { 'r', "Play record Options", 9 },
1978 { 'p', "Auto-picker/destroyer editor", 11 },
1979 { 'd', "Base Delay Factor", 12 },
1980 { 'h', "Hitpoint Warning", 13 },
1981 { 'm', "Mana Color Threshold", 14 },
1982 { 'a', "Autosave Options", 15 },
1983 { 'w', "Window Flags", 16 },
1985 { 'b', "Birth Options (Browse Only)", 18 },
1986 { 'c', "Cheat Options", 19 },
1992 * @brief 標準オプションを変更するコマンドのメインルーチン /
1993 * Set or unset various options.
1997 * The user must use the "Ctrl-R" command to "adapt" to changes
1998 * in any options which control "visual" aspects of the game.
2001 void do_cmd_options(void)
2013 /* Does not list cheat option when cheat option is off */
2014 if (!p_ptr->noscore && !allow_debug_opts) n--;
2017 /* Why are we here */
2018 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2022 /* Give some choices */
2023 for (i = 0; i < n; i++)
2025 byte a = TERM_WHITE;
2026 if (i == y) a = TERM_L_BLUE;
2027 Term_putstr(5, option_fields[i].row, -1, a,
2028 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2031 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2034 skey = inkey_special(TRUE);
2035 if (!(skey & SKEY_MASK)) k = (char)skey;
2039 if (k == ESCAPE) break;
2041 if (my_strchr("\n\r ", k))
2043 k = option_fields[y].key;
2047 for (i = 0; i < n; i++)
2049 if (tolower(k) == option_fields[i].key) break;
2052 /* Command is found */
2055 /* Hack -- browse help */
2056 if (k == '?') break;
2060 if (skey == SKEY_UP) d = 8;
2061 if (skey == SKEY_DOWN) d = 2;
2062 y = (y + ddy[d] + n) % n;
2067 if (k == ESCAPE) break;
2074 /* Process the general options */
2075 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2081 /* Process the general options */
2082 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2089 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2096 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2103 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2110 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2114 /* Play-record Options */
2119 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2128 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2129 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2130 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2134 /* Cheating Options */
2137 if (!p_ptr->noscore && !allow_debug_opts)
2139 /* Cheat options are not permitted */
2145 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2152 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2161 do_cmd_options_win();
2162 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2163 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2164 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2165 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2170 /* Auto-picker/destroyer editor */
2174 do_cmd_edit_autopick();
2178 /* Hack -- Delay Speed */
2184 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2186 /* Get a new value */
2189 int msec = delay_factor * delay_factor * delay_factor;
2190 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2191 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2193 if (k == ESCAPE) break;
2196 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2199 else if (isdigit(k)) delay_factor = D2I(k);
2206 /* Hack -- hitpoint warning factor */
2212 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2214 /* Get a new value */
2217 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2218 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2220 if (k == ESCAPE) break;
2223 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2226 else if (isdigit(k)) hitpoint_warn = D2I(k);
2233 /* Hack -- mana color factor */
2239 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2241 /* Get a new value */
2244 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2245 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2247 if (k == ESCAPE) break;
2250 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2253 else if (isdigit(k)) mana_warn = D2I(k);
2261 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2265 /* Unknown option */
2278 /* Hack - Redraw equippy chars */
2279 p_ptr->redraw |= (PR_EQUIPPY);
2285 * @brief prefファイルを選択して処理する /
2286 * Ask for a "user pref line" and process it
2289 * Allow absolute file names?
2291 void do_cmd_pref(void)
2298 /* Ask for a "user pref command" */
2299 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2301 /* Process that pref command */
2302 (void)process_pref_file_command(buf);
2306 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2309 void do_cmd_reload_autopick(void)
2311 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2312 /* Load the file with messages */
2313 autopick_load_pref(TRUE);
2319 * @brief マクロ情報をprefファイルに保存する /
2320 * @param fname ファイル名
2323 static errr macro_dump(concptr fname)
2325 static concptr mark = "Macro Dump";
2331 /* Build the filename */
2332 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2334 /* File type is "TEXT" */
2335 FILE_TYPE(FILE_TYPE_TEXT);
2337 /* Append to the file */
2338 if (!open_auto_dump(buf, mark)) return (-1);
2341 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2344 for (i = 0; i < macro__num; i++)
2346 /* Extract the action */
2347 ascii_to_text(buf, macro__act[i]);
2349 /* Dump the macro */
2350 auto_dump_printf("A:%s\n", buf);
2352 /* Extract the action */
2353 ascii_to_text(buf, macro__pat[i]);
2355 /* Dump normal macros */
2356 auto_dump_printf("P:%s\n", buf);
2359 auto_dump_printf("\n");
2371 * @brief マクロのトリガーキーを取得する /
2372 * Hack -- ask for a "trigger" (see below)
2373 * @param buf キー表記を保管するバッファ
2377 * Note the complex use of the "inkey()" function from "util.c".
2379 * Note that both "flush()" calls are extremely important.
2382 static void do_cmd_macro_aux(char *buf)
2390 /* Do not process macros */
2396 /* Read the pattern */
2402 /* Do not process macros */
2405 /* Do not wait for keys */
2408 /* Attempt to read a key */
2417 /* Convert the trigger */
2418 ascii_to_text(tmp, buf);
2420 /* Hack -- display the trigger */
2421 Term_addstr(-1, TERM_WHITE, tmp);
2427 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2428 * Hack -- ask for a keymap "trigger" (see below)
2429 * @param buf キー表記を取得するバッファ
2433 * Note that both "flush()" calls are extremely important. This may
2434 * no longer be true, since "util.c" is much simpler now.
2437 static void do_cmd_macro_aux_keymap(char *buf)
2447 /* Convert to ascii */
2448 ascii_to_text(tmp, buf);
2450 /* Hack -- display the trigger */
2451 Term_addstr(-1, TERM_WHITE, tmp);
2458 * @brief キーマップをprefファイルにダンプする /
2459 * Hack -- append all keymaps to the given file
2460 * @param fname ファイルネーム
2464 static errr keymap_dump(concptr fname)
2466 static concptr mark = "Keymap Dump";
2475 if (rogue_like_commands)
2477 mode = KEYMAP_MODE_ROGUE;
2483 mode = KEYMAP_MODE_ORIG;
2487 /* Build the filename */
2488 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2490 /* File type is "TEXT" */
2491 FILE_TYPE(FILE_TYPE_TEXT);
2493 /* Append to the file */
2494 if (!open_auto_dump(buf, mark)) return -1;
2497 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2500 for (i = 0; i < 256; i++)
2504 /* Loop up the keymap */
2505 act = keymap_act[mode][i];
2507 /* Skip empty keymaps */
2510 /* Encode the key */
2513 ascii_to_text(key, buf);
2515 /* Encode the action */
2516 ascii_to_text(buf, act);
2518 /* Dump the macro */
2519 auto_dump_printf("A:%s\n", buf);
2520 auto_dump_printf("C:%d:%s\n", mode, key);
2532 * @brief マクロを設定するコマンドのメインルーチン /
2533 * Interact with "macros"
2537 * Note that the macro "action" must be defined before the trigger.
2539 * Could use some helpful instructions on this page.
2542 void do_cmd_macros(void)
2554 if (rogue_like_commands)
2556 mode = KEYMAP_MODE_ROGUE;
2562 mode = KEYMAP_MODE_ORIG;
2565 /* File type is "TEXT" */
2566 FILE_TYPE(FILE_TYPE_TEXT);
2571 /* Process requests until done */
2575 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2577 /* Describe that action */
2578 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2580 /* Analyze the current action */
2581 ascii_to_text(buf, macro__buf);
2583 /* Display the current action */
2588 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2590 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2591 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2592 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2593 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2594 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2595 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2596 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2597 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2598 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2599 #endif /* ALLOW_MACROS */
2602 prt(_("コマンド: ", "Command: "), 16, 0);
2607 if (i == ESCAPE) break;
2609 /* Load a 'macro' file */
2615 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2618 prt(_("ファイル: ", "File: "), 18, 0);
2620 /* Default filename */
2621 sprintf(tmp, "%s.prf", player_base);
2623 /* Ask for a file */
2624 if (!askfor(tmp, 80)) continue;
2626 /* Process the given filename */
2627 err = process_pref_file(tmp);
2630 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2635 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2639 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2649 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2652 prt(_("ファイル: ", "File: "), 18, 0);
2654 /* Default filename */
2655 sprintf(tmp, "%s.prf", player_base);
2657 /* Ask for a file */
2658 if (!askfor(tmp, 80)) continue;
2660 /* Dump the macros */
2661 (void)macro_dump(tmp);
2664 msg_print(_("マクロを追加しました。", "Appended macros."));
2673 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2677 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2679 /* Get a macro trigger */
2680 do_cmd_macro_aux(buf);
2682 /* Acquire action */
2683 k = macro_find_exact(buf);
2689 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2695 /* Obtain the action */
2696 strcpy(macro__buf, macro__act[k]);
2698 /* Analyze the current action */
2699 ascii_to_text(buf, macro__buf);
2701 /* Display the current action */
2705 msg_print(_("マクロを確認しました。", "Found a macro."));
2709 /* Create a macro */
2713 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2716 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2718 /* Get a macro trigger */
2719 do_cmd_macro_aux(buf);
2725 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2726 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2729 prt(_("マクロ行動: ", "Action: "), 20, 0);
2731 /* Convert to text */
2732 ascii_to_text(tmp, macro__buf);
2734 /* Get an encoded action */
2735 if (askfor(tmp, 80))
2737 /* Convert to ascii */
2738 text_to_ascii(macro__buf, tmp);
2740 /* Link the macro */
2741 macro_add(buf, macro__buf);
2744 msg_print(_("マクロを追加しました。", "Added a macro."));
2748 /* Remove a macro */
2752 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2755 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2757 /* Get a macro trigger */
2758 do_cmd_macro_aux(buf);
2760 /* Link the macro */
2761 macro_add(buf, buf);
2764 msg_print(_("マクロを削除しました。", "Removed a macro."));
2771 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2774 prt(_("ファイル: ", "File: "), 18, 0);
2776 /* Default filename */
2777 sprintf(tmp, "%s.prf", player_base);
2779 /* Ask for a file */
2780 if (!askfor(tmp, 80)) continue;
2782 /* Dump the macros */
2783 (void)keymap_dump(tmp);
2786 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2789 /* Query a keymap */
2795 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2798 prt(_("押すキー: ", "Keypress: "), 18, 0);
2800 /* Get a keymap trigger */
2801 do_cmd_macro_aux_keymap(buf);
2803 /* Look up the keymap */
2804 act = keymap_act[mode][(byte)(buf[0])];
2810 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2816 /* Obtain the action */
2817 strcpy(macro__buf, act);
2819 /* Analyze the current action */
2820 ascii_to_text(buf, macro__buf);
2822 /* Display the current action */
2826 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2830 /* Create a keymap */
2834 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2837 prt(_("押すキー: ", "Keypress: "), 18, 0);
2839 /* Get a keymap trigger */
2840 do_cmd_macro_aux_keymap(buf);
2846 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2847 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2850 prt(_("行動: ", "Action: "), 20, 0);
2852 /* Convert to text */
2853 ascii_to_text(tmp, macro__buf);
2855 /* Get an encoded action */
2856 if (askfor(tmp, 80))
2858 /* Convert to ascii */
2859 text_to_ascii(macro__buf, tmp);
2861 /* Free old keymap */
2862 string_free(keymap_act[mode][(byte)(buf[0])]);
2864 /* Make new keymap */
2865 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2868 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2872 /* Remove a keymap */
2876 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2879 prt(_("押すキー: ", "Keypress: "), 18, 0);
2881 /* Get a keymap trigger */
2882 do_cmd_macro_aux_keymap(buf);
2884 /* Free old keymap */
2885 string_free(keymap_act[mode][(byte)(buf[0])]);
2887 /* Make new keymap */
2888 keymap_act[mode][(byte)(buf[0])] = NULL;
2891 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2894 /* Enter a new action */
2898 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2904 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2905 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2908 prt(_("マクロ行動: ", "Action: "), 20, 0);
2910 /* Hack -- limit the value */
2913 /* Get an encoded action */
2914 if (!askfor(buf, 80)) continue;
2916 /* Extract an action */
2917 text_to_ascii(macro__buf, buf);
2920 #endif /* ALLOW_MACROS */
2933 * @brief キャラクタ色の明暗表現
2935 static concptr lighting_level_str[F_LIT_MAX] =
2950 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2951 * @param i 指定対象となるキャラクタコード
2952 * @param num 指定されたビジュアルIDを返す参照ポインタ
2953 * @param max ビジュアルIDの最大数
2954 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2956 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2963 sprintf(str, "%d", *num);
2965 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2968 tmp = (IDX)strtol(str, NULL, 0);
2969 if (tmp >= 0 && tmp < max)
2972 else if (isupper(i))
2973 *num = (*num + max - 1) % max;
2975 *num = (*num + 1) % max;
2981 * @brief キャラクタの変更メニュー表示
2982 * @param choice_msg 選択メッセージ
2985 static void print_visuals_menu(concptr choice_msg)
2987 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2989 /* Give some choices */
2990 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2992 #ifdef ALLOW_VISUALS
2993 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2994 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2995 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2996 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2997 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2998 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2999 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3000 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3001 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3002 #endif /* ALLOW_VISUALS */
3004 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3007 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3010 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3011 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3012 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3015 * Interact with "visuals"
3017 void do_cmd_visuals(void)
3022 bool need_redraw = FALSE;
3023 concptr empty_symbol = "<< ? >>";
3025 if (use_bigtile) empty_symbol = "<< ?? >>";
3027 /* File type is "TEXT" */
3028 FILE_TYPE(FILE_TYPE_TEXT);
3031 /* Interact until done */
3036 /* Ask for a choice */
3037 print_visuals_menu(NULL);
3042 if (i == ESCAPE) break;
3046 /* Load a 'pref' file */
3049 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3052 prt(_("ファイル: ", "File: "), 17, 0);
3054 /* Default filename */
3055 sprintf(tmp, "%s.prf", player_base);
3058 if (!askfor(tmp, 70)) continue;
3060 /* Process the given filename */
3061 (void)process_pref_file(tmp);
3066 #ifdef ALLOW_VISUALS
3068 /* Dump monster attr/chars */
3071 static concptr mark = "Monster attr/chars";
3074 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3077 prt(_("ファイル: ", "File: "), 17, 0);
3079 /* Default filename */
3080 sprintf(tmp, "%s.prf", player_base);
3082 /* Get a filename */
3083 if (!askfor(tmp, 70)) continue;
3085 /* Build the filename */
3086 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3088 /* Append to the file */
3089 if (!open_auto_dump(buf, mark)) continue;
3092 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3095 for (i = 0; i < max_r_idx; i++)
3097 monster_race *r_ptr = &r_info[i];
3099 /* Skip non-entries */
3100 if (!r_ptr->name) continue;
3102 /* Dump a comment */
3103 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3105 /* Dump the monster attr/char info */
3106 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3107 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3113 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3118 /* Dump object attr/chars */
3121 static concptr mark = "Object attr/chars";
3122 KIND_OBJECT_IDX k_idx;
3125 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3128 prt(_("ファイル: ", "File: "), 17, 0);
3130 /* Default filename */
3131 sprintf(tmp, "%s.prf", player_base);
3133 /* Get a filename */
3134 if (!askfor(tmp, 70)) continue;
3136 /* Build the filename */
3137 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3139 /* Append to the file */
3140 if (!open_auto_dump(buf, mark)) continue;
3143 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3146 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3148 GAME_TEXT o_name[MAX_NLEN];
3149 object_kind *k_ptr = &k_info[k_idx];
3151 /* Skip non-entries */
3152 if (!k_ptr->name) continue;
3157 strip_name(o_name, k_idx);
3163 /* Prepare dummy object */
3164 object_prep(&forge, k_idx);
3166 /* Get un-shuffled flavor name */
3167 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3170 /* Dump a comment */
3171 auto_dump_printf("# %s\n", o_name);
3173 /* Dump the object attr/char info */
3174 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3175 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3181 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3186 /* Dump feature attr/chars */
3189 static concptr mark = "Feature attr/chars";
3192 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3195 prt(_("ファイル: ", "File: "), 17, 0);
3197 /* Default filename */
3198 sprintf(tmp, "%s.prf", player_base);
3200 /* Get a filename */
3201 if (!askfor(tmp, 70)) continue;
3203 /* Build the filename */
3204 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3206 /* Append to the file */
3207 if (!open_auto_dump(buf, mark)) continue;
3210 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3213 for (i = 0; i < max_f_idx; i++)
3215 feature_type *f_ptr = &f_info[i];
3217 /* Skip non-entries */
3218 if (!f_ptr->name) continue;
3220 /* Skip mimiccing features */
3221 if (f_ptr->mimic != i) continue;
3223 /* Dump a comment */
3224 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3226 /* Dump the feature attr/char info */
3227 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3228 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3229 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3230 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3236 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3241 /* Modify monster attr/chars (numeric operation) */
3244 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3245 static MONRACE_IDX r = 0;
3247 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3249 /* Hack -- query until done */
3252 monster_race *r_ptr = &r_info[r];
3256 TERM_COLOR da = r_ptr->d_attr;
3257 byte dc = r_ptr->d_char;
3258 TERM_COLOR ca = r_ptr->x_attr;
3259 byte cc = r_ptr->x_char;
3261 /* Label the object */
3262 Term_putstr(5, 17, -1, TERM_WHITE,
3263 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3265 /* Label the Default values */
3266 Term_putstr(10, 19, -1, TERM_WHITE,
3267 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3269 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3270 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3272 /* Label the Current values */
3273 Term_putstr(10, 20, -1, TERM_WHITE,
3274 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3276 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3277 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3280 Term_putstr(0, 22, -1, TERM_WHITE,
3281 _("コマンド (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): "));
3286 if (i == ESCAPE) break;
3288 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3289 else if (isupper(i)) c = 'a' + i - 'A';
3299 if (!cmd_visuals_aux(i, &r, max_r_idx))
3305 while (!r_info[r].name);
3309 t = (int)r_ptr->x_attr;
3310 (void)cmd_visuals_aux(i, &t, 256);
3311 r_ptr->x_attr = (byte)t;
3315 t = (int)r_ptr->x_char;
3316 (void)cmd_visuals_aux(i, &t, 256);
3317 r_ptr->x_char = (byte)t;
3321 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3323 print_visuals_menu(choice_msg);
3331 /* Modify object attr/chars (numeric operation) */
3334 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3336 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3338 /* Hack -- query until done */
3341 object_kind *k_ptr = &k_info[k];
3345 TERM_COLOR da = k_ptr->d_attr;
3346 SYMBOL_CODE dc = k_ptr->d_char;
3347 TERM_COLOR ca = k_ptr->x_attr;
3348 SYMBOL_CODE cc = k_ptr->x_char;
3350 /* Label the object */
3351 Term_putstr(5, 17, -1, TERM_WHITE,
3352 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3353 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3355 /* Label the Default values */
3356 Term_putstr(10, 19, -1, TERM_WHITE,
3357 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3359 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3360 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3362 /* Label the Current values */
3363 Term_putstr(10, 20, -1, TERM_WHITE,
3364 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3366 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3367 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3370 Term_putstr(0, 22, -1, TERM_WHITE,
3371 _("コマンド (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): "));
3376 if (i == ESCAPE) break;
3378 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3379 else if (isupper(i)) c = 'a' + i - 'A';
3389 if (!cmd_visuals_aux(i, &k, max_k_idx))
3395 while (!k_info[k].name);
3399 t = (int)k_ptr->x_attr;
3400 (void)cmd_visuals_aux(i, &t, 256);
3401 k_ptr->x_attr = (byte)t;
3405 t = (int)k_ptr->x_char;
3406 (void)cmd_visuals_aux(i, &t, 256);
3407 k_ptr->x_char = (byte)t;
3411 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3413 print_visuals_menu(choice_msg);
3421 /* Modify feature attr/chars (numeric operation) */
3424 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3426 static IDX lighting_level = F_LIT_STANDARD;
3427 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3429 /* Hack -- query until done */
3432 feature_type *f_ptr = &f_info[f];
3436 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3437 byte dc = f_ptr->d_char[lighting_level];
3438 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3439 byte cc = f_ptr->x_char[lighting_level];
3441 /* Label the object */
3443 Term_putstr(5, 17, -1, TERM_WHITE,
3444 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3445 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3447 /* Label the Default values */
3448 Term_putstr(10, 19, -1, TERM_WHITE,
3449 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3451 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3452 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3454 /* Label the Current values */
3456 Term_putstr(10, 20, -1, TERM_WHITE,
3457 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3459 Term_putstr(10, 20, -1, TERM_WHITE,
3460 format("Current attr/char = %3d / %3d", ca, cc));
3463 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3464 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3468 Term_putstr(0, 22, -1, TERM_WHITE,
3469 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3471 Term_putstr(0, 22, -1, TERM_WHITE,
3472 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3478 if (i == ESCAPE) break;
3480 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3481 else if (isupper(i)) c = 'a' + i - 'A';
3491 if (!cmd_visuals_aux(i, &f, max_f_idx))
3497 while (!f_info[f].name || (f_info[f].mimic != f));
3501 t = (int)f_ptr->x_attr[lighting_level];
3502 (void)cmd_visuals_aux(i, &t, 256);
3503 f_ptr->x_attr[lighting_level] = (byte)t;
3507 t = (int)f_ptr->x_char[lighting_level];
3508 (void)cmd_visuals_aux(i, &t, 256);
3509 f_ptr->x_char[lighting_level] = (byte)t;
3513 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3516 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3520 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3522 print_visuals_menu(choice_msg);
3530 /* Modify monster attr/chars (visual mode) */
3532 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3535 /* Modify object attr/chars (visual mode) */
3537 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3540 /* Modify feature attr/chars (visual mode) */
3543 IDX lighting_level = F_LIT_STANDARD;
3544 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3548 #endif /* ALLOW_VISUALS */
3556 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3560 /* Unknown option */
3570 if (need_redraw) do_cmd_redraw();
3575 * Interact with "colors"
3577 void do_cmd_colors(void)
3586 /* File type is "TEXT" */
3587 FILE_TYPE(FILE_TYPE_TEXT);
3592 /* Interact until done */
3597 /* Ask for a choice */
3598 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3600 /* Give some choices */
3601 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3604 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3605 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3609 prt(_("コマンド: ", "Command: "), 8, 0);
3613 if (i == ESCAPE) break;
3615 /* Load a 'pref' file */
3619 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3622 prt(_("ファイル: ", "File: "), 10, 0);
3625 sprintf(tmp, "%s.prf", player_base);
3628 if (!askfor(tmp, 70)) continue;
3630 /* Process the given filename */
3631 (void)process_pref_file(tmp);
3633 /* Mega-Hack -- react to changes */
3634 Term_xtra(TERM_XTRA_REACT, 0);
3636 /* Mega-Hack -- redraw */
3645 static concptr mark = "Colors";
3648 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3651 prt(_("ファイル: ", "File: "), 10, 0);
3653 /* Default filename */
3654 sprintf(tmp, "%s.prf", player_base);
3656 /* Get a filename */
3657 if (!askfor(tmp, 70)) continue;
3659 /* Build the filename */
3660 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3662 /* Append to the file */
3663 if (!open_auto_dump(buf, mark)) continue;
3666 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3669 for (i = 0; i < 256; i++)
3671 int kv = angband_color_table[i][0];
3672 int rv = angband_color_table[i][1];
3673 int gv = angband_color_table[i][2];
3674 int bv = angband_color_table[i][3];
3676 concptr name = _("未知", "unknown");
3678 /* Skip non-entries */
3679 if (!kv && !rv && !gv && !bv) continue;
3681 /* Extract the color name */
3682 if (i < 16) name = color_names[i];
3684 /* Dump a comment */
3685 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3687 /* Dump the monster attr/char info */
3688 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3695 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3704 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3706 /* Hack -- query until done */
3715 /* Exhibit the normal colors */
3716 for (j = 0; j < 16; j++)
3718 /* Exhibit this color */
3719 Term_putstr(j*4, 20, -1, a, "###");
3721 /* Exhibit all colors */
3722 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3725 /* Describe the color */
3726 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3728 /* Describe the color */
3729 Term_putstr(5, 10, -1, TERM_WHITE,
3730 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3732 /* Label the Current values */
3733 Term_putstr(5, 12, -1, TERM_WHITE,
3734 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3735 angband_color_table[a][0],
3736 angband_color_table[a][1],
3737 angband_color_table[a][2],
3738 angband_color_table[a][3]));
3741 Term_putstr(0, 14, -1, TERM_WHITE,
3742 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3747 if (i == ESCAPE) break;
3750 if (i == 'n') a = (byte)(a + 1);
3751 if (i == 'N') a = (byte)(a - 1);
3752 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3753 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3754 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3755 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3756 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3757 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3758 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3759 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3761 /* Hack -- react to changes */
3762 Term_xtra(TERM_XTRA_REACT, 0);
3764 /* Hack -- redraw */
3771 /* Unknown option */
3785 * Note something in the message recall
3787 void do_cmd_note(void)
3795 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3797 /* Ignore empty notes */
3798 if (!buf[0] || (buf[0] == ' ')) return;
3800 /* Add the note to the message recall */
3801 msg_format(_("メモ: %s", "Note: %s"), buf);
3806 * Mention the current version
3808 void do_cmd_version(void)
3810 #if FAKE_VER_EXTRA > 0
3811 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3812 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3814 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3815 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3822 * Array of feeling strings
3824 static concptr do_cmd_feeling_text[11] =
3826 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3827 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3828 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3829 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3830 _("とても悪い予感がする...", "You have a very bad feeling..."),
3831 _("悪い予感がする...", "You have a bad feeling..."),
3832 _("何か緊張する。", "You feel nervous."),
3833 _("少し不運な気がする...", "You feel your luck is turning..."),
3834 _("この場所は好きになれない。", "You don't like the look of this place."),
3835 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3836 _("なんて退屈なところだ...", "What a boring place...")
3839 static concptr do_cmd_feeling_text_combat[11] =
3841 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3842 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3843 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3844 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3845 _("とても悪い予感がする...", "You have a very bad feeling..."),
3846 _("悪い予感がする...", "You have a bad feeling..."),
3847 _("何か緊張する。", "You feel nervous."),
3848 _("少し不運な気がする...", "You feel your luck is turning..."),
3849 _("この場所は好きになれない。", "You don't like the look of this place."),
3850 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3851 _("なんて退屈なところだ...", "What a boring place...")
3854 static concptr do_cmd_feeling_text_lucky[11] =
3856 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3857 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3858 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3859 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3860 _("とても良い感じがする...", "You have a very good feeling..."),
3861 _("良い感じがする...", "You have a good feeling..."),
3862 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3863 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3864 _("見た感じ悪くはない...", "You like the look of this place..."),
3865 _("全然駄目ということはないが...", "This level can't be all bad..."),
3866 _("なんて退屈なところだ...", "What a boring place...")
3871 * Note that "feeling" is set to zero unless some time has passed.
3872 * Note that this is done when the level is GENERATED, not entered.
3874 void do_cmd_feeling(void)
3876 if (p_ptr->wild_mode) return;
3878 /* No useful feeling in quests */
3879 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3881 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3885 /* No useful feeling in town */
3886 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3888 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3890 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3895 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3900 /* No useful feeling in the wilderness */
3901 else if (!current_floor_ptr->dun_level)
3903 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3907 /* Display the feeling */
3908 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3909 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3910 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3911 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3912 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3914 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3920 * Description of each monster group.
3922 static concptr monster_group_text[] =
3925 "ユニーク", /* "Uniques" */
3926 "乗馬可能なモンスター", /* "Riding" */
3927 "賞金首", /* "Wanted */
3928 "アンバーの王族", /* "Ambertite" */
3957 /* "古代ドラゴン/ワイアーム", */
4018 /* "Ancient Dragon/Wyrm", */
4027 "Multi-Headed Reptile",
4032 "Reptile/Amphibian",
4033 "Spider/Scorpion/Tick",
4035 /* "Major Demon", */
4052 * Symbols of monsters in each group. Note the "Uniques" group
4053 * is handled differently.
4055 static concptr monster_group_char[] =
4112 "!$&()+./=>?[\\]`{|~",
4122 * Build a list of monster indexes in the given group. Return the number
4123 * of monsters in the group.
4125 * mode & 0x01 : check for non-empty group
4126 * mode & 0x02 : visual operation only
4128 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4134 /* Get a list of x_char in this group */
4135 concptr group_char = monster_group_char[grp_cur];
4137 /* XXX Hack -- Check if this is the "Uniques" group */
4138 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4140 /* XXX Hack -- Check if this is the "Riding" group */
4141 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4143 /* XXX Hack -- Check if this is the "Wanted" group */
4144 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4146 /* XXX Hack -- Check if this is the "Amberite" group */
4147 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4150 /* Check every race */
4151 for (i = 0; i < max_r_idx; i++)
4153 /* Access the race */
4154 monster_race *r_ptr = &r_info[i];
4156 /* Skip empty race */
4157 if (!r_ptr->name) continue ;
4159 /* Require known monsters */
4160 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4164 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4167 else if (grp_riding)
4169 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4172 else if (grp_wanted)
4174 bool wanted = FALSE;
4176 for (j = 0; j < MAX_KUBI; j++)
4178 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4179 (p_ptr->today_mon && p_ptr->today_mon == i))
4185 if (!wanted) continue;
4188 else if (grp_amberite)
4190 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4195 /* Check for race in the group */
4196 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4200 mon_idx[mon_cnt++] = i;
4202 /* XXX Hack -- Just checking for non-empty group */
4203 if (mode & 0x01) break;
4206 /* Terminate the list */
4207 mon_idx[mon_cnt] = -1;
4209 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4211 /* Return the number of races */
4217 * Description of each monster group.
4219 static concptr object_group_text[] =
4222 "キノコ", /* "Mushrooms" */
4223 "薬", /* "Potions" */
4224 "油つぼ", /* "Flasks" */
4225 "巻物", /* "Scrolls" */
4227 "アミュレット", /* "Amulets" */
4228 "笛", /* "Whistle" */
4229 "光源", /* "Lanterns" */
4230 "魔法棒", /* "Wands" */
4233 "カード", /* "Cards" */
4244 "刀剣類", /* "Swords" */
4245 "鈍器", /* "Blunt Weapons" */
4246 "長柄武器", /* "Polearms" */
4247 "採掘道具", /* "Diggers" */
4248 "飛び道具", /* "Bows" */
4252 "軽装鎧", /* "Soft Armor" */
4253 "重装鎧", /* "Hard Armor" */
4254 "ドラゴン鎧", /* "Dragon Armor" */
4255 "盾", /* "Shields" */
4256 "クローク", /* "Cloaks" */
4257 "籠手", /* "Gloves" */
4258 "ヘルメット", /* "Helms" */
4260 "ブーツ", /* "Boots" */
4313 * TVALs of items in each group
4315 static byte object_group_tval[] =
4356 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4364 * Build a list of object indexes in the given group. Return the number
4365 * of objects in the group.
4367 * mode & 0x01 : check for non-empty group
4368 * mode & 0x02 : visual operation only
4370 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4372 KIND_OBJECT_IDX i, object_cnt = 0;
4375 /* Get a list of x_char in this group */
4376 byte group_tval = object_group_tval[grp_cur];
4378 /* Check every object */
4379 for (i = 0; i < max_k_idx; i++)
4381 /* Access the object */
4382 object_kind *k_ptr = &k_info[i];
4384 /* Skip empty objects */
4385 if (!k_ptr->name) continue;
4389 /* Any objects will be displayed */
4395 /* Skip non-flavoured objects */
4396 if (!k_ptr->flavor) continue;
4398 /* Require objects ever seen */
4399 if (!k_ptr->aware) continue;
4402 /* Skip items with no distribution (special artifacts) */
4403 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4407 /* Check for objects in the group */
4408 if (TV_LIFE_BOOK == group_tval)
4410 /* Hack -- All spell books */
4411 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4413 /* Add the object */
4414 object_idx[object_cnt++] = i;
4418 else if (k_ptr->tval == group_tval)
4420 /* Add the object */
4421 object_idx[object_cnt++] = i;
4425 /* XXX Hack -- Just checking for non-empty group */
4426 if (mode & 0x01) break;
4429 /* Terminate the list */
4430 object_idx[object_cnt] = -1;
4432 /* Return the number of objects */
4438 * Description of each feature group.
4440 static concptr feature_group_text[] =
4448 * Build a list of feature indexes in the given group. Return the number
4449 * of features in the group.
4451 * mode & 0x01 : check for non-empty group
4453 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4456 FEAT_IDX feat_cnt = 0;
4458 /* Unused; There is a single group. */
4461 /* Check every feature */
4462 for (i = 0; i < max_f_idx; i++)
4464 feature_type *f_ptr = &f_info[i];
4466 /* Skip empty index */
4467 if (!f_ptr->name) continue;
4469 /* Skip mimiccing features */
4470 if (f_ptr->mimic != i) continue;
4473 feat_idx[feat_cnt++] = i;
4475 /* XXX Hack -- Just checking for non-empty group */
4476 if (mode & 0x01) break;
4479 /* Terminate the list */
4480 feat_idx[feat_cnt] = -1;
4482 /* Return the number of races */
4489 * Build a list of monster indexes in the given group. Return the number
4490 * of monsters in the group.
4492 static int collect_artifacts(int grp_cur, int object_idx[])
4494 int i, object_cnt = 0;
4496 /* Get a list of x_char in this group */
4497 byte group_tval = object_group_tval[grp_cur];
4499 /* Check every object */
4500 for (i = 0; i < max_a_idx; i++)
4502 /* Access the artifact */
4503 artifact_type *a_ptr = &a_info[i];
4505 /* Skip empty artifacts */
4506 if (!a_ptr->name) continue;
4508 /* Skip "uncreated" artifacts */
4509 if (!a_ptr->cur_num) continue;
4511 /* Check for race in the group */
4512 if (a_ptr->tval == group_tval)
4515 object_idx[object_cnt++] = i;
4519 /* Terminate the list */
4520 object_idx[object_cnt] = 0;
4522 /* Return the number of races */
4529 * Encode the screen colors
4531 static char hack[17] = "dwsorgbuDWvyRGBU";
4535 * Hack -- load a screen dump from a file
4537 void do_cmd_load_screen(void)
4542 SYMBOL_CODE c = ' ';
4548 Term_get_size(&wid, &hgt);
4550 /* Build the filename */
4551 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4553 /* Append to the file */
4554 fff = my_fopen(buf, "r");
4557 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4565 /* Load the screen */
4566 for (y = 0; okay; y++)
4568 /* Get a line of data including control code */
4569 if (!fgets(buf, 1024, fff)) okay = FALSE;
4571 /* Get the blank line */
4572 if (buf[0] == '\n' || buf[0] == '\0') break;
4574 /* Ignore too large screen image */
4575 if (y >= hgt) continue;
4578 for (x = 0; x < wid - 1; x++)
4581 if (buf[x] == '\n' || buf[x] == '\0') break;
4583 /* Put the attr/char */
4584 Term_draw(x, y, TERM_WHITE, buf[x]);
4588 /* Dump the screen */
4589 for (y = 0; okay; y++)
4591 /* Get a line of data including control code */
4592 if (!fgets(buf, 1024, fff)) okay = FALSE;
4594 /* Get the blank line */
4595 if (buf[0] == '\n' || buf[0] == '\0') break;
4597 /* Ignore too large screen image */
4598 if (y >= hgt) continue;
4601 for (x = 0; x < wid - 1; x++)
4604 if (buf[x] == '\n' || buf[x] == '\0') break;
4606 /* Get the attr/char */
4607 (void)(Term_what(x, y, &a, &c));
4609 /* Look up the attr */
4610 for (i = 0; i < 16; i++)
4612 /* Use attr matches */
4613 if (hack[i] == buf[x]) a = (byte_hack)i;
4616 /* Put the attr/char */
4617 Term_draw(x, y, a, c);
4622 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4633 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4634 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4637 #define IM_FLAG_STR _("*", "* ")
4638 #define HAS_FLAG_STR _("+", "+ ")
4639 #define NO_FLAG_STR _("・", ". ")
4641 #define print_im_or_res_flag(IM, RES) \
4643 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4644 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4647 #define print_flag(TR) \
4649 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4653 /* XTRA HACK RESLIST */
4654 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4656 GAME_TEXT o_name[MAX_NLEN];
4657 BIT_FLAGS flgs[TR_FLAG_SIZE];
4659 if (!o_ptr->k_idx) return;
4660 if (o_ptr->tval != tval) return;
4662 /* Identified items only */
4663 if (!object_is_known(o_ptr)) return;
4666 * HACK:Ring of Lordly protection and Dragon equipment
4667 * have random resistances.
4669 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4670 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4671 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4672 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4673 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4674 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4675 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4676 || object_is_artifact(o_ptr))
4679 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4681 while (o_name[i] && (i < 26))
4684 if (iskanji(o_name[i])) i++;
4693 o_name[i] = ' '; i++;
4698 fprintf(fff, "%s %s", where, o_name);
4700 if (!(o_ptr->ident & (IDENT_MENTAL)))
4702 fputs(_("-------不明--------------- -------不明---------\n",
4703 "-------unknown------------ -------unknown------\n"), fff);
4707 object_flags_known(o_ptr, flgs);
4709 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4710 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4711 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4712 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4713 print_flag(TR_RES_POIS);
4714 print_flag(TR_RES_LITE);
4715 print_flag(TR_RES_DARK);
4716 print_flag(TR_RES_SHARDS);
4717 print_flag(TR_RES_SOUND);
4718 print_flag(TR_RES_NETHER);
4719 print_flag(TR_RES_NEXUS);
4720 print_flag(TR_RES_CHAOS);
4721 print_flag(TR_RES_DISEN);
4725 print_flag(TR_RES_BLIND);
4726 print_flag(TR_RES_FEAR);
4727 print_flag(TR_RES_CONF);
4728 print_flag(TR_FREE_ACT);
4729 print_flag(TR_SEE_INVIS);
4730 print_flag(TR_HOLD_EXP);
4731 print_flag(TR_TELEPATHY);
4732 print_flag(TR_SLOW_DIGEST);
4733 print_flag(TR_REGEN);
4734 print_flag(TR_LEVITATION);
4742 fprintf(fff, "%s\n", inven_res_label);
4748 * Display *ID* ed weapons/armors's resistances
4750 static void do_cmd_knowledge_inven(void)
4753 GAME_TEXT file_name[1024];
4755 OBJECT_TYPE_VALUE tval;
4761 /* Open a new file */
4762 fff = my_fopen_temp(file_name, 1024);
4765 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4769 fprintf(fff, "%s\n", inven_res_label);
4771 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4775 for (; j < 9; j++) fputc('\n', fff);
4777 fprintf(fff, "%s\n", inven_res_label);
4779 strcpy(where, _("装", "E "));
4780 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4782 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4784 strcpy(where, _("持", "I "));
4785 for (i = 0; i < INVEN_PACK; i++)
4787 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4790 st_ptr = &town_info[1].store[STORE_HOME];
4791 strcpy(where, _("家", "H "));
4792 for (i = 0; i < st_ptr->stock_num; i++)
4794 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4799 /* Display the file contents */
4800 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4805 void do_cmd_save_screen_html_aux(char *filename, int message)
4810 TERM_COLOR a = 0, old_a = 0;
4824 concptr html_head[] = {
4825 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4829 concptr html_foot[] = {
4831 "</body>\n</html>\n",
4837 Term_get_size(&wid, &hgt);
4839 /* File type is "TEXT" */
4840 FILE_TYPE(FILE_TYPE_TEXT);
4842 /* Append to the file */
4843 fff = my_fopen(filename, "w");
4847 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4853 if (message) screen_save();
4855 /* Build the filename */
4856 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4857 tmpfff = my_fopen(buf, "r");
4859 for (i = 0; html_head[i]; i++)
4860 fputs(html_head[i], fff);
4864 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4866 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4870 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4872 fprintf(fff, "%s\n", buf);
4877 /* Dump the screen */
4878 for (y = 0; y < hgt; y++)
4885 for (x = 0; x < wid - 1; x++)
4889 /* Get the attr/char */
4890 (void)(Term_what(x, y, &a, &c));
4894 case '&': cc = "&"; break;
4895 case '<': cc = "<"; break;
4896 case '>': cc = ">"; break;
4898 case 0x1f: c = '.'; break;
4899 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4904 if ((y == 0 && x == 0) || a != old_a) {
4905 rv = angband_color_table[a][1];
4906 gv = angband_color_table[a][2];
4907 bv = angband_color_table[a][3];
4908 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4909 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4913 fprintf(fff, "%s", cc);
4915 fprintf(fff, "%c", c);
4918 fprintf(fff, "</font>");
4921 for (i = 0; html_foot[i]; i++)
4922 fputs(html_foot[i], fff);
4927 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4929 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4933 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4935 fprintf(fff, "%s\n", buf);
4946 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4954 * Hack -- save a screen dump to a file
4956 static void do_cmd_save_screen_html(void)
4958 char buf[1024], tmp[256] = "screen.html";
4960 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4963 /* Build the filename */
4964 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4968 do_cmd_save_screen_html_aux(buf, 1);
4973 * Redefinable "save_screen" action
4975 void (*screendump_aux)(void) = NULL;
4979 * Hack -- save a screen dump to a file
4981 void do_cmd_save_screen(void)
4983 bool old_use_graphics = use_graphics;
4984 bool html_dump = FALSE;
4988 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4992 if (c == 'Y' || c == 'y')
4994 else if (c == 'H' || c == 'h')
5006 Term_get_size(&wid, &hgt);
5008 if (old_use_graphics)
5010 use_graphics = FALSE;
5012 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5018 do_cmd_save_screen_html();
5022 /* Do we use a special screendump function ? */
5023 else if (screendump_aux)
5025 /* Dump the screen to a graphics file */
5026 (*screendump_aux)();
5028 else /* Dump the screen as text */
5032 SYMBOL_CODE c = ' ';
5036 /* Build the filename */
5037 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5039 /* File type is "TEXT" */
5040 FILE_TYPE(FILE_TYPE_TEXT);
5042 /* Append to the file */
5043 fff = my_fopen(buf, "w");
5047 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5055 /* Dump the screen */
5056 for (y = 0; y < hgt; y++)
5059 for (x = 0; x < wid - 1; x++)
5061 /* Get the attr/char */
5062 (void)(Term_what(x, y, &a, &c));
5072 fprintf(fff, "%s\n", buf);
5079 /* Dump the screen */
5080 for (y = 0; y < hgt; y++)
5083 for (x = 0; x < wid - 1; x++)
5085 /* Get the attr/char */
5086 (void)(Term_what(x, y, &a, &c));
5089 buf[x] = hack[a&0x0F];
5096 fprintf(fff, "%s\n", buf);
5103 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5108 if (old_use_graphics)
5110 use_graphics = TRUE;
5112 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5118 * Check the status of "artifacts"
5120 static void do_cmd_knowledge_artifacts(void)
5130 GAME_TEXT file_name[1024];
5131 GAME_TEXT base_name[MAX_NLEN];
5135 /* Open a new file */
5136 fff = my_fopen_temp(file_name, 1024);
5139 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5144 /* Allocate the "who" array */
5145 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5147 /* Allocate the "okay" array */
5148 C_MAKE(okay, max_a_idx, bool);
5150 /* Scan the artifacts */
5151 for (k = 0; k < max_a_idx; k++)
5153 artifact_type *a_ptr = &a_info[k];
5158 /* Skip "empty" artifacts */
5159 if (!a_ptr->name) continue;
5161 /* Skip "uncreated" artifacts */
5162 if (!a_ptr->cur_num) continue;
5168 /* Check the dungeon */
5169 for (y = 0; y < current_floor_ptr->height; y++)
5171 for (x = 0; x < current_floor_ptr->width; x++)
5173 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5175 OBJECT_IDX this_o_idx, next_o_idx = 0;
5177 /* Scan all objects in the grid */
5178 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5181 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5182 next_o_idx = o_ptr->next_o_idx;
5184 /* Ignore non-artifacts */
5185 if (!object_is_fixed_artifact(o_ptr)) continue;
5187 /* Ignore known items */
5188 if (object_is_known(o_ptr)) continue;
5190 /* Note the artifact */
5191 okay[o_ptr->name1] = FALSE;
5196 /* Check the p_ptr->inventory_list and equipment */
5197 for (i = 0; i < INVEN_TOTAL; i++)
5199 object_type *o_ptr = &p_ptr->inventory_list[i];
5201 /* Ignore non-objects */
5202 if (!o_ptr->k_idx) continue;
5204 /* Ignore non-artifacts */
5205 if (!object_is_fixed_artifact(o_ptr)) continue;
5207 /* Ignore known items */
5208 if (object_is_known(o_ptr)) continue;
5210 /* Note the artifact */
5211 okay[o_ptr->name1] = FALSE;
5214 for (k = 0; k < max_a_idx; k++)
5216 if (okay[k]) who[n++] = k;
5219 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5221 /* Scan the artifacts */
5222 for (k = 0; k < n; k++)
5224 artifact_type *a_ptr = &a_info[who[k]];
5225 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5227 /* Obtain the base object type */
5228 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5237 /* Create fake object */
5238 object_prep(q_ptr, z);
5240 /* Make it an artifact */
5241 q_ptr->name1 = (byte)who[k];
5243 /* Display as if known */
5244 q_ptr->ident |= IDENT_STORE;
5246 /* Describe the artifact */
5247 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5250 /* Hack -- Build the artifact name */
5251 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5254 /* Free the "who" array */
5255 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5257 /* Free the "okay" array */
5258 C_KILL(okay, max_a_idx, bool);
5261 /* Display the file contents */
5262 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5268 * Display known uniques
5269 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5271 static void do_cmd_knowledge_uniques(void)
5280 GAME_TEXT file_name[1024];
5283 int n_alive_surface = 0;
5284 int n_alive_over100 = 0;
5285 int n_alive_total = 0;
5288 for (i = 0; i < 10; i++) n_alive[i] = 0;
5290 /* Open a new file */
5291 fff = my_fopen_temp(file_name, 1024);
5295 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5300 /* Allocate the "who" array */
5301 C_MAKE(who, max_r_idx, MONRACE_IDX);
5303 /* Scan the monsters */
5304 for (i = 1; i < max_r_idx; i++)
5306 monster_race *r_ptr = &r_info[i];
5309 if (!r_ptr->name) continue;
5311 /* Require unique monsters */
5312 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5314 /* Only display "known" uniques */
5315 if (!cheat_know && !r_ptr->r_sights) continue;
5317 /* Only print rarity <= 100 uniques */
5318 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5320 /* Only "alive" uniques */
5321 if (r_ptr->max_num == 0) continue;
5325 lev = (r_ptr->level - 1) / 10;
5329 if (max_lev < lev) max_lev = lev;
5331 else n_alive_over100++;
5333 else n_alive_surface++;
5335 /* Collect "appropriate" monsters */
5339 /* Sort the array by dungeon depth of monsters */
5340 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5342 if (n_alive_surface)
5344 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5345 n_alive_total += n_alive_surface;
5347 for (i = 0; i <= max_lev; i++)
5349 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5350 n_alive_total += n_alive[i];
5352 if (n_alive_over100)
5354 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5355 n_alive_total += n_alive_over100;
5360 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5361 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5365 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5368 /* Scan the monster races */
5369 for (k = 0; k < n; k++)
5371 monster_race *r_ptr = &r_info[who[k]];
5373 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5376 /* Free the "who" array */
5377 C_KILL(who, max_r_idx, s16b);
5380 /* Display the file contents */
5381 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5387 * Display weapon-exp
5389 static void do_cmd_knowledge_weapon_exp(void)
5397 GAME_TEXT file_name[1024];
5400 /* Open a new file */
5401 fff = my_fopen_temp(file_name, 1024);
5403 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5408 for (i = 0; i < 5; i++)
5410 for (num = 0; num < 64; num++)
5412 for (j = 0; j < max_k_idx; j++)
5414 object_kind *k_ptr = &k_info[j];
5416 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5418 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5420 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5422 fprintf(fff, "%-25s ", tmp);
5423 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5424 else fprintf(fff, " ");
5425 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5426 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5435 /* Display the file contents */
5436 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5442 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5446 static void do_cmd_knowledge_spell_exp(void)
5453 const magic_type *s_ptr;
5455 GAME_TEXT file_name[1024];
5457 /* Open a new file */
5458 fff = my_fopen_temp(file_name, 1024);
5460 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5465 if (p_ptr->realm1 != REALM_NONE)
5467 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5468 for (i = 0; i < 32; i++)
5470 if (!is_magic(p_ptr->realm1))
5472 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5476 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5478 if (s_ptr->slevel >= 99) continue;
5479 spell_exp = p_ptr->spell_exp[i];
5480 exp_level = spell_exp_level(spell_exp);
5481 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5482 if (p_ptr->realm1 == REALM_HISSATSU)
5483 fprintf(fff, "[--]");
5486 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5487 else fprintf(fff, " ");
5488 fprintf(fff, "%s", exp_level_str[exp_level]);
5490 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5495 if (p_ptr->realm2 != REALM_NONE)
5497 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5498 for (i = 0; i < 32; i++)
5500 if (!is_magic(p_ptr->realm1))
5502 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5506 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5508 if (s_ptr->slevel >= 99) continue;
5510 spell_exp = p_ptr->spell_exp[i + 32];
5511 exp_level = spell_exp_level(spell_exp);
5512 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5513 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5514 else fprintf(fff, " ");
5515 fprintf(fff, "%s", exp_level_str[exp_level]);
5516 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5522 /* Display the file contents */
5523 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5529 * @brief スキル情報を表示するコマンドのメインルーチン /
5533 static void do_cmd_knowledge_skill_exp(void)
5535 int i = 0, skill_exp;
5539 char file_name[1024];
5540 char skill_name[GINOU_TEMPMAX][20] =
5542 _("マーシャルアーツ", "Martial Arts "),
5543 _("二刀流 ", "Dual Wielding "),
5544 _("乗馬 ", "Riding "),
5548 /* Open a new file */
5549 fff = my_fopen_temp(file_name, 1024);
5551 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5556 for (i = 0; i < GINOU_TEMPMAX; i++)
5558 skill_exp = p_ptr->skill_exp[i];
5559 fprintf(fff, "%-20s ", skill_name[i]);
5560 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5561 else fprintf(fff, " ");
5562 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5563 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5568 /* Display the file contents */
5569 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5575 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5576 * @param Name 変換したい文字列の参照ポインタ
5579 void plural_aux(char *Name)
5581 int NameLen = strlen(Name);
5583 if (my_strstr(Name, "Disembodied hand"))
5585 strcpy(Name, "Disembodied hands that strangled people");
5587 else if (my_strstr(Name, "Colour out of space"))
5589 strcpy(Name, "Colours out of space");
5591 else if (my_strstr(Name, "stairway to hell"))
5593 strcpy(Name, "stairways to hell");
5595 else if (my_strstr(Name, "Dweller on the threshold"))
5597 strcpy(Name, "Dwellers on the threshold");
5599 else if (my_strstr(Name, " of "))
5601 concptr aider = my_strstr(Name, " of ");
5612 if (dummy[i-1] == 's')
5614 strcpy(&(dummy[i]), "es");
5619 strcpy(&(dummy[i]), "s");
5622 strcpy(&(dummy[i+1]), aider);
5623 strcpy(Name, dummy);
5625 else if (my_strstr(Name, "coins"))
5628 strcpy(dummy, "piles of ");
5629 strcat(dummy, Name);
5630 strcpy(Name, dummy);
5633 else if (my_strstr(Name, "Manes"))
5637 else if (streq(&(Name[NameLen - 2]), "ey"))
5639 strcpy(&(Name[NameLen - 2]), "eys");
5641 else if (Name[NameLen - 1] == 'y')
5643 strcpy(&(Name[NameLen - 1]), "ies");
5645 else if (streq(&(Name[NameLen - 4]), "ouse"))
5647 strcpy(&(Name[NameLen - 4]), "ice");
5649 else if (streq(&(Name[NameLen - 2]), "us"))
5651 strcpy(&(Name[NameLen - 2]), "i");
5653 else if (streq(&(Name[NameLen - 6]), "kelman"))
5655 strcpy(&(Name[NameLen - 6]), "kelmen");
5657 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5659 strcpy(&(Name[NameLen - 8]), "wordsmen");
5661 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5663 strcpy(&(Name[NameLen - 7]), "oodsmen");
5665 else if (streq(&(Name[NameLen - 7]), "eastman"))
5667 strcpy(&(Name[NameLen - 7]), "eastmen");
5669 else if (streq(&(Name[NameLen - 8]), "izardman"))
5671 strcpy(&(Name[NameLen - 8]), "izardmen");
5673 else if (streq(&(Name[NameLen - 5]), "geist"))
5675 strcpy(&(Name[NameLen - 5]), "geister");
5677 else if (streq(&(Name[NameLen - 2]), "ex"))
5679 strcpy(&(Name[NameLen - 2]), "ices");
5681 else if (streq(&(Name[NameLen - 2]), "lf"))
5683 strcpy(&(Name[NameLen - 2]), "lves");
5685 else if (suffix(Name, "ch") ||
5686 suffix(Name, "sh") ||
5687 suffix(Name, "nx") ||
5688 suffix(Name, "s") ||
5691 strcpy(&(Name[NameLen]), "es");
5695 strcpy(&(Name[NameLen]), "s");
5700 * @brief 現在のペットを表示するコマンドのメインルーチン /
5701 * Display current pets
5704 static void do_cmd_knowledge_pets(void)
5708 monster_type *m_ptr;
5709 GAME_TEXT pet_name[MAX_NLEN];
5711 int show_upkeep = 0;
5712 GAME_TEXT file_name[1024];
5715 /* Open a new file */
5716 fff = my_fopen_temp(file_name, 1024);
5718 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5723 /* Process the monsters (backwards) */
5724 for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
5726 /* Access the monster */
5727 m_ptr = ¤t_floor_ptr->m_list[i];
5729 /* Ignore "dead" monsters */
5730 if (!monster_is_valid(m_ptr)) continue;
5732 /* Calculate "upkeep" for pets */
5736 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5737 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5741 show_upkeep = calculate_upkeep();
5743 fprintf(fff, "----------------------------------------------\n");
5745 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5747 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5749 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5754 /* Display the file contents */
5755 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5761 * @brief 現在のペットを表示するコマンドのメインルーチン /
5764 * @note the player ghosts are ignored.
5766 static void do_cmd_knowledge_kill_count(void)
5773 GAME_TEXT file_name[1024];
5778 /* Open a new file */
5779 fff = my_fopen_temp(file_name, 1024);
5782 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5787 /* Allocate the "who" array */
5788 C_MAKE(who, max_r_idx, MONRACE_IDX);
5791 /* Monsters slain */
5794 for (kk = 1; kk < max_r_idx; kk++)
5796 monster_race *r_ptr = &r_info[kk];
5798 if (r_ptr->flags1 & (RF1_UNIQUE))
5800 bool dead = (r_ptr->max_num == 0);
5809 MONSTER_NUMBER This = r_ptr->r_pkills;
5819 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5822 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5824 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5830 /* Scan the monsters */
5831 for (i = 1; i < max_r_idx; i++)
5833 monster_race *r_ptr = &r_info[i];
5835 /* Use that monster */
5836 if (r_ptr->name) who[n++] = i;
5839 /* Sort the array by dungeon depth of monsters */
5840 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5842 /* Scan the monster races */
5843 for (k = 0; k < n; k++)
5845 monster_race *r_ptr = &r_info[who[k]];
5847 if (r_ptr->flags1 & (RF1_UNIQUE))
5849 bool dead = (r_ptr->max_num == 0);
5853 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5859 MONSTER_NUMBER This = r_ptr->r_pkills;
5864 /* p,tは人と数える by ita */
5865 if (my_strchr("pt", r_ptr->d_char))
5866 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5868 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5872 if (my_strstr(r_name + r_ptr->name, "coins"))
5874 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5878 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5884 strcpy(ToPlural, (r_name + r_ptr->name));
5885 plural_aux(ToPlural);
5886 fprintf(fff, " %d %s\n", This, ToPlural);
5896 fprintf(fff,"----------------------------------------------\n");
5898 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5900 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5904 /* Free the "who" array */
5905 C_KILL(who, max_r_idx, s16b);
5908 /* Display the file contents */
5909 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5915 * @brief モンスター情報リスト中のグループを表示する /
5916 * Display the object groups.
5920 * @param per_page リストの表示行
5921 * @param grp_idx グループのID配列
5922 * @param group_text グループ名の文字列配列
5923 * @param grp_cur 現在の選択ID
5924 * @param grp_top 現在の選択リスト最上部ID
5927 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)
5931 /* Display lines until done */
5932 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5934 /* Get the group index */
5935 int grp = grp_idx[grp_top + i];
5937 /* Choose a color */
5938 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5940 /* Erase the entire line */
5941 Term_erase(col, row + i, wid);
5943 /* Display the group label */
5944 c_put_str(attr, group_text[grp], row + i, col);
5950 * Move the cursor in a browser window
5952 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5953 IDX *list_cur, int list_cnt)
5958 IDX list = *list_cur;
5960 /* Extract direction */
5963 /* Hack -- scroll up full screen */
5968 /* Hack -- scroll down full screen */
5973 d = get_keymap_dir(ch);
5978 /* Diagonals - hack */
5979 if ((ddx[d] > 0) && ddy[d])
5984 Term_get_size(&wid, &hgt);
5986 browser_rows = hgt - 8;
5988 /* Browse group list */
5993 /* Move up or down */
5994 grp += ddy[d] * (browser_rows - 1);
5997 if (grp >= grp_cnt) grp = grp_cnt - 1;
5998 if (grp < 0) grp = 0;
5999 if (grp != old_grp) list = 0;
6002 /* Browse sub-list list */
6005 /* Move up or down */
6006 list += ddy[d] * browser_rows;
6009 if (list >= list_cnt) list = list_cnt - 1;
6010 if (list < 0) list = 0;
6022 if (col < 0) col = 0;
6023 if (col > 1) col = 1;
6030 /* Browse group list */
6035 /* Move up or down */
6039 if (grp >= grp_cnt) grp = grp_cnt - 1;
6040 if (grp < 0) grp = 0;
6041 if (grp != old_grp) list = 0;
6044 /* Browse sub-list list */
6047 /* Move up or down */
6048 list += (IDX)ddy[d];
6051 if (list >= list_cnt) list = list_cnt - 1;
6052 if (list < 0) list = 0;
6063 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6067 /* Clear the display lines */
6068 for (i = 0; i < height; i++)
6070 Term_erase(col, row + i, width);
6073 /* Bigtile mode uses double width */
6074 if (use_bigtile) width /= 2;
6076 /* Display lines until done */
6077 for (i = 0; i < height; i++)
6079 /* Display columns until done */
6080 for (j = 0; j < width; j++)
6084 TERM_LEN x = col + j;
6085 TERM_LEN y = row + i;
6087 /* Bigtile mode uses double width */
6088 if (use_bigtile) x += j;
6093 /* Ignore illegal characters */
6094 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6095 (!use_graphics && ic > 0x7f))
6101 /* Force correct code for both ASCII character and tile */
6102 if (c & 0x80) a |= 0x80;
6104 /* Display symbol */
6105 Term_queue_bigchar(x, y, a, c, 0, 0);
6112 * Place the cursor at the collect position for visual mode
6114 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6116 int i = (a & 0x7f) - attr_top;
6117 int j = c - char_left;
6119 TERM_LEN x = col + j;
6120 TERM_LEN y = row + i;
6122 /* Bigtile mode uses double width */
6123 if (use_bigtile) x += j;
6125 /* Place the cursor */
6131 * Clipboard variables for copy&paste in visual mode
6133 static TERM_COLOR attr_idx = 0;
6134 static SYMBOL_CODE char_idx = 0;
6136 /* Hack -- for feature lighting */
6137 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6138 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6141 * Do visual mode command -- Change symbols
6143 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6144 int height, int width,
6145 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6146 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6148 static TERM_COLOR attr_old = 0;
6149 static SYMBOL_CODE char_old = 0;
6154 if (*visual_list_ptr)
6157 *cur_attr_ptr = attr_old;
6158 *cur_char_ptr = char_old;
6159 *visual_list_ptr = FALSE;
6167 if (*visual_list_ptr)
6170 *visual_list_ptr = FALSE;
6171 *need_redraw = TRUE;
6179 if (!*visual_list_ptr)
6181 *visual_list_ptr = TRUE;
6183 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6184 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6186 attr_old = *cur_attr_ptr;
6187 char_old = *cur_char_ptr;
6198 /* Set the visual */
6199 attr_idx = *cur_attr_ptr;
6200 char_idx = *cur_char_ptr;
6202 /* Hack -- for feature lighting */
6203 for (i = 0; i < F_LIT_MAX; i++)
6205 attr_idx_feat[i] = 0;
6206 char_idx_feat[i] = 0;
6213 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6216 *cur_attr_ptr = attr_idx;
6217 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6218 if (!*visual_list_ptr) *need_redraw = TRUE;
6224 *cur_char_ptr = char_idx;
6225 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6226 if (!*visual_list_ptr) *need_redraw = TRUE;
6232 if (*visual_list_ptr)
6235 int d = get_keymap_dir(ch);
6236 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6237 SYMBOL_CODE c = *cur_char_ptr;
6239 if (use_bigtile) eff_width = width / 2;
6240 else eff_width = width;
6242 /* Restrict direction */
6243 if ((a == 0) && (ddy[d] < 0)) d = 0;
6244 if ((c == 0) && (ddx[d] < 0)) d = 0;
6245 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6246 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6248 a += (TERM_COLOR)ddy[d];
6249 c += (SYMBOL_CODE)ddx[d];
6251 /* Force correct code for both ASCII character and tile */
6252 if (c & 0x80) a |= 0x80;
6254 /* Set the visual */
6259 /* Move the frame */
6260 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6261 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6262 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6263 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6269 /* Visual mode command is not used */
6275 * Display the monsters in a group.
6277 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6278 int mon_cur, int mon_top, bool visual_only)
6282 /* Display lines until done */
6283 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6287 /* Get the race index */
6288 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6290 /* Access the race */
6291 monster_race *r_ptr = &r_info[r_idx];
6293 /* Choose a color */
6294 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6296 /* Display the name */
6297 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6299 /* Hack -- visual_list mode */
6302 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6304 if (p_ptr->wizard || visual_only)
6306 c_prt(attr, format("%d", r_idx), row + i, 62);
6309 /* Erase chars before overwritten by the race letter */
6310 Term_erase(69, row + i, 255);
6312 /* Display symbol */
6313 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6318 if (!(r_ptr->flags1 & RF1_UNIQUE))
6319 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6321 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6322 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6326 /* Clear remaining lines */
6327 for (; i < per_page; i++)
6329 Term_erase(col, row + i, 255);
6335 * Display known monsters.
6337 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6341 IDX grp_cur, grp_top, old_grp_cur;
6342 IDX mon_cur, mon_top;
6343 IDX grp_cnt, grp_idx[100];
6351 bool visual_list = FALSE;
6352 TERM_COLOR attr_top = 0;
6360 Term_get_size(&wid, &hgt);
6362 browser_rows = hgt - 8;
6364 /* Allocate the "mon_idx" array */
6365 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6370 if (direct_r_idx < 0)
6372 mode = visual_only ? 0x03 : 0x01;
6374 /* Check every group */
6375 for (i = 0; monster_group_text[i] != NULL; i++)
6377 /* Measure the label */
6378 len = strlen(monster_group_text[i]);
6380 /* Save the maximum length */
6381 if (len > max) max = len;
6383 /* See if any monsters are known */
6384 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6386 /* Build a list of groups with known monsters */
6387 grp_idx[grp_cnt++] = i;
6395 mon_idx[0] = direct_r_idx;
6398 /* Terminate the list */
6401 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6402 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6405 /* Terminate the list */
6406 grp_idx[grp_cnt] = -1;
6409 grp_cur = grp_top = 0;
6410 mon_cur = mon_top = 0;
6415 mode = visual_only ? 0x02 : 0x00;
6420 monster_race *r_ptr;
6425 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6426 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6427 prt(_("名前", "Name"), 4, max + 3);
6428 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6429 prt(_("文字", "Sym"), 4, 67);
6430 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6432 for (i = 0; i < 78; i++)
6434 Term_putch(i, 5, TERM_WHITE, '=');
6437 if (direct_r_idx < 0)
6439 for (i = 0; i < browser_rows; i++)
6441 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6448 if (direct_r_idx < 0)
6450 /* Scroll group list */
6451 if (grp_cur < grp_top) grp_top = grp_cur;
6452 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6454 /* Display a list of monster groups */
6455 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6457 if (old_grp_cur != grp_cur)
6459 old_grp_cur = grp_cur;
6461 /* Get a list of monsters in the current group */
6462 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6465 /* Scroll monster list */
6466 while (mon_cur < mon_top)
6467 mon_top = MAX(0, mon_top - browser_rows/2);
6468 while (mon_cur >= mon_top + browser_rows)
6469 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6474 /* Display a list of monsters in the current group */
6475 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6481 /* Display a monster name */
6482 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6484 /* Display visual list below first monster */
6485 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6489 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6490 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6491 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6492 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6495 /* Get the current monster */
6496 r_ptr = &r_info[mon_idx[mon_cur]];
6500 /* Mega Hack -- track this monster race */
6501 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6507 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6511 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6515 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6520 /* Do visual mode command if needed */
6521 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))
6523 if (direct_r_idx >= 0)
6548 /* Recall on screen */
6549 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6551 screen_roff(mon_idx[mon_cur], 0);
6562 /* Move the cursor */
6563 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6570 /* Free the "mon_idx" array */
6571 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6576 * Display the objects in a group.
6578 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6579 int object_cur, int object_top, bool visual_only)
6583 /* Display lines until done */
6584 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6586 GAME_TEXT o_name[MAX_NLEN];
6589 object_kind *flavor_k_ptr;
6591 /* Get the object index */
6592 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6594 /* Access the object */
6595 object_kind *k_ptr = &k_info[k_idx];
6597 /* Choose a color */
6598 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6599 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6602 if (!visual_only && k_ptr->flavor)
6604 /* Appearance of this object is shuffled */
6605 flavor_k_ptr = &k_info[k_ptr->flavor];
6609 /* Appearance of this object is very normal */
6610 flavor_k_ptr = k_ptr;
6615 attr = ((i + object_top == object_cur) ? cursor : attr);
6617 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6620 strip_name(o_name, k_idx);
6625 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6628 /* Display the name */
6629 c_prt(attr, o_name, row + i, col);
6631 /* Hack -- visual_list mode */
6634 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);
6636 if (p_ptr->wizard || visual_only)
6638 c_prt(attr, format("%d", k_idx), row + i, 70);
6641 a = flavor_k_ptr->x_attr;
6642 c = flavor_k_ptr->x_char;
6644 /* Display symbol */
6645 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6648 /* Clear remaining lines */
6649 for (; i < per_page; i++)
6651 Term_erase(col, row + i, 255);
6656 * Describe fake object
6658 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6661 object_type object_type_body;
6662 o_ptr = &object_type_body;
6664 object_prep(o_ptr, k_idx);
6666 /* It's fully know */
6667 o_ptr->ident |= IDENT_KNOWN;
6669 /* Track the object */
6670 /* object_actual_track(o_ptr); */
6672 /* Hack - mark as fake */
6673 /* term_obj_real = FALSE; */
6676 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6678 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6686 * Display known objects
6688 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6692 IDX grp_cur, grp_top, old_grp_cur;
6693 IDX object_old, object_cur, object_top;
6697 OBJECT_IDX *object_idx;
6703 bool visual_list = FALSE;
6704 TERM_COLOR attr_top = 0;
6712 Term_get_size(&wid, &hgt);
6714 browser_rows = hgt - 8;
6716 /* Allocate the "object_idx" array */
6717 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6722 if (direct_k_idx < 0)
6724 mode = visual_only ? 0x03 : 0x01;
6726 /* Check every group */
6727 for (i = 0; object_group_text[i] != NULL; i++)
6729 /* Measure the label */
6730 len = strlen(object_group_text[i]);
6732 /* Save the maximum length */
6733 if (len > max) max = len;
6735 /* See if any monsters are known */
6736 if (collect_objects(i, object_idx, mode))
6738 /* Build a list of groups with known monsters */
6739 grp_idx[grp_cnt++] = i;
6748 object_kind *k_ptr = &k_info[direct_k_idx];
6749 object_kind *flavor_k_ptr;
6751 if (!visual_only && k_ptr->flavor)
6753 /* Appearance of this object is shuffled */
6754 flavor_k_ptr = &k_info[k_ptr->flavor];
6758 /* Appearance of this object is very normal */
6759 flavor_k_ptr = k_ptr;
6762 object_idx[0] = direct_k_idx;
6763 object_old = direct_k_idx;
6766 /* Terminate the list */
6769 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6770 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6773 /* Terminate the list */
6774 grp_idx[grp_cnt] = -1;
6777 grp_cur = grp_top = 0;
6778 object_cur = object_top = 0;
6783 mode = visual_only ? 0x02 : 0x00;
6788 object_kind *k_ptr, *flavor_k_ptr;
6795 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6796 if (direct_k_idx < 0) prt("グループ", 4, 0);
6797 prt("名前", 4, max + 3);
6798 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6801 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6802 if (direct_k_idx < 0) prt("Group", 4, 0);
6803 prt("Name", 4, max + 3);
6804 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6808 for (i = 0; i < 78; i++)
6810 Term_putch(i, 5, TERM_WHITE, '=');
6813 if (direct_k_idx < 0)
6815 for (i = 0; i < browser_rows; i++)
6817 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6824 if (direct_k_idx < 0)
6826 /* Scroll group list */
6827 if (grp_cur < grp_top) grp_top = grp_cur;
6828 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6830 /* Display a list of object groups */
6831 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6833 if (old_grp_cur != grp_cur)
6835 old_grp_cur = grp_cur;
6837 /* Get a list of objects in the current group */
6838 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6841 /* Scroll object list */
6842 while (object_cur < object_top)
6843 object_top = MAX(0, object_top - browser_rows/2);
6844 while (object_cur >= object_top + browser_rows)
6845 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6850 /* Display a list of objects in the current group */
6851 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6855 object_top = object_cur;
6857 /* Display a list of objects in the current group */
6858 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6860 /* Display visual list below first object */
6861 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6864 /* Get the current object */
6865 k_ptr = &k_info[object_idx[object_cur]];
6867 if (!visual_only && k_ptr->flavor)
6869 /* Appearance of this object is shuffled */
6870 flavor_k_ptr = &k_info[k_ptr->flavor];
6874 /* Appearance of this object is very normal */
6875 flavor_k_ptr = k_ptr;
6880 prt(format("<方向>%s%s%s, ESC",
6881 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6882 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6883 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6886 prt(format("<dir>%s%s%s, ESC",
6887 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6888 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6889 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6895 /* Mega Hack -- track this object */
6896 if (object_cnt) object_kind_track(object_idx[object_cur]);
6898 /* The "current" object changed */
6899 if (object_old != object_idx[object_cur])
6903 /* Remember the "current" object */
6904 object_old = object_idx[object_cur];
6910 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6914 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6918 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6923 /* Do visual mode command if needed */
6924 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))
6926 if (direct_k_idx >= 0)
6951 /* Recall on screen */
6952 if (!visual_list && !visual_only && (grp_cnt > 0))
6954 desc_obj_fake(object_idx[object_cur]);
6962 /* Move the cursor */
6963 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6969 /* Free the "object_idx" array */
6970 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6975 * Display the features in a group.
6977 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6978 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6980 int lit_col[F_LIT_MAX], i, j;
6981 int f_idx_col = use_bigtile ? 62 : 64;
6983 /* Correct columns 1 and 4 */
6984 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6985 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6986 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6988 /* Display lines until done */
6989 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6992 FEAT_IDX f_idx = feat_idx[feat_top + i];
6993 feature_type *f_ptr = &f_info[f_idx];
6994 int row_i = row + i;
6996 /* Choose a color */
6997 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
6999 /* Display the name */
7000 c_prt(attr, f_name + f_ptr->name, row_i, col);
7002 /* Hack -- visual_list mode */
7005 /* Display lighting level */
7006 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7008 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));
7010 if (p_ptr->wizard || visual_only)
7012 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7015 /* Display symbol */
7016 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);
7018 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7019 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7021 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7023 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7025 /* Mega-hack -- Use non-standard colour */
7026 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7028 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7032 /* Clear remaining lines */
7033 for (; i < per_page; i++)
7035 Term_erase(col, row + i, 255);
7041 * Interact with feature visuals.
7043 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7047 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7048 FEAT_IDX feat_cur, feat_top;
7050 FEAT_IDX grp_idx[100];
7054 TERM_LEN column = 0;
7058 bool visual_list = FALSE;
7059 TERM_COLOR attr_top = 0;
7062 TERM_LEN browser_rows;
7065 TERM_COLOR attr_old[F_LIT_MAX];
7066 SYMBOL_CODE char_old[F_LIT_MAX];
7067 TERM_COLOR *cur_attr_ptr;
7068 SYMBOL_CODE *cur_char_ptr;
7070 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7071 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7073 Term_get_size(&wid, &hgt);
7075 browser_rows = hgt - 8;
7077 /* Allocate the "feat_idx" array */
7078 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7083 if (direct_f_idx < 0)
7085 /* Check every group */
7086 for (i = 0; feature_group_text[i] != NULL; i++)
7088 /* Measure the label */
7089 len = strlen(feature_group_text[i]);
7091 /* Save the maximum length */
7092 if (len > max) max = len;
7094 /* See if any features are known */
7095 if (collect_features(i, feat_idx, 0x01))
7097 /* Build a list of groups with known features */
7098 grp_idx[grp_cnt++] = i;
7106 feature_type *f_ptr = &f_info[direct_f_idx];
7108 feat_idx[0] = direct_f_idx;
7111 /* Terminate the list */
7114 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7115 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7117 for (i = 0; i < F_LIT_MAX; i++)
7119 attr_old[i] = f_ptr->x_attr[i];
7120 char_old[i] = f_ptr->x_char[i];
7124 /* Terminate the list */
7125 grp_idx[grp_cnt] = -1;
7128 grp_cur = grp_top = 0;
7129 feat_cur = feat_top = 0;
7137 feature_type *f_ptr;
7143 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7144 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7145 prt(_("名前", "Name"), 4, max + 3);
7148 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7149 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7153 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7154 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7157 for (i = 0; i < 78; i++)
7159 Term_putch(i, 5, TERM_WHITE, '=');
7162 if (direct_f_idx < 0)
7164 for (i = 0; i < browser_rows; i++)
7166 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7173 if (direct_f_idx < 0)
7175 /* Scroll group list */
7176 if (grp_cur < grp_top) grp_top = grp_cur;
7177 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7179 /* Display a list of feature groups */
7180 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7182 if (old_grp_cur != grp_cur)
7184 old_grp_cur = grp_cur;
7186 /* Get a list of features in the current group */
7187 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7190 /* Scroll feature list */
7191 while (feat_cur < feat_top)
7192 feat_top = MAX(0, feat_top - browser_rows/2);
7193 while (feat_cur >= feat_top + browser_rows)
7194 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7199 /* Display a list of features in the current group */
7200 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7204 feat_top = feat_cur;
7206 /* Display a list of features in the current group */
7207 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7209 /* Display visual list below first object */
7210 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7214 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7215 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7216 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7219 /* Get the current feature */
7220 f_ptr = &f_info[feat_idx[feat_cur]];
7221 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7222 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7226 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7230 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7234 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7239 if (visual_list && ((ch == 'A') || (ch == 'a')))
7241 int prev_lighting_level = *lighting_level;
7245 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7246 else (*lighting_level)--;
7250 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7251 else (*lighting_level)++;
7254 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7255 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7257 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7258 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7263 else if ((ch == 'D') || (ch == 'd'))
7265 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7266 byte prev_x_char = f_ptr->x_char[*lighting_level];
7268 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7272 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7273 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7275 if (prev_x_char != f_ptr->x_char[*lighting_level])
7276 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7278 else *need_redraw = TRUE;
7283 /* Do visual mode command if needed */
7284 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))
7288 /* Restore previous visual settings */
7290 for (i = 0; i < F_LIT_MAX; i++)
7292 f_ptr->x_attr[i] = attr_old[i];
7293 f_ptr->x_char[i] = char_old[i];
7300 if (direct_f_idx >= 0) flag = TRUE;
7301 else *lighting_level = F_LIT_STANDARD;
7304 /* Preserve current visual settings */
7307 for (i = 0; i < F_LIT_MAX; i++)
7309 attr_old[i] = f_ptr->x_attr[i];
7310 char_old[i] = f_ptr->x_char[i];
7312 *lighting_level = F_LIT_STANDARD;
7319 for (i = 0; i < F_LIT_MAX; i++)
7321 attr_idx_feat[i] = f_ptr->x_attr[i];
7322 char_idx_feat[i] = f_ptr->x_char[i];
7331 /* Allow TERM_DARK text */
7332 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7334 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7335 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7353 /* Move the cursor */
7354 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7360 /* Free the "feat_idx" array */
7361 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7366 * List wanted monsters
7368 static void do_cmd_knowledge_kubi(void)
7373 GAME_TEXT file_name[1024];
7376 /* Open a new file */
7377 fff = my_fopen_temp(file_name, 1024);
7379 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7386 bool listed = FALSE;
7388 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7389 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7391 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7392 fprintf(fff, "----------------------------------------------\n");
7394 for (i = 0; i < MAX_KUBI; i++)
7396 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7398 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7406 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7411 /* Display the file contents */
7412 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7417 * List virtues & status
7419 static void do_cmd_knowledge_virtues(void)
7422 GAME_TEXT file_name[1024];
7424 /* Open a new file */
7425 fff = my_fopen_temp(file_name, 1024);
7427 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7434 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7439 /* Display the file contents */
7440 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7447 static void do_cmd_knowledge_dungeon(void)
7451 GAME_TEXT file_name[1024];
7454 /* Open a new file */
7455 fff = my_fopen_temp(file_name, 1024);
7457 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7464 for (i = 1; i < max_d_idx; i++)
7468 if (!d_info[i].maxdepth) continue;
7469 if (!max_dlv[i]) continue;
7470 if (d_info[i].final_guardian)
7472 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7474 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7476 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7481 /* Display the file contents */
7482 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7487 * List virtues & status
7490 static void do_cmd_knowledge_stat(void)
7494 GAME_TEXT file_name[1024];
7497 /* Open a new file */
7498 fff = my_fopen_temp(file_name, 1024);
7500 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7507 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7508 (2 * p_ptr->hitdie +
7509 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7511 if (p_ptr->knowledge & KNOW_HPRATE)
7512 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7513 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7515 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7516 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7518 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);
7519 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7526 /* Display the file contents */
7527 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7533 * Print all active quests
7535 static void do_cmd_knowledge_quests_current(FILE *fff)
7538 char rand_tmp_str[120] = "\0";
7539 GAME_TEXT name[MAX_NLEN];
7540 monster_race *r_ptr;
7542 int rand_level = 100;
7545 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7547 for (i = 1; i < max_q_idx; i++)
7549 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7550 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7551 (quest[i].status == QUEST_STATUS_COMPLETED))
7553 /* Set the quest number temporary */
7554 QUEST_IDX old_quest = p_ptr->inside_quest;
7557 /* Clear the text */
7558 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7559 quest_text_line = 0;
7561 p_ptr->inside_quest = i;
7563 /* Get the quest text */
7564 init_flags = INIT_SHOW_TEXT;
7566 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7568 /* Reset the old quest number */
7569 p_ptr->inside_quest = old_quest;
7571 /* No info from "silent" quests */
7572 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7576 if (quest[i].type != QUEST_TYPE_RANDOM)
7578 char note[80] = "\0";
7580 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7582 switch (quest[i].type)
7584 case QUEST_TYPE_KILL_LEVEL:
7585 case QUEST_TYPE_KILL_ANY_LEVEL:
7586 r_ptr = &r_info[quest[i].r_idx];
7587 strcpy(name, r_name + r_ptr->name);
7588 if (quest[i].max_num > 1)
7591 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7592 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7595 sprintf(note," - kill %d %s, have killed %d.",
7596 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7600 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7603 case QUEST_TYPE_FIND_ARTIFACT:
7606 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7608 object_type *q_ptr = &forge;
7609 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7610 object_prep(q_ptr, k_idx);
7611 q_ptr->name1 = quest[i].k_idx;
7612 q_ptr->ident = IDENT_STORE;
7613 object_desc(name, q_ptr, OD_NAME_ONLY);
7615 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7617 case QUEST_TYPE_FIND_EXIT:
7618 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7621 case QUEST_TYPE_KILL_NUMBER:
7623 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7624 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7626 sprintf(note," - Kill %d monsters, have killed %d.",
7627 (int)quest[i].max_num, (int)quest[i].cur_num);
7631 case QUEST_TYPE_KILL_ALL:
7632 case QUEST_TYPE_TOWER:
7633 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7638 /* Print the quest info */
7639 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7640 quest[i].name, (int)quest[i].level, note);
7642 fputs(tmp_str, fff);
7644 if (quest[i].status == QUEST_STATUS_COMPLETED)
7646 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7647 fputs(tmp_str, fff);
7653 while (quest_text[j][0] && j < 10)
7655 fprintf(fff, " %s\n", quest_text[j]);
7660 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7663 rand_level = quest[i].level;
7665 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7667 /* Print the quest info */
7668 r_ptr = &r_info[quest[i].r_idx];
7669 strcpy(name, r_name + r_ptr->name);
7671 if (quest[i].max_num > 1)
7674 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7675 quest[i].name, (int)quest[i].level,
7676 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7680 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7681 quest[i].name, (int)quest[i].level,
7682 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7687 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7688 quest[i].name, (int)quest[i].level, name);
7695 /* Print the current random quest */
7696 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7698 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7702 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7705 char playtime_str[16];
7706 quest_type* const q_ptr = &quest[q_idx];
7708 if (is_fixed_quest_idx(q_idx))
7710 /* Set the quest number temporary */
7711 IDX old_quest = p_ptr->inside_quest;
7713 p_ptr->inside_quest = q_idx;
7716 init_flags = INIT_NAME_ONLY;
7718 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7720 /* Reset the old quest number */
7721 p_ptr->inside_quest = old_quest;
7723 /* No info from "silent" quests */
7724 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7727 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7728 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7730 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7732 /* Print the quest info */
7733 if (q_ptr->complev == 0)
7736 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7737 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7738 r_name+r_info[q_ptr->r_idx].name,
7739 (int)q_ptr->level, playtime_str);
7744 _(" %-35s (%3d階) - レベル%2d - %s\n",
7745 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7746 r_name+r_info[q_ptr->r_idx].name,
7754 /* Print the quest info */
7756 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7757 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7758 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7761 fputs(tmp_str, fff);
7767 * Print all finished quests
7769 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7772 QUEST_IDX total = 0;
7774 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7775 for (i = 1; i < max_q_idx; i++)
7777 QUEST_IDX q_idx = quest_num[i];
7778 quest_type* const q_ptr = &quest[q_idx];
7780 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7785 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7790 * Print all failed quests
7792 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7795 QUEST_IDX total = 0;
7797 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7798 for (i = 1; i < max_q_idx; i++)
7800 QUEST_IDX q_idx = quest_num[i];
7801 quest_type* const q_ptr = &quest[q_idx];
7803 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7804 do_cmd_knowledge_quests_aux(fff, q_idx))
7809 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7814 * Print all random quests
7816 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7818 GAME_TEXT tmp_str[120];
7820 QUEST_IDX total = 0;
7822 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7823 for (i = 1; i < max_q_idx; i++)
7825 /* No info from "silent" quests */
7826 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7828 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7832 /* Print the quest info */
7833 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7834 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7835 fputs(tmp_str, fff);
7838 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7842 * Print quest status of all active quests
7844 static void do_cmd_knowledge_quests(void)
7847 GAME_TEXT file_name[1024];
7852 /* Open a new file */
7853 fff = my_fopen_temp(file_name, 1024);
7856 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7861 /* Allocate Memory */
7862 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7864 /* Sort by compete level */
7865 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7866 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7868 /* Dump Quest Information */
7869 do_cmd_knowledge_quests_current(fff);
7871 do_cmd_knowledge_quests_completed(fff, quest_num);
7873 do_cmd_knowledge_quests_failed(fff, quest_num);
7877 do_cmd_knowledge_quests_wiz_random(fff);
7881 /* Display the file contents */
7882 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7886 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7893 static void do_cmd_knowledge_home(void)
7898 GAME_TEXT file_name[1024];
7900 GAME_TEXT o_name[MAX_NLEN];
7901 concptr paren = ")";
7903 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7905 /* Open a new file */
7906 fff = my_fopen_temp(file_name, 1024);
7908 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7915 /* Print all homes in the different towns */
7916 st_ptr = &town_info[1].store[STORE_HOME];
7918 /* Home -- if anything there */
7919 if (st_ptr->stock_num)
7924 /* Header with name of the town */
7925 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7927 /* Dump all available items */
7928 for (i = 0; i < st_ptr->stock_num; i++)
7931 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7932 object_desc(o_name, &st_ptr->stock[i], 0);
7933 if (strlen(o_name) <= 80-3)
7935 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7941 for (n = 0, t = o_name; n < 80-3; n++, t++)
7942 if(iskanji(*t)) {t++; n++;}
7943 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7945 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7946 fprintf(fff, " %.77s\n", o_name+n);
7949 object_desc(o_name, &st_ptr->stock[i], 0);
7950 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7955 /* Add an empty line */
7956 fprintf(fff, "\n\n");
7961 /* Display the file contents */
7962 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7968 * Check the status of "autopick"
7970 static void do_cmd_knowledge_autopick(void)
7974 GAME_TEXT file_name[1024];
7976 /* Open a new file */
7977 fff = my_fopen_temp(file_name, 1024);
7981 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7988 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7992 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7993 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7996 for (k = 0; k < max_autopick; k++)
7999 byte act = autopick_list[k].action;
8000 if (act & DONT_AUTOPICK)
8002 tmp = _("放置", "Leave");
8004 else if (act & DO_AUTODESTROY)
8006 tmp = _("破壊", "Destroy");
8008 else if (act & DO_AUTOPICK)
8010 tmp = _("拾う", "Pickup");
8014 tmp = _("確認", "Query");
8017 if (act & DO_DISPLAY)
8018 fprintf(fff, "%11s", format("[%s]", tmp));
8020 fprintf(fff, "%11s", format("(%s)", tmp));
8022 tmp = autopick_line_from_entry(&autopick_list[k]);
8023 fprintf(fff, " %s", tmp);
8028 /* Display the file contents */
8029 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8035 * Interact with "knowledge"
8037 void do_cmd_knowledge(void)
8040 bool need_redraw = FALSE;
8042 /* File type is "TEXT" */
8043 FILE_TYPE(FILE_TYPE_TEXT);
8046 /* Interact until done */
8051 /* Ask for a choice */
8052 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8053 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8055 /* Give some choices */
8059 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8060 prt("(2) 既知のアイテム の一覧", 7, 5);
8061 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8062 prt("(4) 既知のモンスター の一覧", 9, 5);
8063 prt("(5) 倒した敵の数 の一覧", 10, 5);
8064 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8065 prt("(7) 現在のペット の一覧", 12, 5);
8066 prt("(8) 我が家のアイテム の一覧", 13, 5);
8067 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8068 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8072 prt("(a) 自分に関する情報 の一覧", 6, 5);
8073 prt("(b) 突然変異 の一覧", 7, 5);
8074 prt("(c) 武器の経験値 の一覧", 8, 5);
8075 prt("(d) 魔法の経験値 の一覧", 9, 5);
8076 prt("(e) 技能の経験値 の一覧", 10, 5);
8077 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8078 prt("(g) 入ったダンジョン の一覧", 12, 5);
8079 prt("(h) 実行中のクエスト の一覧", 13, 5);
8080 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8085 prt("(1) Display known artifacts", 6, 5);
8086 prt("(2) Display known objects", 7, 5);
8087 prt("(3) Display remaining uniques", 8, 5);
8088 prt("(4) Display known monster", 9, 5);
8089 prt("(5) Display kill count", 10, 5);
8090 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8091 prt("(7) Display current pets", 12, 5);
8092 prt("(8) Display home p_ptr->inventory_list", 13, 5);
8093 prt("(9) Display *identified* equip.", 14, 5);
8094 prt("(0) Display terrain symbols.", 15, 5);
8098 prt("(a) Display about yourself", 6, 5);
8099 prt("(b) Display mutations", 7, 5);
8100 prt("(c) Display weapon proficiency", 8, 5);
8101 prt("(d) Display spell proficiency", 9, 5);
8102 prt("(e) Display misc. proficiency", 10, 5);
8103 prt("(f) Display virtues", 11, 5);
8104 prt("(g) Display dungeons", 12, 5);
8105 prt("(h) Display current quests", 13, 5);
8106 prt("(i) Display auto pick/destroy", 14, 5);
8110 prt(_("-続く-", "-more-"), 17, 8);
8111 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8112 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8113 /*prt("-) 前ページ", 21, 60);*/
8114 prt(_("コマンド:", "Command: "), 20, 0);
8117 if (i == ESCAPE) break;
8120 case ' ': /* Page change */
8124 case '1': /* Artifacts */
8125 do_cmd_knowledge_artifacts();
8127 case '2': /* Objects */
8128 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8130 case '3': /* Uniques */
8131 do_cmd_knowledge_uniques();
8133 case '4': /* Monsters */
8134 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8136 case '5': /* Kill count */
8137 do_cmd_knowledge_kill_count();
8139 case '6': /* wanted */
8140 if (!vanilla_town) do_cmd_knowledge_kubi();
8142 case '7': /* Pets */
8143 do_cmd_knowledge_pets();
8145 case '8': /* Home */
8146 do_cmd_knowledge_home();
8148 case '9': /* Resist list */
8149 do_cmd_knowledge_inven();
8151 case '0': /* Feature list */
8153 IDX lighting_level = F_LIT_STANDARD;
8154 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8158 case 'a': /* Max stat */
8159 do_cmd_knowledge_stat();
8161 case 'b': /* Mutations */
8162 do_cmd_knowledge_mutations();
8164 case 'c': /* weapon-exp */
8165 do_cmd_knowledge_weapon_exp();
8167 case 'd': /* spell-exp */
8168 do_cmd_knowledge_spell_exp();
8170 case 'e': /* skill-exp */
8171 do_cmd_knowledge_skill_exp();
8173 case 'f': /* Virtues */
8174 do_cmd_knowledge_virtues();
8176 case 'g': /* Dungeon */
8177 do_cmd_knowledge_dungeon();
8179 case 'h': /* Quests */
8180 do_cmd_knowledge_quests();
8182 case 'i': /* Autopick */
8183 do_cmd_knowledge_autopick();
8185 default: /* Unknown option */
8193 if (need_redraw) do_cmd_redraw();
8198 * Check on the status of an active quest
8200 void do_cmd_checkquest(void)
8202 /* File type is "TEXT" */
8203 FILE_TYPE(FILE_TYPE_TEXT);
8207 do_cmd_knowledge_quests();
8213 * Display the time and date
8215 void do_cmd_time(void)
8217 int day, hour, min, full, start, end, num;
8225 extract_day_hour_min(&day, &hour, &min);
8227 full = hour * 100 + min;
8234 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8236 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8237 else strcpy(day_buf, "*****");
8239 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8240 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8243 if (!randint0(10) || p_ptr->image)
8245 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8249 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8252 /* Open this file */
8253 fff = my_fopen(buf, "rt");
8257 /* Find this time */
8258 while (!my_fgets(fff, buf, sizeof(buf)))
8260 /* Ignore comments */
8261 if (!buf[0] || (buf[0] == '#')) continue;
8263 /* Ignore invalid lines */
8264 if (buf[1] != ':') continue;
8266 /* Process 'Start' */
8269 /* Extract the starting time */
8270 start = atoi(buf + 2);
8272 /* Assume valid for an hour */
8282 /* Extract the ending time */
8283 end = atoi(buf + 2);
8289 /* Ignore incorrect range */
8290 if ((start > full) || (full > end)) continue;
8292 /* Process 'Description' */
8297 /* Apply the randomizer */
8298 if (!randint0(num)) strcpy(desc, buf + 2);