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.
50 #include "cmd-spell.h"
54 #include "player-effects.h"
55 #include "player-status.h"
56 #include "player-skill.h"
57 #include "player-personality.h"
64 #include "object-flavor.h"
65 #include "object-hook.h"
67 #include "monster-status.h"
69 #include "view-mainwindow.h"
70 #include "dungeon-file.h"
72 #include "player-class.h"
73 #include "player-move.h"
75 #include "objectkind.h"
76 #include "floor-town.h"
82 * Mark strings for auto dump
84 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
85 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
88 * Variables for auto dump
90 static FILE *auto_dump_stream;
91 static concptr auto_dump_mark;
92 static int auto_dump_line_num;
96 * @brief prf出力内容を消去する /
97 * Remove old lines automatically generated before.
98 * @param orig_file 消去を行うファイル名
100 static void remove_auto_dump(concptr orig_file)
102 FILE *tmp_fff, *orig_fff;
106 bool between_mark = FALSE;
107 bool changed = FALSE;
109 long header_location = 0;
110 char header_mark_str[80];
111 char footer_mark_str[80];
114 /* Prepare a header/footer mark string */
115 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
116 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
118 mark_len = strlen(footer_mark_str);
120 /* Open an old dump file in read-only mode */
121 orig_fff = my_fopen(orig_file, "r");
123 /* If original file does not exist, nothing to do */
124 if (!orig_fff) return;
126 /* Open a new (temporary) file */
127 tmp_fff = my_fopen_temp(tmp_file, 1024);
131 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
136 /* Loop for every line */
140 if (my_fgets(orig_fff, buf, sizeof(buf)))
142 /* Read error: Assume End of File */
145 * Was looking for the footer, but not found.
147 * Since automatic dump might be edited by hand,
148 * it's dangerous to kill these lines.
149 * Seek back to the next line of the (pseudo) header,
154 fseek(orig_fff, header_location, SEEK_SET);
155 between_mark = FALSE;
159 /* Success -- End the loop */
166 /* We are looking for the header mark of automatic dump */
169 /* Is this line a header? */
170 if (!strcmp(buf, header_mark_str))
172 /* Memorise seek point of this line */
173 header_location = ftell(orig_fff);
175 /* Initialize counter for number of lines */
178 /* Look for the footer from now */
181 /* There are some changes */
188 /* Copy orginally lines */
189 fprintf(tmp_fff, "%s\n", buf);
193 /* We are looking for the footer mark of automatic dump */
196 /* Is this line a footer? */
197 if (!strncmp(buf, footer_mark_str, mark_len))
202 * Compare the number of lines
204 * If there is an inconsistency between
205 * actual number of lines and the
206 * number here, the automatic dump
207 * might be edited by hand. So it's
208 * dangerous to kill these lines.
209 * Seek back to the next line of the
210 * (pseudo) header, and read again.
212 if (!sscanf(buf + mark_len, " (%d)", &tmp)
215 fseek(orig_fff, header_location, SEEK_SET);
218 /* Look for another header */
219 between_mark = FALSE;
225 /* Ignore old line, and count number of lines */
235 /* If there are some changes, overwrite the original file with new one */
238 /* Copy contents of temporary file */
240 tmp_fff = my_fopen(tmp_file, "r");
241 orig_fff = my_fopen(orig_file, "w");
243 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
244 fprintf(orig_fff, "%s\n", buf);
250 /* Kill the temporary file */
258 * @brief prfファイルのフォーマットに従った内容を出力する /
259 * Dump a formatted line, using "vstrnfmt()".
262 static void auto_dump_printf(concptr fmt, ...)
269 /* Begin the Varargs Stuff */
272 /* Format the args, save the length */
273 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
275 /* End the Varargs Stuff */
278 /* Count number of lines */
279 for (p = buf; *p; p++)
281 if (*p == '\n') auto_dump_line_num++;
285 fprintf(auto_dump_stream, "%s", buf);
290 * @brief prfファイルをファイルオープンする /
291 * Open file to append auto dump.
293 * @param mark 出力するヘッダマーク
294 * @return ファイルポインタを取得できたらTRUEを返す
296 static bool open_auto_dump(concptr buf, concptr mark)
299 char header_mark_str[80];
301 /* Save the mark string */
302 auto_dump_mark = mark;
304 /* Prepare a header mark string */
305 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
307 /* Remove old macro dumps */
308 remove_auto_dump(buf);
310 /* Append to the file */
311 auto_dump_stream = my_fopen(buf, "a");
314 if (!auto_dump_stream) {
315 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
323 fprintf(auto_dump_stream, "%s\n", header_mark_str);
325 /* Initialize counter */
326 auto_dump_line_num = 0;
328 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
329 "# *Warning!* The lines below are an automatic dump.\n"));
330 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
331 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
337 * @brief prfファイルをファイルクローズする /
338 * Append foot part and close auto dump.
341 static void close_auto_dump(void)
343 char footer_mark_str[80];
345 /* Prepare a footer mark string */
346 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
348 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
349 "# *Warning!* The lines below are an automatic dump.\n"));
350 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
351 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
353 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
356 my_fclose(auto_dump_stream);
365 * @brief Return suffix of ordinal number
367 * @return pointer of suffix string.
369 concptr get_ordinal_number_suffix(int num)
371 num = ABS(num) % 100;
375 return (num == 11) ? "th" : "st";
377 return (num == 12) ? "th" : "nd";
379 return (num == 13) ? "th" : "rd";
388 * @brief 日記にメッセージを追加する /
389 * Take note to the diary.
390 * @param type 日記内容のID
391 * @param num 日記内容のIDに応じた数値
392 * @param note 日記内容のIDに応じた文字列参照ポインタ
395 errr do_cmd_write_nikki(int type, int num, concptr note)
399 GAME_TEXT file_name[MAX_NLEN];
401 concptr note_level = "";
402 bool do_level = TRUE;
403 char note_level_buf[40];
406 static bool disable_nikki = FALSE;
408 extract_day_hour_min(&day, &hour, &min);
410 if (disable_nikki) return(-1);
412 if (type == NIKKI_FIX_QUEST_C ||
413 type == NIKKI_FIX_QUEST_F ||
414 type == NIKKI_RAND_QUEST_C ||
415 type == NIKKI_RAND_QUEST_F ||
416 type == NIKKI_TO_QUEST)
420 old_quest = p_ptr->inside_quest;
421 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
423 /* Get the quest text */
424 init_flags = INIT_NAME_ONLY;
426 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
428 /* Reset the old quest number */
429 p_ptr->inside_quest = old_quest;
432 /* different filne name to avoid mixing */
433 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
435 /* Build the filename */
436 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
438 /* File type is "TEXT" */
439 FILE_TYPE(FILE_TYPE_TEXT);
441 fff = my_fopen(buf, "a");
446 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
452 q_idx = quest_number(current_floor_ptr->dun_level);
456 if (p_ptr->inside_arena)
457 note_level = _("アリーナ:", "Arane:");
458 else if (!current_floor_ptr->dun_level)
459 note_level = _("地上:", "Surface:");
460 else if (q_idx && (is_fixed_quest_idx(q_idx)
461 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
462 note_level = _("クエスト:", "Quest:");
466 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
468 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
470 note_level = note_level_buf;
478 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
479 else fputs(_("*****日目\n", "Day *****\n"), fff);
487 fprintf(fff, "%s\n",note);
491 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
496 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
499 case NIKKI_ART_SCROLL:
501 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
506 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
509 case NIKKI_FIX_QUEST_C:
511 if (quest[num].flags & QUEST_FLAG_SILENT) break;
512 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
513 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
516 case NIKKI_FIX_QUEST_F:
518 if (quest[num].flags & QUEST_FLAG_SILENT) break;
519 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
520 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
523 case NIKKI_RAND_QUEST_C:
525 GAME_TEXT name[MAX_NLEN];
526 strcpy(name, r_name+r_info[quest[num].r_idx].name);
527 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
528 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
531 case NIKKI_RAND_QUEST_F:
533 GAME_TEXT name[MAX_NLEN];
534 strcpy(name, r_name+r_info[quest[num].r_idx].name);
535 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
536 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
539 case NIKKI_MAXDEAPTH:
541 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
542 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
543 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
544 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
549 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
550 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
551 _(d_name + d_info[num].name, (int)max_dlv[num]),
552 _((int)max_dlv[num], d_name + d_info[num].name));
558 if (q_idx && (is_fixed_quest_idx(q_idx)
559 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
561 to = _("地上", "the surface");
565 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
566 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
568 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
574 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
575 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
576 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
578 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
583 if (quest[num].flags & QUEST_FLAG_SILENT) break;
584 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
585 hour, min, note_level, quest[num].name);
590 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
591 hour, min, note_level);
596 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
601 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
609 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
610 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
613 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
614 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
616 if (num == MAX_ARENA_MONS)
618 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
619 " won all fight to become a Chanpion.\n"));
626 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
632 if (!current_floor_ptr->dun_level)
633 to = _("地上", "the surface");
635 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
637 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
638 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
644 if (!current_floor_ptr->dun_level)
645 to = _("地上", "the surface");
647 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
649 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
650 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
655 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
658 case NIKKI_GAMESTART:
660 time_t ct = time((time_t*)0);
664 fprintf(fff, "%s %s",note, ctime(&ct));
667 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
670 case NIKKI_NAMED_PET:
672 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
675 case RECORD_NAMED_PET_NAME:
676 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
678 case RECORD_NAMED_PET_UNNAME:
679 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
681 case RECORD_NAMED_PET_DISMISS:
682 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
684 case RECORD_NAMED_PET_DEATH:
685 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
687 case RECORD_NAMED_PET_MOVED:
688 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
690 case RECORD_NAMED_PET_LOST_SIGHT:
691 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
693 case RECORD_NAMED_PET_DESTROY:
694 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
696 case RECORD_NAMED_PET_EARTHQUAKE:
697 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
699 case RECORD_NAMED_PET_GENOCIDE:
700 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
702 case RECORD_NAMED_PET_WIZ_ZAP:
703 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
705 case RECORD_NAMED_PET_TELE_LEVEL:
706 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
708 case RECORD_NAMED_PET_BLAST:
709 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
711 case RECORD_NAMED_PET_HEAL_LEPER:
712 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
714 case RECORD_NAMED_PET_COMPACT:
715 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
717 case RECORD_NAMED_PET_LOSE_PARENT:
718 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
729 case NIKKI_WIZARD_LOG:
730 fprintf(fff, "%s\n", note);
739 if (do_level) write_level = FALSE;
745 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
748 * @brief 日記のタイトル表記と内容出力 /
751 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
753 static void do_cmd_disp_nikki(void)
755 char nikki_title[256];
756 GAME_TEXT file_name[MAX_NLEN];
761 static const char subtitle[][30] = {"最強の肉体を求めて",
792 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
793 "Attack is the best form of defence.",
795 "An unexpected windfall",
796 "A drowning man will catch at a straw",
797 "Don't count your chickens before they are hatched.",
798 "It is no use crying over spilt milk.",
799 "Seeing is believing.",
800 "Strike the iron while it is hot.",
801 "I don't care what follows.",
802 "To dig a well to put out a house on fire.",
803 "Tomorrow is another day.",
804 "Easy come, easy go.",
805 "The more haste, the less speed.",
806 "Where there is life, there is hope.",
807 "There is no royal road to *WINNER*.",
808 "Danger past, God forgotten.",
809 "The best thing to do now is to run away.",
810 "Life is but an empty dream.",
811 "Dead men tell no tales.",
812 "A book that remains shut is but a block.",
813 "Misfortunes never come singly.",
814 "A little knowledge is a dangerous thing.",
815 "History repeats itself.",
816 "*WINNER* was not built in a day.",
817 "Ignorance is bliss.",
818 "To lose is to win?",
819 "No medicine can cure folly.",
820 "All good things come to an end.",
821 "M$ Empire strikes back.",
822 "To see is to believe",
824 "Quest of The World's Greatest Brain"};
826 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
828 /* Build the filename */
829 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
831 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
832 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
833 else if (IS_WIZARD_CLASS())
834 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
835 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
838 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
840 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
843 /* Display the file contents */
844 show_file(FALSE, buf, nikki_title, -1, 0);
848 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
851 static void do_cmd_bunshou(void)
854 char bunshou[80] = "\0";
856 if (get_string(_("内容: ", "diary note: "), tmp, 79))
858 strcpy(bunshou, tmp);
860 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
865 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
868 static void do_cmd_last_get(void)
873 if (record_o_name[0] == '\0') return;
875 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
876 if (!get_check(buf)) return;
878 turn_tmp = current_world_ptr->game_turn;
879 current_world_ptr->game_turn = record_turn;
880 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
881 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
882 current_world_ptr->game_turn = turn_tmp;
886 * @brief ファイル中の全日記記録を消去する /
889 static void do_cmd_erase_nikki(void)
891 GAME_TEXT file_name[MAX_NLEN];
895 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
896 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
898 /* Build the filename */
899 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
902 fff = my_fopen(buf, "w");
905 msg_format(_("記録を消去しました。", "deleted record."));
907 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
916 void do_cmd_nikki(void)
920 /* File type is "TEXT" */
921 FILE_TYPE(FILE_TYPE_TEXT);
924 /* Interact until done */
929 /* Ask for a choice */
930 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
932 /* Give some choices */
933 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
934 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
935 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
936 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
938 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
941 prt(_("コマンド:", "Command: "), 18, 0);
946 if (i == ESCAPE) break;
960 do_cmd_erase_nikki();
964 prepare_movie_hooks();
966 default: /* Unknown option */
976 * @brief 画面を再描画するコマンドのメインルーチン
977 * Hack -- redraw the screen
981 * This command performs various low level updates, clears all the "extra"
982 * windows, does a total redraw of the main window, and requests all of the
983 * interesting updates and redraws that I can think of.
985 * This command is also used to "instantiate" the results of the user
986 * selecting various things, such as graphics mode, so it must call
987 * the "TERM_XTRA_REACT" hook before redrawing the windows.
990 void do_cmd_redraw(void)
996 /* Hack -- react to changes */
997 Term_xtra(TERM_XTRA_REACT, 0);
999 /* Combine and Reorder the pack (later) */
1000 p_ptr->update |= (PU_COMBINE | PU_REORDER);
1001 p_ptr->update |= (PU_TORCH);
1002 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1003 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1004 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1005 p_ptr->update |= (PU_MONSTERS);
1007 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1009 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1010 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1016 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1019 /* Redraw every window */
1020 for (j = 0; j < 8; j++)
1023 if (!angband_term[j]) continue;
1026 Term_activate(angband_term[j]);
1035 * @brief 名前を変更するコマンドのメインルーチン
1036 * Hack -- change name
1039 void do_cmd_change_name(void)
1054 /* Display the player */
1055 display_player(mode);
1060 display_player(mode);
1065 Term_putstr(2, 23, -1, TERM_WHITE,
1066 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1068 Term_putstr(2, 23, -1, TERM_WHITE,
1069 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1077 if (c == ESCAPE) break;
1084 /* Process the player name */
1085 process_player_name(FALSE);
1091 sprintf(tmp, "%s.txt", player_base);
1092 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1094 if (tmp[0] && (tmp[0] != ' '))
1096 file_character(tmp);
1114 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1121 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1122 * Recall the most recent message
1125 void do_cmd_message_one(void)
1127 /* Recall one message */
1128 prt(format("> %s", message_str(0)), 0, 0);
1133 * @brief メッセージのログを表示するコマンドのメインルーチン
1134 * Recall the most recent message
1138 * Show previous messages to the user -BEN-
1140 * The screen format uses line 0 and 23 for headers and prompts,
1141 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1143 * This command shows you which commands you are viewing, and allows
1144 * you to "search" for strings in the recall.
1146 * Note that messages may be longer than 80 characters, but they are
1147 * displayed using "infinite" length, with a special sub-command to
1148 * "slide" the virtual display to the left or right.
1150 * Attempt to only hilite the matching portions of the string.
1153 void do_cmd_messages(int num_now)
1157 char shower_str[81];
1158 char finder_str[81];
1160 concptr shower = NULL;
1164 Term_get_size(&wid, &hgt);
1166 /* Number of message lines in a screen */
1167 num_lines = hgt - 4;
1170 strcpy(finder_str, "");
1173 strcpy(shower_str, "");
1175 /* Total messages */
1178 /* Start on first message */
1183 /* Process requests until done */
1189 /* Dump up to 20 lines of messages */
1190 for (j = 0; (j < num_lines) && (i + j < n); j++)
1192 concptr msg = message_str(i+j);
1194 /* Dump the messages, bottom to top */
1195 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1197 /* Hilite "shower" */
1198 if (shower && shower[0])
1202 /* Display matches */
1203 while ((str = my_strstr(str, shower)) != NULL)
1205 int len = strlen(shower);
1207 /* Display the match */
1208 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1216 /* Erase remaining lines */
1217 for (; j < num_lines; j++)
1219 Term_erase(0, num_lines + 1 - j, 255);
1222 /* Display header */
1224 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1225 i, i + j - 1, n), 0, 0);
1227 /* Display prompt (not very informative) */
1228 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1229 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1231 skey = inkey_special(TRUE);
1233 /* Exit on Escape */
1234 if (skey == ESCAPE) break;
1236 /* Hack -- Save the old index */
1241 /* Hack -- handle show */
1244 prt(_("強調: ", "Show: "), hgt - 1, 0);
1246 /* Get a "shower" string, or continue */
1247 strcpy(back_str, shower_str);
1248 if (askfor(shower_str, 80))
1251 shower = shower_str[0] ? shower_str : NULL;
1253 else strcpy(shower_str, back_str);
1257 /* Hack -- handle find */
1264 prt(_("検索: ", "Find: "), hgt - 1, 0);
1266 /* Get a "finder" string, or continue */
1267 strcpy(back_str, finder_str);
1268 if (!askfor(finder_str, 80))
1270 strcpy(finder_str, back_str);
1273 else if (!finder_str[0])
1275 shower = NULL; /* Stop showing */
1280 shower = finder_str;
1283 for (z = i + 1; z < n; z++)
1285 concptr msg = message_str(z);
1288 if (my_strstr(msg, finder_str))
1299 /* Recall 1 older message */
1301 /* Go to the oldest line */
1305 /* Recall 1 newer message */
1307 /* Go to the newest line */
1311 /* Recall 1 older message */
1316 /* Go older if legal */
1317 i = MIN(i + 1, n - num_lines);
1320 /* Recall 10 older messages */
1322 /* Go older if legal */
1323 i = MIN(i + 10, n - num_lines);
1326 /* Recall 20 older messages */
1331 /* Go older if legal */
1332 i = MIN(i + num_lines, n - num_lines);
1335 /* Recall 20 newer messages */
1339 /* Go newer (if able) */
1340 i = MAX(0, i - num_lines);
1343 /* Recall 10 newer messages */
1345 /* Go newer (if able) */
1349 /* Recall 1 newer messages */
1352 /* Go newer (if able) */
1357 /* Hack -- Error of some kind */
1365 * @brief チートオプションを変更するコマンドのメインルーチン
1366 * Interact with some options for cheating
1367 * @param info 表示メッセージ
1370 static void do_cmd_options_cheat(concptr info)
1373 int i, k = 0, n = CHEAT_MAX;
1377 /* Interact with the player */
1383 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1388 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1389 prt(" << 注意 >>", 11, 0);
1390 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1391 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1392 prt(" じらないようにして下さい。", 14, 0);
1394 /* Display the options */
1395 for (i = 0; i < n; i++)
1397 byte a = TERM_WHITE;
1399 /* Color current option */
1400 if (i == k) a = TERM_L_BLUE;
1402 /* Display the option text */
1403 sprintf(buf, "%-48s: %s (%s)",
1404 cheat_info[i].o_desc,
1405 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1406 cheat_info[i].o_text);
1407 c_prt(a, buf, i + 2, 0);
1410 /* Hilite current option */
1411 move_cursor(k + 2, 50);
1417 * HACK - Try to translate the key into a direction
1418 * to allow using the roguelike keys for navigation.
1420 dir = get_keymap_dir(ch);
1421 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1435 k = (n + k - 1) % n;
1453 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1454 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1455 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1456 (*cheat_info[k].o_var) = TRUE;
1465 (*cheat_info[k].o_var) = FALSE;
1472 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1473 /* Peruse the help file */
1474 (void)show_file(TRUE, buf, NULL, 0, 0);
1491 * @brief セーブ頻度ターンの次の値を返す
1492 * @param current 現在のセーブ頻度ターン値
1493 * @return 次のセーブ頻度ターン値
1495 static s16b toggle_frequency(s16b current)
1500 case 50: return 100;
1501 case 100: return 250;
1502 case 250: return 500;
1503 case 500: return 1000;
1504 case 1000: return 2500;
1505 case 2500: return 5000;
1506 case 5000: return 10000;
1507 case 10000: return 25000;
1514 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1515 * @param info 表示メッセージ
1518 static void do_cmd_options_autosave(concptr info)
1521 int i, k = 0, n = 2;
1526 /* Interact with the player */
1530 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1531 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1535 /* Display the options */
1536 for (i = 0; i < n; i++)
1538 byte a = TERM_WHITE;
1540 /* Color current option */
1541 if (i == k) a = TERM_L_BLUE;
1543 /* Display the option text */
1544 sprintf(buf, "%-48s: %s (%s)",
1545 autosave_info[i].o_desc,
1546 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1547 autosave_info[i].o_text);
1548 c_prt(a, buf, i + 2, 0);
1550 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1552 /* Hilite current option */
1553 move_cursor(k + 2, 50);
1569 k = (n + k - 1) % n;
1587 (*autosave_info[k].o_var) = TRUE;
1596 (*autosave_info[k].o_var) = FALSE;
1604 autosave_freq = toggle_frequency(autosave_freq);
1605 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1611 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1627 * @brief 標準オプションを変更するコマンドのサブルーチン /
1628 * Interact with some options
1629 * @param page オプションページ番号
1630 * @param info 表示メッセージ
1633 void do_cmd_options_aux(int page, concptr info)
1636 int i, k = 0, n = 0, l;
1639 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1640 (!p_ptr->wizard || !allow_debug_opts);
1643 /* Lookup the options */
1644 for (i = 0; i < 24; i++) opt[i] = 0;
1646 /* Scan the options */
1647 for (i = 0; option_info[i].o_desc; i++)
1649 /* Notice options on this "page" */
1650 if (option_info[i].o_page == page) opt[n++] = i;
1654 /* Interact with the player */
1660 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1661 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1664 /* HACK -- description for easy-auto-destroy options */
1665 if (page == OPT_PAGE_AUTODESTROY)
1666 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1667 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1669 /* Display the options */
1670 for (i = 0; i < n; i++)
1672 byte a = TERM_WHITE;
1674 /* Color current option */
1675 if (i == k) a = TERM_L_BLUE;
1677 /* Display the option text */
1678 sprintf(buf, "%-48s: %s (%.19s)",
1679 option_info[opt[i]].o_desc,
1680 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1681 option_info[opt[i]].o_text);
1682 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1683 else c_prt(a, buf, i + 2, 0);
1686 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1689 /* Hilite current option */
1690 move_cursor(k + 2 + l, 50);
1696 * HACK - Try to translate the key into a direction
1697 * to allow using the roguelike keys for navigation.
1699 dir = get_keymap_dir(ch);
1700 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1714 k = (n + k - 1) % n;
1731 if (browse_only) break;
1732 (*option_info[opt[k]].o_var) = TRUE;
1741 if (browse_only) break;
1742 (*option_info[opt[k]].o_var) = FALSE;
1750 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1756 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1757 /* Peruse the help file */
1758 (void)show_file(TRUE, buf, NULL, 0, 0);
1775 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1776 * Modify the "window" options
1779 static void do_cmd_options_win(void)
1789 /* Memorize old flags */
1790 for (j = 0; j < 8; j++)
1792 /* Acquire current flags */
1793 old_flag[j] = window_flag[j];
1802 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1804 /* Display the windows */
1805 for (j = 0; j < 8; j++)
1807 byte a = TERM_WHITE;
1809 concptr s = angband_term_name[j];
1812 if (j == x) a = TERM_L_BLUE;
1814 /* Window name, staggered, centered */
1815 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1818 /* Display the options */
1819 for (i = 0; i < 16; i++)
1821 byte a = TERM_WHITE;
1823 concptr str = window_flag_desc[i];
1826 if (i == y) a = TERM_L_BLUE;
1829 if (!str) str = _("(未使用)", "(Unused option)");
1832 Term_putstr(0, i + 5, -1, a, str);
1834 /* Display the windows */
1835 for (j = 0; j < 8; j++)
1841 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1844 if (window_flag[j] & (1L << i)) c = 'X';
1847 Term_putch(35 + j * 5, i + 5, a, c);
1852 Term_gotoxy(35 + x * 5, y + 5);
1870 for (j = 0; j < 8; j++)
1872 window_flag[j] &= ~(1L << y);
1876 for (i = 0; i < 16; i++)
1878 window_flag[x] &= ~(1L << i);
1891 window_flag[x] |= (1L << y);
1899 window_flag[x] &= ~(1L << y);
1905 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1913 d = get_keymap_dir(ch);
1915 x = (x + ddx[d] + 8) % 8;
1916 y = (y + ddy[d] + 16) % 16;
1923 /* Notice changes */
1924 for (j = 0; j < 8; j++)
1929 if (!angband_term[j]) continue;
1931 /* Ignore non-changes */
1932 if (window_flag[j] == old_flag[j]) continue;
1935 Term_activate(angband_term[j]);
1952 option_fields[OPT_NUM] =
1955 { '1', " キー入力 オプション", 3 },
1956 { '2', " マップ画面 オプション", 4 },
1957 { '3', " テキスト表示 オプション", 5 },
1958 { '4', " ゲームプレイ オプション", 6 },
1959 { '5', " 行動中止関係 オプション", 7 },
1960 { '6', " 簡易自動破壊 オプション", 8 },
1961 { 'r', " プレイ記録 オプション", 9 },
1963 { 'p', "自動拾いエディタ", 11 },
1964 { 'd', " 基本ウェイト量 ", 12 },
1965 { 'h', "低ヒットポイント", 13 },
1966 { 'm', " 低魔力色閾値 ", 14 },
1967 { 'a', " 自動セーブ オプション", 15 },
1968 { 'w', "ウインドウフラグ", 16 },
1970 { 'b', " 初期 オプション (参照のみ)", 18 },
1971 { 'c', " 詐欺 オプション", 19 },
1973 { '1', "Input Options", 3 },
1974 { '2', "Map Screen Options", 4 },
1975 { '3', "Text Display Options", 5 },
1976 { '4', "Game-Play Options", 6 },
1977 { '5', "Disturbance Options", 7 },
1978 { '6', "Easy Auto-Destroyer Options", 8 },
1979 { 'r', "Play record Options", 9 },
1981 { 'p', "Auto-picker/destroyer editor", 11 },
1982 { 'd', "Base Delay Factor", 12 },
1983 { 'h', "Hitpoint Warning", 13 },
1984 { 'm', "Mana Color Threshold", 14 },
1985 { 'a', "Autosave Options", 15 },
1986 { 'w', "Window Flags", 16 },
1988 { 'b', "Birth Options (Browse Only)", 18 },
1989 { 'c', "Cheat Options", 19 },
1995 * @brief 標準オプションを変更するコマンドのメインルーチン /
1996 * Set or unset various options.
2000 * The user must use the "Ctrl-R" command to "adapt" to changes
2001 * in any options which control "visual" aspects of the game.
2004 void do_cmd_options(void)
2016 /* Does not list cheat option when cheat option is off */
2017 if (!p_ptr->noscore && !allow_debug_opts) n--;
2020 /* Why are we here */
2021 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2025 /* Give some choices */
2026 for (i = 0; i < n; i++)
2028 byte a = TERM_WHITE;
2029 if (i == y) a = TERM_L_BLUE;
2030 Term_putstr(5, option_fields[i].row, -1, a,
2031 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2034 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2037 skey = inkey_special(TRUE);
2038 if (!(skey & SKEY_MASK)) k = (char)skey;
2042 if (k == ESCAPE) break;
2044 if (my_strchr("\n\r ", k))
2046 k = option_fields[y].key;
2050 for (i = 0; i < n; i++)
2052 if (tolower(k) == option_fields[i].key) break;
2055 /* Command is found */
2058 /* Hack -- browse help */
2059 if (k == '?') break;
2063 if (skey == SKEY_UP) d = 8;
2064 if (skey == SKEY_DOWN) d = 2;
2065 y = (y + ddy[d] + n) % n;
2070 if (k == ESCAPE) break;
2077 /* Process the general options */
2078 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2084 /* Process the general options */
2085 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2092 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2099 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2106 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2113 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2117 /* Play-record Options */
2122 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2131 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2132 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2133 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2137 /* Cheating Options */
2140 if (!p_ptr->noscore && !allow_debug_opts)
2142 /* Cheat options are not permitted */
2148 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2155 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2164 do_cmd_options_win();
2165 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2166 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2167 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2168 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2173 /* Auto-picker/destroyer editor */
2177 do_cmd_edit_autopick();
2181 /* Hack -- Delay Speed */
2187 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2189 /* Get a new value */
2192 int msec = delay_factor * delay_factor * delay_factor;
2193 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2194 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2196 if (k == ESCAPE) break;
2199 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2202 else if (isdigit(k)) delay_factor = D2I(k);
2209 /* Hack -- hitpoint warning factor */
2215 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2217 /* Get a new value */
2220 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2221 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2223 if (k == ESCAPE) break;
2226 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2229 else if (isdigit(k)) hitpoint_warn = D2I(k);
2236 /* Hack -- mana color factor */
2242 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2244 /* Get a new value */
2247 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2248 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2250 if (k == ESCAPE) break;
2253 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2256 else if (isdigit(k)) mana_warn = D2I(k);
2264 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2268 /* Unknown option */
2281 /* Hack - Redraw equippy chars */
2282 p_ptr->redraw |= (PR_EQUIPPY);
2288 * @brief prefファイルを選択して処理する /
2289 * Ask for a "user pref line" and process it
2292 * Allow absolute file names?
2294 void do_cmd_pref(void)
2301 /* Ask for a "user pref command" */
2302 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2304 /* Process that pref command */
2305 (void)process_pref_file_command(buf);
2309 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2312 void do_cmd_reload_autopick(void)
2314 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2315 /* Load the file with messages */
2316 autopick_load_pref(TRUE);
2322 * @brief マクロ情報をprefファイルに保存する /
2323 * @param fname ファイル名
2326 static errr macro_dump(concptr fname)
2328 static concptr mark = "Macro Dump";
2334 /* Build the filename */
2335 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2337 /* File type is "TEXT" */
2338 FILE_TYPE(FILE_TYPE_TEXT);
2340 /* Append to the file */
2341 if (!open_auto_dump(buf, mark)) return (-1);
2344 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2347 for (i = 0; i < macro__num; i++)
2349 /* Extract the action */
2350 ascii_to_text(buf, macro__act[i]);
2352 /* Dump the macro */
2353 auto_dump_printf("A:%s\n", buf);
2355 /* Extract the action */
2356 ascii_to_text(buf, macro__pat[i]);
2358 /* Dump normal macros */
2359 auto_dump_printf("P:%s\n", buf);
2362 auto_dump_printf("\n");
2374 * @brief マクロのトリガーキーを取得する /
2375 * Hack -- ask for a "trigger" (see below)
2376 * @param buf キー表記を保管するバッファ
2380 * Note the complex use of the "inkey()" function from "util.c".
2382 * Note that both "flush()" calls are extremely important.
2385 static void do_cmd_macro_aux(char *buf)
2393 /* Do not process macros */
2399 /* Read the pattern */
2405 /* Do not process macros */
2408 /* Do not wait for keys */
2411 /* Attempt to read a key */
2420 /* Convert the trigger */
2421 ascii_to_text(tmp, buf);
2423 /* Hack -- display the trigger */
2424 Term_addstr(-1, TERM_WHITE, tmp);
2430 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2431 * Hack -- ask for a keymap "trigger" (see below)
2432 * @param buf キー表記を取得するバッファ
2436 * Note that both "flush()" calls are extremely important. This may
2437 * no longer be true, since "util.c" is much simpler now.
2440 static void do_cmd_macro_aux_keymap(char *buf)
2450 /* Convert to ascii */
2451 ascii_to_text(tmp, buf);
2453 /* Hack -- display the trigger */
2454 Term_addstr(-1, TERM_WHITE, tmp);
2461 * @brief キーマップをprefファイルにダンプする /
2462 * Hack -- append all keymaps to the given file
2463 * @param fname ファイルネーム
2467 static errr keymap_dump(concptr fname)
2469 static concptr mark = "Keymap Dump";
2478 if (rogue_like_commands)
2480 mode = KEYMAP_MODE_ROGUE;
2486 mode = KEYMAP_MODE_ORIG;
2490 /* Build the filename */
2491 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2493 /* File type is "TEXT" */
2494 FILE_TYPE(FILE_TYPE_TEXT);
2496 /* Append to the file */
2497 if (!open_auto_dump(buf, mark)) return -1;
2500 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2503 for (i = 0; i < 256; i++)
2507 /* Loop up the keymap */
2508 act = keymap_act[mode][i];
2510 /* Skip empty keymaps */
2513 /* Encode the key */
2516 ascii_to_text(key, buf);
2518 /* Encode the action */
2519 ascii_to_text(buf, act);
2521 /* Dump the macro */
2522 auto_dump_printf("A:%s\n", buf);
2523 auto_dump_printf("C:%d:%s\n", mode, key);
2535 * @brief マクロを設定するコマンドのメインルーチン /
2536 * Interact with "macros"
2540 * Note that the macro "action" must be defined before the trigger.
2542 * Could use some helpful instructions on this page.
2545 void do_cmd_macros(void)
2557 if (rogue_like_commands)
2559 mode = KEYMAP_MODE_ROGUE;
2565 mode = KEYMAP_MODE_ORIG;
2568 /* File type is "TEXT" */
2569 FILE_TYPE(FILE_TYPE_TEXT);
2574 /* Process requests until done */
2578 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2580 /* Describe that action */
2581 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2583 /* Analyze the current action */
2584 ascii_to_text(buf, macro__buf);
2586 /* Display the current action */
2591 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2593 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2594 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2595 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2596 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2597 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2598 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2599 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2600 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2601 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2602 #endif /* ALLOW_MACROS */
2605 prt(_("コマンド: ", "Command: "), 16, 0);
2610 if (i == ESCAPE) break;
2612 /* Load a 'macro' file */
2618 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2621 prt(_("ファイル: ", "File: "), 18, 0);
2623 /* Default filename */
2624 sprintf(tmp, "%s.prf", player_base);
2626 /* Ask for a file */
2627 if (!askfor(tmp, 80)) continue;
2629 /* Process the given filename */
2630 err = process_pref_file(tmp);
2633 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2638 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2642 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2652 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2655 prt(_("ファイル: ", "File: "), 18, 0);
2657 /* Default filename */
2658 sprintf(tmp, "%s.prf", player_base);
2660 /* Ask for a file */
2661 if (!askfor(tmp, 80)) continue;
2663 /* Dump the macros */
2664 (void)macro_dump(tmp);
2667 msg_print(_("マクロを追加しました。", "Appended macros."));
2676 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2680 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2682 /* Get a macro trigger */
2683 do_cmd_macro_aux(buf);
2685 /* Acquire action */
2686 k = macro_find_exact(buf);
2692 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2698 /* Obtain the action */
2699 strcpy(macro__buf, macro__act[k]);
2701 /* Analyze the current action */
2702 ascii_to_text(buf, macro__buf);
2704 /* Display the current action */
2708 msg_print(_("マクロを確認しました。", "Found a macro."));
2712 /* Create a macro */
2716 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2719 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2721 /* Get a macro trigger */
2722 do_cmd_macro_aux(buf);
2728 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2729 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2732 prt(_("マクロ行動: ", "Action: "), 20, 0);
2734 /* Convert to text */
2735 ascii_to_text(tmp, macro__buf);
2737 /* Get an encoded action */
2738 if (askfor(tmp, 80))
2740 /* Convert to ascii */
2741 text_to_ascii(macro__buf, tmp);
2743 /* Link the macro */
2744 macro_add(buf, macro__buf);
2747 msg_print(_("マクロを追加しました。", "Added a macro."));
2751 /* Remove a macro */
2755 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2758 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2760 /* Get a macro trigger */
2761 do_cmd_macro_aux(buf);
2763 /* Link the macro */
2764 macro_add(buf, buf);
2767 msg_print(_("マクロを削除しました。", "Removed a macro."));
2774 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2777 prt(_("ファイル: ", "File: "), 18, 0);
2779 /* Default filename */
2780 sprintf(tmp, "%s.prf", player_base);
2782 /* Ask for a file */
2783 if (!askfor(tmp, 80)) continue;
2785 /* Dump the macros */
2786 (void)keymap_dump(tmp);
2789 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2792 /* Query a keymap */
2798 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2801 prt(_("押すキー: ", "Keypress: "), 18, 0);
2803 /* Get a keymap trigger */
2804 do_cmd_macro_aux_keymap(buf);
2806 /* Look up the keymap */
2807 act = keymap_act[mode][(byte)(buf[0])];
2813 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2819 /* Obtain the action */
2820 strcpy(macro__buf, act);
2822 /* Analyze the current action */
2823 ascii_to_text(buf, macro__buf);
2825 /* Display the current action */
2829 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2833 /* Create a keymap */
2837 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2840 prt(_("押すキー: ", "Keypress: "), 18, 0);
2842 /* Get a keymap trigger */
2843 do_cmd_macro_aux_keymap(buf);
2849 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2850 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2853 prt(_("行動: ", "Action: "), 20, 0);
2855 /* Convert to text */
2856 ascii_to_text(tmp, macro__buf);
2858 /* Get an encoded action */
2859 if (askfor(tmp, 80))
2861 /* Convert to ascii */
2862 text_to_ascii(macro__buf, tmp);
2864 /* Free old keymap */
2865 string_free(keymap_act[mode][(byte)(buf[0])]);
2867 /* Make new keymap */
2868 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2871 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2875 /* Remove a keymap */
2879 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2882 prt(_("押すキー: ", "Keypress: "), 18, 0);
2884 /* Get a keymap trigger */
2885 do_cmd_macro_aux_keymap(buf);
2887 /* Free old keymap */
2888 string_free(keymap_act[mode][(byte)(buf[0])]);
2890 /* Make new keymap */
2891 keymap_act[mode][(byte)(buf[0])] = NULL;
2894 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2897 /* Enter a new action */
2901 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2907 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2908 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2911 prt(_("マクロ行動: ", "Action: "), 20, 0);
2913 /* Hack -- limit the value */
2916 /* Get an encoded action */
2917 if (!askfor(buf, 80)) continue;
2919 /* Extract an action */
2920 text_to_ascii(macro__buf, buf);
2923 #endif /* ALLOW_MACROS */
2936 * @brief キャラクタ色の明暗表現
2938 static concptr lighting_level_str[F_LIT_MAX] =
2953 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2954 * @param i 指定対象となるキャラクタコード
2955 * @param num 指定されたビジュアルIDを返す参照ポインタ
2956 * @param max ビジュアルIDの最大数
2957 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2959 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2966 sprintf(str, "%d", *num);
2968 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2971 tmp = (IDX)strtol(str, NULL, 0);
2972 if (tmp >= 0 && tmp < max)
2975 else if (isupper(i))
2976 *num = (*num + max - 1) % max;
2978 *num = (*num + 1) % max;
2984 * @brief キャラクタの変更メニュー表示
2985 * @param choice_msg 選択メッセージ
2988 static void print_visuals_menu(concptr choice_msg)
2990 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2992 /* Give some choices */
2993 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2995 #ifdef ALLOW_VISUALS
2996 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2997 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2998 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2999 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
3000 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
3001 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
3002 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3003 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3004 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3005 #endif /* ALLOW_VISUALS */
3007 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3010 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3013 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3014 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3015 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3018 * Interact with "visuals"
3020 void do_cmd_visuals(void)
3025 bool need_redraw = FALSE;
3026 concptr empty_symbol = "<< ? >>";
3028 if (use_bigtile) empty_symbol = "<< ?? >>";
3030 /* File type is "TEXT" */
3031 FILE_TYPE(FILE_TYPE_TEXT);
3034 /* Interact until done */
3039 /* Ask for a choice */
3040 print_visuals_menu(NULL);
3045 if (i == ESCAPE) break;
3049 /* Load a 'pref' file */
3052 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3055 prt(_("ファイル: ", "File: "), 17, 0);
3057 /* Default filename */
3058 sprintf(tmp, "%s.prf", player_base);
3061 if (!askfor(tmp, 70)) continue;
3063 /* Process the given filename */
3064 (void)process_pref_file(tmp);
3069 #ifdef ALLOW_VISUALS
3071 /* Dump monster attr/chars */
3074 static concptr mark = "Monster attr/chars";
3077 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3080 prt(_("ファイル: ", "File: "), 17, 0);
3082 /* Default filename */
3083 sprintf(tmp, "%s.prf", player_base);
3085 /* Get a filename */
3086 if (!askfor(tmp, 70)) continue;
3088 /* Build the filename */
3089 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3091 /* Append to the file */
3092 if (!open_auto_dump(buf, mark)) continue;
3095 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3098 for (i = 0; i < max_r_idx; i++)
3100 monster_race *r_ptr = &r_info[i];
3102 /* Skip non-entries */
3103 if (!r_ptr->name) continue;
3105 /* Dump a comment */
3106 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3108 /* Dump the monster attr/char info */
3109 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3110 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3116 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3121 /* Dump object attr/chars */
3124 static concptr mark = "Object attr/chars";
3125 KIND_OBJECT_IDX k_idx;
3128 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3131 prt(_("ファイル: ", "File: "), 17, 0);
3133 /* Default filename */
3134 sprintf(tmp, "%s.prf", player_base);
3136 /* Get a filename */
3137 if (!askfor(tmp, 70)) continue;
3139 /* Build the filename */
3140 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3142 /* Append to the file */
3143 if (!open_auto_dump(buf, mark)) continue;
3146 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3149 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3151 GAME_TEXT o_name[MAX_NLEN];
3152 object_kind *k_ptr = &k_info[k_idx];
3154 /* Skip non-entries */
3155 if (!k_ptr->name) continue;
3160 strip_name(o_name, k_idx);
3166 /* Prepare dummy object */
3167 object_prep(&forge, k_idx);
3169 /* Get un-shuffled flavor name */
3170 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3173 /* Dump a comment */
3174 auto_dump_printf("# %s\n", o_name);
3176 /* Dump the object attr/char info */
3177 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3178 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3184 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3189 /* Dump feature attr/chars */
3192 static concptr mark = "Feature attr/chars";
3195 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3198 prt(_("ファイル: ", "File: "), 17, 0);
3200 /* Default filename */
3201 sprintf(tmp, "%s.prf", player_base);
3203 /* Get a filename */
3204 if (!askfor(tmp, 70)) continue;
3206 /* Build the filename */
3207 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3209 /* Append to the file */
3210 if (!open_auto_dump(buf, mark)) continue;
3213 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3216 for (i = 0; i < max_f_idx; i++)
3218 feature_type *f_ptr = &f_info[i];
3220 /* Skip non-entries */
3221 if (!f_ptr->name) continue;
3223 /* Skip mimiccing features */
3224 if (f_ptr->mimic != i) continue;
3226 /* Dump a comment */
3227 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3229 /* Dump the feature attr/char info */
3230 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3231 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3232 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3233 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3239 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3244 /* Modify monster attr/chars (numeric operation) */
3247 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3248 static MONRACE_IDX r = 0;
3250 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3252 /* Hack -- query until done */
3255 monster_race *r_ptr = &r_info[r];
3259 TERM_COLOR da = r_ptr->d_attr;
3260 byte dc = r_ptr->d_char;
3261 TERM_COLOR ca = r_ptr->x_attr;
3262 byte cc = r_ptr->x_char;
3264 /* Label the object */
3265 Term_putstr(5, 17, -1, TERM_WHITE,
3266 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3268 /* Label the Default values */
3269 Term_putstr(10, 19, -1, TERM_WHITE,
3270 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3272 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3273 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3275 /* Label the Current values */
3276 Term_putstr(10, 20, -1, TERM_WHITE,
3277 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3279 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3280 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3283 Term_putstr(0, 22, -1, TERM_WHITE,
3284 _("コマンド (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): "));
3289 if (i == ESCAPE) break;
3291 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3292 else if (isupper(i)) c = 'a' + i - 'A';
3302 if (!cmd_visuals_aux(i, &r, max_r_idx))
3308 while (!r_info[r].name);
3312 t = (int)r_ptr->x_attr;
3313 (void)cmd_visuals_aux(i, &t, 256);
3314 r_ptr->x_attr = (byte)t;
3318 t = (int)r_ptr->x_char;
3319 (void)cmd_visuals_aux(i, &t, 256);
3320 r_ptr->x_char = (byte)t;
3324 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3326 print_visuals_menu(choice_msg);
3334 /* Modify object attr/chars (numeric operation) */
3337 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3339 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3341 /* Hack -- query until done */
3344 object_kind *k_ptr = &k_info[k];
3348 TERM_COLOR da = k_ptr->d_attr;
3349 SYMBOL_CODE dc = k_ptr->d_char;
3350 TERM_COLOR ca = k_ptr->x_attr;
3351 SYMBOL_CODE cc = k_ptr->x_char;
3353 /* Label the object */
3354 Term_putstr(5, 17, -1, TERM_WHITE,
3355 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3356 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3358 /* Label the Default values */
3359 Term_putstr(10, 19, -1, TERM_WHITE,
3360 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3362 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3363 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3365 /* Label the Current values */
3366 Term_putstr(10, 20, -1, TERM_WHITE,
3367 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3369 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3370 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3373 Term_putstr(0, 22, -1, TERM_WHITE,
3374 _("コマンド (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): "));
3379 if (i == ESCAPE) break;
3381 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3382 else if (isupper(i)) c = 'a' + i - 'A';
3392 if (!cmd_visuals_aux(i, &k, max_k_idx))
3398 while (!k_info[k].name);
3402 t = (int)k_ptr->x_attr;
3403 (void)cmd_visuals_aux(i, &t, 256);
3404 k_ptr->x_attr = (byte)t;
3408 t = (int)k_ptr->x_char;
3409 (void)cmd_visuals_aux(i, &t, 256);
3410 k_ptr->x_char = (byte)t;
3414 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3416 print_visuals_menu(choice_msg);
3424 /* Modify feature attr/chars (numeric operation) */
3427 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3429 static IDX lighting_level = F_LIT_STANDARD;
3430 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3432 /* Hack -- query until done */
3435 feature_type *f_ptr = &f_info[f];
3439 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3440 byte dc = f_ptr->d_char[lighting_level];
3441 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3442 byte cc = f_ptr->x_char[lighting_level];
3444 /* Label the object */
3446 Term_putstr(5, 17, -1, TERM_WHITE,
3447 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3448 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3450 /* Label the Default values */
3451 Term_putstr(10, 19, -1, TERM_WHITE,
3452 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3454 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3455 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3457 /* Label the Current values */
3459 Term_putstr(10, 20, -1, TERM_WHITE,
3460 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3462 Term_putstr(10, 20, -1, TERM_WHITE,
3463 format("Current attr/char = %3d / %3d", ca, cc));
3466 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3467 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3471 Term_putstr(0, 22, -1, TERM_WHITE,
3472 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3474 Term_putstr(0, 22, -1, TERM_WHITE,
3475 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3481 if (i == ESCAPE) break;
3483 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3484 else if (isupper(i)) c = 'a' + i - 'A';
3494 if (!cmd_visuals_aux(i, &f, max_f_idx))
3500 while (!f_info[f].name || (f_info[f].mimic != f));
3504 t = (int)f_ptr->x_attr[lighting_level];
3505 (void)cmd_visuals_aux(i, &t, 256);
3506 f_ptr->x_attr[lighting_level] = (byte)t;
3510 t = (int)f_ptr->x_char[lighting_level];
3511 (void)cmd_visuals_aux(i, &t, 256);
3512 f_ptr->x_char[lighting_level] = (byte)t;
3516 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3519 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3523 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3525 print_visuals_menu(choice_msg);
3533 /* Modify monster attr/chars (visual mode) */
3535 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3538 /* Modify object attr/chars (visual mode) */
3540 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3543 /* Modify feature attr/chars (visual mode) */
3546 IDX lighting_level = F_LIT_STANDARD;
3547 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3551 #endif /* ALLOW_VISUALS */
3559 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3563 /* Unknown option */
3573 if (need_redraw) do_cmd_redraw();
3578 * Interact with "colors"
3580 void do_cmd_colors(void)
3589 /* File type is "TEXT" */
3590 FILE_TYPE(FILE_TYPE_TEXT);
3595 /* Interact until done */
3600 /* Ask for a choice */
3601 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3603 /* Give some choices */
3604 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3607 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3608 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3612 prt(_("コマンド: ", "Command: "), 8, 0);
3616 if (i == ESCAPE) break;
3618 /* Load a 'pref' file */
3622 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3625 prt(_("ファイル: ", "File: "), 10, 0);
3628 sprintf(tmp, "%s.prf", player_base);
3631 if (!askfor(tmp, 70)) continue;
3633 /* Process the given filename */
3634 (void)process_pref_file(tmp);
3636 /* Mega-Hack -- react to changes */
3637 Term_xtra(TERM_XTRA_REACT, 0);
3639 /* Mega-Hack -- redraw */
3648 static concptr mark = "Colors";
3651 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3654 prt(_("ファイル: ", "File: "), 10, 0);
3656 /* Default filename */
3657 sprintf(tmp, "%s.prf", player_base);
3659 /* Get a filename */
3660 if (!askfor(tmp, 70)) continue;
3662 /* Build the filename */
3663 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3665 /* Append to the file */
3666 if (!open_auto_dump(buf, mark)) continue;
3669 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3672 for (i = 0; i < 256; i++)
3674 int kv = angband_color_table[i][0];
3675 int rv = angband_color_table[i][1];
3676 int gv = angband_color_table[i][2];
3677 int bv = angband_color_table[i][3];
3679 concptr name = _("未知", "unknown");
3681 /* Skip non-entries */
3682 if (!kv && !rv && !gv && !bv) continue;
3684 /* Extract the color name */
3685 if (i < 16) name = color_names[i];
3687 /* Dump a comment */
3688 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3690 /* Dump the monster attr/char info */
3691 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3698 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3707 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3709 /* Hack -- query until done */
3718 /* Exhibit the normal colors */
3719 for (j = 0; j < 16; j++)
3721 /* Exhibit this color */
3722 Term_putstr(j*4, 20, -1, a, "###");
3724 /* Exhibit all colors */
3725 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3728 /* Describe the color */
3729 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3731 /* Describe the color */
3732 Term_putstr(5, 10, -1, TERM_WHITE,
3733 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3735 /* Label the Current values */
3736 Term_putstr(5, 12, -1, TERM_WHITE,
3737 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3738 angband_color_table[a][0],
3739 angband_color_table[a][1],
3740 angband_color_table[a][2],
3741 angband_color_table[a][3]));
3744 Term_putstr(0, 14, -1, TERM_WHITE,
3745 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3750 if (i == ESCAPE) break;
3753 if (i == 'n') a = (byte)(a + 1);
3754 if (i == 'N') a = (byte)(a - 1);
3755 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3756 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3757 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3758 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3759 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3760 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3761 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3762 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3764 /* Hack -- react to changes */
3765 Term_xtra(TERM_XTRA_REACT, 0);
3767 /* Hack -- redraw */
3774 /* Unknown option */
3788 * Note something in the message recall
3790 void do_cmd_note(void)
3798 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3800 /* Ignore empty notes */
3801 if (!buf[0] || (buf[0] == ' ')) return;
3803 /* Add the note to the message recall */
3804 msg_format(_("メモ: %s", "Note: %s"), buf);
3809 * Mention the current version
3811 void do_cmd_version(void)
3813 #if FAKE_VER_EXTRA > 0
3814 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3815 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3817 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3818 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3825 * Array of feeling strings
3827 static concptr do_cmd_feeling_text[11] =
3829 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3830 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3831 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3832 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3833 _("とても悪い予感がする...", "You have a very bad feeling..."),
3834 _("悪い予感がする...", "You have a bad feeling..."),
3835 _("何か緊張する。", "You feel nervous."),
3836 _("少し不運な気がする...", "You feel your luck is turning..."),
3837 _("この場所は好きになれない。", "You don't like the look of this place."),
3838 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3839 _("なんて退屈なところだ...", "What a boring place...")
3842 static concptr do_cmd_feeling_text_combat[11] =
3844 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3845 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3846 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3847 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3848 _("とても悪い予感がする...", "You have a very bad feeling..."),
3849 _("悪い予感がする...", "You have a bad feeling..."),
3850 _("何か緊張する。", "You feel nervous."),
3851 _("少し不運な気がする...", "You feel your luck is turning..."),
3852 _("この場所は好きになれない。", "You don't like the look of this place."),
3853 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3854 _("なんて退屈なところだ...", "What a boring place...")
3857 static concptr do_cmd_feeling_text_lucky[11] =
3859 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3860 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3861 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3862 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3863 _("とても良い感じがする...", "You have a very good feeling..."),
3864 _("良い感じがする...", "You have a good feeling..."),
3865 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3866 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3867 _("見た感じ悪くはない...", "You like the look of this place..."),
3868 _("全然駄目ということはないが...", "This level can't be all bad..."),
3869 _("なんて退屈なところだ...", "What a boring place...")
3874 * Note that "feeling" is set to zero unless some time has passed.
3875 * Note that this is done when the level is GENERATED, not entered.
3877 void do_cmd_feeling(void)
3879 if (p_ptr->wild_mode) return;
3881 /* No useful feeling in quests */
3882 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3884 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3888 /* No useful feeling in town */
3889 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3891 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3893 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3898 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3903 /* No useful feeling in the wilderness */
3904 else if (!current_floor_ptr->dun_level)
3906 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3910 /* Display the feeling */
3911 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3912 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3913 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3914 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3915 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3917 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3923 * Description of each monster group.
3925 static concptr monster_group_text[] =
3928 "ユニーク", /* "Uniques" */
3929 "乗馬可能なモンスター", /* "Riding" */
3930 "賞金首", /* "Wanted */
3931 "アンバーの王族", /* "Ambertite" */
3960 /* "古代ドラゴン/ワイアーム", */
4021 /* "Ancient Dragon/Wyrm", */
4030 "Multi-Headed Reptile",
4035 "Reptile/Amphibian",
4036 "Spider/Scorpion/Tick",
4038 /* "Major Demon", */
4055 * Symbols of monsters in each group. Note the "Uniques" group
4056 * is handled differently.
4058 static concptr monster_group_char[] =
4115 "!$&()+./=>?[\\]`{|~",
4125 * Build a list of monster indexes in the given group. Return the number
4126 * of monsters in the group.
4128 * mode & 0x01 : check for non-empty group
4129 * mode & 0x02 : visual operation only
4131 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4137 /* Get a list of x_char in this group */
4138 concptr group_char = monster_group_char[grp_cur];
4140 /* XXX Hack -- Check if this is the "Uniques" group */
4141 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4143 /* XXX Hack -- Check if this is the "Riding" group */
4144 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4146 /* XXX Hack -- Check if this is the "Wanted" group */
4147 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4149 /* XXX Hack -- Check if this is the "Amberite" group */
4150 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4153 /* Check every race */
4154 for (i = 0; i < max_r_idx; i++)
4156 /* Access the race */
4157 monster_race *r_ptr = &r_info[i];
4159 /* Skip empty race */
4160 if (!r_ptr->name) continue ;
4162 /* Require known monsters */
4163 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4167 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4170 else if (grp_riding)
4172 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4175 else if (grp_wanted)
4177 bool wanted = FALSE;
4179 for (j = 0; j < MAX_KUBI; j++)
4181 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4182 (p_ptr->today_mon && p_ptr->today_mon == i))
4188 if (!wanted) continue;
4191 else if (grp_amberite)
4193 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4198 /* Check for race in the group */
4199 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4203 mon_idx[mon_cnt++] = i;
4205 /* XXX Hack -- Just checking for non-empty group */
4206 if (mode & 0x01) break;
4209 /* Terminate the list */
4210 mon_idx[mon_cnt] = -1;
4212 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4214 /* Return the number of races */
4220 * Description of each monster group.
4222 static concptr object_group_text[] =
4225 "キノコ", /* "Mushrooms" */
4226 "薬", /* "Potions" */
4227 "油つぼ", /* "Flasks" */
4228 "巻物", /* "Scrolls" */
4230 "アミュレット", /* "Amulets" */
4231 "笛", /* "Whistle" */
4232 "光源", /* "Lanterns" */
4233 "魔法棒", /* "Wands" */
4236 "カード", /* "Cards" */
4247 "刀剣類", /* "Swords" */
4248 "鈍器", /* "Blunt Weapons" */
4249 "長柄武器", /* "Polearms" */
4250 "採掘道具", /* "Diggers" */
4251 "飛び道具", /* "Bows" */
4255 "軽装鎧", /* "Soft Armor" */
4256 "重装鎧", /* "Hard Armor" */
4257 "ドラゴン鎧", /* "Dragon Armor" */
4258 "盾", /* "Shields" */
4259 "クローク", /* "Cloaks" */
4260 "籠手", /* "Gloves" */
4261 "ヘルメット", /* "Helms" */
4263 "ブーツ", /* "Boots" */
4316 * TVALs of items in each group
4318 static byte object_group_tval[] =
4359 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4367 * Build a list of object indexes in the given group. Return the number
4368 * of objects in the group.
4370 * mode & 0x01 : check for non-empty group
4371 * mode & 0x02 : visual operation only
4373 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4375 KIND_OBJECT_IDX i, object_cnt = 0;
4378 /* Get a list of x_char in this group */
4379 byte group_tval = object_group_tval[grp_cur];
4381 /* Check every object */
4382 for (i = 0; i < max_k_idx; i++)
4384 /* Access the object */
4385 object_kind *k_ptr = &k_info[i];
4387 /* Skip empty objects */
4388 if (!k_ptr->name) continue;
4392 /* Any objects will be displayed */
4398 /* Skip non-flavoured objects */
4399 if (!k_ptr->flavor) continue;
4401 /* Require objects ever seen */
4402 if (!k_ptr->aware) continue;
4405 /* Skip items with no distribution (special artifacts) */
4406 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4410 /* Check for objects in the group */
4411 if (TV_LIFE_BOOK == group_tval)
4413 /* Hack -- All spell books */
4414 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4416 /* Add the object */
4417 object_idx[object_cnt++] = i;
4421 else if (k_ptr->tval == group_tval)
4423 /* Add the object */
4424 object_idx[object_cnt++] = i;
4428 /* XXX Hack -- Just checking for non-empty group */
4429 if (mode & 0x01) break;
4432 /* Terminate the list */
4433 object_idx[object_cnt] = -1;
4435 /* Return the number of objects */
4441 * Description of each feature group.
4443 static concptr feature_group_text[] =
4451 * Build a list of feature indexes in the given group. Return the number
4452 * of features in the group.
4454 * mode & 0x01 : check for non-empty group
4456 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4459 FEAT_IDX feat_cnt = 0;
4461 /* Unused; There is a single group. */
4464 /* Check every feature */
4465 for (i = 0; i < max_f_idx; i++)
4467 feature_type *f_ptr = &f_info[i];
4469 /* Skip empty index */
4470 if (!f_ptr->name) continue;
4472 /* Skip mimiccing features */
4473 if (f_ptr->mimic != i) continue;
4476 feat_idx[feat_cnt++] = i;
4478 /* XXX Hack -- Just checking for non-empty group */
4479 if (mode & 0x01) break;
4482 /* Terminate the list */
4483 feat_idx[feat_cnt] = -1;
4485 /* Return the number of races */
4492 * Build a list of monster indexes in the given group. Return the number
4493 * of monsters in the group.
4495 static int collect_artifacts(int grp_cur, int object_idx[])
4497 int i, object_cnt = 0;
4499 /* Get a list of x_char in this group */
4500 byte group_tval = object_group_tval[grp_cur];
4502 /* Check every object */
4503 for (i = 0; i < max_a_idx; i++)
4505 /* Access the artifact */
4506 artifact_type *a_ptr = &a_info[i];
4508 /* Skip empty artifacts */
4509 if (!a_ptr->name) continue;
4511 /* Skip "uncreated" artifacts */
4512 if (!a_ptr->cur_num) continue;
4514 /* Check for race in the group */
4515 if (a_ptr->tval == group_tval)
4518 object_idx[object_cnt++] = i;
4522 /* Terminate the list */
4523 object_idx[object_cnt] = 0;
4525 /* Return the number of races */
4532 * Encode the screen colors
4534 static char hack[17] = "dwsorgbuDWvyRGBU";
4538 * Hack -- load a screen dump from a file
4540 void do_cmd_load_screen(void)
4545 SYMBOL_CODE c = ' ';
4551 Term_get_size(&wid, &hgt);
4553 /* Build the filename */
4554 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4556 /* Append to the file */
4557 fff = my_fopen(buf, "r");
4560 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4568 /* Load the screen */
4569 for (y = 0; okay; y++)
4571 /* Get a line of data including control code */
4572 if (!fgets(buf, 1024, fff)) okay = FALSE;
4574 /* Get the blank line */
4575 if (buf[0] == '\n' || buf[0] == '\0') break;
4577 /* Ignore too large screen image */
4578 if (y >= hgt) continue;
4581 for (x = 0; x < wid - 1; x++)
4584 if (buf[x] == '\n' || buf[x] == '\0') break;
4586 /* Put the attr/char */
4587 Term_draw(x, y, TERM_WHITE, buf[x]);
4591 /* Dump the screen */
4592 for (y = 0; okay; y++)
4594 /* Get a line of data including control code */
4595 if (!fgets(buf, 1024, fff)) okay = FALSE;
4597 /* Get the blank line */
4598 if (buf[0] == '\n' || buf[0] == '\0') break;
4600 /* Ignore too large screen image */
4601 if (y >= hgt) continue;
4604 for (x = 0; x < wid - 1; x++)
4607 if (buf[x] == '\n' || buf[x] == '\0') break;
4609 /* Get the attr/char */
4610 (void)(Term_what(x, y, &a, &c));
4612 /* Look up the attr */
4613 for (i = 0; i < 16; i++)
4615 /* Use attr matches */
4616 if (hack[i] == buf[x]) a = (byte_hack)i;
4619 /* Put the attr/char */
4620 Term_draw(x, y, a, c);
4625 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4636 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4637 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4640 #define IM_FLAG_STR _("*", "* ")
4641 #define HAS_FLAG_STR _("+", "+ ")
4642 #define NO_FLAG_STR _("・", ". ")
4644 #define print_im_or_res_flag(IM, RES) \
4646 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4647 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4650 #define print_flag(TR) \
4652 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4656 /* XTRA HACK RESLIST */
4657 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4659 GAME_TEXT o_name[MAX_NLEN];
4660 BIT_FLAGS flgs[TR_FLAG_SIZE];
4662 if (!o_ptr->k_idx) return;
4663 if (o_ptr->tval != tval) return;
4665 /* Identified items only */
4666 if (!object_is_known(o_ptr)) return;
4669 * HACK:Ring of Lordly protection and Dragon equipment
4670 * have random resistances.
4672 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4673 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4674 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4675 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4676 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4677 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4678 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4679 || object_is_artifact(o_ptr))
4682 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4684 while (o_name[i] && (i < 26))
4687 if (iskanji(o_name[i])) i++;
4696 o_name[i] = ' '; i++;
4701 fprintf(fff, "%s %s", where, o_name);
4703 if (!(o_ptr->ident & (IDENT_MENTAL)))
4705 fputs(_("-------不明--------------- -------不明---------\n",
4706 "-------unknown------------ -------unknown------\n"), fff);
4710 object_flags_known(o_ptr, flgs);
4712 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4713 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4714 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4715 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4716 print_flag(TR_RES_POIS);
4717 print_flag(TR_RES_LITE);
4718 print_flag(TR_RES_DARK);
4719 print_flag(TR_RES_SHARDS);
4720 print_flag(TR_RES_SOUND);
4721 print_flag(TR_RES_NETHER);
4722 print_flag(TR_RES_NEXUS);
4723 print_flag(TR_RES_CHAOS);
4724 print_flag(TR_RES_DISEN);
4728 print_flag(TR_RES_BLIND);
4729 print_flag(TR_RES_FEAR);
4730 print_flag(TR_RES_CONF);
4731 print_flag(TR_FREE_ACT);
4732 print_flag(TR_SEE_INVIS);
4733 print_flag(TR_HOLD_EXP);
4734 print_flag(TR_TELEPATHY);
4735 print_flag(TR_SLOW_DIGEST);
4736 print_flag(TR_REGEN);
4737 print_flag(TR_LEVITATION);
4745 fprintf(fff, "%s\n", inven_res_label);
4751 * Display *ID* ed weapons/armors's resistances
4753 static void do_cmd_knowledge_inven(void)
4756 GAME_TEXT file_name[1024];
4758 OBJECT_TYPE_VALUE tval;
4764 /* Open a new file */
4765 fff = my_fopen_temp(file_name, 1024);
4768 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4772 fprintf(fff, "%s\n", inven_res_label);
4774 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4778 for (; j < 9; j++) fputc('\n', fff);
4780 fprintf(fff, "%s\n", inven_res_label);
4782 strcpy(where, _("装", "E "));
4783 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4785 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4787 strcpy(where, _("持", "I "));
4788 for (i = 0; i < INVEN_PACK; i++)
4790 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4793 st_ptr = &town_info[1].store[STORE_HOME];
4794 strcpy(where, _("家", "H "));
4795 for (i = 0; i < st_ptr->stock_num; i++)
4797 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4802 /* Display the file contents */
4803 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4808 void do_cmd_save_screen_html_aux(char *filename, int message)
4813 TERM_COLOR a = 0, old_a = 0;
4827 concptr html_head[] = {
4828 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4832 concptr html_foot[] = {
4834 "</body>\n</html>\n",
4840 Term_get_size(&wid, &hgt);
4842 /* File type is "TEXT" */
4843 FILE_TYPE(FILE_TYPE_TEXT);
4845 /* Append to the file */
4846 fff = my_fopen(filename, "w");
4850 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4856 if (message) screen_save();
4858 /* Build the filename */
4859 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4860 tmpfff = my_fopen(buf, "r");
4862 for (i = 0; html_head[i]; i++)
4863 fputs(html_head[i], fff);
4867 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4869 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4873 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4875 fprintf(fff, "%s\n", buf);
4880 /* Dump the screen */
4881 for (y = 0; y < hgt; y++)
4888 for (x = 0; x < wid - 1; x++)
4892 /* Get the attr/char */
4893 (void)(Term_what(x, y, &a, &c));
4897 case '&': cc = "&"; break;
4898 case '<': cc = "<"; break;
4899 case '>': cc = ">"; break;
4901 case 0x1f: c = '.'; break;
4902 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4907 if ((y == 0 && x == 0) || a != old_a) {
4908 rv = angband_color_table[a][1];
4909 gv = angband_color_table[a][2];
4910 bv = angband_color_table[a][3];
4911 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4912 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4916 fprintf(fff, "%s", cc);
4918 fprintf(fff, "%c", c);
4921 fprintf(fff, "</font>");
4924 for (i = 0; html_foot[i]; i++)
4925 fputs(html_foot[i], fff);
4930 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4932 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4936 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4938 fprintf(fff, "%s\n", buf);
4949 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4957 * Hack -- save a screen dump to a file
4959 static void do_cmd_save_screen_html(void)
4961 char buf[1024], tmp[256] = "screen.html";
4963 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4966 /* Build the filename */
4967 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4971 do_cmd_save_screen_html_aux(buf, 1);
4976 * Redefinable "save_screen" action
4978 void (*screendump_aux)(void) = NULL;
4982 * Hack -- save a screen dump to a file
4984 void do_cmd_save_screen(void)
4986 bool old_use_graphics = use_graphics;
4987 bool html_dump = FALSE;
4991 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4995 if (c == 'Y' || c == 'y')
4997 else if (c == 'H' || c == 'h')
5009 Term_get_size(&wid, &hgt);
5011 if (old_use_graphics)
5013 use_graphics = FALSE;
5015 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5021 do_cmd_save_screen_html();
5025 /* Do we use a special screendump function ? */
5026 else if (screendump_aux)
5028 /* Dump the screen to a graphics file */
5029 (*screendump_aux)();
5031 else /* Dump the screen as text */
5035 SYMBOL_CODE c = ' ';
5039 /* Build the filename */
5040 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5042 /* File type is "TEXT" */
5043 FILE_TYPE(FILE_TYPE_TEXT);
5045 /* Append to the file */
5046 fff = my_fopen(buf, "w");
5050 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5058 /* Dump the screen */
5059 for (y = 0; y < hgt; y++)
5062 for (x = 0; x < wid - 1; x++)
5064 /* Get the attr/char */
5065 (void)(Term_what(x, y, &a, &c));
5075 fprintf(fff, "%s\n", buf);
5082 /* Dump the screen */
5083 for (y = 0; y < hgt; y++)
5086 for (x = 0; x < wid - 1; x++)
5088 /* Get the attr/char */
5089 (void)(Term_what(x, y, &a, &c));
5092 buf[x] = hack[a&0x0F];
5099 fprintf(fff, "%s\n", buf);
5106 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5111 if (old_use_graphics)
5113 use_graphics = TRUE;
5115 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5121 * Check the status of "artifacts"
5123 static void do_cmd_knowledge_artifacts(void)
5133 GAME_TEXT file_name[1024];
5134 GAME_TEXT base_name[MAX_NLEN];
5138 /* Open a new file */
5139 fff = my_fopen_temp(file_name, 1024);
5142 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5147 /* Allocate the "who" array */
5148 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5150 /* Allocate the "okay" array */
5151 C_MAKE(okay, max_a_idx, bool);
5153 /* Scan the artifacts */
5154 for (k = 0; k < max_a_idx; k++)
5156 artifact_type *a_ptr = &a_info[k];
5161 /* Skip "empty" artifacts */
5162 if (!a_ptr->name) continue;
5164 /* Skip "uncreated" artifacts */
5165 if (!a_ptr->cur_num) continue;
5171 /* Check the dungeon */
5172 for (y = 0; y < current_floor_ptr->height; y++)
5174 for (x = 0; x < current_floor_ptr->width; x++)
5176 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5178 OBJECT_IDX this_o_idx, next_o_idx = 0;
5180 /* Scan all objects in the grid */
5181 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5184 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5185 next_o_idx = o_ptr->next_o_idx;
5187 /* Ignore non-artifacts */
5188 if (!object_is_fixed_artifact(o_ptr)) continue;
5190 /* Ignore known items */
5191 if (object_is_known(o_ptr)) continue;
5193 /* Note the artifact */
5194 okay[o_ptr->name1] = FALSE;
5199 /* Check the p_ptr->inventory_list and equipment */
5200 for (i = 0; i < INVEN_TOTAL; i++)
5202 object_type *o_ptr = &p_ptr->inventory_list[i];
5204 /* Ignore non-objects */
5205 if (!o_ptr->k_idx) continue;
5207 /* Ignore non-artifacts */
5208 if (!object_is_fixed_artifact(o_ptr)) continue;
5210 /* Ignore known items */
5211 if (object_is_known(o_ptr)) continue;
5213 /* Note the artifact */
5214 okay[o_ptr->name1] = FALSE;
5217 for (k = 0; k < max_a_idx; k++)
5219 if (okay[k]) who[n++] = k;
5222 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5224 /* Scan the artifacts */
5225 for (k = 0; k < n; k++)
5227 artifact_type *a_ptr = &a_info[who[k]];
5228 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5230 /* Obtain the base object type */
5231 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5240 /* Create fake object */
5241 object_prep(q_ptr, z);
5243 /* Make it an artifact */
5244 q_ptr->name1 = (byte)who[k];
5246 /* Display as if known */
5247 q_ptr->ident |= IDENT_STORE;
5249 /* Describe the artifact */
5250 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5253 /* Hack -- Build the artifact name */
5254 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5257 /* Free the "who" array */
5258 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5260 /* Free the "okay" array */
5261 C_KILL(okay, max_a_idx, bool);
5264 /* Display the file contents */
5265 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5271 * Display known uniques
5272 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5274 static void do_cmd_knowledge_uniques(void)
5283 GAME_TEXT file_name[1024];
5286 int n_alive_surface = 0;
5287 int n_alive_over100 = 0;
5288 int n_alive_total = 0;
5291 for (i = 0; i < 10; i++) n_alive[i] = 0;
5293 /* Open a new file */
5294 fff = my_fopen_temp(file_name, 1024);
5298 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5303 /* Allocate the "who" array */
5304 C_MAKE(who, max_r_idx, MONRACE_IDX);
5306 /* Scan the monsters */
5307 for (i = 1; i < max_r_idx; i++)
5309 monster_race *r_ptr = &r_info[i];
5312 if (!r_ptr->name) continue;
5314 /* Require unique monsters */
5315 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5317 /* Only display "known" uniques */
5318 if (!cheat_know && !r_ptr->r_sights) continue;
5320 /* Only print rarity <= 100 uniques */
5321 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5323 /* Only "alive" uniques */
5324 if (r_ptr->max_num == 0) continue;
5328 lev = (r_ptr->level - 1) / 10;
5332 if (max_lev < lev) max_lev = lev;
5334 else n_alive_over100++;
5336 else n_alive_surface++;
5338 /* Collect "appropriate" monsters */
5342 /* Sort the array by dungeon depth of monsters */
5343 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5345 if (n_alive_surface)
5347 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5348 n_alive_total += n_alive_surface;
5350 for (i = 0; i <= max_lev; i++)
5352 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5353 n_alive_total += n_alive[i];
5355 if (n_alive_over100)
5357 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5358 n_alive_total += n_alive_over100;
5363 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5364 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5368 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5371 /* Scan the monster races */
5372 for (k = 0; k < n; k++)
5374 monster_race *r_ptr = &r_info[who[k]];
5376 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5379 /* Free the "who" array */
5380 C_KILL(who, max_r_idx, s16b);
5383 /* Display the file contents */
5384 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5390 * Display weapon-exp
5392 static void do_cmd_knowledge_weapon_exp(void)
5400 GAME_TEXT file_name[1024];
5403 /* Open a new file */
5404 fff = my_fopen_temp(file_name, 1024);
5406 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5411 for (i = 0; i < 5; i++)
5413 for (num = 0; num < 64; num++)
5415 for (j = 0; j < max_k_idx; j++)
5417 object_kind *k_ptr = &k_info[j];
5419 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5421 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5423 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5425 fprintf(fff, "%-25s ", tmp);
5426 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5427 else fprintf(fff, " ");
5428 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5429 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5438 /* Display the file contents */
5439 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5445 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5449 static void do_cmd_knowledge_spell_exp(void)
5456 const magic_type *s_ptr;
5458 GAME_TEXT file_name[1024];
5460 /* Open a new file */
5461 fff = my_fopen_temp(file_name, 1024);
5463 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5468 if (p_ptr->realm1 != REALM_NONE)
5470 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5471 for (i = 0; i < 32; i++)
5473 if (!is_magic(p_ptr->realm1))
5475 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5479 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5481 if (s_ptr->slevel >= 99) continue;
5482 spell_exp = p_ptr->spell_exp[i];
5483 exp_level = spell_exp_level(spell_exp);
5484 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5485 if (p_ptr->realm1 == REALM_HISSATSU)
5486 fprintf(fff, "[--]");
5489 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5490 else fprintf(fff, " ");
5491 fprintf(fff, "%s", exp_level_str[exp_level]);
5493 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5498 if (p_ptr->realm2 != REALM_NONE)
5500 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5501 for (i = 0; i < 32; i++)
5503 if (!is_magic(p_ptr->realm1))
5505 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5509 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5511 if (s_ptr->slevel >= 99) continue;
5513 spell_exp = p_ptr->spell_exp[i + 32];
5514 exp_level = spell_exp_level(spell_exp);
5515 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5516 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5517 else fprintf(fff, " ");
5518 fprintf(fff, "%s", exp_level_str[exp_level]);
5519 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5525 /* Display the file contents */
5526 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5532 * @brief スキル情報を表示するコマンドのメインルーチン /
5536 static void do_cmd_knowledge_skill_exp(void)
5538 int i = 0, skill_exp;
5542 char file_name[1024];
5543 char skill_name[GINOU_TEMPMAX][20] =
5545 _("マーシャルアーツ", "Martial Arts "),
5546 _("二刀流 ", "Dual Wielding "),
5547 _("乗馬 ", "Riding "),
5551 /* Open a new file */
5552 fff = my_fopen_temp(file_name, 1024);
5554 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5559 for (i = 0; i < GINOU_TEMPMAX; i++)
5561 skill_exp = p_ptr->skill_exp[i];
5562 fprintf(fff, "%-20s ", skill_name[i]);
5563 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5564 else fprintf(fff, " ");
5565 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5566 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5571 /* Display the file contents */
5572 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5578 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5579 * @param Name 変換したい文字列の参照ポインタ
5582 void plural_aux(char *Name)
5584 int NameLen = strlen(Name);
5586 if (my_strstr(Name, "Disembodied hand"))
5588 strcpy(Name, "Disembodied hands that strangled people");
5590 else if (my_strstr(Name, "Colour out of space"))
5592 strcpy(Name, "Colours out of space");
5594 else if (my_strstr(Name, "stairway to hell"))
5596 strcpy(Name, "stairways to hell");
5598 else if (my_strstr(Name, "Dweller on the threshold"))
5600 strcpy(Name, "Dwellers on the threshold");
5602 else if (my_strstr(Name, " of "))
5604 concptr aider = my_strstr(Name, " of ");
5615 if (dummy[i-1] == 's')
5617 strcpy(&(dummy[i]), "es");
5622 strcpy(&(dummy[i]), "s");
5625 strcpy(&(dummy[i+1]), aider);
5626 strcpy(Name, dummy);
5628 else if (my_strstr(Name, "coins"))
5631 strcpy(dummy, "piles of ");
5632 strcat(dummy, Name);
5633 strcpy(Name, dummy);
5636 else if (my_strstr(Name, "Manes"))
5640 else if (streq(&(Name[NameLen - 2]), "ey"))
5642 strcpy(&(Name[NameLen - 2]), "eys");
5644 else if (Name[NameLen - 1] == 'y')
5646 strcpy(&(Name[NameLen - 1]), "ies");
5648 else if (streq(&(Name[NameLen - 4]), "ouse"))
5650 strcpy(&(Name[NameLen - 4]), "ice");
5652 else if (streq(&(Name[NameLen - 2]), "us"))
5654 strcpy(&(Name[NameLen - 2]), "i");
5656 else if (streq(&(Name[NameLen - 6]), "kelman"))
5658 strcpy(&(Name[NameLen - 6]), "kelmen");
5660 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5662 strcpy(&(Name[NameLen - 8]), "wordsmen");
5664 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5666 strcpy(&(Name[NameLen - 7]), "oodsmen");
5668 else if (streq(&(Name[NameLen - 7]), "eastman"))
5670 strcpy(&(Name[NameLen - 7]), "eastmen");
5672 else if (streq(&(Name[NameLen - 8]), "izardman"))
5674 strcpy(&(Name[NameLen - 8]), "izardmen");
5676 else if (streq(&(Name[NameLen - 5]), "geist"))
5678 strcpy(&(Name[NameLen - 5]), "geister");
5680 else if (streq(&(Name[NameLen - 2]), "ex"))
5682 strcpy(&(Name[NameLen - 2]), "ices");
5684 else if (streq(&(Name[NameLen - 2]), "lf"))
5686 strcpy(&(Name[NameLen - 2]), "lves");
5688 else if (suffix(Name, "ch") ||
5689 suffix(Name, "sh") ||
5690 suffix(Name, "nx") ||
5691 suffix(Name, "s") ||
5694 strcpy(&(Name[NameLen]), "es");
5698 strcpy(&(Name[NameLen]), "s");
5703 * @brief 現在のペットを表示するコマンドのメインルーチン /
5704 * Display current pets
5707 static void do_cmd_knowledge_pets(void)
5711 monster_type *m_ptr;
5712 GAME_TEXT pet_name[MAX_NLEN];
5714 int show_upkeep = 0;
5715 GAME_TEXT file_name[1024];
5718 /* Open a new file */
5719 fff = my_fopen_temp(file_name, 1024);
5721 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5726 /* Process the monsters (backwards) */
5727 for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
5729 /* Access the monster */
5730 m_ptr = ¤t_floor_ptr->m_list[i];
5732 /* Ignore "dead" monsters */
5733 if (!monster_is_valid(m_ptr)) continue;
5735 /* Calculate "upkeep" for pets */
5739 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5740 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5744 show_upkeep = calculate_upkeep();
5746 fprintf(fff, "----------------------------------------------\n");
5748 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5750 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5752 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5757 /* Display the file contents */
5758 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5764 * @brief 現在のペットを表示するコマンドのメインルーチン /
5767 * @note the player ghosts are ignored.
5769 static void do_cmd_knowledge_kill_count(void)
5776 GAME_TEXT file_name[1024];
5781 /* Open a new file */
5782 fff = my_fopen_temp(file_name, 1024);
5785 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5790 /* Allocate the "who" array */
5791 C_MAKE(who, max_r_idx, MONRACE_IDX);
5794 /* Monsters slain */
5797 for (kk = 1; kk < max_r_idx; kk++)
5799 monster_race *r_ptr = &r_info[kk];
5801 if (r_ptr->flags1 & (RF1_UNIQUE))
5803 bool dead = (r_ptr->max_num == 0);
5812 MONSTER_NUMBER This = r_ptr->r_pkills;
5822 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5825 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5827 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5833 /* Scan the monsters */
5834 for (i = 1; i < max_r_idx; i++)
5836 monster_race *r_ptr = &r_info[i];
5838 /* Use that monster */
5839 if (r_ptr->name) who[n++] = i;
5842 /* Sort the array by dungeon depth of monsters */
5843 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5845 /* Scan the monster races */
5846 for (k = 0; k < n; k++)
5848 monster_race *r_ptr = &r_info[who[k]];
5850 if (r_ptr->flags1 & (RF1_UNIQUE))
5852 bool dead = (r_ptr->max_num == 0);
5856 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5862 MONSTER_NUMBER This = r_ptr->r_pkills;
5867 /* p,tは人と数える by ita */
5868 if (my_strchr("pt", r_ptr->d_char))
5869 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5871 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5875 if (my_strstr(r_name + r_ptr->name, "coins"))
5877 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5881 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5887 strcpy(ToPlural, (r_name + r_ptr->name));
5888 plural_aux(ToPlural);
5889 fprintf(fff, " %d %s\n", This, ToPlural);
5899 fprintf(fff,"----------------------------------------------\n");
5901 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5903 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5907 /* Free the "who" array */
5908 C_KILL(who, max_r_idx, s16b);
5911 /* Display the file contents */
5912 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5918 * @brief モンスター情報リスト中のグループを表示する /
5919 * Display the object groups.
5923 * @param per_page リストの表示行
5924 * @param grp_idx グループのID配列
5925 * @param group_text グループ名の文字列配列
5926 * @param grp_cur 現在の選択ID
5927 * @param grp_top 現在の選択リスト最上部ID
5930 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)
5934 /* Display lines until done */
5935 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5937 /* Get the group index */
5938 int grp = grp_idx[grp_top + i];
5940 /* Choose a color */
5941 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5943 /* Erase the entire line */
5944 Term_erase(col, row + i, wid);
5946 /* Display the group label */
5947 c_put_str(attr, group_text[grp], row + i, col);
5953 * Move the cursor in a browser window
5955 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5956 IDX *list_cur, int list_cnt)
5961 IDX list = *list_cur;
5963 /* Extract direction */
5966 /* Hack -- scroll up full screen */
5971 /* Hack -- scroll down full screen */
5976 d = get_keymap_dir(ch);
5981 /* Diagonals - hack */
5982 if ((ddx[d] > 0) && ddy[d])
5987 Term_get_size(&wid, &hgt);
5989 browser_rows = hgt - 8;
5991 /* Browse group list */
5996 /* Move up or down */
5997 grp += ddy[d] * (browser_rows - 1);
6000 if (grp >= grp_cnt) grp = grp_cnt - 1;
6001 if (grp < 0) grp = 0;
6002 if (grp != old_grp) list = 0;
6005 /* Browse sub-list list */
6008 /* Move up or down */
6009 list += ddy[d] * browser_rows;
6012 if (list >= list_cnt) list = list_cnt - 1;
6013 if (list < 0) list = 0;
6025 if (col < 0) col = 0;
6026 if (col > 1) col = 1;
6033 /* Browse group list */
6038 /* Move up or down */
6042 if (grp >= grp_cnt) grp = grp_cnt - 1;
6043 if (grp < 0) grp = 0;
6044 if (grp != old_grp) list = 0;
6047 /* Browse sub-list list */
6050 /* Move up or down */
6051 list += (IDX)ddy[d];
6054 if (list >= list_cnt) list = list_cnt - 1;
6055 if (list < 0) list = 0;
6066 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6070 /* Clear the display lines */
6071 for (i = 0; i < height; i++)
6073 Term_erase(col, row + i, width);
6076 /* Bigtile mode uses double width */
6077 if (use_bigtile) width /= 2;
6079 /* Display lines until done */
6080 for (i = 0; i < height; i++)
6082 /* Display columns until done */
6083 for (j = 0; j < width; j++)
6087 TERM_LEN x = col + j;
6088 TERM_LEN y = row + i;
6090 /* Bigtile mode uses double width */
6091 if (use_bigtile) x += j;
6096 /* Ignore illegal characters */
6097 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6098 (!use_graphics && ic > 0x7f))
6104 /* Force correct code for both ASCII character and tile */
6105 if (c & 0x80) a |= 0x80;
6107 /* Display symbol */
6108 Term_queue_bigchar(x, y, a, c, 0, 0);
6115 * Place the cursor at the collect position for visual mode
6117 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6119 int i = (a & 0x7f) - attr_top;
6120 int j = c - char_left;
6122 TERM_LEN x = col + j;
6123 TERM_LEN y = row + i;
6125 /* Bigtile mode uses double width */
6126 if (use_bigtile) x += j;
6128 /* Place the cursor */
6134 * Clipboard variables for copy&paste in visual mode
6136 static TERM_COLOR attr_idx = 0;
6137 static SYMBOL_CODE char_idx = 0;
6139 /* Hack -- for feature lighting */
6140 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6141 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6144 * Do visual mode command -- Change symbols
6146 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6147 int height, int width,
6148 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6149 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6151 static TERM_COLOR attr_old = 0;
6152 static SYMBOL_CODE char_old = 0;
6157 if (*visual_list_ptr)
6160 *cur_attr_ptr = attr_old;
6161 *cur_char_ptr = char_old;
6162 *visual_list_ptr = FALSE;
6170 if (*visual_list_ptr)
6173 *visual_list_ptr = FALSE;
6174 *need_redraw = TRUE;
6182 if (!*visual_list_ptr)
6184 *visual_list_ptr = TRUE;
6186 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6187 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6189 attr_old = *cur_attr_ptr;
6190 char_old = *cur_char_ptr;
6201 /* Set the visual */
6202 attr_idx = *cur_attr_ptr;
6203 char_idx = *cur_char_ptr;
6205 /* Hack -- for feature lighting */
6206 for (i = 0; i < F_LIT_MAX; i++)
6208 attr_idx_feat[i] = 0;
6209 char_idx_feat[i] = 0;
6216 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6219 *cur_attr_ptr = attr_idx;
6220 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6221 if (!*visual_list_ptr) *need_redraw = TRUE;
6227 *cur_char_ptr = char_idx;
6228 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6229 if (!*visual_list_ptr) *need_redraw = TRUE;
6235 if (*visual_list_ptr)
6238 int d = get_keymap_dir(ch);
6239 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6240 SYMBOL_CODE c = *cur_char_ptr;
6242 if (use_bigtile) eff_width = width / 2;
6243 else eff_width = width;
6245 /* Restrict direction */
6246 if ((a == 0) && (ddy[d] < 0)) d = 0;
6247 if ((c == 0) && (ddx[d] < 0)) d = 0;
6248 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6249 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6251 a += (TERM_COLOR)ddy[d];
6252 c += (SYMBOL_CODE)ddx[d];
6254 /* Force correct code for both ASCII character and tile */
6255 if (c & 0x80) a |= 0x80;
6257 /* Set the visual */
6262 /* Move the frame */
6263 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6264 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6265 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6266 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6272 /* Visual mode command is not used */
6278 * Display the monsters in a group.
6280 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6281 int mon_cur, int mon_top, bool visual_only)
6285 /* Display lines until done */
6286 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6290 /* Get the race index */
6291 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6293 /* Access the race */
6294 monster_race *r_ptr = &r_info[r_idx];
6296 /* Choose a color */
6297 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6299 /* Display the name */
6300 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6302 /* Hack -- visual_list mode */
6305 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6307 if (p_ptr->wizard || visual_only)
6309 c_prt(attr, format("%d", r_idx), row + i, 62);
6312 /* Erase chars before overwritten by the race letter */
6313 Term_erase(69, row + i, 255);
6315 /* Display symbol */
6316 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6321 if (!(r_ptr->flags1 & RF1_UNIQUE))
6322 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6324 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6325 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6329 /* Clear remaining lines */
6330 for (; i < per_page; i++)
6332 Term_erase(col, row + i, 255);
6338 * Display known monsters.
6340 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6344 IDX grp_cur, grp_top, old_grp_cur;
6345 IDX mon_cur, mon_top;
6346 IDX grp_cnt, grp_idx[100];
6354 bool visual_list = FALSE;
6355 TERM_COLOR attr_top = 0;
6363 Term_get_size(&wid, &hgt);
6365 browser_rows = hgt - 8;
6367 /* Allocate the "mon_idx" array */
6368 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6373 if (direct_r_idx < 0)
6375 mode = visual_only ? 0x03 : 0x01;
6377 /* Check every group */
6378 for (i = 0; monster_group_text[i] != NULL; i++)
6380 /* Measure the label */
6381 len = strlen(monster_group_text[i]);
6383 /* Save the maximum length */
6384 if (len > max) max = len;
6386 /* See if any monsters are known */
6387 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6389 /* Build a list of groups with known monsters */
6390 grp_idx[grp_cnt++] = i;
6398 mon_idx[0] = direct_r_idx;
6401 /* Terminate the list */
6404 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6405 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6408 /* Terminate the list */
6409 grp_idx[grp_cnt] = -1;
6412 grp_cur = grp_top = 0;
6413 mon_cur = mon_top = 0;
6418 mode = visual_only ? 0x02 : 0x00;
6423 monster_race *r_ptr;
6428 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6429 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6430 prt(_("名前", "Name"), 4, max + 3);
6431 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6432 prt(_("文字", "Sym"), 4, 67);
6433 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6435 for (i = 0; i < 78; i++)
6437 Term_putch(i, 5, TERM_WHITE, '=');
6440 if (direct_r_idx < 0)
6442 for (i = 0; i < browser_rows; i++)
6444 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6451 if (direct_r_idx < 0)
6453 /* Scroll group list */
6454 if (grp_cur < grp_top) grp_top = grp_cur;
6455 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6457 /* Display a list of monster groups */
6458 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6460 if (old_grp_cur != grp_cur)
6462 old_grp_cur = grp_cur;
6464 /* Get a list of monsters in the current group */
6465 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6468 /* Scroll monster list */
6469 while (mon_cur < mon_top)
6470 mon_top = MAX(0, mon_top - browser_rows/2);
6471 while (mon_cur >= mon_top + browser_rows)
6472 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6477 /* Display a list of monsters in the current group */
6478 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6484 /* Display a monster name */
6485 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6487 /* Display visual list below first monster */
6488 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6492 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6493 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6494 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6495 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6498 /* Get the current monster */
6499 r_ptr = &r_info[mon_idx[mon_cur]];
6503 /* Mega Hack -- track this monster race */
6504 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6510 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6514 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6518 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6523 /* Do visual mode command if needed */
6524 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))
6526 if (direct_r_idx >= 0)
6551 /* Recall on screen */
6552 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6554 screen_roff(mon_idx[mon_cur], 0);
6565 /* Move the cursor */
6566 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6573 /* Free the "mon_idx" array */
6574 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6579 * Display the objects in a group.
6581 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6582 int object_cur, int object_top, bool visual_only)
6586 /* Display lines until done */
6587 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6589 GAME_TEXT o_name[MAX_NLEN];
6592 object_kind *flavor_k_ptr;
6594 /* Get the object index */
6595 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6597 /* Access the object */
6598 object_kind *k_ptr = &k_info[k_idx];
6600 /* Choose a color */
6601 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6602 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6605 if (!visual_only && k_ptr->flavor)
6607 /* Appearance of this object is shuffled */
6608 flavor_k_ptr = &k_info[k_ptr->flavor];
6612 /* Appearance of this object is very normal */
6613 flavor_k_ptr = k_ptr;
6618 attr = ((i + object_top == object_cur) ? cursor : attr);
6620 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6623 strip_name(o_name, k_idx);
6628 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6631 /* Display the name */
6632 c_prt(attr, o_name, row + i, col);
6634 /* Hack -- visual_list mode */
6637 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);
6639 if (p_ptr->wizard || visual_only)
6641 c_prt(attr, format("%d", k_idx), row + i, 70);
6644 a = flavor_k_ptr->x_attr;
6645 c = flavor_k_ptr->x_char;
6647 /* Display symbol */
6648 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6651 /* Clear remaining lines */
6652 for (; i < per_page; i++)
6654 Term_erase(col, row + i, 255);
6659 * Describe fake object
6661 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6664 object_type object_type_body;
6665 o_ptr = &object_type_body;
6667 object_prep(o_ptr, k_idx);
6669 /* It's fully know */
6670 o_ptr->ident |= IDENT_KNOWN;
6672 /* Track the object */
6673 /* object_actual_track(o_ptr); */
6675 /* Hack - mark as fake */
6676 /* term_obj_real = FALSE; */
6679 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6681 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6689 * Display known objects
6691 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6695 IDX grp_cur, grp_top, old_grp_cur;
6696 IDX object_old, object_cur, object_top;
6700 OBJECT_IDX *object_idx;
6706 bool visual_list = FALSE;
6707 TERM_COLOR attr_top = 0;
6715 Term_get_size(&wid, &hgt);
6717 browser_rows = hgt - 8;
6719 /* Allocate the "object_idx" array */
6720 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6725 if (direct_k_idx < 0)
6727 mode = visual_only ? 0x03 : 0x01;
6729 /* Check every group */
6730 for (i = 0; object_group_text[i] != NULL; i++)
6732 /* Measure the label */
6733 len = strlen(object_group_text[i]);
6735 /* Save the maximum length */
6736 if (len > max) max = len;
6738 /* See if any monsters are known */
6739 if (collect_objects(i, object_idx, mode))
6741 /* Build a list of groups with known monsters */
6742 grp_idx[grp_cnt++] = i;
6751 object_kind *k_ptr = &k_info[direct_k_idx];
6752 object_kind *flavor_k_ptr;
6754 if (!visual_only && k_ptr->flavor)
6756 /* Appearance of this object is shuffled */
6757 flavor_k_ptr = &k_info[k_ptr->flavor];
6761 /* Appearance of this object is very normal */
6762 flavor_k_ptr = k_ptr;
6765 object_idx[0] = direct_k_idx;
6766 object_old = direct_k_idx;
6769 /* Terminate the list */
6772 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6773 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6776 /* Terminate the list */
6777 grp_idx[grp_cnt] = -1;
6780 grp_cur = grp_top = 0;
6781 object_cur = object_top = 0;
6786 mode = visual_only ? 0x02 : 0x00;
6791 object_kind *k_ptr, *flavor_k_ptr;
6798 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6799 if (direct_k_idx < 0) prt("グループ", 4, 0);
6800 prt("名前", 4, max + 3);
6801 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6804 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6805 if (direct_k_idx < 0) prt("Group", 4, 0);
6806 prt("Name", 4, max + 3);
6807 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6811 for (i = 0; i < 78; i++)
6813 Term_putch(i, 5, TERM_WHITE, '=');
6816 if (direct_k_idx < 0)
6818 for (i = 0; i < browser_rows; i++)
6820 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6827 if (direct_k_idx < 0)
6829 /* Scroll group list */
6830 if (grp_cur < grp_top) grp_top = grp_cur;
6831 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6833 /* Display a list of object groups */
6834 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6836 if (old_grp_cur != grp_cur)
6838 old_grp_cur = grp_cur;
6840 /* Get a list of objects in the current group */
6841 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6844 /* Scroll object list */
6845 while (object_cur < object_top)
6846 object_top = MAX(0, object_top - browser_rows/2);
6847 while (object_cur >= object_top + browser_rows)
6848 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6853 /* Display a list of objects in the current group */
6854 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6858 object_top = object_cur;
6860 /* Display a list of objects in the current group */
6861 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6863 /* Display visual list below first object */
6864 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6867 /* Get the current object */
6868 k_ptr = &k_info[object_idx[object_cur]];
6870 if (!visual_only && k_ptr->flavor)
6872 /* Appearance of this object is shuffled */
6873 flavor_k_ptr = &k_info[k_ptr->flavor];
6877 /* Appearance of this object is very normal */
6878 flavor_k_ptr = k_ptr;
6883 prt(format("<方向>%s%s%s, ESC",
6884 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6885 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6886 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6889 prt(format("<dir>%s%s%s, ESC",
6890 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6891 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6892 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6898 /* Mega Hack -- track this object */
6899 if (object_cnt) object_kind_track(object_idx[object_cur]);
6901 /* The "current" object changed */
6902 if (object_old != object_idx[object_cur])
6906 /* Remember the "current" object */
6907 object_old = object_idx[object_cur];
6913 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6917 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6921 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6926 /* Do visual mode command if needed */
6927 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))
6929 if (direct_k_idx >= 0)
6954 /* Recall on screen */
6955 if (!visual_list && !visual_only && (grp_cnt > 0))
6957 desc_obj_fake(object_idx[object_cur]);
6965 /* Move the cursor */
6966 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6972 /* Free the "object_idx" array */
6973 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6978 * Display the features in a group.
6980 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6981 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6983 int lit_col[F_LIT_MAX], i, j;
6984 int f_idx_col = use_bigtile ? 62 : 64;
6986 /* Correct columns 1 and 4 */
6987 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6988 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6989 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6991 /* Display lines until done */
6992 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6995 FEAT_IDX f_idx = feat_idx[feat_top + i];
6996 feature_type *f_ptr = &f_info[f_idx];
6997 int row_i = row + i;
6999 /* Choose a color */
7000 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7002 /* Display the name */
7003 c_prt(attr, f_name + f_ptr->name, row_i, col);
7005 /* Hack -- visual_list mode */
7008 /* Display lighting level */
7009 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7011 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));
7013 if (p_ptr->wizard || visual_only)
7015 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7018 /* Display symbol */
7019 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);
7021 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7022 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7024 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7026 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7028 /* Mega-hack -- Use non-standard colour */
7029 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7031 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7035 /* Clear remaining lines */
7036 for (; i < per_page; i++)
7038 Term_erase(col, row + i, 255);
7044 * Interact with feature visuals.
7046 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7050 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7051 FEAT_IDX feat_cur, feat_top;
7053 FEAT_IDX grp_idx[100];
7057 TERM_LEN column = 0;
7061 bool visual_list = FALSE;
7062 TERM_COLOR attr_top = 0;
7065 TERM_LEN browser_rows;
7068 TERM_COLOR attr_old[F_LIT_MAX];
7069 SYMBOL_CODE char_old[F_LIT_MAX];
7070 TERM_COLOR *cur_attr_ptr;
7071 SYMBOL_CODE *cur_char_ptr;
7073 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7074 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7076 Term_get_size(&wid, &hgt);
7078 browser_rows = hgt - 8;
7080 /* Allocate the "feat_idx" array */
7081 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7086 if (direct_f_idx < 0)
7088 /* Check every group */
7089 for (i = 0; feature_group_text[i] != NULL; i++)
7091 /* Measure the label */
7092 len = strlen(feature_group_text[i]);
7094 /* Save the maximum length */
7095 if (len > max) max = len;
7097 /* See if any features are known */
7098 if (collect_features(i, feat_idx, 0x01))
7100 /* Build a list of groups with known features */
7101 grp_idx[grp_cnt++] = i;
7109 feature_type *f_ptr = &f_info[direct_f_idx];
7111 feat_idx[0] = direct_f_idx;
7114 /* Terminate the list */
7117 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7118 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7120 for (i = 0; i < F_LIT_MAX; i++)
7122 attr_old[i] = f_ptr->x_attr[i];
7123 char_old[i] = f_ptr->x_char[i];
7127 /* Terminate the list */
7128 grp_idx[grp_cnt] = -1;
7131 grp_cur = grp_top = 0;
7132 feat_cur = feat_top = 0;
7140 feature_type *f_ptr;
7146 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7147 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7148 prt(_("名前", "Name"), 4, max + 3);
7151 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7152 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7156 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7157 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7160 for (i = 0; i < 78; i++)
7162 Term_putch(i, 5, TERM_WHITE, '=');
7165 if (direct_f_idx < 0)
7167 for (i = 0; i < browser_rows; i++)
7169 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7176 if (direct_f_idx < 0)
7178 /* Scroll group list */
7179 if (grp_cur < grp_top) grp_top = grp_cur;
7180 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7182 /* Display a list of feature groups */
7183 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7185 if (old_grp_cur != grp_cur)
7187 old_grp_cur = grp_cur;
7189 /* Get a list of features in the current group */
7190 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7193 /* Scroll feature list */
7194 while (feat_cur < feat_top)
7195 feat_top = MAX(0, feat_top - browser_rows/2);
7196 while (feat_cur >= feat_top + browser_rows)
7197 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7202 /* Display a list of features in the current group */
7203 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7207 feat_top = feat_cur;
7209 /* Display a list of features in the current group */
7210 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7212 /* Display visual list below first object */
7213 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7217 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7218 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7219 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7222 /* Get the current feature */
7223 f_ptr = &f_info[feat_idx[feat_cur]];
7224 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7225 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7229 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7233 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7237 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7242 if (visual_list && ((ch == 'A') || (ch == 'a')))
7244 int prev_lighting_level = *lighting_level;
7248 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7249 else (*lighting_level)--;
7253 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7254 else (*lighting_level)++;
7257 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7258 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7260 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7261 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7266 else if ((ch == 'D') || (ch == 'd'))
7268 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7269 byte prev_x_char = f_ptr->x_char[*lighting_level];
7271 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7275 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7276 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7278 if (prev_x_char != f_ptr->x_char[*lighting_level])
7279 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7281 else *need_redraw = TRUE;
7286 /* Do visual mode command if needed */
7287 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))
7291 /* Restore previous visual settings */
7293 for (i = 0; i < F_LIT_MAX; i++)
7295 f_ptr->x_attr[i] = attr_old[i];
7296 f_ptr->x_char[i] = char_old[i];
7303 if (direct_f_idx >= 0) flag = TRUE;
7304 else *lighting_level = F_LIT_STANDARD;
7307 /* Preserve current visual settings */
7310 for (i = 0; i < F_LIT_MAX; i++)
7312 attr_old[i] = f_ptr->x_attr[i];
7313 char_old[i] = f_ptr->x_char[i];
7315 *lighting_level = F_LIT_STANDARD;
7322 for (i = 0; i < F_LIT_MAX; i++)
7324 attr_idx_feat[i] = f_ptr->x_attr[i];
7325 char_idx_feat[i] = f_ptr->x_char[i];
7334 /* Allow TERM_DARK text */
7335 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7337 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7338 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7356 /* Move the cursor */
7357 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7363 /* Free the "feat_idx" array */
7364 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7369 * List wanted monsters
7371 static void do_cmd_knowledge_kubi(void)
7376 GAME_TEXT file_name[1024];
7379 /* Open a new file */
7380 fff = my_fopen_temp(file_name, 1024);
7382 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7389 bool listed = FALSE;
7391 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7392 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7394 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7395 fprintf(fff, "----------------------------------------------\n");
7397 for (i = 0; i < MAX_KUBI; i++)
7399 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7401 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7409 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7414 /* Display the file contents */
7415 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7420 * List virtues & status
7422 static void do_cmd_knowledge_virtues(void)
7425 GAME_TEXT file_name[1024];
7427 /* Open a new file */
7428 fff = my_fopen_temp(file_name, 1024);
7430 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7437 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7442 /* Display the file contents */
7443 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7450 static void do_cmd_knowledge_dungeon(void)
7454 GAME_TEXT file_name[1024];
7457 /* Open a new file */
7458 fff = my_fopen_temp(file_name, 1024);
7460 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7467 for (i = 1; i < max_d_idx; i++)
7471 if (!d_info[i].maxdepth) continue;
7472 if (!max_dlv[i]) continue;
7473 if (d_info[i].final_guardian)
7475 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7477 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7479 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7484 /* Display the file contents */
7485 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7490 * List virtues & status
7493 static void do_cmd_knowledge_stat(void)
7497 GAME_TEXT file_name[1024];
7500 /* Open a new file */
7501 fff = my_fopen_temp(file_name, 1024);
7503 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7510 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7511 (2 * p_ptr->hitdie +
7512 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7514 if (p_ptr->knowledge & KNOW_HPRATE)
7515 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7516 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7518 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7519 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7521 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);
7522 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7529 /* Display the file contents */
7530 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7536 * Print all active quests
7538 static void do_cmd_knowledge_quests_current(FILE *fff)
7541 char rand_tmp_str[120] = "\0";
7542 GAME_TEXT name[MAX_NLEN];
7543 monster_race *r_ptr;
7545 int rand_level = 100;
7548 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7550 for (i = 1; i < max_q_idx; i++)
7552 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7553 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7554 (quest[i].status == QUEST_STATUS_COMPLETED))
7556 /* Set the quest number temporary */
7557 QUEST_IDX old_quest = p_ptr->inside_quest;
7560 /* Clear the text */
7561 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7562 quest_text_line = 0;
7564 p_ptr->inside_quest = i;
7566 /* Get the quest text */
7567 init_flags = INIT_SHOW_TEXT;
7569 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7571 /* Reset the old quest number */
7572 p_ptr->inside_quest = old_quest;
7574 /* No info from "silent" quests */
7575 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7579 if (quest[i].type != QUEST_TYPE_RANDOM)
7581 char note[80] = "\0";
7583 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7585 switch (quest[i].type)
7587 case QUEST_TYPE_KILL_LEVEL:
7588 case QUEST_TYPE_KILL_ANY_LEVEL:
7589 r_ptr = &r_info[quest[i].r_idx];
7590 strcpy(name, r_name + r_ptr->name);
7591 if (quest[i].max_num > 1)
7594 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7595 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7598 sprintf(note," - kill %d %s, have killed %d.",
7599 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7603 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7606 case QUEST_TYPE_FIND_ARTIFACT:
7609 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7611 object_type *q_ptr = &forge;
7612 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7613 object_prep(q_ptr, k_idx);
7614 q_ptr->name1 = quest[i].k_idx;
7615 q_ptr->ident = IDENT_STORE;
7616 object_desc(name, q_ptr, OD_NAME_ONLY);
7618 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7620 case QUEST_TYPE_FIND_EXIT:
7621 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7624 case QUEST_TYPE_KILL_NUMBER:
7626 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7627 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7629 sprintf(note," - Kill %d monsters, have killed %d.",
7630 (int)quest[i].max_num, (int)quest[i].cur_num);
7634 case QUEST_TYPE_KILL_ALL:
7635 case QUEST_TYPE_TOWER:
7636 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7641 /* Print the quest info */
7642 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7643 quest[i].name, (int)quest[i].level, note);
7645 fputs(tmp_str, fff);
7647 if (quest[i].status == QUEST_STATUS_COMPLETED)
7649 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7650 fputs(tmp_str, fff);
7656 while (quest_text[j][0] && j < 10)
7658 fprintf(fff, " %s\n", quest_text[j]);
7663 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7666 rand_level = quest[i].level;
7668 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7670 /* Print the quest info */
7671 r_ptr = &r_info[quest[i].r_idx];
7672 strcpy(name, r_name + r_ptr->name);
7674 if (quest[i].max_num > 1)
7677 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7678 quest[i].name, (int)quest[i].level,
7679 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7683 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7684 quest[i].name, (int)quest[i].level,
7685 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7690 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7691 quest[i].name, (int)quest[i].level, name);
7698 /* Print the current random quest */
7699 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7701 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7705 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7708 char playtime_str[16];
7709 quest_type* const q_ptr = &quest[q_idx];
7711 if (is_fixed_quest_idx(q_idx))
7713 /* Set the quest number temporary */
7714 IDX old_quest = p_ptr->inside_quest;
7716 p_ptr->inside_quest = q_idx;
7719 init_flags = INIT_NAME_ONLY;
7721 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7723 /* Reset the old quest number */
7724 p_ptr->inside_quest = old_quest;
7726 /* No info from "silent" quests */
7727 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7730 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7731 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7733 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7735 /* Print the quest info */
7736 if (q_ptr->complev == 0)
7739 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7740 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7741 r_name+r_info[q_ptr->r_idx].name,
7742 (int)q_ptr->level, playtime_str);
7747 _(" %-35s (%3d階) - レベル%2d - %s\n",
7748 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7749 r_name+r_info[q_ptr->r_idx].name,
7757 /* Print the quest info */
7759 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7760 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7761 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7764 fputs(tmp_str, fff);
7770 * Print all finished quests
7772 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7775 QUEST_IDX total = 0;
7777 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7778 for (i = 1; i < max_q_idx; i++)
7780 QUEST_IDX q_idx = quest_num[i];
7781 quest_type* const q_ptr = &quest[q_idx];
7783 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7788 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7793 * Print all failed quests
7795 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7798 QUEST_IDX total = 0;
7800 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7801 for (i = 1; i < max_q_idx; i++)
7803 QUEST_IDX q_idx = quest_num[i];
7804 quest_type* const q_ptr = &quest[q_idx];
7806 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7807 do_cmd_knowledge_quests_aux(fff, q_idx))
7812 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7817 * Print all random quests
7819 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7821 GAME_TEXT tmp_str[120];
7823 QUEST_IDX total = 0;
7825 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7826 for (i = 1; i < max_q_idx; i++)
7828 /* No info from "silent" quests */
7829 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7831 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7835 /* Print the quest info */
7836 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7837 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7838 fputs(tmp_str, fff);
7841 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7845 * Print quest status of all active quests
7847 static void do_cmd_knowledge_quests(void)
7850 GAME_TEXT file_name[1024];
7855 /* Open a new file */
7856 fff = my_fopen_temp(file_name, 1024);
7859 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7864 /* Allocate Memory */
7865 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7867 /* Sort by compete level */
7868 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7869 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7871 /* Dump Quest Information */
7872 do_cmd_knowledge_quests_current(fff);
7874 do_cmd_knowledge_quests_completed(fff, quest_num);
7876 do_cmd_knowledge_quests_failed(fff, quest_num);
7880 do_cmd_knowledge_quests_wiz_random(fff);
7884 /* Display the file contents */
7885 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7889 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7896 static void do_cmd_knowledge_home(void)
7901 GAME_TEXT file_name[1024];
7903 GAME_TEXT o_name[MAX_NLEN];
7904 concptr paren = ")";
7906 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7908 /* Open a new file */
7909 fff = my_fopen_temp(file_name, 1024);
7911 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7918 /* Print all homes in the different towns */
7919 st_ptr = &town_info[1].store[STORE_HOME];
7921 /* Home -- if anything there */
7922 if (st_ptr->stock_num)
7927 /* Header with name of the town */
7928 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7930 /* Dump all available items */
7931 for (i = 0; i < st_ptr->stock_num; i++)
7934 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7935 object_desc(o_name, &st_ptr->stock[i], 0);
7936 if (strlen(o_name) <= 80-3)
7938 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7944 for (n = 0, t = o_name; n < 80-3; n++, t++)
7945 if(iskanji(*t)) {t++; n++;}
7946 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7948 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7949 fprintf(fff, " %.77s\n", o_name+n);
7952 object_desc(o_name, &st_ptr->stock[i], 0);
7953 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7958 /* Add an empty line */
7959 fprintf(fff, "\n\n");
7964 /* Display the file contents */
7965 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7971 * Check the status of "autopick"
7973 static void do_cmd_knowledge_autopick(void)
7977 GAME_TEXT file_name[1024];
7979 /* Open a new file */
7980 fff = my_fopen_temp(file_name, 1024);
7984 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7991 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7995 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7996 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7999 for (k = 0; k < max_autopick; k++)
8002 byte act = autopick_list[k].action;
8003 if (act & DONT_AUTOPICK)
8005 tmp = _("放置", "Leave");
8007 else if (act & DO_AUTODESTROY)
8009 tmp = _("破壊", "Destroy");
8011 else if (act & DO_AUTOPICK)
8013 tmp = _("拾う", "Pickup");
8017 tmp = _("確認", "Query");
8020 if (act & DO_DISPLAY)
8021 fprintf(fff, "%11s", format("[%s]", tmp));
8023 fprintf(fff, "%11s", format("(%s)", tmp));
8025 tmp = autopick_line_from_entry(&autopick_list[k]);
8026 fprintf(fff, " %s", tmp);
8031 /* Display the file contents */
8032 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8038 * Interact with "knowledge"
8040 void do_cmd_knowledge(void)
8043 bool need_redraw = FALSE;
8045 /* File type is "TEXT" */
8046 FILE_TYPE(FILE_TYPE_TEXT);
8049 /* Interact until done */
8054 /* Ask for a choice */
8055 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8056 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8058 /* Give some choices */
8062 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8063 prt("(2) 既知のアイテム の一覧", 7, 5);
8064 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8065 prt("(4) 既知のモンスター の一覧", 9, 5);
8066 prt("(5) 倒した敵の数 の一覧", 10, 5);
8067 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8068 prt("(7) 現在のペット の一覧", 12, 5);
8069 prt("(8) 我が家のアイテム の一覧", 13, 5);
8070 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8071 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8075 prt("(a) 自分に関する情報 の一覧", 6, 5);
8076 prt("(b) 突然変異 の一覧", 7, 5);
8077 prt("(c) 武器の経験値 の一覧", 8, 5);
8078 prt("(d) 魔法の経験値 の一覧", 9, 5);
8079 prt("(e) 技能の経験値 の一覧", 10, 5);
8080 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8081 prt("(g) 入ったダンジョン の一覧", 12, 5);
8082 prt("(h) 実行中のクエスト の一覧", 13, 5);
8083 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8088 prt("(1) Display known artifacts", 6, 5);
8089 prt("(2) Display known objects", 7, 5);
8090 prt("(3) Display remaining uniques", 8, 5);
8091 prt("(4) Display known monster", 9, 5);
8092 prt("(5) Display kill count", 10, 5);
8093 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8094 prt("(7) Display current pets", 12, 5);
8095 prt("(8) Display home p_ptr->inventory_list", 13, 5);
8096 prt("(9) Display *identified* equip.", 14, 5);
8097 prt("(0) Display terrain symbols.", 15, 5);
8101 prt("(a) Display about yourself", 6, 5);
8102 prt("(b) Display mutations", 7, 5);
8103 prt("(c) Display weapon proficiency", 8, 5);
8104 prt("(d) Display spell proficiency", 9, 5);
8105 prt("(e) Display misc. proficiency", 10, 5);
8106 prt("(f) Display virtues", 11, 5);
8107 prt("(g) Display dungeons", 12, 5);
8108 prt("(h) Display current quests", 13, 5);
8109 prt("(i) Display auto pick/destroy", 14, 5);
8113 prt(_("-続く-", "-more-"), 17, 8);
8114 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8115 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8116 /*prt("-) 前ページ", 21, 60);*/
8117 prt(_("コマンド:", "Command: "), 20, 0);
8120 if (i == ESCAPE) break;
8123 case ' ': /* Page change */
8127 case '1': /* Artifacts */
8128 do_cmd_knowledge_artifacts();
8130 case '2': /* Objects */
8131 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8133 case '3': /* Uniques */
8134 do_cmd_knowledge_uniques();
8136 case '4': /* Monsters */
8137 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8139 case '5': /* Kill count */
8140 do_cmd_knowledge_kill_count();
8142 case '6': /* wanted */
8143 if (!vanilla_town) do_cmd_knowledge_kubi();
8145 case '7': /* Pets */
8146 do_cmd_knowledge_pets();
8148 case '8': /* Home */
8149 do_cmd_knowledge_home();
8151 case '9': /* Resist list */
8152 do_cmd_knowledge_inven();
8154 case '0': /* Feature list */
8156 IDX lighting_level = F_LIT_STANDARD;
8157 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8161 case 'a': /* Max stat */
8162 do_cmd_knowledge_stat();
8164 case 'b': /* Mutations */
8165 do_cmd_knowledge_mutations();
8167 case 'c': /* weapon-exp */
8168 do_cmd_knowledge_weapon_exp();
8170 case 'd': /* spell-exp */
8171 do_cmd_knowledge_spell_exp();
8173 case 'e': /* skill-exp */
8174 do_cmd_knowledge_skill_exp();
8176 case 'f': /* Virtues */
8177 do_cmd_knowledge_virtues();
8179 case 'g': /* Dungeon */
8180 do_cmd_knowledge_dungeon();
8182 case 'h': /* Quests */
8183 do_cmd_knowledge_quests();
8185 case 'i': /* Autopick */
8186 do_cmd_knowledge_autopick();
8188 default: /* Unknown option */
8196 if (need_redraw) do_cmd_redraw();
8201 * Check on the status of an active quest
8203 void do_cmd_checkquest(void)
8205 /* File type is "TEXT" */
8206 FILE_TYPE(FILE_TYPE_TEXT);
8210 do_cmd_knowledge_quests();
8216 * Display the time and date
8218 void do_cmd_time(void)
8220 int day, hour, min, full, start, end, num;
8228 extract_day_hour_min(&day, &hour, &min);
8230 full = hour * 100 + min;
8237 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8239 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8240 else strcpy(day_buf, "*****");
8242 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8243 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8246 if (!randint0(10) || p_ptr->image)
8248 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8252 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8255 /* Open this file */
8256 fff = my_fopen(buf, "rt");
8260 /* Find this time */
8261 while (!my_fgets(fff, buf, sizeof(buf)))
8263 /* Ignore comments */
8264 if (!buf[0] || (buf[0] == '#')) continue;
8266 /* Ignore invalid lines */
8267 if (buf[1] != ':') continue;
8269 /* Process 'Start' */
8272 /* Extract the starting time */
8273 start = atoi(buf + 2);
8275 /* Assume valid for an hour */
8285 /* Extract the ending time */
8286 end = atoi(buf + 2);
8292 /* Ignore incorrect range */
8293 if ((start > full) || (full > end)) continue;
8295 /* Process 'Description' */
8300 /* Apply the randomizer */
8301 if (!randint0(num)) strcpy(desc, buf + 2);