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.
53 #include "cmd-spell.h"
57 #include "player-effects.h"
58 #include "player-status.h"
59 #include "player-skill.h"
60 #include "player-personality.h"
67 #include "object-flavor.h"
68 #include "object-hook.h"
70 #include "monster-status.h"
72 #include "view-mainwindow.h"
73 #include "dungeon-file.h"
75 #include "player-class.h"
76 #include "player-move.h"
78 #include "objectkind.h"
79 #include "floor-town.h"
83 * Mark strings for auto dump
85 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
86 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
89 * Variables for auto dump
91 static FILE *auto_dump_stream;
92 static concptr auto_dump_mark;
93 static int auto_dump_line_num;
99 * @brief prf出力内容を消去する /
100 * Remove old lines automatically generated before.
101 * @param orig_file 消去を行うファイル名
103 static void remove_auto_dump(concptr orig_file)
105 FILE *tmp_fff, *orig_fff;
109 bool between_mark = FALSE;
110 bool changed = FALSE;
112 long header_location = 0;
113 char header_mark_str[80];
114 char footer_mark_str[80];
117 /* Prepare a header/footer mark string */
118 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
119 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
121 mark_len = strlen(footer_mark_str);
123 /* Open an old dump file in read-only mode */
124 orig_fff = my_fopen(orig_file, "r");
126 /* If original file does not exist, nothing to do */
127 if (!orig_fff) return;
129 /* Open a new (temporary) file */
130 tmp_fff = my_fopen_temp(tmp_file, 1024);
134 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
139 /* Loop for every line */
143 if (my_fgets(orig_fff, buf, sizeof(buf)))
145 /* Read error: Assume End of File */
148 * Was looking for the footer, but not found.
150 * Since automatic dump might be edited by hand,
151 * it's dangerous to kill these lines.
152 * Seek back to the next line of the (pseudo) header,
157 fseek(orig_fff, header_location, SEEK_SET);
158 between_mark = FALSE;
162 /* Success -- End the loop */
169 /* We are looking for the header mark of automatic dump */
172 /* Is this line a header? */
173 if (!strcmp(buf, header_mark_str))
175 /* Memorise seek point of this line */
176 header_location = ftell(orig_fff);
178 /* Initialize counter for number of lines */
181 /* Look for the footer from now */
184 /* There are some changes */
191 /* Copy orginally lines */
192 fprintf(tmp_fff, "%s\n", buf);
196 /* We are looking for the footer mark of automatic dump */
199 /* Is this line a footer? */
200 if (!strncmp(buf, footer_mark_str, mark_len))
205 * Compare the number of lines
207 * If there is an inconsistency between
208 * actual number of lines and the
209 * number here, the automatic dump
210 * might be edited by hand. So it's
211 * dangerous to kill these lines.
212 * Seek back to the next line of the
213 * (pseudo) header, and read again.
215 if (!sscanf(buf + mark_len, " (%d)", &tmp)
218 fseek(orig_fff, header_location, SEEK_SET);
221 /* Look for another header */
222 between_mark = FALSE;
228 /* Ignore old line, and count number of lines */
238 /* If there are some changes, overwrite the original file with new one */
241 /* Copy contents of temporary file */
243 tmp_fff = my_fopen(tmp_file, "r");
244 orig_fff = my_fopen(orig_file, "w");
246 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
247 fprintf(orig_fff, "%s\n", buf);
253 /* Kill the temporary file */
261 * @brief prfファイルのフォーマットに従った内容を出力する /
262 * Dump a formatted line, using "vstrnfmt()".
265 static void auto_dump_printf(concptr fmt, ...)
272 /* Begin the Varargs Stuff */
275 /* Format the args, save the length */
276 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
278 /* End the Varargs Stuff */
281 /* Count number of lines */
282 for (p = buf; *p; p++)
284 if (*p == '\n') auto_dump_line_num++;
288 fprintf(auto_dump_stream, "%s", buf);
293 * @brief prfファイルをファイルオープンする /
294 * Open file to append auto dump.
296 * @param mark 出力するヘッダマーク
297 * @return ファイルポインタを取得できたらTRUEを返す
299 static bool open_auto_dump(concptr buf, concptr mark)
302 char header_mark_str[80];
304 /* Save the mark string */
305 auto_dump_mark = mark;
307 /* Prepare a header mark string */
308 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
310 /* Remove old macro dumps */
311 remove_auto_dump(buf);
313 /* Append to the file */
314 auto_dump_stream = my_fopen(buf, "a");
317 if (!auto_dump_stream) {
318 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
326 fprintf(auto_dump_stream, "%s\n", header_mark_str);
328 /* Initialize counter */
329 auto_dump_line_num = 0;
331 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
332 "# *Warning!* The lines below are an automatic dump.\n"));
333 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
334 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
340 * @brief prfファイルをファイルクローズする /
341 * Append foot part and close auto dump.
344 static void close_auto_dump(void)
346 char footer_mark_str[80];
348 /* Prepare a footer mark string */
349 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
351 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
352 "# *Warning!* The lines below are an automatic dump.\n"));
353 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
354 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
356 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
359 my_fclose(auto_dump_stream);
368 * @brief Return suffix of ordinal number
370 * @return pointer of suffix string.
372 concptr get_ordinal_number_suffix(int num)
374 num = ABS(num) % 100;
378 return (num == 11) ? "th" : "st";
380 return (num == 12) ? "th" : "nd";
382 return (num == 13) ? "th" : "rd";
391 * @brief 日記にメッセージを追加する /
392 * Take note to the diary.
393 * @param type 日記内容のID
394 * @param num 日記内容のIDに応じた数値
395 * @param note 日記内容のIDに応じた文字列参照ポインタ
398 errr do_cmd_write_nikki(int type, int num, concptr note)
402 GAME_TEXT file_name[MAX_NLEN];
404 concptr note_level = "";
405 bool do_level = TRUE;
406 char note_level_buf[40];
409 static bool disable_nikki = FALSE;
411 extract_day_hour_min(&day, &hour, &min);
413 if (disable_nikki) return(-1);
415 if (type == NIKKI_FIX_QUEST_C ||
416 type == NIKKI_FIX_QUEST_F ||
417 type == NIKKI_RAND_QUEST_C ||
418 type == NIKKI_RAND_QUEST_F ||
419 type == NIKKI_TO_QUEST)
423 old_quest = p_ptr->inside_quest;
424 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
426 /* Get the quest text */
427 init_flags = INIT_NAME_ONLY;
429 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
431 /* Reset the old quest number */
432 p_ptr->inside_quest = old_quest;
435 /* different filne name to avoid mixing */
436 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
438 /* Build the filename */
439 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
441 /* File type is "TEXT" */
442 FILE_TYPE(FILE_TYPE_TEXT);
444 fff = my_fopen(buf, "a");
449 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
455 q_idx = quest_number(current_floor_ptr->dun_level);
459 if (p_ptr->inside_arena)
460 note_level = _("アリーナ:", "Arane:");
461 else if (!current_floor_ptr->dun_level)
462 note_level = _("地上:", "Surface:");
463 else if (q_idx && (is_fixed_quest_idx(q_idx)
464 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
465 note_level = _("クエスト:", "Quest:");
469 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
471 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
473 note_level = note_level_buf;
481 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
482 else fputs(_("*****日目\n", "Day *****\n"), fff);
490 fprintf(fff, "%s\n",note);
494 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
499 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
502 case NIKKI_ART_SCROLL:
504 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
509 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
512 case NIKKI_FIX_QUEST_C:
514 if (quest[num].flags & QUEST_FLAG_SILENT) break;
515 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
516 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
519 case NIKKI_FIX_QUEST_F:
521 if (quest[num].flags & QUEST_FLAG_SILENT) break;
522 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
523 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
526 case NIKKI_RAND_QUEST_C:
528 GAME_TEXT name[MAX_NLEN];
529 strcpy(name, r_name+r_info[quest[num].r_idx].name);
530 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
531 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
534 case NIKKI_RAND_QUEST_F:
536 GAME_TEXT name[MAX_NLEN];
537 strcpy(name, r_name+r_info[quest[num].r_idx].name);
538 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
539 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
542 case NIKKI_MAXDEAPTH:
544 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
545 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
546 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
547 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
552 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
553 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
554 _(d_name + d_info[num].name, (int)max_dlv[num]),
555 _((int)max_dlv[num], d_name + d_info[num].name));
561 if (q_idx && (is_fixed_quest_idx(q_idx)
562 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
564 to = _("地上", "the surface");
568 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
569 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
571 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
577 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
578 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
579 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
581 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
586 if (quest[num].flags & QUEST_FLAG_SILENT) break;
587 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
588 hour, min, note_level, quest[num].name);
593 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
594 hour, min, note_level);
599 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
604 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
612 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
613 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
616 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
617 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
619 if (num == MAX_ARENA_MONS)
621 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
622 " won all fight to become a Chanpion.\n"));
629 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
635 if (!current_floor_ptr->dun_level)
636 to = _("地上", "the surface");
638 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
640 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
641 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
647 if (!current_floor_ptr->dun_level)
648 to = _("地上", "the surface");
650 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
652 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
653 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
658 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
661 case NIKKI_GAMESTART:
663 time_t ct = time((time_t*)0);
667 fprintf(fff, "%s %s",note, ctime(&ct));
670 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
673 case NIKKI_NAMED_PET:
675 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
678 case RECORD_NAMED_PET_NAME:
679 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
681 case RECORD_NAMED_PET_UNNAME:
682 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
684 case RECORD_NAMED_PET_DISMISS:
685 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
687 case RECORD_NAMED_PET_DEATH:
688 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
690 case RECORD_NAMED_PET_MOVED:
691 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
693 case RECORD_NAMED_PET_LOST_SIGHT:
694 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
696 case RECORD_NAMED_PET_DESTROY:
697 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
699 case RECORD_NAMED_PET_EARTHQUAKE:
700 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
702 case RECORD_NAMED_PET_GENOCIDE:
703 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
705 case RECORD_NAMED_PET_WIZ_ZAP:
706 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
708 case RECORD_NAMED_PET_TELE_LEVEL:
709 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
711 case RECORD_NAMED_PET_BLAST:
712 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
714 case RECORD_NAMED_PET_HEAL_LEPER:
715 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
717 case RECORD_NAMED_PET_COMPACT:
718 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
720 case RECORD_NAMED_PET_LOSE_PARENT:
721 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
732 case NIKKI_WIZARD_LOG:
733 fprintf(fff, "%s\n", note);
742 if (do_level) write_level = FALSE;
748 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
751 * @brief 日記のタイトル表記と内容出力 /
754 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
756 static void do_cmd_disp_nikki(void)
758 char nikki_title[256];
759 GAME_TEXT file_name[MAX_NLEN];
764 static const char subtitle[][30] = {"最強の肉体を求めて",
795 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
796 "Attack is the best form of defence.",
798 "An unexpected windfall",
799 "A drowning man will catch at a straw",
800 "Don't count your chickens before they are hatched.",
801 "It is no use crying over spilt milk.",
802 "Seeing is believing.",
803 "Strike the iron while it is hot.",
804 "I don't care what follows.",
805 "To dig a well to put out a house on fire.",
806 "Tomorrow is another day.",
807 "Easy come, easy go.",
808 "The more haste, the less speed.",
809 "Where there is life, there is hope.",
810 "There is no royal road to *WINNER*.",
811 "Danger past, God forgotten.",
812 "The best thing to do now is to run away.",
813 "Life is but an empty dream.",
814 "Dead men tell no tales.",
815 "A book that remains shut is but a block.",
816 "Misfortunes never come singly.",
817 "A little knowledge is a dangerous thing.",
818 "History repeats itself.",
819 "*WINNER* was not built in a day.",
820 "Ignorance is bliss.",
821 "To lose is to win?",
822 "No medicine can cure folly.",
823 "All good things come to an end.",
824 "M$ Empire strikes back.",
825 "To see is to believe",
827 "Quest of The World's Greatest Brain"};
829 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
831 /* Build the filename */
832 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
834 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
835 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
836 else if (IS_WIZARD_CLASS())
837 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
838 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
841 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
843 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
846 /* Display the file contents */
847 show_file(FALSE, buf, nikki_title, -1, 0);
851 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
854 static void do_cmd_bunshou(void)
857 char bunshou[80] = "\0";
859 if (get_string(_("内容: ", "diary note: "), tmp, 79))
861 strcpy(bunshou, tmp);
863 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
868 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
871 static void do_cmd_last_get(void)
876 if (record_o_name[0] == '\0') return;
878 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
879 if (!get_check(buf)) return;
881 turn_tmp = current_world_ptr->game_turn;
882 current_world_ptr->game_turn = record_turn;
883 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
884 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
885 current_world_ptr->game_turn = turn_tmp;
889 * @brief ファイル中の全日記記録を消去する /
892 static void do_cmd_erase_nikki(void)
894 GAME_TEXT file_name[MAX_NLEN];
898 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
899 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
901 /* Build the filename */
902 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
905 fff = my_fopen(buf, "w");
908 msg_format(_("記録を消去しました。", "deleted record."));
910 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
919 void do_cmd_nikki(void)
923 /* File type is "TEXT" */
924 FILE_TYPE(FILE_TYPE_TEXT);
927 /* Interact until done */
932 /* Ask for a choice */
933 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
935 /* Give some choices */
936 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
937 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
938 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
939 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
941 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
944 prt(_("コマンド:", "Command: "), 18, 0);
949 if (i == ESCAPE) break;
963 do_cmd_erase_nikki();
967 prepare_movie_hooks();
969 default: /* Unknown option */
979 * @brief 画面を再描画するコマンドのメインルーチン
980 * Hack -- redraw the screen
984 * This command performs various low level updates, clears all the "extra"
985 * windows, does a total redraw of the main window, and requests all of the
986 * interesting updates and redraws that I can think of.
988 * This command is also used to "instantiate" the results of the user
989 * selecting various things, such as graphics mode, so it must call
990 * the "TERM_XTRA_REACT" hook before redrawing the windows.
993 void do_cmd_redraw(void)
999 /* Hack -- react to changes */
1000 Term_xtra(TERM_XTRA_REACT, 0);
1002 /* Combine and Reorder the pack (later) */
1003 p_ptr->update |= (PU_COMBINE | PU_REORDER);
1004 p_ptr->update |= (PU_TORCH);
1005 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1006 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1007 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1008 p_ptr->update |= (PU_MONSTERS);
1010 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1012 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1013 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1019 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1022 /* Redraw every window */
1023 for (j = 0; j < 8; j++)
1026 if (!angband_term[j]) continue;
1029 Term_activate(angband_term[j]);
1038 * @brief 名前を変更するコマンドのメインルーチン
1039 * Hack -- change name
1042 void do_cmd_change_name(void)
1057 /* Display the player */
1058 display_player(mode);
1063 display_player(mode);
1068 Term_putstr(2, 23, -1, TERM_WHITE,
1069 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1071 Term_putstr(2, 23, -1, TERM_WHITE,
1072 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1080 if (c == ESCAPE) break;
1087 /* Process the player name */
1088 process_player_name(FALSE);
1094 sprintf(tmp, "%s.txt", p_ptr->base_name);
1095 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1097 if (tmp[0] && (tmp[0] != ' '))
1099 file_character(tmp);
1117 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1124 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1125 * Recall the most recent message
1128 void do_cmd_message_one(void)
1130 /* Recall one message */
1131 prt(format("> %s", message_str(0)), 0, 0);
1136 * @brief メッセージのログを表示するコマンドのメインルーチン
1137 * Recall the most recent message
1141 * Show previous messages to the user -BEN-
1143 * The screen format uses line 0 and 23 for headers and prompts,
1144 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1146 * This command shows you which commands you are viewing, and allows
1147 * you to "search" for strings in the recall.
1149 * Note that messages may be longer than 80 characters, but they are
1150 * displayed using "infinite" length, with a special sub-command to
1151 * "slide" the virtual display to the left or right.
1153 * Attempt to only hilite the matching portions of the string.
1156 void do_cmd_messages(int num_now)
1160 char shower_str[81];
1161 char finder_str[81];
1163 concptr shower = NULL;
1167 Term_get_size(&wid, &hgt);
1169 /* Number of message lines in a screen */
1170 num_lines = hgt - 4;
1173 strcpy(finder_str, "");
1176 strcpy(shower_str, "");
1178 /* Total messages */
1181 /* Start on first message */
1186 /* Process requests until done */
1192 /* Dump up to 20 lines of messages */
1193 for (j = 0; (j < num_lines) && (i + j < n); j++)
1195 concptr msg = message_str(i+j);
1197 /* Dump the messages, bottom to top */
1198 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1200 /* Hilite "shower" */
1201 if (shower && shower[0])
1205 /* Display matches */
1206 while ((str = my_strstr(str, shower)) != NULL)
1208 int len = strlen(shower);
1210 /* Display the match */
1211 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1219 /* Erase remaining lines */
1220 for (; j < num_lines; j++)
1222 Term_erase(0, num_lines + 1 - j, 255);
1225 /* Display header */
1227 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1228 i, i + j - 1, n), 0, 0);
1230 /* Display prompt (not very informative) */
1231 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1232 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1234 skey = inkey_special(TRUE);
1236 /* Exit on Escape */
1237 if (skey == ESCAPE) break;
1239 /* Hack -- Save the old index */
1244 /* Hack -- handle show */
1247 prt(_("強調: ", "Show: "), hgt - 1, 0);
1249 /* Get a "shower" string, or continue */
1250 strcpy(back_str, shower_str);
1251 if (askfor(shower_str, 80))
1254 shower = shower_str[0] ? shower_str : NULL;
1256 else strcpy(shower_str, back_str);
1260 /* Hack -- handle find */
1267 prt(_("検索: ", "Find: "), hgt - 1, 0);
1269 /* Get a "finder" string, or continue */
1270 strcpy(back_str, finder_str);
1271 if (!askfor(finder_str, 80))
1273 strcpy(finder_str, back_str);
1276 else if (!finder_str[0])
1278 shower = NULL; /* Stop showing */
1283 shower = finder_str;
1286 for (z = i + 1; z < n; z++)
1288 concptr msg = message_str(z);
1291 if (my_strstr(msg, finder_str))
1302 /* Recall 1 older message */
1304 /* Go to the oldest line */
1308 /* Recall 1 newer message */
1310 /* Go to the newest line */
1314 /* Recall 1 older message */
1319 /* Go older if legal */
1320 i = MIN(i + 1, n - num_lines);
1323 /* Recall 10 older messages */
1325 /* Go older if legal */
1326 i = MIN(i + 10, n - num_lines);
1329 /* Recall 20 older messages */
1334 /* Go older if legal */
1335 i = MIN(i + num_lines, n - num_lines);
1338 /* Recall 20 newer messages */
1342 /* Go newer (if able) */
1343 i = MAX(0, i - num_lines);
1346 /* Recall 10 newer messages */
1348 /* Go newer (if able) */
1352 /* Recall 1 newer messages */
1355 /* Go newer (if able) */
1360 /* Hack -- Error of some kind */
1368 * @brief チートオプションを変更するコマンドのメインルーチン
1369 * Interact with some options for cheating
1370 * @param info 表示メッセージ
1373 static void do_cmd_options_cheat(concptr info)
1376 int i, k = 0, n = CHEAT_MAX;
1380 /* Interact with the player */
1386 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1391 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1392 prt(" << 注意 >>", 11, 0);
1393 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1394 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1395 prt(" じらないようにして下さい。", 14, 0);
1397 /* Display the options */
1398 for (i = 0; i < n; i++)
1400 byte a = TERM_WHITE;
1402 /* Color current option */
1403 if (i == k) a = TERM_L_BLUE;
1405 /* Display the option text */
1406 sprintf(buf, "%-48s: %s (%s)",
1407 cheat_info[i].o_desc,
1408 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1409 cheat_info[i].o_text);
1410 c_prt(a, buf, i + 2, 0);
1413 /* Hilite current option */
1414 move_cursor(k + 2, 50);
1420 * HACK - Try to translate the key into a direction
1421 * to allow using the roguelike keys for navigation.
1423 dir = get_keymap_dir(ch);
1424 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1438 k = (n + k - 1) % n;
1456 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1457 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1458 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1459 (*cheat_info[k].o_var) = TRUE;
1468 (*cheat_info[k].o_var) = FALSE;
1475 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1476 /* Peruse the help file */
1477 (void)show_file(TRUE, buf, NULL, 0, 0);
1494 * @brief セーブ頻度ターンの次の値を返す
1495 * @param current 現在のセーブ頻度ターン値
1496 * @return 次のセーブ頻度ターン値
1498 static s16b toggle_frequency(s16b current)
1503 case 50: return 100;
1504 case 100: return 250;
1505 case 250: return 500;
1506 case 500: return 1000;
1507 case 1000: return 2500;
1508 case 2500: return 5000;
1509 case 5000: return 10000;
1510 case 10000: return 25000;
1517 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1518 * @param info 表示メッセージ
1521 static void do_cmd_options_autosave(concptr info)
1524 int i, k = 0, n = 2;
1529 /* Interact with the player */
1533 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1534 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1538 /* Display the options */
1539 for (i = 0; i < n; i++)
1541 byte a = TERM_WHITE;
1543 /* Color current option */
1544 if (i == k) a = TERM_L_BLUE;
1546 /* Display the option text */
1547 sprintf(buf, "%-48s: %s (%s)",
1548 autosave_info[i].o_desc,
1549 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1550 autosave_info[i].o_text);
1551 c_prt(a, buf, i + 2, 0);
1553 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1555 /* Hilite current option */
1556 move_cursor(k + 2, 50);
1572 k = (n + k - 1) % n;
1590 (*autosave_info[k].o_var) = TRUE;
1599 (*autosave_info[k].o_var) = FALSE;
1607 autosave_freq = toggle_frequency(autosave_freq);
1608 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1614 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1630 * @brief 標準オプションを変更するコマンドのサブルーチン /
1631 * Interact with some options
1632 * @param page オプションページ番号
1633 * @param info 表示メッセージ
1636 void do_cmd_options_aux(int page, concptr info)
1639 int i, k = 0, n = 0, l;
1642 bool browse_only = (page == OPT_PAGE_BIRTH) && current_world_ptr->character_generated &&
1643 (!p_ptr->wizard || !allow_debug_opts);
1646 /* Lookup the options */
1647 for (i = 0; i < 24; i++) opt[i] = 0;
1649 /* Scan the options */
1650 for (i = 0; option_info[i].o_desc; i++)
1652 /* Notice options on this "page" */
1653 if (option_info[i].o_page == page) opt[n++] = i;
1657 /* Interact with the player */
1663 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1664 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1667 /* HACK -- description for easy-auto-destroy options */
1668 if (page == OPT_PAGE_AUTODESTROY)
1669 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1670 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1672 /* Display the options */
1673 for (i = 0; i < n; i++)
1675 byte a = TERM_WHITE;
1677 /* Color current option */
1678 if (i == k) a = TERM_L_BLUE;
1680 /* Display the option text */
1681 sprintf(buf, "%-48s: %s (%.19s)",
1682 option_info[opt[i]].o_desc,
1683 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1684 option_info[opt[i]].o_text);
1685 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1686 else c_prt(a, buf, i + 2, 0);
1689 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1692 /* Hilite current option */
1693 move_cursor(k + 2 + l, 50);
1699 * HACK - Try to translate the key into a direction
1700 * to allow using the roguelike keys for navigation.
1702 dir = get_keymap_dir(ch);
1703 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1717 k = (n + k - 1) % n;
1734 if (browse_only) break;
1735 (*option_info[opt[k]].o_var) = TRUE;
1744 if (browse_only) break;
1745 (*option_info[opt[k]].o_var) = FALSE;
1753 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1759 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1760 /* Peruse the help file */
1761 (void)show_file(TRUE, buf, NULL, 0, 0);
1778 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1779 * Modify the "window" options
1782 static void do_cmd_options_win(void)
1792 /* Memorize old flags */
1793 for (j = 0; j < 8; j++)
1795 /* Acquire current flags */
1796 old_flag[j] = window_flag[j];
1805 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1807 /* Display the windows */
1808 for (j = 0; j < 8; j++)
1810 byte a = TERM_WHITE;
1812 concptr s = angband_term_name[j];
1815 if (j == x) a = TERM_L_BLUE;
1817 /* Window name, staggered, centered */
1818 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1821 /* Display the options */
1822 for (i = 0; i < 16; i++)
1824 byte a = TERM_WHITE;
1826 concptr str = window_flag_desc[i];
1829 if (i == y) a = TERM_L_BLUE;
1832 if (!str) str = _("(未使用)", "(Unused option)");
1835 Term_putstr(0, i + 5, -1, a, str);
1837 /* Display the windows */
1838 for (j = 0; j < 8; j++)
1844 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1847 if (window_flag[j] & (1L << i)) c = 'X';
1850 Term_putch(35 + j * 5, i + 5, a, c);
1855 Term_gotoxy(35 + x * 5, y + 5);
1873 for (j = 0; j < 8; j++)
1875 window_flag[j] &= ~(1L << y);
1879 for (i = 0; i < 16; i++)
1881 window_flag[x] &= ~(1L << i);
1894 window_flag[x] |= (1L << y);
1902 window_flag[x] &= ~(1L << y);
1908 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1916 d = get_keymap_dir(ch);
1918 x = (x + ddx[d] + 8) % 8;
1919 y = (y + ddy[d] + 16) % 16;
1926 /* Notice changes */
1927 for (j = 0; j < 8; j++)
1932 if (!angband_term[j]) continue;
1934 /* Ignore non-changes */
1935 if (window_flag[j] == old_flag[j]) continue;
1938 Term_activate(angband_term[j]);
1955 option_fields[OPT_NUM] =
1958 { '1', " キー入力 オプション", 3 },
1959 { '2', " マップ画面 オプション", 4 },
1960 { '3', " テキスト表示 オプション", 5 },
1961 { '4', " ゲームプレイ オプション", 6 },
1962 { '5', " 行動中止関係 オプション", 7 },
1963 { '6', " 簡易自動破壊 オプション", 8 },
1964 { 'r', " プレイ記録 オプション", 9 },
1966 { 'p', "自動拾いエディタ", 11 },
1967 { 'd', " 基本ウェイト量 ", 12 },
1968 { 'h', "低ヒットポイント", 13 },
1969 { 'm', " 低魔力色閾値 ", 14 },
1970 { 'a', " 自動セーブ オプション", 15 },
1971 { 'w', "ウインドウフラグ", 16 },
1973 { 'b', " 初期 オプション (参照のみ)", 18 },
1974 { 'c', " 詐欺 オプション", 19 },
1976 { '1', "Input Options", 3 },
1977 { '2', "Map Screen Options", 4 },
1978 { '3', "Text Display Options", 5 },
1979 { '4', "Game-Play Options", 6 },
1980 { '5', "Disturbance Options", 7 },
1981 { '6', "Easy Auto-Destroyer Options", 8 },
1982 { 'r', "Play record Options", 9 },
1984 { 'p', "Auto-picker/destroyer editor", 11 },
1985 { 'd', "Base Delay Factor", 12 },
1986 { 'h', "Hitpoint Warning", 13 },
1987 { 'm', "Mana Color Threshold", 14 },
1988 { 'a', "Autosave Options", 15 },
1989 { 'w', "Window Flags", 16 },
1991 { 'b', "Birth Options (Browse Only)", 18 },
1992 { 'c', "Cheat Options", 19 },
1998 * @brief 標準オプションを変更するコマンドのメインルーチン /
1999 * Set or unset various options.
2003 * The user must use the "Ctrl-R" command to "adapt" to changes
2004 * in any options which control "visual" aspects of the game.
2007 void do_cmd_options(void)
2019 /* Does not list cheat option when cheat option is off */
2020 if (!p_ptr->noscore && !allow_debug_opts) n--;
2023 /* Why are we here */
2024 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2028 /* Give some choices */
2029 for (i = 0; i < n; i++)
2031 byte a = TERM_WHITE;
2032 if (i == y) a = TERM_L_BLUE;
2033 Term_putstr(5, option_fields[i].row, -1, a,
2034 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2037 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2040 skey = inkey_special(TRUE);
2041 if (!(skey & SKEY_MASK)) k = (char)skey;
2045 if (k == ESCAPE) break;
2047 if (my_strchr("\n\r ", k))
2049 k = option_fields[y].key;
2053 for (i = 0; i < n; i++)
2055 if (tolower(k) == option_fields[i].key) break;
2058 /* Command is found */
2061 /* Hack -- browse help */
2062 if (k == '?') break;
2066 if (skey == SKEY_UP) d = 8;
2067 if (skey == SKEY_DOWN) d = 2;
2068 y = (y + ddy[d] + n) % n;
2073 if (k == ESCAPE) break;
2080 /* Process the general options */
2081 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2087 /* Process the general options */
2088 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2095 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2102 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2109 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2116 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2120 /* Play-record Options */
2125 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2134 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2135 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2136 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2140 /* Cheating Options */
2143 if (!p_ptr->noscore && !allow_debug_opts)
2145 /* Cheat options are not permitted */
2151 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2158 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2167 do_cmd_options_win();
2168 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2169 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2170 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2171 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2176 /* Auto-picker/destroyer editor */
2180 do_cmd_edit_autopick();
2184 /* Hack -- Delay Speed */
2190 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2192 /* Get a new value */
2195 int msec = delay_factor * delay_factor * delay_factor;
2196 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2197 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2199 if (k == ESCAPE) break;
2202 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2205 else if (isdigit(k)) delay_factor = D2I(k);
2212 /* Hack -- hitpoint warning factor */
2218 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2220 /* Get a new value */
2223 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2224 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2226 if (k == ESCAPE) break;
2229 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2232 else if (isdigit(k)) hitpoint_warn = D2I(k);
2239 /* Hack -- mana color factor */
2245 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2247 /* Get a new value */
2250 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2251 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2253 if (k == ESCAPE) break;
2256 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2259 else if (isdigit(k)) mana_warn = D2I(k);
2267 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2271 /* Unknown option */
2284 /* Hack - Redraw equippy chars */
2285 p_ptr->redraw |= (PR_EQUIPPY);
2291 * @brief prefファイルを選択して処理する /
2292 * Ask for a "user pref line" and process it
2295 * Allow absolute file names?
2297 void do_cmd_pref(void)
2304 /* Ask for a "user pref command" */
2305 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2307 /* Process that pref command */
2308 (void)process_pref_file_command(buf);
2312 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2315 void do_cmd_reload_autopick(void)
2317 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2318 /* Load the file with messages */
2319 autopick_load_pref(TRUE);
2325 * @brief マクロ情報をprefファイルに保存する /
2326 * @param fname ファイル名
2329 static errr macro_dump(concptr fname)
2331 static concptr mark = "Macro Dump";
2337 /* Build the filename */
2338 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2340 /* File type is "TEXT" */
2341 FILE_TYPE(FILE_TYPE_TEXT);
2343 /* Append to the file */
2344 if (!open_auto_dump(buf, mark)) return (-1);
2347 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2350 for (i = 0; i < macro__num; i++)
2352 /* Extract the action */
2353 ascii_to_text(buf, macro__act[i]);
2355 /* Dump the macro */
2356 auto_dump_printf("A:%s\n", buf);
2358 /* Extract the action */
2359 ascii_to_text(buf, macro__pat[i]);
2361 /* Dump normal macros */
2362 auto_dump_printf("P:%s\n", buf);
2365 auto_dump_printf("\n");
2377 * @brief マクロのトリガーキーを取得する /
2378 * Hack -- ask for a "trigger" (see below)
2379 * @param buf キー表記を保管するバッファ
2383 * Note the complex use of the "inkey()" function from "util.c".
2385 * Note that both "flush()" calls are extremely important.
2388 static void do_cmd_macro_aux(char *buf)
2396 /* Do not process macros */
2402 /* Read the pattern */
2408 /* Do not process macros */
2411 /* Do not wait for keys */
2414 /* Attempt to read a key */
2423 /* Convert the trigger */
2424 ascii_to_text(tmp, buf);
2426 /* Hack -- display the trigger */
2427 Term_addstr(-1, TERM_WHITE, tmp);
2433 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2434 * Hack -- ask for a keymap "trigger" (see below)
2435 * @param buf キー表記を取得するバッファ
2439 * Note that both "flush()" calls are extremely important. This may
2440 * no longer be true, since "util.c" is much simpler now.
2443 static void do_cmd_macro_aux_keymap(char *buf)
2453 /* Convert to ascii */
2454 ascii_to_text(tmp, buf);
2456 /* Hack -- display the trigger */
2457 Term_addstr(-1, TERM_WHITE, tmp);
2464 * @brief キーマップをprefファイルにダンプする /
2465 * Hack -- append all keymaps to the given file
2466 * @param fname ファイルネーム
2470 static errr keymap_dump(concptr fname)
2472 static concptr mark = "Keymap Dump";
2481 if (rogue_like_commands)
2483 mode = KEYMAP_MODE_ROGUE;
2489 mode = KEYMAP_MODE_ORIG;
2493 /* Build the filename */
2494 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2496 /* File type is "TEXT" */
2497 FILE_TYPE(FILE_TYPE_TEXT);
2499 /* Append to the file */
2500 if (!open_auto_dump(buf, mark)) return -1;
2503 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2506 for (i = 0; i < 256; i++)
2510 /* Loop up the keymap */
2511 act = keymap_act[mode][i];
2513 /* Skip empty keymaps */
2516 /* Encode the key */
2519 ascii_to_text(key, buf);
2521 /* Encode the action */
2522 ascii_to_text(buf, act);
2524 /* Dump the macro */
2525 auto_dump_printf("A:%s\n", buf);
2526 auto_dump_printf("C:%d:%s\n", mode, key);
2538 * @brief マクロを設定するコマンドのメインルーチン /
2539 * Interact with "macros"
2543 * Note that the macro "action" must be defined before the trigger.
2545 * Could use some helpful instructions on this page.
2548 void do_cmd_macros(void)
2560 if (rogue_like_commands)
2562 mode = KEYMAP_MODE_ROGUE;
2568 mode = KEYMAP_MODE_ORIG;
2571 /* File type is "TEXT" */
2572 FILE_TYPE(FILE_TYPE_TEXT);
2577 /* Process requests until done */
2581 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2583 /* Describe that action */
2584 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2586 /* Analyze the current action */
2587 ascii_to_text(buf, macro__buf);
2589 /* Display the current action */
2594 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2596 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2597 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2598 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2599 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2600 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2601 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2602 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2603 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2604 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2605 #endif /* ALLOW_MACROS */
2608 prt(_("コマンド: ", "Command: "), 16, 0);
2613 if (i == ESCAPE) break;
2615 /* Load a 'macro' file */
2621 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2624 prt(_("ファイル: ", "File: "), 18, 0);
2626 /* Default filename */
2627 sprintf(tmp, "%s.prf", p_ptr->base_name);
2629 /* Ask for a file */
2630 if (!askfor(tmp, 80)) continue;
2632 /* Process the given filename */
2633 err = process_pref_file(tmp);
2636 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2641 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2645 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2655 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2658 prt(_("ファイル: ", "File: "), 18, 0);
2660 /* Default filename */
2661 sprintf(tmp, "%s.prf", p_ptr->base_name);
2663 /* Ask for a file */
2664 if (!askfor(tmp, 80)) continue;
2666 /* Dump the macros */
2667 (void)macro_dump(tmp);
2670 msg_print(_("マクロを追加しました。", "Appended macros."));
2679 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2683 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2685 /* Get a macro trigger */
2686 do_cmd_macro_aux(buf);
2688 /* Acquire action */
2689 k = macro_find_exact(buf);
2695 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2701 /* Obtain the action */
2702 strcpy(macro__buf, macro__act[k]);
2704 /* Analyze the current action */
2705 ascii_to_text(buf, macro__buf);
2707 /* Display the current action */
2711 msg_print(_("マクロを確認しました。", "Found a macro."));
2715 /* Create a macro */
2719 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2722 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2724 /* Get a macro trigger */
2725 do_cmd_macro_aux(buf);
2731 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2732 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2735 prt(_("マクロ行動: ", "Action: "), 20, 0);
2737 /* Convert to text */
2738 ascii_to_text(tmp, macro__buf);
2740 /* Get an encoded action */
2741 if (askfor(tmp, 80))
2743 /* Convert to ascii */
2744 text_to_ascii(macro__buf, tmp);
2746 /* Link the macro */
2747 macro_add(buf, macro__buf);
2750 msg_print(_("マクロを追加しました。", "Added a macro."));
2754 /* Remove a macro */
2758 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2761 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2763 /* Get a macro trigger */
2764 do_cmd_macro_aux(buf);
2766 /* Link the macro */
2767 macro_add(buf, buf);
2770 msg_print(_("マクロを削除しました。", "Removed a macro."));
2777 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2780 prt(_("ファイル: ", "File: "), 18, 0);
2782 /* Default filename */
2783 sprintf(tmp, "%s.prf", p_ptr->base_name);
2785 /* Ask for a file */
2786 if (!askfor(tmp, 80)) continue;
2788 /* Dump the macros */
2789 (void)keymap_dump(tmp);
2792 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2795 /* Query a keymap */
2801 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2804 prt(_("押すキー: ", "Keypress: "), 18, 0);
2806 /* Get a keymap trigger */
2807 do_cmd_macro_aux_keymap(buf);
2809 /* Look up the keymap */
2810 act = keymap_act[mode][(byte)(buf[0])];
2816 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2822 /* Obtain the action */
2823 strcpy(macro__buf, act);
2825 /* Analyze the current action */
2826 ascii_to_text(buf, macro__buf);
2828 /* Display the current action */
2832 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2836 /* Create a keymap */
2840 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2843 prt(_("押すキー: ", "Keypress: "), 18, 0);
2845 /* Get a keymap trigger */
2846 do_cmd_macro_aux_keymap(buf);
2852 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2853 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2856 prt(_("行動: ", "Action: "), 20, 0);
2858 /* Convert to text */
2859 ascii_to_text(tmp, macro__buf);
2861 /* Get an encoded action */
2862 if (askfor(tmp, 80))
2864 /* Convert to ascii */
2865 text_to_ascii(macro__buf, tmp);
2867 /* Free old keymap */
2868 string_free(keymap_act[mode][(byte)(buf[0])]);
2870 /* Make new keymap */
2871 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2874 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2878 /* Remove a keymap */
2882 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2885 prt(_("押すキー: ", "Keypress: "), 18, 0);
2887 /* Get a keymap trigger */
2888 do_cmd_macro_aux_keymap(buf);
2890 /* Free old keymap */
2891 string_free(keymap_act[mode][(byte)(buf[0])]);
2893 /* Make new keymap */
2894 keymap_act[mode][(byte)(buf[0])] = NULL;
2897 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2900 /* Enter a new action */
2904 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2910 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2911 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2914 prt(_("マクロ行動: ", "Action: "), 20, 0);
2916 /* Hack -- limit the value */
2919 /* Get an encoded action */
2920 if (!askfor(buf, 80)) continue;
2922 /* Extract an action */
2923 text_to_ascii(macro__buf, buf);
2926 #endif /* ALLOW_MACROS */
2939 * @brief キャラクタ色の明暗表現
2941 static concptr lighting_level_str[F_LIT_MAX] =
2956 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2957 * @param i 指定対象となるキャラクタコード
2958 * @param num 指定されたビジュアルIDを返す参照ポインタ
2959 * @param max ビジュアルIDの最大数
2960 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2962 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2969 sprintf(str, "%d", *num);
2971 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2974 tmp = (IDX)strtol(str, NULL, 0);
2975 if (tmp >= 0 && tmp < max)
2978 else if (isupper(i))
2979 *num = (*num + max - 1) % max;
2981 *num = (*num + 1) % max;
2987 * @brief キャラクタの変更メニュー表示
2988 * @param choice_msg 選択メッセージ
2991 static void print_visuals_menu(concptr choice_msg)
2993 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2995 /* Give some choices */
2996 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2998 #ifdef ALLOW_VISUALS
2999 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
3000 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
3001 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
3002 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
3003 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
3004 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
3005 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3006 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3007 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3008 #endif /* ALLOW_VISUALS */
3010 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3013 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3016 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3017 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3018 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3021 * Interact with "visuals"
3023 void do_cmd_visuals(void)
3028 bool need_redraw = FALSE;
3029 concptr empty_symbol = "<< ? >>";
3031 if (use_bigtile) empty_symbol = "<< ?? >>";
3033 /* File type is "TEXT" */
3034 FILE_TYPE(FILE_TYPE_TEXT);
3037 /* Interact until done */
3042 /* Ask for a choice */
3043 print_visuals_menu(NULL);
3048 if (i == ESCAPE) break;
3052 /* Load a 'pref' file */
3055 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3058 prt(_("ファイル: ", "File: "), 17, 0);
3060 /* Default filename */
3061 sprintf(tmp, "%s.prf", p_ptr->base_name);
3064 if (!askfor(tmp, 70)) continue;
3066 /* Process the given filename */
3067 (void)process_pref_file(tmp);
3072 #ifdef ALLOW_VISUALS
3074 /* Dump monster attr/chars */
3077 static concptr mark = "Monster attr/chars";
3080 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3083 prt(_("ファイル: ", "File: "), 17, 0);
3085 /* Default filename */
3086 sprintf(tmp, "%s.prf", p_ptr->base_name);
3088 /* Get a filename */
3089 if (!askfor(tmp, 70)) continue;
3091 /* Build the filename */
3092 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3094 /* Append to the file */
3095 if (!open_auto_dump(buf, mark)) continue;
3098 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3101 for (i = 0; i < max_r_idx; i++)
3103 monster_race *r_ptr = &r_info[i];
3105 /* Skip non-entries */
3106 if (!r_ptr->name) continue;
3108 /* Dump a comment */
3109 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3111 /* Dump the monster attr/char info */
3112 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3113 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3119 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3124 /* Dump object attr/chars */
3127 static concptr mark = "Object attr/chars";
3128 KIND_OBJECT_IDX k_idx;
3131 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3134 prt(_("ファイル: ", "File: "), 17, 0);
3136 /* Default filename */
3137 sprintf(tmp, "%s.prf", p_ptr->base_name);
3139 /* Get a filename */
3140 if (!askfor(tmp, 70)) continue;
3142 /* Build the filename */
3143 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3145 /* Append to the file */
3146 if (!open_auto_dump(buf, mark)) continue;
3149 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3152 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3154 GAME_TEXT o_name[MAX_NLEN];
3155 object_kind *k_ptr = &k_info[k_idx];
3157 /* Skip non-entries */
3158 if (!k_ptr->name) continue;
3163 strip_name(o_name, k_idx);
3169 /* Prepare dummy object */
3170 object_prep(&forge, k_idx);
3172 /* Get un-shuffled flavor name */
3173 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3176 /* Dump a comment */
3177 auto_dump_printf("# %s\n", o_name);
3179 /* Dump the object attr/char info */
3180 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3181 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3187 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3192 /* Dump feature attr/chars */
3195 static concptr mark = "Feature attr/chars";
3198 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3201 prt(_("ファイル: ", "File: "), 17, 0);
3203 /* Default filename */
3204 sprintf(tmp, "%s.prf", p_ptr->base_name);
3206 /* Get a filename */
3207 if (!askfor(tmp, 70)) continue;
3209 /* Build the filename */
3210 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3212 /* Append to the file */
3213 if (!open_auto_dump(buf, mark)) continue;
3216 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3219 for (i = 0; i < max_f_idx; i++)
3221 feature_type *f_ptr = &f_info[i];
3223 /* Skip non-entries */
3224 if (!f_ptr->name) continue;
3226 /* Skip mimiccing features */
3227 if (f_ptr->mimic != i) continue;
3229 /* Dump a comment */
3230 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3232 /* Dump the feature attr/char info */
3233 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3234 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3235 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3236 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3242 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3247 /* Modify monster attr/chars (numeric operation) */
3250 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3251 static MONRACE_IDX r = 0;
3253 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3255 /* Hack -- query until done */
3258 monster_race *r_ptr = &r_info[r];
3262 TERM_COLOR da = r_ptr->d_attr;
3263 byte dc = r_ptr->d_char;
3264 TERM_COLOR ca = r_ptr->x_attr;
3265 byte cc = r_ptr->x_char;
3267 /* Label the object */
3268 Term_putstr(5, 17, -1, TERM_WHITE,
3269 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3271 /* Label the Default values */
3272 Term_putstr(10, 19, -1, TERM_WHITE,
3273 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3275 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3276 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3278 /* Label the Current values */
3279 Term_putstr(10, 20, -1, TERM_WHITE,
3280 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3282 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3283 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3286 Term_putstr(0, 22, -1, TERM_WHITE,
3287 _("コマンド (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): "));
3292 if (i == ESCAPE) break;
3294 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3295 else if (isupper(i)) c = 'a' + i - 'A';
3305 if (!cmd_visuals_aux(i, &r, max_r_idx))
3311 while (!r_info[r].name);
3315 t = (int)r_ptr->x_attr;
3316 (void)cmd_visuals_aux(i, &t, 256);
3317 r_ptr->x_attr = (byte)t;
3321 t = (int)r_ptr->x_char;
3322 (void)cmd_visuals_aux(i, &t, 256);
3323 r_ptr->x_char = (byte)t;
3327 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3329 print_visuals_menu(choice_msg);
3337 /* Modify object attr/chars (numeric operation) */
3340 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3342 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3344 /* Hack -- query until done */
3347 object_kind *k_ptr = &k_info[k];
3351 TERM_COLOR da = k_ptr->d_attr;
3352 SYMBOL_CODE dc = k_ptr->d_char;
3353 TERM_COLOR ca = k_ptr->x_attr;
3354 SYMBOL_CODE cc = k_ptr->x_char;
3356 /* Label the object */
3357 Term_putstr(5, 17, -1, TERM_WHITE,
3358 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3359 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3361 /* Label the Default values */
3362 Term_putstr(10, 19, -1, TERM_WHITE,
3363 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3365 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3366 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3368 /* Label the Current values */
3369 Term_putstr(10, 20, -1, TERM_WHITE,
3370 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3372 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3373 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3376 Term_putstr(0, 22, -1, TERM_WHITE,
3377 _("コマンド (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): "));
3382 if (i == ESCAPE) break;
3384 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3385 else if (isupper(i)) c = 'a' + i - 'A';
3395 if (!cmd_visuals_aux(i, &k, max_k_idx))
3401 while (!k_info[k].name);
3405 t = (int)k_ptr->x_attr;
3406 (void)cmd_visuals_aux(i, &t, 256);
3407 k_ptr->x_attr = (byte)t;
3411 t = (int)k_ptr->x_char;
3412 (void)cmd_visuals_aux(i, &t, 256);
3413 k_ptr->x_char = (byte)t;
3417 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3419 print_visuals_menu(choice_msg);
3427 /* Modify feature attr/chars (numeric operation) */
3430 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3432 static IDX lighting_level = F_LIT_STANDARD;
3433 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3435 /* Hack -- query until done */
3438 feature_type *f_ptr = &f_info[f];
3442 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3443 byte dc = f_ptr->d_char[lighting_level];
3444 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3445 byte cc = f_ptr->x_char[lighting_level];
3447 /* Label the object */
3449 Term_putstr(5, 17, -1, TERM_WHITE,
3450 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3451 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3453 /* Label the Default values */
3454 Term_putstr(10, 19, -1, TERM_WHITE,
3455 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3457 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3458 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3460 /* Label the Current values */
3462 Term_putstr(10, 20, -1, TERM_WHITE,
3463 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3465 Term_putstr(10, 20, -1, TERM_WHITE,
3466 format("Current attr/char = %3d / %3d", ca, cc));
3469 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3470 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3474 Term_putstr(0, 22, -1, TERM_WHITE,
3475 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3477 Term_putstr(0, 22, -1, TERM_WHITE,
3478 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3484 if (i == ESCAPE) break;
3486 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3487 else if (isupper(i)) c = 'a' + i - 'A';
3497 if (!cmd_visuals_aux(i, &f, max_f_idx))
3503 while (!f_info[f].name || (f_info[f].mimic != f));
3507 t = (int)f_ptr->x_attr[lighting_level];
3508 (void)cmd_visuals_aux(i, &t, 256);
3509 f_ptr->x_attr[lighting_level] = (byte)t;
3513 t = (int)f_ptr->x_char[lighting_level];
3514 (void)cmd_visuals_aux(i, &t, 256);
3515 f_ptr->x_char[lighting_level] = (byte)t;
3519 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3522 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3526 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3528 print_visuals_menu(choice_msg);
3536 /* Modify monster attr/chars (visual mode) */
3538 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3541 /* Modify object attr/chars (visual mode) */
3543 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3546 /* Modify feature attr/chars (visual mode) */
3549 IDX lighting_level = F_LIT_STANDARD;
3550 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3554 #endif /* ALLOW_VISUALS */
3562 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3566 /* Unknown option */
3576 if (need_redraw) do_cmd_redraw();
3581 * Interact with "colors"
3583 void do_cmd_colors(void)
3592 /* File type is "TEXT" */
3593 FILE_TYPE(FILE_TYPE_TEXT);
3598 /* Interact until done */
3603 /* Ask for a choice */
3604 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3606 /* Give some choices */
3607 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3610 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3611 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3615 prt(_("コマンド: ", "Command: "), 8, 0);
3619 if (i == ESCAPE) break;
3621 /* Load a 'pref' file */
3625 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3628 prt(_("ファイル: ", "File: "), 10, 0);
3631 sprintf(tmp, "%s.prf", p_ptr->base_name);
3634 if (!askfor(tmp, 70)) continue;
3636 /* Process the given filename */
3637 (void)process_pref_file(tmp);
3639 /* Mega-Hack -- react to changes */
3640 Term_xtra(TERM_XTRA_REACT, 0);
3642 /* Mega-Hack -- redraw */
3651 static concptr mark = "Colors";
3654 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3657 prt(_("ファイル: ", "File: "), 10, 0);
3659 /* Default filename */
3660 sprintf(tmp, "%s.prf", p_ptr->base_name);
3662 /* Get a filename */
3663 if (!askfor(tmp, 70)) continue;
3665 /* Build the filename */
3666 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3668 /* Append to the file */
3669 if (!open_auto_dump(buf, mark)) continue;
3672 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3675 for (i = 0; i < 256; i++)
3677 int kv = angband_color_table[i][0];
3678 int rv = angband_color_table[i][1];
3679 int gv = angband_color_table[i][2];
3680 int bv = angband_color_table[i][3];
3682 concptr name = _("未知", "unknown");
3684 /* Skip non-entries */
3685 if (!kv && !rv && !gv && !bv) continue;
3687 /* Extract the color name */
3688 if (i < 16) name = color_names[i];
3690 /* Dump a comment */
3691 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3693 /* Dump the monster attr/char info */
3694 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3701 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3710 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3712 /* Hack -- query until done */
3721 /* Exhibit the normal colors */
3722 for (j = 0; j < 16; j++)
3724 /* Exhibit this color */
3725 Term_putstr(j*4, 20, -1, a, "###");
3727 /* Exhibit all colors */
3728 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3731 /* Describe the color */
3732 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3734 /* Describe the color */
3735 Term_putstr(5, 10, -1, TERM_WHITE,
3736 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3738 /* Label the Current values */
3739 Term_putstr(5, 12, -1, TERM_WHITE,
3740 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3741 angband_color_table[a][0],
3742 angband_color_table[a][1],
3743 angband_color_table[a][2],
3744 angband_color_table[a][3]));
3747 Term_putstr(0, 14, -1, TERM_WHITE,
3748 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3753 if (i == ESCAPE) break;
3756 if (i == 'n') a = (byte)(a + 1);
3757 if (i == 'N') a = (byte)(a - 1);
3758 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3759 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3760 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3761 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3762 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3763 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3764 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3765 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3767 /* Hack -- react to changes */
3768 Term_xtra(TERM_XTRA_REACT, 0);
3770 /* Hack -- redraw */
3777 /* Unknown option */
3791 * Note something in the message recall
3793 void do_cmd_note(void)
3801 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3803 /* Ignore empty notes */
3804 if (!buf[0] || (buf[0] == ' ')) return;
3806 /* Add the note to the message recall */
3807 msg_format(_("メモ: %s", "Note: %s"), buf);
3812 * Mention the current version
3814 void do_cmd_version(void)
3816 #if FAKE_VER_EXTRA > 0
3817 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3818 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3820 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3821 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3828 * Array of feeling strings
3830 static concptr do_cmd_feeling_text[11] =
3832 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3833 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3834 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3835 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3836 _("とても悪い予感がする...", "You have a very bad feeling..."),
3837 _("悪い予感がする...", "You have a bad feeling..."),
3838 _("何か緊張する。", "You feel nervous."),
3839 _("少し不運な気がする...", "You feel your luck is turning..."),
3840 _("この場所は好きになれない。", "You don't like the look of this place."),
3841 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3842 _("なんて退屈なところだ...", "What a boring place...")
3845 static concptr do_cmd_feeling_text_combat[11] =
3847 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3848 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3849 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3850 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3851 _("とても悪い予感がする...", "You have a very bad feeling..."),
3852 _("悪い予感がする...", "You have a bad feeling..."),
3853 _("何か緊張する。", "You feel nervous."),
3854 _("少し不運な気がする...", "You feel your luck is turning..."),
3855 _("この場所は好きになれない。", "You don't like the look of this place."),
3856 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3857 _("なんて退屈なところだ...", "What a boring place...")
3860 static concptr do_cmd_feeling_text_lucky[11] =
3862 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3863 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3864 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3865 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3866 _("とても良い感じがする...", "You have a very good feeling..."),
3867 _("良い感じがする...", "You have a good feeling..."),
3868 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3869 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3870 _("見た感じ悪くはない...", "You like the look of this place..."),
3871 _("全然駄目ということはないが...", "This level can't be all bad..."),
3872 _("なんて退屈なところだ...", "What a boring place...")
3877 * Note that "feeling" is set to zero unless some time has passed.
3878 * Note that this is done when the level is GENERATED, not entered.
3880 void do_cmd_feeling(void)
3882 if (p_ptr->wild_mode) return;
3884 /* No useful feeling in quests */
3885 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3887 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3891 /* No useful feeling in town */
3892 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3894 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3896 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3901 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3906 /* No useful feeling in the wilderness */
3907 else if (!current_floor_ptr->dun_level)
3909 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3913 /* Display the feeling */
3914 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3915 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3916 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3917 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3918 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3920 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3926 * Description of each monster group.
3928 static concptr monster_group_text[] =
3931 "ユニーク", /* "Uniques" */
3932 "乗馬可能なモンスター", /* "Riding" */
3933 "賞金首", /* "Wanted */
3934 "アンバーの王族", /* "Ambertite" */
3963 /* "古代ドラゴン/ワイアーム", */
4024 /* "Ancient Dragon/Wyrm", */
4033 "Multi-Headed Reptile",
4038 "Reptile/Amphibian",
4039 "Spider/Scorpion/Tick",
4041 /* "Major Demon", */
4058 * Symbols of monsters in each group. Note the "Uniques" group
4059 * is handled differently.
4061 static concptr monster_group_char[] =
4118 "!$&()+./=>?[\\]`{|~",
4128 * Build a list of monster indexes in the given group. Return the number
4129 * of monsters in the group.
4131 * mode & 0x01 : check for non-empty group
4132 * mode & 0x02 : visual operation only
4134 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4140 /* Get a list of x_char in this group */
4141 concptr group_char = monster_group_char[grp_cur];
4143 /* XXX Hack -- Check if this is the "Uniques" group */
4144 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4146 /* XXX Hack -- Check if this is the "Riding" group */
4147 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4149 /* XXX Hack -- Check if this is the "Wanted" group */
4150 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4152 /* XXX Hack -- Check if this is the "Amberite" group */
4153 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4156 /* Check every race */
4157 for (i = 0; i < max_r_idx; i++)
4159 /* Access the race */
4160 monster_race *r_ptr = &r_info[i];
4162 /* Skip empty race */
4163 if (!r_ptr->name) continue ;
4165 /* Require known monsters */
4166 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4170 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4173 else if (grp_riding)
4175 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4178 else if (grp_wanted)
4180 bool wanted = FALSE;
4182 for (j = 0; j < MAX_KUBI; j++)
4184 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4185 (p_ptr->today_mon && p_ptr->today_mon == i))
4191 if (!wanted) continue;
4194 else if (grp_amberite)
4196 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4201 /* Check for race in the group */
4202 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4206 mon_idx[mon_cnt++] = i;
4208 /* XXX Hack -- Just checking for non-empty group */
4209 if (mode & 0x01) break;
4212 /* Terminate the list */
4213 mon_idx[mon_cnt] = -1;
4215 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4217 /* Return the number of races */
4223 * Description of each monster group.
4225 static concptr object_group_text[] =
4228 "キノコ", /* "Mushrooms" */
4229 "薬", /* "Potions" */
4230 "油つぼ", /* "Flasks" */
4231 "巻物", /* "Scrolls" */
4233 "アミュレット", /* "Amulets" */
4234 "笛", /* "Whistle" */
4235 "光源", /* "Lanterns" */
4236 "魔法棒", /* "Wands" */
4239 "カード", /* "Cards" */
4250 "刀剣類", /* "Swords" */
4251 "鈍器", /* "Blunt Weapons" */
4252 "長柄武器", /* "Polearms" */
4253 "採掘道具", /* "Diggers" */
4254 "飛び道具", /* "Bows" */
4258 "軽装鎧", /* "Soft Armor" */
4259 "重装鎧", /* "Hard Armor" */
4260 "ドラゴン鎧", /* "Dragon Armor" */
4261 "盾", /* "Shields" */
4262 "クローク", /* "Cloaks" */
4263 "籠手", /* "Gloves" */
4264 "ヘルメット", /* "Helms" */
4266 "ブーツ", /* "Boots" */
4319 * TVALs of items in each group
4321 static byte object_group_tval[] =
4362 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4370 * Build a list of object indexes in the given group. Return the number
4371 * of objects in the group.
4373 * mode & 0x01 : check for non-empty group
4374 * mode & 0x02 : visual operation only
4376 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4378 KIND_OBJECT_IDX i, object_cnt = 0;
4381 /* Get a list of x_char in this group */
4382 byte group_tval = object_group_tval[grp_cur];
4384 /* Check every object */
4385 for (i = 0; i < max_k_idx; i++)
4387 /* Access the object */
4388 object_kind *k_ptr = &k_info[i];
4390 /* Skip empty objects */
4391 if (!k_ptr->name) continue;
4395 /* Any objects will be displayed */
4401 /* Skip non-flavoured objects */
4402 if (!k_ptr->flavor) continue;
4404 /* Require objects ever seen */
4405 if (!k_ptr->aware) continue;
4408 /* Skip items with no distribution (special artifacts) */
4409 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4413 /* Check for objects in the group */
4414 if (TV_LIFE_BOOK == group_tval)
4416 /* Hack -- All spell books */
4417 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4419 /* Add the object */
4420 object_idx[object_cnt++] = i;
4424 else if (k_ptr->tval == group_tval)
4426 /* Add the object */
4427 object_idx[object_cnt++] = i;
4431 /* XXX Hack -- Just checking for non-empty group */
4432 if (mode & 0x01) break;
4435 /* Terminate the list */
4436 object_idx[object_cnt] = -1;
4438 /* Return the number of objects */
4444 * Description of each feature group.
4446 static concptr feature_group_text[] =
4454 * Build a list of feature indexes in the given group. Return the number
4455 * of features in the group.
4457 * mode & 0x01 : check for non-empty group
4459 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4462 FEAT_IDX feat_cnt = 0;
4464 /* Unused; There is a single group. */
4467 /* Check every feature */
4468 for (i = 0; i < max_f_idx; i++)
4470 feature_type *f_ptr = &f_info[i];
4472 /* Skip empty index */
4473 if (!f_ptr->name) continue;
4475 /* Skip mimiccing features */
4476 if (f_ptr->mimic != i) continue;
4479 feat_idx[feat_cnt++] = i;
4481 /* XXX Hack -- Just checking for non-empty group */
4482 if (mode & 0x01) break;
4485 /* Terminate the list */
4486 feat_idx[feat_cnt] = -1;
4488 /* Return the number of races */
4495 * Build a list of monster indexes in the given group. Return the number
4496 * of monsters in the group.
4498 static int collect_artifacts(int grp_cur, int object_idx[])
4500 int i, object_cnt = 0;
4502 /* Get a list of x_char in this group */
4503 byte group_tval = object_group_tval[grp_cur];
4505 /* Check every object */
4506 for (i = 0; i < max_a_idx; i++)
4508 /* Access the artifact */
4509 artifact_type *a_ptr = &a_info[i];
4511 /* Skip empty artifacts */
4512 if (!a_ptr->name) continue;
4514 /* Skip "uncreated" artifacts */
4515 if (!a_ptr->cur_num) continue;
4517 /* Check for race in the group */
4518 if (a_ptr->tval == group_tval)
4521 object_idx[object_cnt++] = i;
4525 /* Terminate the list */
4526 object_idx[object_cnt] = 0;
4528 /* Return the number of races */
4535 * Encode the screen colors
4537 static char hack[17] = "dwsorgbuDWvyRGBU";
4541 * Hack -- load a screen dump from a file
4543 void do_cmd_load_screen(void)
4548 SYMBOL_CODE c = ' ';
4554 Term_get_size(&wid, &hgt);
4556 /* Build the filename */
4557 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4559 /* Append to the file */
4560 fff = my_fopen(buf, "r");
4563 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4571 /* Load the screen */
4572 for (y = 0; okay; y++)
4574 /* Get a line of data including control code */
4575 if (!fgets(buf, 1024, fff)) okay = FALSE;
4577 /* Get the blank line */
4578 if (buf[0] == '\n' || buf[0] == '\0') break;
4580 /* Ignore too large screen image */
4581 if (y >= hgt) continue;
4584 for (x = 0; x < wid - 1; x++)
4587 if (buf[x] == '\n' || buf[x] == '\0') break;
4589 /* Put the attr/char */
4590 Term_draw(x, y, TERM_WHITE, buf[x]);
4594 /* Dump the screen */
4595 for (y = 0; okay; y++)
4597 /* Get a line of data including control code */
4598 if (!fgets(buf, 1024, fff)) okay = FALSE;
4600 /* Get the blank line */
4601 if (buf[0] == '\n' || buf[0] == '\0') break;
4603 /* Ignore too large screen image */
4604 if (y >= hgt) continue;
4607 for (x = 0; x < wid - 1; x++)
4610 if (buf[x] == '\n' || buf[x] == '\0') break;
4612 /* Get the attr/char */
4613 (void)(Term_what(x, y, &a, &c));
4615 /* Look up the attr */
4616 for (i = 0; i < 16; i++)
4618 /* Use attr matches */
4619 if (hack[i] == buf[x]) a = (byte_hack)i;
4622 /* Put the attr/char */
4623 Term_draw(x, y, a, c);
4628 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4639 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4640 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4643 #define IM_FLAG_STR _("*", "* ")
4644 #define HAS_FLAG_STR _("+", "+ ")
4645 #define NO_FLAG_STR _("・", ". ")
4647 #define print_im_or_res_flag(IM, RES) \
4649 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4650 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4653 #define print_flag(TR) \
4655 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4659 /* XTRA HACK RESLIST */
4660 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4662 GAME_TEXT o_name[MAX_NLEN];
4663 BIT_FLAGS flgs[TR_FLAG_SIZE];
4665 if (!o_ptr->k_idx) return;
4666 if (o_ptr->tval != tval) return;
4668 /* Identified items only */
4669 if (!object_is_known(o_ptr)) return;
4672 * HACK:Ring of Lordly protection and Dragon equipment
4673 * have random resistances.
4675 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4676 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4677 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4678 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4679 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4680 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4681 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4682 || object_is_artifact(o_ptr))
4685 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4687 while (o_name[i] && (i < 26))
4690 if (iskanji(o_name[i])) i++;
4699 o_name[i] = ' '; i++;
4704 fprintf(fff, "%s %s", where, o_name);
4706 if (!(o_ptr->ident & (IDENT_MENTAL)))
4708 fputs(_("-------不明--------------- -------不明---------\n",
4709 "-------unknown------------ -------unknown------\n"), fff);
4713 object_flags_known(o_ptr, flgs);
4715 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4716 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4717 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4718 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4719 print_flag(TR_RES_POIS);
4720 print_flag(TR_RES_LITE);
4721 print_flag(TR_RES_DARK);
4722 print_flag(TR_RES_SHARDS);
4723 print_flag(TR_RES_SOUND);
4724 print_flag(TR_RES_NETHER);
4725 print_flag(TR_RES_NEXUS);
4726 print_flag(TR_RES_CHAOS);
4727 print_flag(TR_RES_DISEN);
4731 print_flag(TR_RES_BLIND);
4732 print_flag(TR_RES_FEAR);
4733 print_flag(TR_RES_CONF);
4734 print_flag(TR_FREE_ACT);
4735 print_flag(TR_SEE_INVIS);
4736 print_flag(TR_HOLD_EXP);
4737 print_flag(TR_TELEPATHY);
4738 print_flag(TR_SLOW_DIGEST);
4739 print_flag(TR_REGEN);
4740 print_flag(TR_LEVITATION);
4748 fprintf(fff, "%s\n", inven_res_label);
4754 * Display *ID* ed weapons/armors's resistances
4756 static void do_cmd_knowledge_inven(void)
4759 GAME_TEXT file_name[1024];
4761 OBJECT_TYPE_VALUE tval;
4767 /* Open a new file */
4768 fff = my_fopen_temp(file_name, 1024);
4771 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4775 fprintf(fff, "%s\n", inven_res_label);
4777 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4781 for (; j < 9; j++) fputc('\n', fff);
4783 fprintf(fff, "%s\n", inven_res_label);
4785 strcpy(where, _("装", "E "));
4786 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4788 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4790 strcpy(where, _("持", "I "));
4791 for (i = 0; i < INVEN_PACK; i++)
4793 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4796 st_ptr = &town_info[1].store[STORE_HOME];
4797 strcpy(where, _("家", "H "));
4798 for (i = 0; i < st_ptr->stock_num; i++)
4800 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4805 /* Display the file contents */
4806 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4811 void do_cmd_save_screen_html_aux(char *filename, int message)
4816 TERM_COLOR a = 0, old_a = 0;
4830 concptr html_head[] = {
4831 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4835 concptr html_foot[] = {
4837 "</body>\n</html>\n",
4843 Term_get_size(&wid, &hgt);
4845 /* File type is "TEXT" */
4846 FILE_TYPE(FILE_TYPE_TEXT);
4848 /* Append to the file */
4849 fff = my_fopen(filename, "w");
4853 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4859 if (message) screen_save();
4861 /* Build the filename */
4862 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4863 tmpfff = my_fopen(buf, "r");
4865 for (i = 0; html_head[i]; i++)
4866 fputs(html_head[i], fff);
4870 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4872 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4876 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4878 fprintf(fff, "%s\n", buf);
4883 /* Dump the screen */
4884 for (y = 0; y < hgt; y++)
4891 for (x = 0; x < wid - 1; x++)
4895 /* Get the attr/char */
4896 (void)(Term_what(x, y, &a, &c));
4900 case '&': cc = "&"; break;
4901 case '<': cc = "<"; break;
4902 case '>': cc = ">"; break;
4904 case 0x1f: c = '.'; break;
4905 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4910 if ((y == 0 && x == 0) || a != old_a) {
4911 rv = angband_color_table[a][1];
4912 gv = angband_color_table[a][2];
4913 bv = angband_color_table[a][3];
4914 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4915 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4919 fprintf(fff, "%s", cc);
4921 fprintf(fff, "%c", c);
4924 fprintf(fff, "</font>");
4927 for (i = 0; html_foot[i]; i++)
4928 fputs(html_foot[i], fff);
4933 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4935 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4939 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4941 fprintf(fff, "%s\n", buf);
4952 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4960 * Hack -- save a screen dump to a file
4962 static void do_cmd_save_screen_html(void)
4964 char buf[1024], tmp[256] = "screen.html";
4966 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4969 /* Build the filename */
4970 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4974 do_cmd_save_screen_html_aux(buf, 1);
4979 * Redefinable "save_screen" action
4981 void (*screendump_aux)(void) = NULL;
4985 * Hack -- save a screen dump to a file
4987 void do_cmd_save_screen(void)
4989 bool old_use_graphics = use_graphics;
4990 bool html_dump = FALSE;
4994 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4998 if (c == 'Y' || c == 'y')
5000 else if (c == 'H' || c == 'h')
5012 Term_get_size(&wid, &hgt);
5014 if (old_use_graphics)
5016 use_graphics = FALSE;
5018 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5024 do_cmd_save_screen_html();
5028 /* Do we use a special screendump function ? */
5029 else if (screendump_aux)
5031 /* Dump the screen to a graphics file */
5032 (*screendump_aux)();
5034 else /* Dump the screen as text */
5038 SYMBOL_CODE c = ' ';
5042 /* Build the filename */
5043 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5045 /* File type is "TEXT" */
5046 FILE_TYPE(FILE_TYPE_TEXT);
5048 /* Append to the file */
5049 fff = my_fopen(buf, "w");
5053 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5061 /* Dump the screen */
5062 for (y = 0; y < hgt; y++)
5065 for (x = 0; x < wid - 1; x++)
5067 /* Get the attr/char */
5068 (void)(Term_what(x, y, &a, &c));
5078 fprintf(fff, "%s\n", buf);
5085 /* Dump the screen */
5086 for (y = 0; y < hgt; y++)
5089 for (x = 0; x < wid - 1; x++)
5091 /* Get the attr/char */
5092 (void)(Term_what(x, y, &a, &c));
5095 buf[x] = hack[a&0x0F];
5102 fprintf(fff, "%s\n", buf);
5109 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5114 if (old_use_graphics)
5116 use_graphics = TRUE;
5118 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5124 * Check the status of "artifacts"
5126 static void do_cmd_knowledge_artifacts(void)
5136 GAME_TEXT file_name[1024];
5137 GAME_TEXT base_name[MAX_NLEN];
5141 /* Open a new file */
5142 fff = my_fopen_temp(file_name, 1024);
5145 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5150 /* Allocate the "who" array */
5151 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5153 /* Allocate the "okay" array */
5154 C_MAKE(okay, max_a_idx, bool);
5156 /* Scan the artifacts */
5157 for (k = 0; k < max_a_idx; k++)
5159 artifact_type *a_ptr = &a_info[k];
5164 /* Skip "empty" artifacts */
5165 if (!a_ptr->name) continue;
5167 /* Skip "uncreated" artifacts */
5168 if (!a_ptr->cur_num) continue;
5174 /* Check the dungeon */
5175 for (y = 0; y < current_floor_ptr->height; y++)
5177 for (x = 0; x < current_floor_ptr->width; x++)
5179 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5181 OBJECT_IDX this_o_idx, next_o_idx = 0;
5183 /* Scan all objects in the grid */
5184 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5187 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5188 next_o_idx = o_ptr->next_o_idx;
5190 /* Ignore non-artifacts */
5191 if (!object_is_fixed_artifact(o_ptr)) continue;
5193 /* Ignore known items */
5194 if (object_is_known(o_ptr)) continue;
5196 /* Note the artifact */
5197 okay[o_ptr->name1] = FALSE;
5202 /* Check the p_ptr->inventory_list and equipment */
5203 for (i = 0; i < INVEN_TOTAL; i++)
5205 object_type *o_ptr = &p_ptr->inventory_list[i];
5207 /* Ignore non-objects */
5208 if (!o_ptr->k_idx) continue;
5210 /* Ignore non-artifacts */
5211 if (!object_is_fixed_artifact(o_ptr)) continue;
5213 /* Ignore known items */
5214 if (object_is_known(o_ptr)) continue;
5216 /* Note the artifact */
5217 okay[o_ptr->name1] = FALSE;
5220 for (k = 0; k < max_a_idx; k++)
5222 if (okay[k]) who[n++] = k;
5225 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5227 /* Scan the artifacts */
5228 for (k = 0; k < n; k++)
5230 artifact_type *a_ptr = &a_info[who[k]];
5231 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5233 /* Obtain the base object type */
5234 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5243 /* Create fake object */
5244 object_prep(q_ptr, z);
5246 /* Make it an artifact */
5247 q_ptr->name1 = (byte)who[k];
5249 /* Display as if known */
5250 q_ptr->ident |= IDENT_STORE;
5252 /* Describe the artifact */
5253 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5256 /* Hack -- Build the artifact name */
5257 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5260 /* Free the "who" array */
5261 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5263 /* Free the "okay" array */
5264 C_KILL(okay, max_a_idx, bool);
5267 /* Display the file contents */
5268 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5274 * Display known uniques
5275 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5277 static void do_cmd_knowledge_uniques(void)
5286 GAME_TEXT file_name[1024];
5289 int n_alive_surface = 0;
5290 int n_alive_over100 = 0;
5291 int n_alive_total = 0;
5294 for (i = 0; i < 10; i++) n_alive[i] = 0;
5296 /* Open a new file */
5297 fff = my_fopen_temp(file_name, 1024);
5301 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5306 /* Allocate the "who" array */
5307 C_MAKE(who, max_r_idx, MONRACE_IDX);
5309 /* Scan the monsters */
5310 for (i = 1; i < max_r_idx; i++)
5312 monster_race *r_ptr = &r_info[i];
5315 if (!r_ptr->name) continue;
5317 /* Require unique monsters */
5318 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5320 /* Only display "known" uniques */
5321 if (!cheat_know && !r_ptr->r_sights) continue;
5323 /* Only print rarity <= 100 uniques */
5324 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5326 /* Only "alive" uniques */
5327 if (r_ptr->max_num == 0) continue;
5331 lev = (r_ptr->level - 1) / 10;
5335 if (max_lev < lev) max_lev = lev;
5337 else n_alive_over100++;
5339 else n_alive_surface++;
5341 /* Collect "appropriate" monsters */
5345 /* Sort the array by dungeon depth of monsters */
5346 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5348 if (n_alive_surface)
5350 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5351 n_alive_total += n_alive_surface;
5353 for (i = 0; i <= max_lev; i++)
5355 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5356 n_alive_total += n_alive[i];
5358 if (n_alive_over100)
5360 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5361 n_alive_total += n_alive_over100;
5366 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5367 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5371 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5374 /* Scan the monster races */
5375 for (k = 0; k < n; k++)
5377 monster_race *r_ptr = &r_info[who[k]];
5379 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5382 /* Free the "who" array */
5383 C_KILL(who, max_r_idx, s16b);
5386 /* Display the file contents */
5387 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5393 * Display weapon-exp
5395 static void do_cmd_knowledge_weapon_exp(void)
5403 GAME_TEXT file_name[1024];
5406 /* Open a new file */
5407 fff = my_fopen_temp(file_name, 1024);
5409 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5414 for (i = 0; i < 5; i++)
5416 for (num = 0; num < 64; num++)
5418 for (j = 0; j < max_k_idx; j++)
5420 object_kind *k_ptr = &k_info[j];
5422 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5424 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5426 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5428 fprintf(fff, "%-25s ", tmp);
5429 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5430 else fprintf(fff, " ");
5431 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5432 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5441 /* Display the file contents */
5442 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5448 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5452 static void do_cmd_knowledge_spell_exp(void)
5459 const magic_type *s_ptr;
5461 GAME_TEXT file_name[1024];
5463 /* Open a new file */
5464 fff = my_fopen_temp(file_name, 1024);
5466 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5471 if (p_ptr->realm1 != REALM_NONE)
5473 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5474 for (i = 0; i < 32; i++)
5476 if (!is_magic(p_ptr->realm1))
5478 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5482 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5484 if (s_ptr->slevel >= 99) continue;
5485 spell_exp = p_ptr->spell_exp[i];
5486 exp_level = spell_exp_level(spell_exp);
5487 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5488 if (p_ptr->realm1 == REALM_HISSATSU)
5489 fprintf(fff, "[--]");
5492 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5493 else fprintf(fff, " ");
5494 fprintf(fff, "%s", exp_level_str[exp_level]);
5496 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5501 if (p_ptr->realm2 != REALM_NONE)
5503 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5504 for (i = 0; i < 32; i++)
5506 if (!is_magic(p_ptr->realm1))
5508 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5512 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5514 if (s_ptr->slevel >= 99) continue;
5516 spell_exp = p_ptr->spell_exp[i + 32];
5517 exp_level = spell_exp_level(spell_exp);
5518 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5519 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5520 else fprintf(fff, " ");
5521 fprintf(fff, "%s", exp_level_str[exp_level]);
5522 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5528 /* Display the file contents */
5529 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5535 * @brief スキル情報を表示するコマンドのメインルーチン /
5539 static void do_cmd_knowledge_skill_exp(void)
5541 int i = 0, skill_exp;
5545 char file_name[1024];
5546 char skill_name[GINOU_TEMPMAX][20] =
5548 _("マーシャルアーツ", "Martial Arts "),
5549 _("二刀流 ", "Dual Wielding "),
5550 _("乗馬 ", "Riding "),
5554 /* Open a new file */
5555 fff = my_fopen_temp(file_name, 1024);
5557 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5562 for (i = 0; i < GINOU_TEMPMAX; i++)
5564 skill_exp = p_ptr->skill_exp[i];
5565 fprintf(fff, "%-20s ", skill_name[i]);
5566 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5567 else fprintf(fff, " ");
5568 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5569 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5574 /* Display the file contents */
5575 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5581 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5582 * @param Name 変換したい文字列の参照ポインタ
5585 void plural_aux(char *Name)
5587 int NameLen = strlen(Name);
5589 if (my_strstr(Name, "Disembodied hand"))
5591 strcpy(Name, "Disembodied hands that strangled people");
5593 else if (my_strstr(Name, "Colour out of space"))
5595 strcpy(Name, "Colours out of space");
5597 else if (my_strstr(Name, "stairway to hell"))
5599 strcpy(Name, "stairways to hell");
5601 else if (my_strstr(Name, "Dweller on the threshold"))
5603 strcpy(Name, "Dwellers on the threshold");
5605 else if (my_strstr(Name, " of "))
5607 concptr aider = my_strstr(Name, " of ");
5618 if (dummy[i-1] == 's')
5620 strcpy(&(dummy[i]), "es");
5625 strcpy(&(dummy[i]), "s");
5628 strcpy(&(dummy[i+1]), aider);
5629 strcpy(Name, dummy);
5631 else if (my_strstr(Name, "coins"))
5634 strcpy(dummy, "piles of ");
5635 strcat(dummy, Name);
5636 strcpy(Name, dummy);
5639 else if (my_strstr(Name, "Manes"))
5643 else if (streq(&(Name[NameLen - 2]), "ey"))
5645 strcpy(&(Name[NameLen - 2]), "eys");
5647 else if (Name[NameLen - 1] == 'y')
5649 strcpy(&(Name[NameLen - 1]), "ies");
5651 else if (streq(&(Name[NameLen - 4]), "ouse"))
5653 strcpy(&(Name[NameLen - 4]), "ice");
5655 else if (streq(&(Name[NameLen - 2]), "us"))
5657 strcpy(&(Name[NameLen - 2]), "i");
5659 else if (streq(&(Name[NameLen - 6]), "kelman"))
5661 strcpy(&(Name[NameLen - 6]), "kelmen");
5663 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5665 strcpy(&(Name[NameLen - 8]), "wordsmen");
5667 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5669 strcpy(&(Name[NameLen - 7]), "oodsmen");
5671 else if (streq(&(Name[NameLen - 7]), "eastman"))
5673 strcpy(&(Name[NameLen - 7]), "eastmen");
5675 else if (streq(&(Name[NameLen - 8]), "izardman"))
5677 strcpy(&(Name[NameLen - 8]), "izardmen");
5679 else if (streq(&(Name[NameLen - 5]), "geist"))
5681 strcpy(&(Name[NameLen - 5]), "geister");
5683 else if (streq(&(Name[NameLen - 2]), "ex"))
5685 strcpy(&(Name[NameLen - 2]), "ices");
5687 else if (streq(&(Name[NameLen - 2]), "lf"))
5689 strcpy(&(Name[NameLen - 2]), "lves");
5691 else if (suffix(Name, "ch") ||
5692 suffix(Name, "sh") ||
5693 suffix(Name, "nx") ||
5694 suffix(Name, "s") ||
5697 strcpy(&(Name[NameLen]), "es");
5701 strcpy(&(Name[NameLen]), "s");
5706 * @brief 現在のペットを表示するコマンドのメインルーチン /
5707 * Display current pets
5710 static void do_cmd_knowledge_pets(void)
5714 monster_type *m_ptr;
5715 GAME_TEXT pet_name[MAX_NLEN];
5717 int show_upkeep = 0;
5718 GAME_TEXT file_name[1024];
5721 /* Open a new file */
5722 fff = my_fopen_temp(file_name, 1024);
5724 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5729 /* Process the monsters (backwards) */
5730 for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
5732 /* Access the monster */
5733 m_ptr = ¤t_floor_ptr->m_list[i];
5735 /* Ignore "dead" monsters */
5736 if (!monster_is_valid(m_ptr)) continue;
5738 /* Calculate "upkeep" for pets */
5742 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5743 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5747 show_upkeep = calculate_upkeep();
5749 fprintf(fff, "----------------------------------------------\n");
5751 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5753 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5755 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5760 /* Display the file contents */
5761 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5767 * @brief 現在のペットを表示するコマンドのメインルーチン /
5770 * @note the player ghosts are ignored.
5772 static void do_cmd_knowledge_kill_count(void)
5779 GAME_TEXT file_name[1024];
5784 /* Open a new file */
5785 fff = my_fopen_temp(file_name, 1024);
5788 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5793 /* Allocate the "who" array */
5794 C_MAKE(who, max_r_idx, MONRACE_IDX);
5797 /* Monsters slain */
5800 for (kk = 1; kk < max_r_idx; kk++)
5802 monster_race *r_ptr = &r_info[kk];
5804 if (r_ptr->flags1 & (RF1_UNIQUE))
5806 bool dead = (r_ptr->max_num == 0);
5815 MONSTER_NUMBER This = r_ptr->r_pkills;
5825 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5828 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5830 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5836 /* Scan the monsters */
5837 for (i = 1; i < max_r_idx; i++)
5839 monster_race *r_ptr = &r_info[i];
5841 /* Use that monster */
5842 if (r_ptr->name) who[n++] = i;
5845 /* Sort the array by dungeon depth of monsters */
5846 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5848 /* Scan the monster races */
5849 for (k = 0; k < n; k++)
5851 monster_race *r_ptr = &r_info[who[k]];
5853 if (r_ptr->flags1 & (RF1_UNIQUE))
5855 bool dead = (r_ptr->max_num == 0);
5859 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5865 MONSTER_NUMBER This = r_ptr->r_pkills;
5870 /* p,tは人と数える by ita */
5871 if (my_strchr("pt", r_ptr->d_char))
5872 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5874 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5878 if (my_strstr(r_name + r_ptr->name, "coins"))
5880 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5884 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5890 strcpy(ToPlural, (r_name + r_ptr->name));
5891 plural_aux(ToPlural);
5892 fprintf(fff, " %d %s\n", This, ToPlural);
5902 fprintf(fff,"----------------------------------------------\n");
5904 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5906 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5910 /* Free the "who" array */
5911 C_KILL(who, max_r_idx, s16b);
5914 /* Display the file contents */
5915 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5921 * @brief モンスター情報リスト中のグループを表示する /
5922 * Display the object groups.
5926 * @param per_page リストの表示行
5927 * @param grp_idx グループのID配列
5928 * @param group_text グループ名の文字列配列
5929 * @param grp_cur 現在の選択ID
5930 * @param grp_top 現在の選択リスト最上部ID
5933 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)
5937 /* Display lines until done */
5938 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5940 /* Get the group index */
5941 int grp = grp_idx[grp_top + i];
5943 /* Choose a color */
5944 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5946 /* Erase the entire line */
5947 Term_erase(col, row + i, wid);
5949 /* Display the group label */
5950 c_put_str(attr, group_text[grp], row + i, col);
5956 * Move the cursor in a browser window
5958 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5959 IDX *list_cur, int list_cnt)
5964 IDX list = *list_cur;
5966 /* Extract direction */
5969 /* Hack -- scroll up full screen */
5974 /* Hack -- scroll down full screen */
5979 d = get_keymap_dir(ch);
5984 /* Diagonals - hack */
5985 if ((ddx[d] > 0) && ddy[d])
5990 Term_get_size(&wid, &hgt);
5992 browser_rows = hgt - 8;
5994 /* Browse group list */
5999 /* Move up or down */
6000 grp += ddy[d] * (browser_rows - 1);
6003 if (grp >= grp_cnt) grp = grp_cnt - 1;
6004 if (grp < 0) grp = 0;
6005 if (grp != old_grp) list = 0;
6008 /* Browse sub-list list */
6011 /* Move up or down */
6012 list += ddy[d] * browser_rows;
6015 if (list >= list_cnt) list = list_cnt - 1;
6016 if (list < 0) list = 0;
6028 if (col < 0) col = 0;
6029 if (col > 1) col = 1;
6036 /* Browse group list */
6041 /* Move up or down */
6045 if (grp >= grp_cnt) grp = grp_cnt - 1;
6046 if (grp < 0) grp = 0;
6047 if (grp != old_grp) list = 0;
6050 /* Browse sub-list list */
6053 /* Move up or down */
6054 list += (IDX)ddy[d];
6057 if (list >= list_cnt) list = list_cnt - 1;
6058 if (list < 0) list = 0;
6069 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6073 /* Clear the display lines */
6074 for (i = 0; i < height; i++)
6076 Term_erase(col, row + i, width);
6079 /* Bigtile mode uses double width */
6080 if (use_bigtile) width /= 2;
6082 /* Display lines until done */
6083 for (i = 0; i < height; i++)
6085 /* Display columns until done */
6086 for (j = 0; j < width; j++)
6090 TERM_LEN x = col + j;
6091 TERM_LEN y = row + i;
6093 /* Bigtile mode uses double width */
6094 if (use_bigtile) x += j;
6099 /* Ignore illegal characters */
6100 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6101 (!use_graphics && ic > 0x7f))
6107 /* Force correct code for both ASCII character and tile */
6108 if (c & 0x80) a |= 0x80;
6110 /* Display symbol */
6111 Term_queue_bigchar(x, y, a, c, 0, 0);
6118 * Place the cursor at the collect position for visual mode
6120 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6122 int i = (a & 0x7f) - attr_top;
6123 int j = c - char_left;
6125 TERM_LEN x = col + j;
6126 TERM_LEN y = row + i;
6128 /* Bigtile mode uses double width */
6129 if (use_bigtile) x += j;
6131 /* Place the cursor */
6137 * Clipboard variables for copy&paste in visual mode
6139 static TERM_COLOR attr_idx = 0;
6140 static SYMBOL_CODE char_idx = 0;
6142 /* Hack -- for feature lighting */
6143 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6144 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6147 * Do visual mode command -- Change symbols
6149 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6150 int height, int width,
6151 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6152 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6154 static TERM_COLOR attr_old = 0;
6155 static SYMBOL_CODE char_old = 0;
6160 if (*visual_list_ptr)
6163 *cur_attr_ptr = attr_old;
6164 *cur_char_ptr = char_old;
6165 *visual_list_ptr = FALSE;
6173 if (*visual_list_ptr)
6176 *visual_list_ptr = FALSE;
6177 *need_redraw = TRUE;
6185 if (!*visual_list_ptr)
6187 *visual_list_ptr = TRUE;
6189 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6190 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6192 attr_old = *cur_attr_ptr;
6193 char_old = *cur_char_ptr;
6204 /* Set the visual */
6205 attr_idx = *cur_attr_ptr;
6206 char_idx = *cur_char_ptr;
6208 /* Hack -- for feature lighting */
6209 for (i = 0; i < F_LIT_MAX; i++)
6211 attr_idx_feat[i] = 0;
6212 char_idx_feat[i] = 0;
6219 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6222 *cur_attr_ptr = attr_idx;
6223 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6224 if (!*visual_list_ptr) *need_redraw = TRUE;
6230 *cur_char_ptr = char_idx;
6231 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6232 if (!*visual_list_ptr) *need_redraw = TRUE;
6238 if (*visual_list_ptr)
6241 int d = get_keymap_dir(ch);
6242 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6243 SYMBOL_CODE c = *cur_char_ptr;
6245 if (use_bigtile) eff_width = width / 2;
6246 else eff_width = width;
6248 /* Restrict direction */
6249 if ((a == 0) && (ddy[d] < 0)) d = 0;
6250 if ((c == 0) && (ddx[d] < 0)) d = 0;
6251 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6252 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6254 a += (TERM_COLOR)ddy[d];
6255 c += (SYMBOL_CODE)ddx[d];
6257 /* Force correct code for both ASCII character and tile */
6258 if (c & 0x80) a |= 0x80;
6260 /* Set the visual */
6265 /* Move the frame */
6266 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6267 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6268 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6269 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6275 /* Visual mode command is not used */
6281 * Display the monsters in a group.
6283 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6284 int mon_cur, int mon_top, bool visual_only)
6288 /* Display lines until done */
6289 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6293 /* Get the race index */
6294 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6296 /* Access the race */
6297 monster_race *r_ptr = &r_info[r_idx];
6299 /* Choose a color */
6300 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6302 /* Display the name */
6303 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6305 /* Hack -- visual_list mode */
6308 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6310 if (p_ptr->wizard || visual_only)
6312 c_prt(attr, format("%d", r_idx), row + i, 62);
6315 /* Erase chars before overwritten by the race letter */
6316 Term_erase(69, row + i, 255);
6318 /* Display symbol */
6319 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6324 if (!(r_ptr->flags1 & RF1_UNIQUE))
6325 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6327 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6328 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6332 /* Clear remaining lines */
6333 for (; i < per_page; i++)
6335 Term_erase(col, row + i, 255);
6341 * Display known monsters.
6343 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6347 IDX grp_cur, grp_top, old_grp_cur;
6348 IDX mon_cur, mon_top;
6349 IDX grp_cnt, grp_idx[100];
6357 bool visual_list = FALSE;
6358 TERM_COLOR attr_top = 0;
6366 Term_get_size(&wid, &hgt);
6368 browser_rows = hgt - 8;
6370 /* Allocate the "mon_idx" array */
6371 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6376 if (direct_r_idx < 0)
6378 mode = visual_only ? 0x03 : 0x01;
6380 /* Check every group */
6381 for (i = 0; monster_group_text[i] != NULL; i++)
6383 /* Measure the label */
6384 len = strlen(monster_group_text[i]);
6386 /* Save the maximum length */
6387 if (len > max) max = len;
6389 /* See if any monsters are known */
6390 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6392 /* Build a list of groups with known monsters */
6393 grp_idx[grp_cnt++] = i;
6401 mon_idx[0] = direct_r_idx;
6404 /* Terminate the list */
6407 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6408 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6411 /* Terminate the list */
6412 grp_idx[grp_cnt] = -1;
6415 grp_cur = grp_top = 0;
6416 mon_cur = mon_top = 0;
6421 mode = visual_only ? 0x02 : 0x00;
6426 monster_race *r_ptr;
6431 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6432 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6433 prt(_("名前", "Name"), 4, max + 3);
6434 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6435 prt(_("文字", "Sym"), 4, 67);
6436 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6438 for (i = 0; i < 78; i++)
6440 Term_putch(i, 5, TERM_WHITE, '=');
6443 if (direct_r_idx < 0)
6445 for (i = 0; i < browser_rows; i++)
6447 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6454 if (direct_r_idx < 0)
6456 /* Scroll group list */
6457 if (grp_cur < grp_top) grp_top = grp_cur;
6458 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6460 /* Display a list of monster groups */
6461 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6463 if (old_grp_cur != grp_cur)
6465 old_grp_cur = grp_cur;
6467 /* Get a list of monsters in the current group */
6468 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6471 /* Scroll monster list */
6472 while (mon_cur < mon_top)
6473 mon_top = MAX(0, mon_top - browser_rows/2);
6474 while (mon_cur >= mon_top + browser_rows)
6475 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6480 /* Display a list of monsters in the current group */
6481 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6487 /* Display a monster name */
6488 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6490 /* Display visual list below first monster */
6491 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6495 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6496 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6497 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6498 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6501 /* Get the current monster */
6502 r_ptr = &r_info[mon_idx[mon_cur]];
6506 /* Mega Hack -- track this monster race */
6507 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6513 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6517 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6521 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6526 /* Do visual mode command if needed */
6527 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))
6529 if (direct_r_idx >= 0)
6554 /* Recall on screen */
6555 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6557 screen_roff(mon_idx[mon_cur], 0);
6568 /* Move the cursor */
6569 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6576 /* Free the "mon_idx" array */
6577 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6582 * Display the objects in a group.
6584 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6585 int object_cur, int object_top, bool visual_only)
6589 /* Display lines until done */
6590 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6592 GAME_TEXT o_name[MAX_NLEN];
6595 object_kind *flavor_k_ptr;
6597 /* Get the object index */
6598 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6600 /* Access the object */
6601 object_kind *k_ptr = &k_info[k_idx];
6603 /* Choose a color */
6604 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6605 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6608 if (!visual_only && k_ptr->flavor)
6610 /* Appearance of this object is shuffled */
6611 flavor_k_ptr = &k_info[k_ptr->flavor];
6615 /* Appearance of this object is very normal */
6616 flavor_k_ptr = k_ptr;
6621 attr = ((i + object_top == object_cur) ? cursor : attr);
6623 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6626 strip_name(o_name, k_idx);
6631 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6634 /* Display the name */
6635 c_prt(attr, o_name, row + i, col);
6637 /* Hack -- visual_list mode */
6640 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);
6642 if (p_ptr->wizard || visual_only)
6644 c_prt(attr, format("%d", k_idx), row + i, 70);
6647 a = flavor_k_ptr->x_attr;
6648 c = flavor_k_ptr->x_char;
6650 /* Display symbol */
6651 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6654 /* Clear remaining lines */
6655 for (; i < per_page; i++)
6657 Term_erase(col, row + i, 255);
6662 * Describe fake object
6664 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6667 object_type object_type_body;
6668 o_ptr = &object_type_body;
6670 object_prep(o_ptr, k_idx);
6672 /* It's fully know */
6673 o_ptr->ident |= IDENT_KNOWN;
6675 /* Track the object */
6676 /* object_actual_track(o_ptr); */
6678 /* Hack - mark as fake */
6679 /* term_obj_real = FALSE; */
6682 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6684 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6692 * Display known objects
6694 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6698 IDX grp_cur, grp_top, old_grp_cur;
6699 IDX object_old, object_cur, object_top;
6703 OBJECT_IDX *object_idx;
6709 bool visual_list = FALSE;
6710 TERM_COLOR attr_top = 0;
6718 Term_get_size(&wid, &hgt);
6720 browser_rows = hgt - 8;
6722 /* Allocate the "object_idx" array */
6723 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6728 if (direct_k_idx < 0)
6730 mode = visual_only ? 0x03 : 0x01;
6732 /* Check every group */
6733 for (i = 0; object_group_text[i] != NULL; i++)
6735 /* Measure the label */
6736 len = strlen(object_group_text[i]);
6738 /* Save the maximum length */
6739 if (len > max) max = len;
6741 /* See if any monsters are known */
6742 if (collect_objects(i, object_idx, mode))
6744 /* Build a list of groups with known monsters */
6745 grp_idx[grp_cnt++] = i;
6754 object_kind *k_ptr = &k_info[direct_k_idx];
6755 object_kind *flavor_k_ptr;
6757 if (!visual_only && k_ptr->flavor)
6759 /* Appearance of this object is shuffled */
6760 flavor_k_ptr = &k_info[k_ptr->flavor];
6764 /* Appearance of this object is very normal */
6765 flavor_k_ptr = k_ptr;
6768 object_idx[0] = direct_k_idx;
6769 object_old = direct_k_idx;
6772 /* Terminate the list */
6775 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6776 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6779 /* Terminate the list */
6780 grp_idx[grp_cnt] = -1;
6783 grp_cur = grp_top = 0;
6784 object_cur = object_top = 0;
6789 mode = visual_only ? 0x02 : 0x00;
6794 object_kind *k_ptr, *flavor_k_ptr;
6801 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6802 if (direct_k_idx < 0) prt("グループ", 4, 0);
6803 prt("名前", 4, max + 3);
6804 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6807 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6808 if (direct_k_idx < 0) prt("Group", 4, 0);
6809 prt("Name", 4, max + 3);
6810 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6814 for (i = 0; i < 78; i++)
6816 Term_putch(i, 5, TERM_WHITE, '=');
6819 if (direct_k_idx < 0)
6821 for (i = 0; i < browser_rows; i++)
6823 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6830 if (direct_k_idx < 0)
6832 /* Scroll group list */
6833 if (grp_cur < grp_top) grp_top = grp_cur;
6834 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6836 /* Display a list of object groups */
6837 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6839 if (old_grp_cur != grp_cur)
6841 old_grp_cur = grp_cur;
6843 /* Get a list of objects in the current group */
6844 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6847 /* Scroll object list */
6848 while (object_cur < object_top)
6849 object_top = MAX(0, object_top - browser_rows/2);
6850 while (object_cur >= object_top + browser_rows)
6851 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6856 /* Display a list of objects in the current group */
6857 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6861 object_top = object_cur;
6863 /* Display a list of objects in the current group */
6864 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6866 /* Display visual list below first object */
6867 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6870 /* Get the current object */
6871 k_ptr = &k_info[object_idx[object_cur]];
6873 if (!visual_only && k_ptr->flavor)
6875 /* Appearance of this object is shuffled */
6876 flavor_k_ptr = &k_info[k_ptr->flavor];
6880 /* Appearance of this object is very normal */
6881 flavor_k_ptr = k_ptr;
6886 prt(format("<方向>%s%s%s, ESC",
6887 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6888 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6889 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6892 prt(format("<dir>%s%s%s, ESC",
6893 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6894 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6895 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6901 /* Mega Hack -- track this object */
6902 if (object_cnt) object_kind_track(object_idx[object_cur]);
6904 /* The "current" object changed */
6905 if (object_old != object_idx[object_cur])
6909 /* Remember the "current" object */
6910 object_old = object_idx[object_cur];
6916 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6920 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6924 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6929 /* Do visual mode command if needed */
6930 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))
6932 if (direct_k_idx >= 0)
6957 /* Recall on screen */
6958 if (!visual_list && !visual_only && (grp_cnt > 0))
6960 desc_obj_fake(object_idx[object_cur]);
6968 /* Move the cursor */
6969 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6975 /* Free the "object_idx" array */
6976 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6981 * Display the features in a group.
6983 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6984 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6986 int lit_col[F_LIT_MAX], i, j;
6987 int f_idx_col = use_bigtile ? 62 : 64;
6989 /* Correct columns 1 and 4 */
6990 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6991 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6992 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6994 /* Display lines until done */
6995 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6998 FEAT_IDX f_idx = feat_idx[feat_top + i];
6999 feature_type *f_ptr = &f_info[f_idx];
7000 int row_i = row + i;
7002 /* Choose a color */
7003 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7005 /* Display the name */
7006 c_prt(attr, f_name + f_ptr->name, row_i, col);
7008 /* Hack -- visual_list mode */
7011 /* Display lighting level */
7012 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7014 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));
7016 if (p_ptr->wizard || visual_only)
7018 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7021 /* Display symbol */
7022 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);
7024 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7025 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7027 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7029 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7031 /* Mega-hack -- Use non-standard colour */
7032 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7034 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7038 /* Clear remaining lines */
7039 for (; i < per_page; i++)
7041 Term_erase(col, row + i, 255);
7047 * Interact with feature visuals.
7049 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7053 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7054 FEAT_IDX feat_cur, feat_top;
7056 FEAT_IDX grp_idx[100];
7060 TERM_LEN column = 0;
7064 bool visual_list = FALSE;
7065 TERM_COLOR attr_top = 0;
7068 TERM_LEN browser_rows;
7071 TERM_COLOR attr_old[F_LIT_MAX];
7072 SYMBOL_CODE char_old[F_LIT_MAX];
7073 TERM_COLOR *cur_attr_ptr;
7074 SYMBOL_CODE *cur_char_ptr;
7076 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7077 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7079 Term_get_size(&wid, &hgt);
7081 browser_rows = hgt - 8;
7083 /* Allocate the "feat_idx" array */
7084 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7089 if (direct_f_idx < 0)
7091 /* Check every group */
7092 for (i = 0; feature_group_text[i] != NULL; i++)
7094 /* Measure the label */
7095 len = strlen(feature_group_text[i]);
7097 /* Save the maximum length */
7098 if (len > max) max = len;
7100 /* See if any features are known */
7101 if (collect_features(i, feat_idx, 0x01))
7103 /* Build a list of groups with known features */
7104 grp_idx[grp_cnt++] = i;
7112 feature_type *f_ptr = &f_info[direct_f_idx];
7114 feat_idx[0] = direct_f_idx;
7117 /* Terminate the list */
7120 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7121 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7123 for (i = 0; i < F_LIT_MAX; i++)
7125 attr_old[i] = f_ptr->x_attr[i];
7126 char_old[i] = f_ptr->x_char[i];
7130 /* Terminate the list */
7131 grp_idx[grp_cnt] = -1;
7134 grp_cur = grp_top = 0;
7135 feat_cur = feat_top = 0;
7143 feature_type *f_ptr;
7149 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7150 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7151 prt(_("名前", "Name"), 4, max + 3);
7154 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7155 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7159 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7160 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7163 for (i = 0; i < 78; i++)
7165 Term_putch(i, 5, TERM_WHITE, '=');
7168 if (direct_f_idx < 0)
7170 for (i = 0; i < browser_rows; i++)
7172 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7179 if (direct_f_idx < 0)
7181 /* Scroll group list */
7182 if (grp_cur < grp_top) grp_top = grp_cur;
7183 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7185 /* Display a list of feature groups */
7186 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7188 if (old_grp_cur != grp_cur)
7190 old_grp_cur = grp_cur;
7192 /* Get a list of features in the current group */
7193 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7196 /* Scroll feature list */
7197 while (feat_cur < feat_top)
7198 feat_top = MAX(0, feat_top - browser_rows/2);
7199 while (feat_cur >= feat_top + browser_rows)
7200 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7205 /* Display a list of features in the current group */
7206 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7210 feat_top = feat_cur;
7212 /* Display a list of features in the current group */
7213 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7215 /* Display visual list below first object */
7216 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7220 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7221 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7222 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7225 /* Get the current feature */
7226 f_ptr = &f_info[feat_idx[feat_cur]];
7227 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7228 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7232 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7236 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7240 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7245 if (visual_list && ((ch == 'A') || (ch == 'a')))
7247 int prev_lighting_level = *lighting_level;
7251 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7252 else (*lighting_level)--;
7256 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7257 else (*lighting_level)++;
7260 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7261 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7263 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7264 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7269 else if ((ch == 'D') || (ch == 'd'))
7271 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7272 byte prev_x_char = f_ptr->x_char[*lighting_level];
7274 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7278 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7279 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7281 if (prev_x_char != f_ptr->x_char[*lighting_level])
7282 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7284 else *need_redraw = TRUE;
7289 /* Do visual mode command if needed */
7290 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))
7294 /* Restore previous visual settings */
7296 for (i = 0; i < F_LIT_MAX; i++)
7298 f_ptr->x_attr[i] = attr_old[i];
7299 f_ptr->x_char[i] = char_old[i];
7306 if (direct_f_idx >= 0) flag = TRUE;
7307 else *lighting_level = F_LIT_STANDARD;
7310 /* Preserve current visual settings */
7313 for (i = 0; i < F_LIT_MAX; i++)
7315 attr_old[i] = f_ptr->x_attr[i];
7316 char_old[i] = f_ptr->x_char[i];
7318 *lighting_level = F_LIT_STANDARD;
7325 for (i = 0; i < F_LIT_MAX; i++)
7327 attr_idx_feat[i] = f_ptr->x_attr[i];
7328 char_idx_feat[i] = f_ptr->x_char[i];
7337 /* Allow TERM_DARK text */
7338 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7340 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7341 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7359 /* Move the cursor */
7360 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7366 /* Free the "feat_idx" array */
7367 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7372 * List wanted monsters
7374 static void do_cmd_knowledge_kubi(void)
7379 GAME_TEXT file_name[1024];
7382 /* Open a new file */
7383 fff = my_fopen_temp(file_name, 1024);
7385 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7392 bool listed = FALSE;
7394 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7395 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7397 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7398 fprintf(fff, "----------------------------------------------\n");
7400 for (i = 0; i < MAX_KUBI; i++)
7402 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7404 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7412 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7417 /* Display the file contents */
7418 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7423 * List virtues & status
7425 static void do_cmd_knowledge_virtues(void)
7428 GAME_TEXT file_name[1024];
7430 /* Open a new file */
7431 fff = my_fopen_temp(file_name, 1024);
7433 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7440 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7445 /* Display the file contents */
7446 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7453 static void do_cmd_knowledge_dungeon(void)
7457 GAME_TEXT file_name[1024];
7460 /* Open a new file */
7461 fff = my_fopen_temp(file_name, 1024);
7463 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7470 for (i = 1; i < max_d_idx; i++)
7474 if (!d_info[i].maxdepth) continue;
7475 if (!max_dlv[i]) continue;
7476 if (d_info[i].final_guardian)
7478 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7480 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7482 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7487 /* Display the file contents */
7488 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7493 * List virtues & status
7496 static void do_cmd_knowledge_stat(void)
7500 GAME_TEXT file_name[1024];
7503 /* Open a new file */
7504 fff = my_fopen_temp(file_name, 1024);
7506 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7513 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7514 (2 * p_ptr->hitdie +
7515 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7517 if (p_ptr->knowledge & KNOW_HPRATE)
7518 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7519 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7521 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7522 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7524 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);
7525 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7532 /* Display the file contents */
7533 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7539 * Print all active quests
7541 static void do_cmd_knowledge_quests_current(FILE *fff)
7544 char rand_tmp_str[120] = "\0";
7545 GAME_TEXT name[MAX_NLEN];
7546 monster_race *r_ptr;
7548 int rand_level = 100;
7551 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7553 for (i = 1; i < max_q_idx; i++)
7555 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7556 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7557 (quest[i].status == QUEST_STATUS_COMPLETED))
7559 /* Set the quest number temporary */
7560 QUEST_IDX old_quest = p_ptr->inside_quest;
7563 /* Clear the text */
7564 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7565 quest_text_line = 0;
7567 p_ptr->inside_quest = i;
7569 /* Get the quest text */
7570 init_flags = INIT_SHOW_TEXT;
7572 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7574 /* Reset the old quest number */
7575 p_ptr->inside_quest = old_quest;
7577 /* No info from "silent" quests */
7578 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7582 if (quest[i].type != QUEST_TYPE_RANDOM)
7584 char note[80] = "\0";
7586 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7588 switch (quest[i].type)
7590 case QUEST_TYPE_KILL_LEVEL:
7591 case QUEST_TYPE_KILL_ANY_LEVEL:
7592 r_ptr = &r_info[quest[i].r_idx];
7593 strcpy(name, r_name + r_ptr->name);
7594 if (quest[i].max_num > 1)
7597 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7598 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7601 sprintf(note," - kill %d %s, have killed %d.",
7602 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7606 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7609 case QUEST_TYPE_FIND_ARTIFACT:
7612 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7614 object_type *q_ptr = &forge;
7615 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7616 object_prep(q_ptr, k_idx);
7617 q_ptr->name1 = quest[i].k_idx;
7618 q_ptr->ident = IDENT_STORE;
7619 object_desc(name, q_ptr, OD_NAME_ONLY);
7621 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7623 case QUEST_TYPE_FIND_EXIT:
7624 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7627 case QUEST_TYPE_KILL_NUMBER:
7629 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7630 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7632 sprintf(note," - Kill %d monsters, have killed %d.",
7633 (int)quest[i].max_num, (int)quest[i].cur_num);
7637 case QUEST_TYPE_KILL_ALL:
7638 case QUEST_TYPE_TOWER:
7639 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7644 /* Print the quest info */
7645 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7646 quest[i].name, (int)quest[i].level, note);
7648 fputs(tmp_str, fff);
7650 if (quest[i].status == QUEST_STATUS_COMPLETED)
7652 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7653 fputs(tmp_str, fff);
7659 while (quest_text[j][0] && j < 10)
7661 fprintf(fff, " %s\n", quest_text[j]);
7666 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7669 rand_level = quest[i].level;
7671 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7673 /* Print the quest info */
7674 r_ptr = &r_info[quest[i].r_idx];
7675 strcpy(name, r_name + r_ptr->name);
7677 if (quest[i].max_num > 1)
7680 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7681 quest[i].name, (int)quest[i].level,
7682 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7686 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7687 quest[i].name, (int)quest[i].level,
7688 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7693 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7694 quest[i].name, (int)quest[i].level, name);
7701 /* Print the current random quest */
7702 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7704 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7708 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7711 char playtime_str[16];
7712 quest_type* const q_ptr = &quest[q_idx];
7714 if (is_fixed_quest_idx(q_idx))
7716 /* Set the quest number temporary */
7717 IDX old_quest = p_ptr->inside_quest;
7719 p_ptr->inside_quest = q_idx;
7722 init_flags = INIT_NAME_ONLY;
7724 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7726 /* Reset the old quest number */
7727 p_ptr->inside_quest = old_quest;
7729 /* No info from "silent" quests */
7730 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7733 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7734 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7736 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7738 /* Print the quest info */
7739 if (q_ptr->complev == 0)
7742 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7743 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7744 r_name+r_info[q_ptr->r_idx].name,
7745 (int)q_ptr->level, playtime_str);
7750 _(" %-35s (%3d階) - レベル%2d - %s\n",
7751 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7752 r_name+r_info[q_ptr->r_idx].name,
7760 /* Print the quest info */
7762 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7763 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7764 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7767 fputs(tmp_str, fff);
7773 * Print all finished quests
7775 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7778 QUEST_IDX total = 0;
7780 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7781 for (i = 1; i < max_q_idx; i++)
7783 QUEST_IDX q_idx = quest_num[i];
7784 quest_type* const q_ptr = &quest[q_idx];
7786 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7791 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7796 * Print all failed quests
7798 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7801 QUEST_IDX total = 0;
7803 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7804 for (i = 1; i < max_q_idx; i++)
7806 QUEST_IDX q_idx = quest_num[i];
7807 quest_type* const q_ptr = &quest[q_idx];
7809 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7810 do_cmd_knowledge_quests_aux(fff, q_idx))
7815 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7820 * Print all random quests
7822 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7824 GAME_TEXT tmp_str[120];
7826 QUEST_IDX total = 0;
7828 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7829 for (i = 1; i < max_q_idx; i++)
7831 /* No info from "silent" quests */
7832 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7834 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7838 /* Print the quest info */
7839 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7840 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7841 fputs(tmp_str, fff);
7844 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7848 * Print quest status of all active quests
7850 static void do_cmd_knowledge_quests(void)
7853 GAME_TEXT file_name[1024];
7858 /* Open a new file */
7859 fff = my_fopen_temp(file_name, 1024);
7862 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7867 /* Allocate Memory */
7868 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7870 /* Sort by compete level */
7871 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7872 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7874 /* Dump Quest Information */
7875 do_cmd_knowledge_quests_current(fff);
7877 do_cmd_knowledge_quests_completed(fff, quest_num);
7879 do_cmd_knowledge_quests_failed(fff, quest_num);
7883 do_cmd_knowledge_quests_wiz_random(fff);
7887 /* Display the file contents */
7888 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7892 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7899 static void do_cmd_knowledge_home(void)
7904 GAME_TEXT file_name[1024];
7906 GAME_TEXT o_name[MAX_NLEN];
7907 concptr paren = ")";
7909 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7911 /* Open a new file */
7912 fff = my_fopen_temp(file_name, 1024);
7914 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7921 /* Print all homes in the different towns */
7922 st_ptr = &town_info[1].store[STORE_HOME];
7924 /* Home -- if anything there */
7925 if (st_ptr->stock_num)
7930 /* Header with name of the town */
7931 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7933 /* Dump all available items */
7934 for (i = 0; i < st_ptr->stock_num; i++)
7937 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7938 object_desc(o_name, &st_ptr->stock[i], 0);
7939 if (strlen(o_name) <= 80-3)
7941 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7947 for (n = 0, t = o_name; n < 80-3; n++, t++)
7948 if(iskanji(*t)) {t++; n++;}
7949 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7951 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7952 fprintf(fff, " %.77s\n", o_name+n);
7955 object_desc(o_name, &st_ptr->stock[i], 0);
7956 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7961 /* Add an empty line */
7962 fprintf(fff, "\n\n");
7967 /* Display the file contents */
7968 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7974 * Check the status of "autopick"
7976 static void do_cmd_knowledge_autopick(void)
7980 GAME_TEXT file_name[1024];
7982 /* Open a new file */
7983 fff = my_fopen_temp(file_name, 1024);
7987 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7994 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7998 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7999 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8002 for (k = 0; k < max_autopick; k++)
8005 byte act = autopick_list[k].action;
8006 if (act & DONT_AUTOPICK)
8008 tmp = _("放置", "Leave");
8010 else if (act & DO_AUTODESTROY)
8012 tmp = _("破壊", "Destroy");
8014 else if (act & DO_AUTOPICK)
8016 tmp = _("拾う", "Pickup");
8020 tmp = _("確認", "Query");
8023 if (act & DO_DISPLAY)
8024 fprintf(fff, "%11s", format("[%s]", tmp));
8026 fprintf(fff, "%11s", format("(%s)", tmp));
8028 tmp = autopick_line_from_entry(&autopick_list[k]);
8029 fprintf(fff, " %s", tmp);
8034 /* Display the file contents */
8035 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8041 * Interact with "knowledge"
8043 void do_cmd_knowledge(void)
8046 bool need_redraw = FALSE;
8048 /* File type is "TEXT" */
8049 FILE_TYPE(FILE_TYPE_TEXT);
8052 /* Interact until done */
8057 /* Ask for a choice */
8058 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8059 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8061 /* Give some choices */
8065 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8066 prt("(2) 既知のアイテム の一覧", 7, 5);
8067 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8068 prt("(4) 既知のモンスター の一覧", 9, 5);
8069 prt("(5) 倒した敵の数 の一覧", 10, 5);
8070 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8071 prt("(7) 現在のペット の一覧", 12, 5);
8072 prt("(8) 我が家のアイテム の一覧", 13, 5);
8073 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8074 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8078 prt("(a) 自分に関する情報 の一覧", 6, 5);
8079 prt("(b) 突然変異 の一覧", 7, 5);
8080 prt("(c) 武器の経験値 の一覧", 8, 5);
8081 prt("(d) 魔法の経験値 の一覧", 9, 5);
8082 prt("(e) 技能の経験値 の一覧", 10, 5);
8083 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8084 prt("(g) 入ったダンジョン の一覧", 12, 5);
8085 prt("(h) 実行中のクエスト の一覧", 13, 5);
8086 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8091 prt("(1) Display known artifacts", 6, 5);
8092 prt("(2) Display known objects", 7, 5);
8093 prt("(3) Display remaining uniques", 8, 5);
8094 prt("(4) Display known monster", 9, 5);
8095 prt("(5) Display kill count", 10, 5);
8096 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8097 prt("(7) Display current pets", 12, 5);
8098 prt("(8) Display home inventory", 13, 5);
8099 prt("(9) Display *identified* equip.", 14, 5);
8100 prt("(0) Display terrain symbols.", 15, 5);
8104 prt("(a) Display about yourself", 6, 5);
8105 prt("(b) Display mutations", 7, 5);
8106 prt("(c) Display weapon proficiency", 8, 5);
8107 prt("(d) Display spell proficiency", 9, 5);
8108 prt("(e) Display misc. proficiency", 10, 5);
8109 prt("(f) Display virtues", 11, 5);
8110 prt("(g) Display dungeons", 12, 5);
8111 prt("(h) Display current quests", 13, 5);
8112 prt("(i) Display auto pick/destroy", 14, 5);
8116 prt(_("-続く-", "-more-"), 17, 8);
8117 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8118 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8119 /*prt("-) 前ページ", 21, 60);*/
8120 prt(_("コマンド:", "Command: "), 20, 0);
8123 if (i == ESCAPE) break;
8126 case ' ': /* Page change */
8130 case '1': /* Artifacts */
8131 do_cmd_knowledge_artifacts();
8133 case '2': /* Objects */
8134 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8136 case '3': /* Uniques */
8137 do_cmd_knowledge_uniques();
8139 case '4': /* Monsters */
8140 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8142 case '5': /* Kill count */
8143 do_cmd_knowledge_kill_count();
8145 case '6': /* wanted */
8146 if (!vanilla_town) do_cmd_knowledge_kubi();
8148 case '7': /* Pets */
8149 do_cmd_knowledge_pets();
8151 case '8': /* Home */
8152 do_cmd_knowledge_home();
8154 case '9': /* Resist list */
8155 do_cmd_knowledge_inven();
8157 case '0': /* Feature list */
8159 IDX lighting_level = F_LIT_STANDARD;
8160 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8164 case 'a': /* Max stat */
8165 do_cmd_knowledge_stat();
8167 case 'b': /* Mutations */
8168 do_cmd_knowledge_mutations();
8170 case 'c': /* weapon-exp */
8171 do_cmd_knowledge_weapon_exp();
8173 case 'd': /* spell-exp */
8174 do_cmd_knowledge_spell_exp();
8176 case 'e': /* skill-exp */
8177 do_cmd_knowledge_skill_exp();
8179 case 'f': /* Virtues */
8180 do_cmd_knowledge_virtues();
8182 case 'g': /* Dungeon */
8183 do_cmd_knowledge_dungeon();
8185 case 'h': /* Quests */
8186 do_cmd_knowledge_quests();
8188 case 'i': /* Autopick */
8189 do_cmd_knowledge_autopick();
8191 default: /* Unknown option */
8199 if (need_redraw) do_cmd_redraw();
8204 * Check on the status of an active quest
8206 void do_cmd_checkquest(void)
8208 /* File type is "TEXT" */
8209 FILE_TYPE(FILE_TYPE_TEXT);
8213 do_cmd_knowledge_quests();
8219 * Display the time and date
8221 void do_cmd_time(void)
8223 int day, hour, min, full, start, end, num;
8231 extract_day_hour_min(&day, &hour, &min);
8233 full = hour * 100 + min;
8240 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8242 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8243 else strcpy(day_buf, "*****");
8245 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8246 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8249 if (!randint0(10) || p_ptr->image)
8251 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8255 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8258 /* Open this file */
8259 fff = my_fopen(buf, "rt");
8263 /* Find this time */
8264 while (!my_fgets(fff, buf, sizeof(buf)))
8266 /* Ignore comments */
8267 if (!buf[0] || (buf[0] == '#')) continue;
8269 /* Ignore invalid lines */
8270 if (buf[1] != ':') continue;
8272 /* Process 'Start' */
8275 /* Extract the starting time */
8276 start = atoi(buf + 2);
8278 /* Assume valid for an hour */
8288 /* Extract the ending time */
8289 end = atoi(buf + 2);
8295 /* Ignore incorrect range */
8296 if ((start > full) || (full > end)) continue;
8298 /* Process 'Description' */
8303 /* Apply the randomizer */
8304 if (!randint0(num)) strcpy(desc, buf + 2);