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 * Mark strings for auto dump
52 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
53 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
56 * Variables for auto dump
58 static FILE *auto_dump_stream;
59 static cptr auto_dump_mark;
60 static int auto_dump_line_num;
64 * @brief prf出力内容を消去する /
65 * Remove old lines automatically generated before.
66 * @param orig_file 消去を行うファイル名
68 static void remove_auto_dump(cptr orig_file)
70 FILE *tmp_fff, *orig_fff;
74 bool between_mark = FALSE;
77 long header_location = 0;
78 char header_mark_str[80];
79 char footer_mark_str[80];
82 /* Prepare a header/footer mark string */
83 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
84 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
86 mark_len = strlen(footer_mark_str);
88 /* Open an old dump file in read-only mode */
89 orig_fff = my_fopen(orig_file, "r");
91 /* If original file does not exist, nothing to do */
92 if (!orig_fff) return;
94 /* Open a new (temporary) file */
95 tmp_fff = my_fopen_temp(tmp_file, 1024);
99 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
104 /* Loop for every line */
108 if (my_fgets(orig_fff, buf, sizeof(buf)))
110 /* Read error: Assume End of File */
113 * Was looking for the footer, but not found.
115 * Since automatic dump might be edited by hand,
116 * it's dangerous to kill these lines.
117 * Seek back to the next line of the (pseudo) header,
122 fseek(orig_fff, header_location, SEEK_SET);
123 between_mark = FALSE;
127 /* Success -- End the loop */
134 /* We are looking for the header mark of automatic dump */
137 /* Is this line a header? */
138 if (!strcmp(buf, header_mark_str))
140 /* Memorise seek point of this line */
141 header_location = ftell(orig_fff);
143 /* Initialize counter for number of lines */
146 /* Look for the footer from now */
149 /* There are some changes */
156 /* Copy orginally lines */
157 fprintf(tmp_fff, "%s\n", buf);
161 /* We are looking for the footer mark of automatic dump */
164 /* Is this line a footer? */
165 if (!strncmp(buf, footer_mark_str, mark_len))
170 * Compare the number of lines
172 * If there is an inconsistency between
173 * actual number of lines and the
174 * number here, the automatic dump
175 * might be edited by hand. So it's
176 * dangerous to kill these lines.
177 * Seek back to the next line of the
178 * (pseudo) header, and read again.
180 if (!sscanf(buf + mark_len, " (%d)", &tmp)
183 fseek(orig_fff, header_location, SEEK_SET);
186 /* Look for another header */
187 between_mark = FALSE;
193 /* Ignore old line, and count number of lines */
203 /* If there are some changes, overwrite the original file with new one */
206 /* Copy contents of temporary file */
208 tmp_fff = my_fopen(tmp_file, "r");
209 orig_fff = my_fopen(orig_file, "w");
211 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
212 fprintf(orig_fff, "%s\n", buf);
218 /* Kill the temporary file */
226 * @brief prfファイルのフォーマットに従った内容を出力する /
227 * Dump a formatted line, using "vstrnfmt()".
230 static void auto_dump_printf(cptr fmt, ...)
237 /* Begin the Varargs Stuff */
240 /* Format the args, save the length */
241 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
243 /* End the Varargs Stuff */
246 /* Count number of lines */
247 for (p = buf; *p; p++)
249 if (*p == '\n') auto_dump_line_num++;
253 fprintf(auto_dump_stream, "%s", buf);
258 * @brief prfファイルをファイルオープンする /
259 * Open file to append auto dump.
261 * @param mark 出力するヘッダマーク
262 * @return ファイルポインタを取得できたらTRUEを返す
264 static bool open_auto_dump(cptr buf, cptr mark)
267 char header_mark_str[80];
269 /* Save the mark string */
270 auto_dump_mark = mark;
272 /* Prepare a header mark string */
273 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
275 /* Remove old macro dumps */
276 remove_auto_dump(buf);
278 /* Append to the file */
279 auto_dump_stream = my_fopen(buf, "a");
282 if (!auto_dump_stream) {
283 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
291 fprintf(auto_dump_stream, "%s\n", header_mark_str);
293 /* Initialize counter */
294 auto_dump_line_num = 0;
296 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
297 "# *Warning!* The lines below are an automatic dump.\n"));
298 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
299 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
305 * @brief prfファイルをファイルクローズする /
306 * Append foot part and close auto dump.
309 static void close_auto_dump(void)
311 char footer_mark_str[80];
313 /* Prepare a footer mark string */
314 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
316 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
317 "# *Warning!* The lines below are an automatic dump.\n"));
318 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
319 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
321 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
324 my_fclose(auto_dump_stream);
333 * @brief Return suffix of ordinal number
335 * @return pointer of suffix string.
337 cptr get_ordinal_number_suffix(int num)
339 num = ABS(num) % 100;
343 return (num == 11) ? "th" : "st";
345 return (num == 12) ? "th" : "nd";
347 return (num == 13) ? "th" : "rd";
356 * @brief 日記にメッセージを追加する /
357 * Take note to the diary.
358 * @param type 日記内容のID
359 * @param num 日記内容のIDに応じた数値
360 * @param note 日記内容のIDに応じた文字列参照ポインタ
363 errr do_cmd_write_nikki(int type, int num, cptr note)
369 cptr note_level = "";
370 bool do_level = TRUE;
371 char note_level_buf[40];
374 static bool disable_nikki = FALSE;
376 extract_day_hour_min(&day, &hour, &min);
378 if (disable_nikki) return(-1);
380 if (type == NIKKI_FIX_QUEST_C ||
381 type == NIKKI_FIX_QUEST_F ||
382 type == NIKKI_RAND_QUEST_C ||
383 type == NIKKI_RAND_QUEST_F ||
384 type == NIKKI_TO_QUEST)
388 old_quest = p_ptr->inside_quest;
389 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
391 /* Get the quest text */
392 init_flags = INIT_NAME_ONLY;
394 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
396 /* Reset the old quest number */
397 p_ptr->inside_quest = old_quest;
400 /* different filne name to avoid mixing */
401 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
403 /* Build the filename */
404 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
406 /* File type is "TEXT" */
407 FILE_TYPE(FILE_TYPE_TEXT);
409 fff = my_fopen(buf, "a");
414 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
420 q_idx = quest_number(dun_level);
424 if (p_ptr->inside_arena)
425 note_level = _("アリーナ:", "Arane:");
427 note_level = _("地上:", "Surface:");
428 else if (q_idx && (is_fixed_quest_idx(q_idx)
429 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
430 note_level = _("クエスト:", "Quest:");
434 sprintf(note_level_buf, "%d階(%s):", dun_level, d_name+d_info[dungeon_type].name);
436 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, dun_level);
438 note_level = note_level_buf;
446 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
447 else fputs(_("*****日目\n", "Day *****\n"), fff);
455 fprintf(fff, "%s\n",note);
459 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
464 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
469 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
472 case NIKKI_FIX_QUEST_C:
474 if (quest[num].flags & QUEST_FLAG_SILENT) break;
475 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
476 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
479 case NIKKI_FIX_QUEST_F:
481 if (quest[num].flags & QUEST_FLAG_SILENT) break;
482 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
483 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
486 case NIKKI_RAND_QUEST_C:
489 strcpy(name, r_name+r_info[quest[num].r_idx].name);
490 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
491 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
494 case NIKKI_RAND_QUEST_F:
497 strcpy(name, r_name+r_info[quest[num].r_idx].name);
498 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
499 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
502 case NIKKI_MAXDEAPTH:
504 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
505 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
506 _(d_name+d_info[dungeon_type].name, num),
507 _(num, d_name+d_info[dungeon_type].name));
512 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
513 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
514 _(d_name + d_info[num].name, max_dlv[num]),
515 _(max_dlv[num], d_name + d_info[num].name));
521 if (q_idx && (is_fixed_quest_idx(q_idx)
522 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
524 to = _("地上", "the surface");
528 if (!(dun_level+num)) to = _("地上", "the surface");
529 else to = format(_("%d階", "level %d"), dun_level+num);
531 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
537 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
538 hour, min, note_level, _(d_name+d_info[dungeon_type].name, max_dlv[dungeon_type]),
539 _(max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
541 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
546 if (quest[num].flags & QUEST_FLAG_SILENT) break;
547 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
548 hour, min, note_level, quest[num].name);
553 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
554 hour, min, note_level);
559 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
564 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
572 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
573 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
576 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
577 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
579 if (num == MAX_ARENA_MONS)
581 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
582 " won all fight to become a Chanpion.\n"));
589 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
596 to = _("地上", "the surface");
598 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
600 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
601 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
608 to = _("地上", "the surface");
610 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
612 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
613 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
618 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
621 case NIKKI_GAMESTART:
623 time_t ct = time((time_t*)0);
627 fprintf(fff, "%s %s",note, ctime(&ct));
630 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
633 case NIKKI_NAMED_PET:
635 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
638 case RECORD_NAMED_PET_NAME:
639 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
641 case RECORD_NAMED_PET_UNNAME:
642 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
644 case RECORD_NAMED_PET_DISMISS:
645 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
647 case RECORD_NAMED_PET_DEATH:
648 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
650 case RECORD_NAMED_PET_MOVED:
651 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
653 case RECORD_NAMED_PET_LOST_SIGHT:
654 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
656 case RECORD_NAMED_PET_DESTROY:
657 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
659 case RECORD_NAMED_PET_EARTHQUAKE:
660 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
662 case RECORD_NAMED_PET_GENOCIDE:
663 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
665 case RECORD_NAMED_PET_WIZ_ZAP:
666 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
668 case RECORD_NAMED_PET_TELE_LEVEL:
669 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
671 case RECORD_NAMED_PET_BLAST:
672 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
674 case RECORD_NAMED_PET_HEAL_LEPER:
675 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
677 case RECORD_NAMED_PET_COMPACT:
678 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
680 case RECORD_NAMED_PET_LOSE_PARENT:
681 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
695 if (do_level) write_level = FALSE;
701 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
704 * @brief 日記のタイトル表記と内容出力 /
707 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
709 static void do_cmd_disp_nikki(void)
711 char nikki_title[256];
717 static const char subtitle[][30] = {"最強の肉体を求めて",
748 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
749 "Attack is the best form of defence.",
751 "An unexpected windfall",
752 "A drowning man will catch at a straw",
753 "Don't count your chickens before they are hatched.",
754 "It is no use crying over spilt milk.",
755 "Seeing is believing.",
756 "Strike the iron while it is hot.",
757 "I don't care what follows.",
758 "To dig a well to put out a house on fire.",
759 "Tomorrow is another day.",
760 "Easy come, easy go.",
761 "The more haste, the less speed.",
762 "Where there is life, there is hope.",
763 "There is no royal road to *WINNER*.",
764 "Danger past, God forgotten.",
765 "The best thing to do now is to run away.",
766 "Life is but an empty dream.",
767 "Dead men tell no tales.",
768 "A book that remains shut is but a block.",
769 "Misfortunes never come singly.",
770 "A little knowledge is a dangerous thing.",
771 "History repeats itself.",
772 "*WINNER* was not built in a day.",
773 "Ignorance is bliss.",
774 "To lose is to win?",
775 "No medicine can cure folly.",
776 "All good things come to an end.",
777 "M$ Empire strikes back.",
778 "To see is to believe",
780 "Quest of The World's Greatest Brain"};
782 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
784 /* Build the filename */
785 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
787 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
788 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
789 else if (p_ptr->pclass == CLASS_MAGE || p_ptr->pclass == CLASS_HIGH_MAGE || p_ptr->pclass == CLASS_SORCERER)
790 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
791 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
794 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」",
795 ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
797 sprintf(nikki_title, "Legend of %s %s '%s'",
798 ap_ptr->title, p_ptr->name, tmp);
801 /* Display the file contents */
802 show_file(FALSE, buf, nikki_title, -1, 0);
806 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
809 static void do_cmd_bunshou(void)
812 char bunshou[80] = "\0";
814 if (get_string(_("内容: ", "diary note: "), tmp, 79))
816 strcpy(bunshou, tmp);
818 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
823 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
826 static void do_cmd_last_get(void)
831 if (record_o_name[0] == '\0') return;
833 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
834 if (!get_check(buf)) return;
838 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
839 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
844 * @brief ファイル中の全日記記録を消去する /
847 static void do_cmd_erase_nikki(void)
853 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
854 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
856 /* Build the filename */
857 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
859 /* Remove the file */
862 fff = my_fopen(buf, "w");
865 msg_format(_("記録を消去しました。", "deleted record."));
867 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
876 void do_cmd_nikki(void)
880 /* File type is "TEXT" */
881 FILE_TYPE(FILE_TYPE_TEXT);
883 /* Save the screen */
886 /* Interact until done */
892 /* Ask for a choice */
893 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
895 /* Give some choices */
896 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
897 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
898 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
899 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
901 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
904 prt(_("コマンド:", "Command: "), 18, 0);
910 if (i == ESCAPE) break;
924 do_cmd_erase_nikki();
928 prepare_movie_hooks();
930 default: /* Unknown option */
938 /* Restore the screen */
943 * @brief 画面を再描画するコマンドのメインルーチン
944 * Hack -- redraw the screen
948 * This command performs various low level updates, clears all the "extra"
949 * windows, does a total redraw of the main window, and requests all of the
950 * interesting updates and redraws that I can think of.
952 * This command is also used to "instantiate" the results of the user
953 * selecting various things, such as graphics mode, so it must call
954 * the "TERM_XTRA_REACT" hook before redrawing the windows.
957 void do_cmd_redraw(void)
964 /* Hack -- react to changes */
965 Term_xtra(TERM_XTRA_REACT, 0);
968 /* Combine and Reorder the pack (later) */
969 p_ptr->notice |= (PN_COMBINE | PN_REORDER);
973 p_ptr->update |= (PU_TORCH);
976 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
978 /* Forget lite/view */
979 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
981 /* Update lite/view */
982 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
984 /* Update monsters */
985 p_ptr->update |= (PU_MONSTERS);
987 /* Redraw everything */
988 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
991 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
994 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1001 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1004 /* Redraw every window */
1005 for (j = 0; j < 8; j++)
1008 if (!angband_term[j]) continue;
1011 Term_activate(angband_term[j]);
1026 * @brief 名前を変更するコマンドのメインルーチン
1027 * Hack -- change name
1030 void do_cmd_change_name(void)
1039 /* Save the screen */
1047 /* Display the player */
1048 display_player(mode);
1053 display_player(mode);
1058 Term_putstr(2, 23, -1, TERM_WHITE,
1059 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1061 Term_putstr(2, 23, -1, TERM_WHITE,
1062 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1070 if (c == ESCAPE) break;
1077 /* Process the player name */
1078 process_player_name(FALSE);
1084 sprintf(tmp, "%s.txt", player_base);
1085 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1087 if (tmp[0] && (tmp[0] != ' '))
1089 file_character(tmp);
1106 /* Flush messages */
1110 /* Restore the screen */
1113 /* Redraw everything */
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 XXX XXX XXX */
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];
1165 Term_get_size(&wid, &hgt);
1167 /* Number of message lines in a screen */
1168 num_lines = hgt - 4;
1171 strcpy(finder_str, "");
1174 strcpy(shower_str, "");
1176 /* Total messages */
1179 /* Start on first message */
1182 /* Save the screen */
1188 /* Process requests until done */
1194 /* Dump up to 20 lines of messages */
1195 for (j = 0; (j < num_lines) && (i + j < n); j++)
1197 cptr msg = message_str(i+j);
1199 /* Dump the messages, bottom to top */
1200 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1202 /* Hilite "shower" */
1203 if (shower && shower[0])
1207 /* Display matches */
1208 while ((str = my_strstr(str, shower)) != NULL)
1210 int len = strlen(shower);
1212 /* Display the match */
1213 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1221 /* Erase remaining lines */
1222 for (; j < num_lines; j++)
1224 Term_erase(0, num_lines + 1 - j, 255);
1227 /* Display header XXX XXX XXX */
1230 prt(format("以前のメッセージ %d-%d 全部で(%d)",
1231 i, i + j - 1, n), 0, 0);
1233 prt(format("Message Recall (%d-%d of %d)",
1234 i, i + j - 1, n), 0, 0);
1237 /* Display prompt (not very informative) */
1238 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1239 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1242 skey = inkey_special(TRUE);
1244 /* Exit on Escape */
1245 if (skey == ESCAPE) break;
1247 /* Hack -- Save the old index */
1252 /* Hack -- handle show */
1255 prt(_("強調: ", "Show: "), hgt - 1, 0);
1257 /* Get a "shower" string, or continue */
1258 strcpy(back_str, shower_str);
1259 if (askfor(shower_str, 80))
1262 shower = shower_str[0] ? shower_str : NULL;
1264 else strcpy(shower_str, back_str);
1269 /* Hack -- handle find */
1276 prt(_("検索: ", "Find: "), hgt - 1, 0);
1278 /* Get a "finder" string, or continue */
1279 strcpy(back_str, finder_str);
1280 if (!askfor(finder_str, 80))
1282 strcpy(finder_str, back_str);
1285 else if (!finder_str[0])
1287 shower = NULL; /* Stop showing */
1292 shower = finder_str;
1295 for (z = i + 1; z < n; z++)
1297 cptr msg = message_str(z);
1300 if (my_strstr(msg, finder_str))
1312 /* Recall 1 older message */
1314 /* Go to the oldest line */
1318 /* Recall 1 newer message */
1320 /* Go to the newest line */
1324 /* Recall 1 older message */
1329 /* Go older if legal */
1330 i = MIN(i + 1, n - num_lines);
1333 /* Recall 10 older messages */
1335 /* Go older if legal */
1336 i = MIN(i + 10, n - num_lines);
1339 /* Recall 20 older messages */
1344 /* Go older if legal */
1345 i = MIN(i + num_lines, n - num_lines);
1348 /* Recall 20 newer messages */
1352 /* Go newer (if able) */
1353 i = MAX(0, i - num_lines);
1356 /* Recall 10 newer messages */
1358 /* Go newer (if able) */
1362 /* Recall 1 newer messages */
1365 /* Go newer (if able) */
1370 /* Hack -- Error of some kind */
1374 /* Restore the screen */
1381 * チートオプションの最大数 / Number of cheating options
1386 * チーとオプションの定義テーブル / Cheating options
1388 static option_type cheat_info[CHEAT_MAX] =
1390 { &cheat_peek, FALSE, 255, 0x01, 0x00,
1391 "cheat_peek", _("アイテムの生成をのぞき見る", "Peek into object creation")
1394 { &cheat_hear, FALSE, 255, 0x02, 0x00,
1395 "cheat_hear", _("モンスターの生成をのぞき見る", "Peek into monster creation")
1398 { &cheat_room, FALSE, 255, 0x04, 0x00,
1399 "cheat_room", _("ダンジョンの生成をのぞき見る", "Peek into dungeon creation")
1402 { &cheat_xtra, FALSE, 255, 0x08, 0x00,
1403 "cheat_xtra", _("その他の事をのぞき見る", "Peek into something else")
1406 { &cheat_know, FALSE, 255, 0x10, 0x00,
1407 "cheat_know", _("完全なモンスターの思い出を知る", "Know complete monster info")
1410 { &cheat_live, FALSE, 255, 0x20, 0x00,
1411 "cheat_live", _("死を回避することを可能にする", "Allow player to avoid death")
1414 { &cheat_save, FALSE, 255, 0x40, 0x00,
1415 "cheat_save", _("死んだ時セーブするか確認する", "Ask for saving death")
1420 * @brief チートオプションを変更するコマンドのメインルーチン
1421 * Interact with some options for cheating
1422 * @param info 表示メッセージ
1425 static void do_cmd_options_cheat(cptr info)
1429 int i, k = 0, n = CHEAT_MAX;
1437 /* Interact with the player */
1442 /* Prompt XXX XXX XXX */
1443 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1448 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1449 prt(" << 注意 >>", 11, 0);
1450 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1451 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1452 prt(" じらないようにして下さい。", 14, 0);
1454 /* Display the options */
1455 for (i = 0; i < n; i++)
1457 byte a = TERM_WHITE;
1459 /* Color current option */
1460 if (i == k) a = TERM_L_BLUE;
1462 /* Display the option text */
1463 sprintf(buf, "%-48s: %s (%s)",
1464 cheat_info[i].o_desc,
1465 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1466 cheat_info[i].o_text);
1467 c_prt(a, buf, i + 2, 0);
1470 /* Hilite current option */
1471 move_cursor(k + 2, 50);
1477 * HACK - Try to translate the key into a direction
1478 * to allow using the roguelike keys for navigation.
1480 dir = get_keymap_dir(ch);
1481 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1495 k = (n + k - 1) % n;
1513 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1514 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1515 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1516 (*cheat_info[k].o_var) = TRUE;
1525 (*cheat_info[k].o_var) = FALSE;
1532 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1533 /* Peruse the help file */
1534 (void)show_file(TRUE, buf, NULL, 0, 0);
1553 static option_type autosave_info[2] =
1555 { &autosave_l, FALSE, 255, 0x01, 0x00,
1556 "autosave_l", _("新しい階に入る度に自動セーブする", "Autosave when entering new levels") },
1558 { &autosave_t, FALSE, 255, 0x02, 0x00,
1559 "autosave_t", _("一定ターン毎に自動セーブする", "Timed autosave") },
1563 * @brief セーブ頻度ターンの次の値を返す
1564 * @param current 現在のセーブ頻度ターン値
1565 * @return 次のセーブ頻度ターン値
1567 static s16b toggle_frequency(s16b current)
1572 case 50: return 100;
1573 case 100: return 250;
1574 case 250: return 500;
1575 case 500: return 1000;
1576 case 1000: return 2500;
1577 case 2500: return 5000;
1578 case 5000: return 10000;
1579 case 10000: return 25000;
1586 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1587 * @param info 表示メッセージ
1590 static void do_cmd_options_autosave(cptr info)
1594 int i, k = 0, n = 2;
1602 /* Interact with the player */
1605 /* Prompt XXX XXX XXX */
1606 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1607 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1611 /* Display the options */
1612 for (i = 0; i < n; i++)
1614 byte a = TERM_WHITE;
1616 /* Color current option */
1617 if (i == k) a = TERM_L_BLUE;
1619 /* Display the option text */
1620 sprintf(buf, "%-48s: %s (%s)",
1621 autosave_info[i].o_desc,
1622 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1623 autosave_info[i].o_text);
1624 c_prt(a, buf, i + 2, 0);
1626 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1628 /* Hilite current option */
1629 move_cursor(k + 2, 50);
1645 k = (n + k - 1) % n;
1663 (*autosave_info[k].o_var) = TRUE;
1672 (*autosave_info[k].o_var) = FALSE;
1680 autosave_freq = toggle_frequency(autosave_freq);
1681 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1687 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1703 * @brief 標準オプションを変更するコマンドのサブルーチン /
1704 * Interact with some options
1705 * @param page オプションページ番号
1706 * @param info 表示メッセージ
1709 void do_cmd_options_aux(int page, cptr info)
1712 int i, k = 0, n = 0, l;
1715 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1716 (!p_ptr->wizard || !allow_debug_opts);
1719 /* Lookup the options */
1720 for (i = 0; i < 24; i++) opt[i] = 0;
1722 /* Scan the options */
1723 for (i = 0; option_info[i].o_desc; i++)
1725 /* Notice options on this "page" */
1726 if (option_info[i].o_page == page) opt[n++] = i;
1733 /* Interact with the player */
1738 /* Prompt XXX XXX XXX */
1739 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1740 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1743 /* HACK -- description for easy-auto-destroy options */
1744 if (page == OPT_PAGE_AUTODESTROY)
1745 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1746 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1748 /* Display the options */
1749 for (i = 0; i < n; i++)
1751 byte a = TERM_WHITE;
1753 /* Color current option */
1754 if (i == k) a = TERM_L_BLUE;
1756 /* Display the option text */
1757 sprintf(buf, "%-48s: %s (%.19s)",
1758 option_info[opt[i]].o_desc,
1759 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1760 option_info[opt[i]].o_text);
1761 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1762 else c_prt(a, buf, i + 2, 0);
1765 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1768 /* Hilite current option */
1769 move_cursor(k + 2 + l, 50);
1775 * HACK - Try to translate the key into a direction
1776 * to allow using the roguelike keys for navigation.
1778 dir = get_keymap_dir(ch);
1779 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1793 k = (n + k - 1) % n;
1810 if (browse_only) break;
1811 (*option_info[opt[k]].o_var) = TRUE;
1820 if (browse_only) break;
1821 (*option_info[opt[k]].o_var) = FALSE;
1829 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1835 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1836 /* Peruse the help file */
1837 (void)show_file(TRUE, buf, NULL, 0, 0);
1854 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1855 * Modify the "window" options
1858 static void do_cmd_options_win(void)
1872 /* Memorize old flags */
1873 for (j = 0; j < 8; j++)
1875 /* Acquire current flags */
1876 old_flag[j] = window_flag[j];
1886 /* Prompt XXX XXX XXX */
1887 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1889 /* Display the windows */
1890 for (j = 0; j < 8; j++)
1892 byte a = TERM_WHITE;
1894 cptr s = angband_term_name[j];
1897 if (j == x) a = TERM_L_BLUE;
1899 /* Window name, staggered, centered */
1900 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1903 /* Display the options */
1904 for (i = 0; i < 16; i++)
1906 byte a = TERM_WHITE;
1908 cptr str = window_flag_desc[i];
1911 if (i == y) a = TERM_L_BLUE;
1914 if (!str) str = _("(未使用)", "(Unused option)");
1917 Term_putstr(0, i + 5, -1, a, str);
1919 /* Display the windows */
1920 for (j = 0; j < 8; j++)
1922 byte a = TERM_WHITE;
1927 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1930 if (window_flag[j] & (1L << i)) c = 'X';
1933 Term_putch(35 + j * 5, i + 5, a, c);
1938 Term_gotoxy(35 + x * 5, y + 5);
1956 for (j = 0; j < 8; j++)
1958 window_flag[j] &= ~(1L << y);
1962 for (i = 0; i < 16; i++)
1964 window_flag[x] &= ~(1L << i);
1977 window_flag[x] |= (1L << y);
1985 window_flag[x] &= ~(1L << y);
1991 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1999 d = get_keymap_dir(ch);
2001 x = (x + ddx[d] + 8) % 8;
2002 y = (y + ddy[d] + 16) % 16;
2009 /* Notice changes */
2010 for (j = 0; j < 8; j++)
2015 if (!angband_term[j]) continue;
2017 /* Ignore non-changes */
2018 if (window_flag[j] == old_flag[j]) continue;
2021 Term_activate(angband_term[j]);
2044 option_fields[OPT_NUM] =
2047 { '1', " キー入力 オプション", 3 },
2048 { '2', " マップ画面 オプション", 4 },
2049 { '3', " テキスト表示 オプション", 5 },
2050 { '4', " ゲームプレイ オプション", 6 },
2051 { '5', " 行動中止関係 オプション", 7 },
2052 { '6', " 簡易自動破壊 オプション", 8 },
2053 { 'r', " プレイ記録 オプション", 9 },
2055 { 'p', "自動拾いエディタ", 11 },
2056 { 'd', " 基本ウェイト量 ", 12 },
2057 { 'h', "低ヒットポイント", 13 },
2058 { 'm', " 低魔力色閾値 ", 14 },
2059 { 'a', " 自動セーブ オプション", 15 },
2060 { 'w', "ウインドウフラグ", 16 },
2062 { 'b', " 初期 オプション (参照のみ)", 18 },
2063 { 'c', " 詐欺 オプション", 19 },
2065 { '1', "Input Options", 3 },
2066 { '2', "Map Screen Options", 4 },
2067 { '3', "Text Display Options", 5 },
2068 { '4', "Game-Play Options", 6 },
2069 { '5', "Disturbance Options", 7 },
2070 { '6', "Easy Auto-Destroyer Options", 8 },
2071 { 'r', "Play record Options", 9 },
2073 { 'p', "Auto-picker/destroyer editor", 11 },
2074 { 'd', "Base Delay Factor", 12 },
2075 { 'h', "Hitpoint Warning", 13 },
2076 { 'm', "Mana Color Threshold", 14 },
2077 { 'a', "Autosave Options", 15 },
2078 { 'w', "Window Flags", 16 },
2080 { 'b', "Birth Options (Browse Only)", 18 },
2081 { 'c', "Cheat Options", 19 },
2087 * @brief 標準オプションを変更するコマンドのメインルーチン /
2088 * Set or unset various options.
2092 * The user must use the "Ctrl-R" command to "adapt" to changes
2093 * in any options which control "visual" aspects of the game.
2096 void do_cmd_options(void)
2102 /* Save the screen */
2110 /* Does not list cheat option when cheat option is off */
2111 if (!p_ptr->noscore && !allow_debug_opts) n--;
2116 /* Why are we here */
2117 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2121 /* Give some choices */
2122 for (i = 0; i < n; i++)
2124 byte a = TERM_WHITE;
2125 if (i == y) a = TERM_L_BLUE;
2126 Term_putstr(5, option_fields[i].row, -1, a,
2127 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2130 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2133 skey = inkey_special(TRUE);
2134 if (!(skey & SKEY_MASK)) k = (char)skey;
2138 if (k == ESCAPE) break;
2140 if (my_strchr("\n\r ", k))
2142 k = option_fields[y].key;
2146 for (i = 0; i < n; i++)
2148 if (tolower(k) == option_fields[i].key) break;
2151 /* Command is found */
2154 /* Hack -- browse help */
2155 if (k == '?') break;
2159 if (skey == SKEY_UP) d = 8;
2160 if (skey == SKEY_DOWN) d = 2;
2161 y = (y + ddy[d] + n) % n;
2166 if (k == ESCAPE) break;
2173 /* Process the general options */
2174 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2180 /* Process the general options */
2181 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2188 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2195 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2202 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2209 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2213 /* Play-record Options */
2218 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2227 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2228 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2229 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2233 /* Cheating Options */
2236 if (!p_ptr->noscore && !allow_debug_opts)
2238 /* Cheat options are not permitted */
2244 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2251 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2260 do_cmd_options_win();
2261 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2262 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2263 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2264 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2269 /* Auto-picker/destroyer editor */
2273 do_cmd_edit_autopick();
2277 /* Hack -- Delay Speed */
2283 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2285 /* Get a new value */
2288 int msec = delay_factor * delay_factor * delay_factor;
2289 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2290 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2292 if (k == ESCAPE) break;
2295 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2298 else if (isdigit(k)) delay_factor = D2I(k);
2305 /* Hack -- hitpoint warning factor */
2311 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2313 /* Get a new value */
2316 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2317 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2319 if (k == ESCAPE) break;
2322 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2325 else if (isdigit(k)) hitpoint_warn = D2I(k);
2332 /* Hack -- mana color factor */
2338 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2340 /* Get a new value */
2343 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2344 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2346 if (k == ESCAPE) break;
2349 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2352 else if (isdigit(k)) mana_warn = D2I(k);
2360 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2364 /* Unknown option */
2373 /* Flush messages */
2378 /* Restore the screen */
2381 /* Hack - Redraw equippy chars */
2382 p_ptr->redraw |= (PR_EQUIPPY);
2388 * @brief prefファイルを選択して処理する /
2389 * Ask for a "user pref line" and process it
2392 * XXX XXX XXX Allow absolute file names?
2394 void do_cmd_pref(void)
2401 /* Ask for a "user pref command" */
2402 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2404 /* Process that pref command */
2405 (void)process_pref_file_command(buf);
2409 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2412 void do_cmd_reload_autopick(void)
2414 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2415 /* Load the file with messages */
2416 autopick_load_pref(TRUE);
2422 * @brief マクロ情報をprefファイルに保存する /
2423 * @param fname ファイル名
2426 static errr macro_dump(cptr fname)
2428 static cptr mark = "Macro Dump";
2434 /* Build the filename */
2435 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2437 /* File type is "TEXT" */
2438 FILE_TYPE(FILE_TYPE_TEXT);
2440 /* Append to the file */
2441 if (!open_auto_dump(buf, mark)) return (-1);
2444 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2447 for (i = 0; i < macro__num; i++)
2449 /* Extract the action */
2450 ascii_to_text(buf, macro__act[i]);
2452 /* Dump the macro */
2453 auto_dump_printf("A:%s\n", buf);
2455 /* Extract the action */
2456 ascii_to_text(buf, macro__pat[i]);
2458 /* Dump normal macros */
2459 auto_dump_printf("P:%s\n", buf);
2462 auto_dump_printf("\n");
2474 * @brief マクロのトリガーキーを取得する /
2475 * Hack -- ask for a "trigger" (see below)
2476 * @param buf キー表記を保管するバッファ
2480 * Note the complex use of the "inkey()" function from "util.c".
2482 * Note that both "flush()" calls are extremely important.
2485 static void do_cmd_macro_aux(char *buf)
2495 /* Do not process macros */
2501 /* Read the pattern */
2507 /* Do not process macros */
2510 /* Do not wait for keys */
2513 /* Attempt to read a key */
2524 /* Convert the trigger */
2525 ascii_to_text(tmp, buf);
2527 /* Hack -- display the trigger */
2528 Term_addstr(-1, TERM_WHITE, tmp);
2534 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2535 * Hack -- ask for a keymap "trigger" (see below)
2536 * @param buf キー表記を取得するバッファ
2540 * Note that both "flush()" calls are extremely important. This may
2541 * no longer be true, since "util.c" is much simpler now. XXX XXX XXX
2544 static void do_cmd_macro_aux_keymap(char *buf)
2558 /* Convert to ascii */
2559 ascii_to_text(tmp, buf);
2561 /* Hack -- display the trigger */
2562 Term_addstr(-1, TERM_WHITE, tmp);
2571 * @brief キーマップをprefファイルにダンプする /
2572 * Hack -- append all keymaps to the given file
2573 * @param fname ファイルネーム
2577 static errr keymap_dump(cptr fname)
2579 static cptr mark = "Keymap Dump";
2588 if (rogue_like_commands)
2590 mode = KEYMAP_MODE_ROGUE;
2596 mode = KEYMAP_MODE_ORIG;
2600 /* Build the filename */
2601 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2603 /* File type is "TEXT" */
2604 FILE_TYPE(FILE_TYPE_TEXT);
2606 /* Append to the file */
2607 if (!open_auto_dump(buf, mark)) return -1;
2610 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2613 for (i = 0; i < 256; i++)
2617 /* Loop up the keymap */
2618 act = keymap_act[mode][i];
2620 /* Skip empty keymaps */
2623 /* Encode the key */
2626 ascii_to_text(key, buf);
2628 /* Encode the action */
2629 ascii_to_text(buf, act);
2631 /* Dump the macro */
2632 auto_dump_printf("A:%s\n", buf);
2633 auto_dump_printf("C:%d:%s\n", mode, key);
2645 * @brief マクロを設定するコマンドのメインルーチン /
2646 * Interact with "macros"
2650 * Note that the macro "action" must be defined before the trigger.
2652 * Could use some helpful instructions on this page. XXX XXX XXX
2655 void do_cmd_macros(void)
2667 if (rogue_like_commands)
2669 mode = KEYMAP_MODE_ROGUE;
2675 mode = KEYMAP_MODE_ORIG;
2678 /* File type is "TEXT" */
2679 FILE_TYPE(FILE_TYPE_TEXT);
2686 /* Process requests until done */
2693 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2695 /* Describe that action */
2696 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2698 /* Analyze the current action */
2699 ascii_to_text(buf, macro__buf);
2701 /* Display the current action */
2706 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2708 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2709 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2710 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2711 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2712 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2713 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2714 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2715 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2716 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2717 #endif /* ALLOW_MACROS */
2720 prt(_("コマンド: ", "Command: "), 16, 0);
2726 if (i == ESCAPE) break;
2728 /* Load a 'macro' file */
2734 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2737 prt(_("ファイル: ", "File: "), 18, 0);
2739 /* Default filename */
2740 sprintf(tmp, "%s.prf", player_base);
2742 /* Ask for a file */
2743 if (!askfor(tmp, 80)) continue;
2745 /* Process the given filename */
2746 err = process_pref_file(tmp);
2749 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2754 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2758 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2768 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2771 prt(_("ファイル: ", "File: "), 18, 0);
2773 /* Default filename */
2774 sprintf(tmp, "%s.prf", player_base);
2776 /* Ask for a file */
2777 if (!askfor(tmp, 80)) continue;
2779 /* Dump the macros */
2780 (void)macro_dump(tmp);
2783 msg_print(_("マクロを追加しました。", "Appended macros."));
2792 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2796 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2798 /* Get a macro trigger */
2799 do_cmd_macro_aux(buf);
2801 /* Acquire action */
2802 k = macro_find_exact(buf);
2808 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2814 /* Obtain the action */
2815 strcpy(macro__buf, macro__act[k]);
2817 /* Analyze the current action */
2818 ascii_to_text(buf, macro__buf);
2820 /* Display the current action */
2824 msg_print(_("マクロを確認しました。", "Found a macro."));
2828 /* Create a macro */
2832 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2835 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2837 /* Get a macro trigger */
2838 do_cmd_macro_aux(buf);
2844 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2845 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2848 prt(_("マクロ行動: ", "Action: "), 20, 0);
2850 /* Convert to text */
2851 ascii_to_text(tmp, macro__buf);
2853 /* Get an encoded action */
2854 if (askfor(tmp, 80))
2856 /* Convert to ascii */
2857 text_to_ascii(macro__buf, tmp);
2859 /* Link the macro */
2860 macro_add(buf, macro__buf);
2863 msg_print(_("マクロを追加しました。", "Added a macro."));
2867 /* Remove a macro */
2871 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2874 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2876 /* Get a macro trigger */
2877 do_cmd_macro_aux(buf);
2879 /* Link the macro */
2880 macro_add(buf, buf);
2883 msg_print(_("マクロを削除しました。", "Removed a macro."));
2890 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2893 prt(_("ファイル: ", "File: "), 18, 0);
2895 /* Default filename */
2896 sprintf(tmp, "%s.prf", player_base);
2898 /* Ask for a file */
2899 if (!askfor(tmp, 80)) continue;
2901 /* Dump the macros */
2902 (void)keymap_dump(tmp);
2905 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2908 /* Query a keymap */
2914 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2917 prt(_("押すキー: ", "Keypress: "), 18, 0);
2919 /* Get a keymap trigger */
2920 do_cmd_macro_aux_keymap(buf);
2922 /* Look up the keymap */
2923 act = keymap_act[mode][(byte)(buf[0])];
2929 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2935 /* Obtain the action */
2936 strcpy(macro__buf, act);
2938 /* Analyze the current action */
2939 ascii_to_text(buf, macro__buf);
2941 /* Display the current action */
2945 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2949 /* Create a keymap */
2953 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2956 prt(_("押すキー: ", "Keypress: "), 18, 0);
2958 /* Get a keymap trigger */
2959 do_cmd_macro_aux_keymap(buf);
2965 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2966 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2969 prt(_("行動: ", "Action: "), 20, 0);
2971 /* Convert to text */
2972 ascii_to_text(tmp, macro__buf);
2974 /* Get an encoded action */
2975 if (askfor(tmp, 80))
2977 /* Convert to ascii */
2978 text_to_ascii(macro__buf, tmp);
2980 /* Free old keymap */
2981 string_free(keymap_act[mode][(byte)(buf[0])]);
2983 /* Make new keymap */
2984 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2987 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2991 /* Remove a keymap */
2995 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2998 prt(_("押すキー: ", "Keypress: "), 18, 0);
3000 /* Get a keymap trigger */
3001 do_cmd_macro_aux_keymap(buf);
3003 /* Free old keymap */
3004 string_free(keymap_act[mode][(byte)(buf[0])]);
3006 /* Make new keymap */
3007 keymap_act[mode][(byte)(buf[0])] = NULL;
3010 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
3013 /* Enter a new action */
3017 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
3023 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
3024 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
3027 prt(_("マクロ行動: ", "Action: "), 20, 0);
3029 /* Hack -- limit the value */
3032 /* Get an encoded action */
3033 if (!askfor(buf, 80)) continue;
3035 /* Extract an action */
3036 text_to_ascii(macro__buf, buf);
3039 #endif /* ALLOW_MACROS */
3048 /* Flush messages */
3057 * @brief キャラクタ色の明暗表現
3059 static cptr lighting_level_str[F_LIT_MAX] =
3074 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
3075 * @param i 指定対象となるキャラクタコード
3076 * @param num 指定されたビジュアルIDを返す参照ポインタ
3077 * @param max ビジュアルIDの最大数
3078 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
3080 static bool cmd_visuals_aux(int i, int *num, int max)
3087 sprintf(str, "%d", *num);
3089 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
3092 tmp = strtol(str, NULL, 0);
3093 if (tmp >= 0 && tmp < max)
3096 else if (isupper(i))
3097 *num = (*num + max - 1) % max;
3099 *num = (*num + 1) % max;
3105 * @brief キャラクタの変更メニュー表示
3106 * @param choice_msg 選択メッセージ
3109 static void print_visuals_menu(cptr choice_msg)
3111 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
3113 /* Give some choices */
3114 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
3116 #ifdef ALLOW_VISUALS
3117 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
3118 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
3119 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
3120 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
3121 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
3122 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
3123 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3124 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3125 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3126 #endif /* ALLOW_VISUALS */
3128 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3131 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3134 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx);
3135 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx);
3136 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level);
3139 * Interact with "visuals"
3141 void do_cmd_visuals(void)
3146 bool need_redraw = FALSE;
3147 const char *empty_symbol = "<< ? >>";
3149 if (use_bigtile) empty_symbol = "<< ?? >>";
3151 /* File type is "TEXT" */
3152 FILE_TYPE(FILE_TYPE_TEXT);
3154 /* Save the screen */
3157 /* Interact until done */
3163 /* Ask for a choice */
3164 print_visuals_menu(NULL);
3170 if (i == ESCAPE) break;
3174 /* Load a 'pref' file */
3177 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3180 prt(_("ファイル: ", "File: "), 17, 0);
3182 /* Default filename */
3183 sprintf(tmp, "%s.prf", player_base);
3186 if (!askfor(tmp, 70)) continue;
3188 /* Process the given filename */
3189 (void)process_pref_file(tmp);
3194 #ifdef ALLOW_VISUALS
3196 /* Dump monster attr/chars */
3199 static cptr mark = "Monster attr/chars";
3202 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3205 prt(_("ファイル: ", "File: "), 17, 0);
3207 /* Default filename */
3208 sprintf(tmp, "%s.prf", player_base);
3210 /* Get a filename */
3211 if (!askfor(tmp, 70)) continue;
3213 /* Build the filename */
3214 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3216 /* Append to the file */
3217 if (!open_auto_dump(buf, mark)) continue;
3220 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3223 for (i = 0; i < max_r_idx; i++)
3225 monster_race *r_ptr = &r_info[i];
3227 /* Skip non-entries */
3228 if (!r_ptr->name) continue;
3230 /* Dump a comment */
3231 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3233 /* Dump the monster attr/char info */
3234 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3235 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3242 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3247 /* Dump object attr/chars */
3250 static cptr mark = "Object attr/chars";
3253 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3256 prt(_("ファイル: ", "File: "), 17, 0);
3258 /* Default filename */
3259 sprintf(tmp, "%s.prf", player_base);
3261 /* Get a filename */
3262 if (!askfor(tmp, 70)) continue;
3264 /* Build the filename */
3265 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3267 /* Append to the file */
3268 if (!open_auto_dump(buf, mark)) continue;
3271 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3274 for (i = 0; i < max_k_idx; i++)
3277 object_kind *k_ptr = &k_info[i];
3279 /* Skip non-entries */
3280 if (!k_ptr->name) continue;
3285 strip_name(o_name, i);
3291 /* Prepare dummy object */
3292 object_prep(&forge, i);
3294 /* Get un-shuffled flavor name */
3295 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3298 /* Dump a comment */
3299 auto_dump_printf("# %s\n", o_name);
3301 /* Dump the object attr/char info */
3302 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", i,
3303 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3310 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3315 /* Dump feature attr/chars */
3318 static cptr mark = "Feature attr/chars";
3321 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3324 prt(_("ファイル: ", "File: "), 17, 0);
3326 /* Default filename */
3327 sprintf(tmp, "%s.prf", player_base);
3329 /* Get a filename */
3330 if (!askfor(tmp, 70)) continue;
3332 /* Build the filename */
3333 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3335 /* Append to the file */
3336 if (!open_auto_dump(buf, mark)) continue;
3339 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3342 for (i = 0; i < max_f_idx; i++)
3344 feature_type *f_ptr = &f_info[i];
3346 /* Skip non-entries */
3347 if (!f_ptr->name) continue;
3349 /* Skip mimiccing features */
3350 if (f_ptr->mimic != i) continue;
3352 /* Dump a comment */
3353 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3355 /* Dump the feature attr/char info */
3356 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3357 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3358 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3359 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3366 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3371 /* Modify monster attr/chars (numeric operation) */
3374 static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3377 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3379 /* Hack -- query until done */
3382 monster_race *r_ptr = &r_info[r];
3386 byte da = r_ptr->d_attr;
3387 byte dc = r_ptr->d_char;
3388 byte ca = r_ptr->x_attr;
3389 byte cc = r_ptr->x_char;
3391 /* Label the object */
3392 Term_putstr(5, 17, -1, TERM_WHITE,
3393 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3395 /* Label the Default values */
3396 Term_putstr(10, 19, -1, TERM_WHITE,
3397 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3399 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3400 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3402 /* Label the Current values */
3403 Term_putstr(10, 20, -1, TERM_WHITE,
3404 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3406 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3407 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3410 Term_putstr(0, 22, -1, TERM_WHITE,
3411 _("コマンド (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): "));
3417 if (i == ESCAPE) break;
3419 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3420 else if (isupper(i)) c = 'a' + i - 'A';
3430 if (!cmd_visuals_aux(i, &r, max_r_idx))
3436 while (!r_info[r].name);
3440 t = (int)r_ptr->x_attr;
3441 (void)cmd_visuals_aux(i, &t, 256);
3442 r_ptr->x_attr = (byte)t;
3446 t = (int)r_ptr->x_char;
3447 (void)cmd_visuals_aux(i, &t, 256);
3448 r_ptr->x_char = (byte)t;
3452 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3456 print_visuals_menu(choice_msg);
3464 /* Modify object attr/chars (numeric operation) */
3467 static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3469 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3471 /* Hack -- query until done */
3474 object_kind *k_ptr = &k_info[k];
3478 byte da = k_ptr->d_attr;
3479 byte dc = k_ptr->d_char;
3480 byte ca = k_ptr->x_attr;
3481 byte cc = k_ptr->x_char;
3483 /* Label the object */
3484 Term_putstr(5, 17, -1, TERM_WHITE,
3485 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3486 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3488 /* Label the Default values */
3489 Term_putstr(10, 19, -1, TERM_WHITE,
3490 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3492 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3493 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3495 /* Label the Current values */
3496 Term_putstr(10, 20, -1, TERM_WHITE,
3497 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3499 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3500 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3503 Term_putstr(0, 22, -1, TERM_WHITE,
3504 _("コマンド (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): "));
3510 if (i == ESCAPE) break;
3512 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3513 else if (isupper(i)) c = 'a' + i - 'A';
3523 if (!cmd_visuals_aux(i, &k, max_k_idx))
3529 while (!k_info[k].name);
3533 t = (int)k_ptr->x_attr;
3534 (void)cmd_visuals_aux(i, &t, 256);
3535 k_ptr->x_attr = (byte)t;
3539 t = (int)k_ptr->x_char;
3540 (void)cmd_visuals_aux(i, &t, 256);
3541 k_ptr->x_char = (byte)t;
3545 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3549 print_visuals_menu(choice_msg);
3557 /* Modify feature attr/chars (numeric operation) */
3560 static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3562 static int lighting_level = F_LIT_STANDARD;
3563 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3565 /* Hack -- query until done */
3568 feature_type *f_ptr = &f_info[f];
3572 byte da = f_ptr->d_attr[lighting_level];
3573 byte dc = f_ptr->d_char[lighting_level];
3574 byte ca = f_ptr->x_attr[lighting_level];
3575 byte cc = f_ptr->x_char[lighting_level];
3577 /* Label the object */
3579 Term_putstr(5, 17, -1, TERM_WHITE,
3580 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3581 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3583 /* Label the Default values */
3584 Term_putstr(10, 19, -1, TERM_WHITE,
3585 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3587 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3588 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3590 /* Label the Current values */
3592 Term_putstr(10, 20, -1, TERM_WHITE,
3593 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3595 Term_putstr(10, 20, -1, TERM_WHITE,
3596 format("Current attr/char = %3d / %3d", ca, cc));
3599 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3600 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3604 Term_putstr(0, 22, -1, TERM_WHITE,
3605 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3607 Term_putstr(0, 22, -1, TERM_WHITE,
3608 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3615 if (i == ESCAPE) break;
3617 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3618 else if (isupper(i)) c = 'a' + i - 'A';
3628 if (!cmd_visuals_aux(i, &f, max_f_idx))
3634 while (!f_info[f].name || (f_info[f].mimic != f));
3638 t = (int)f_ptr->x_attr[lighting_level];
3639 (void)cmd_visuals_aux(i, &t, 256);
3640 f_ptr->x_attr[lighting_level] = (byte)t;
3644 t = (int)f_ptr->x_char[lighting_level];
3645 (void)cmd_visuals_aux(i, &t, 256);
3646 f_ptr->x_char[lighting_level] = (byte)t;
3650 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3653 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3657 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3661 print_visuals_menu(choice_msg);
3669 /* Modify monster attr/chars (visual mode) */
3671 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3674 /* Modify object attr/chars (visual mode) */
3676 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3679 /* Modify feature attr/chars (visual mode) */
3682 int lighting_level = F_LIT_STANDARD;
3683 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3687 #endif /* ALLOW_VISUALS */
3696 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3700 /* Unknown option */
3706 /* Flush messages */
3710 /* Restore the screen */
3713 if (need_redraw) do_cmd_redraw();
3718 * Interact with "colors"
3720 void do_cmd_colors(void)
3729 /* File type is "TEXT" */
3730 FILE_TYPE(FILE_TYPE_TEXT);
3733 /* Save the screen */
3737 /* Interact until done */
3743 /* Ask for a choice */
3744 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3746 /* Give some choices */
3747 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3750 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3751 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3755 prt(_("コマンド: ", "Command: "), 8, 0);
3760 if (i == ESCAPE) break;
3762 /* Load a 'pref' file */
3766 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3769 prt(_("ファイル: ", "File: "), 10, 0);
3772 sprintf(tmp, "%s.prf", player_base);
3775 if (!askfor(tmp, 70)) continue;
3777 /* Process the given filename */
3778 (void)process_pref_file(tmp);
3780 /* Mega-Hack -- react to changes */
3781 Term_xtra(TERM_XTRA_REACT, 0);
3783 /* Mega-Hack -- redraw */
3792 static cptr mark = "Colors";
3795 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3798 prt(_("ファイル: ", "File: "), 10, 0);
3800 /* Default filename */
3801 sprintf(tmp, "%s.prf", player_base);
3803 /* Get a filename */
3804 if (!askfor(tmp, 70)) continue;
3806 /* Build the filename */
3807 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3809 /* Append to the file */
3810 if (!open_auto_dump(buf, mark)) continue;
3813 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3816 for (i = 0; i < 256; i++)
3818 int kv = angband_color_table[i][0];
3819 int rv = angband_color_table[i][1];
3820 int gv = angband_color_table[i][2];
3821 int bv = angband_color_table[i][3];
3823 cptr name = _("未知", "unknown");
3825 /* Skip non-entries */
3826 if (!kv && !rv && !gv && !bv) continue;
3828 /* Extract the color name */
3829 if (i < 16) name = color_names[i];
3831 /* Dump a comment */
3832 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3834 /* Dump the monster attr/char info */
3835 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3843 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3852 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3854 /* Hack -- query until done */
3863 /* Exhibit the normal colors */
3864 for (j = 0; j < 16; j++)
3866 /* Exhibit this color */
3867 Term_putstr(j*4, 20, -1, a, "###");
3869 /* Exhibit all colors */
3870 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3873 /* Describe the color */
3874 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3876 /* Describe the color */
3877 Term_putstr(5, 10, -1, TERM_WHITE,
3878 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3880 /* Label the Current values */
3881 Term_putstr(5, 12, -1, TERM_WHITE,
3882 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3883 angband_color_table[a][0],
3884 angband_color_table[a][1],
3885 angband_color_table[a][2],
3886 angband_color_table[a][3]));
3889 Term_putstr(0, 14, -1, TERM_WHITE,
3890 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3897 if (i == ESCAPE) break;
3900 if (i == 'n') a = (byte)(a + 1);
3901 if (i == 'N') a = (byte)(a - 1);
3902 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3903 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3904 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3905 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3906 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3907 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3908 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3909 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3911 /* Hack -- react to changes */
3912 Term_xtra(TERM_XTRA_REACT, 0);
3914 /* Hack -- redraw */
3921 /* Unknown option */
3927 /* Flush messages */
3932 /* Restore the screen */
3938 * Note something in the message recall
3940 void do_cmd_note(void)
3948 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3950 /* Ignore empty notes */
3951 if (!buf[0] || (buf[0] == ' ')) return;
3953 /* Add the note to the message recall */
3954 msg_format(_("メモ: %s", "Note: %s"), buf);
3959 * Mention the current version
3961 void do_cmd_version(void)
3964 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3965 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3971 * Array of feeling strings
3973 static cptr do_cmd_feeling_text[11] =
3975 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3976 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3977 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3978 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3979 _("とても悪い予感がする...", "You have a very bad feeling..."),
3980 _("悪い予感がする...", "You have a bad feeling..."),
3981 _("何か緊張する。", "You feel nervous."),
3982 _("少し不運な気がする...", "You feel your luck is turning..."),
3983 _("この場所は好きになれない。", "You don't like the look of this place."),
3984 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3985 _("なんて退屈なところだ...", "What a boring place...")
3988 static cptr do_cmd_feeling_text_combat[11] =
3990 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3991 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3992 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3993 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3994 _("とても悪い予感がする...", "You have a very bad feeling..."),
3995 _("悪い予感がする...", "You have a bad feeling..."),
3996 _("何か緊張する。", "You feel nervous."),
3997 _("少し不運な気がする...", "You feel your luck is turning..."),
3998 _("この場所は好きになれない。", "You don't like the look of this place."),
3999 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
4000 _("なんて退屈なところだ...", "What a boring place...")
4003 static cptr do_cmd_feeling_text_lucky[11] =
4005 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
4006 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
4007 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
4008 _("素晴らしい感じがする...", "You have an excellent feeling..."),
4009 _("とても良い感じがする...", "You have a very good feeling..."),
4010 _("良い感じがする...", "You have a good feeling..."),
4011 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
4012 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
4013 _("見た感じ悪くはない...", "You like the look of this place..."),
4014 _("全然駄目ということはないが...", "This level can't be all bad..."),
4015 _("なんて退屈なところだ...", "What a boring place...")
4020 * Note that "feeling" is set to zero unless some time has passed.
4021 * Note that this is done when the level is GENERATED, not entered.
4023 void do_cmd_feeling(void)
4025 /* No useful feeling in quests */
4026 if (p_ptr->inside_quest && !random_quest_number(dun_level))
4028 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
4032 /* No useful feeling in town */
4033 else if (p_ptr->town_num && !dun_level)
4035 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
4037 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
4042 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
4047 /* No useful feeling in the wilderness */
4048 else if (!dun_level)
4050 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
4054 /* Display the feeling */
4055 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
4056 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
4057 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
4058 inventory[INVEN_BOW].name1 == ART_CRIMSON)
4059 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
4061 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
4067 * Description of each monster group.
4069 static cptr monster_group_text[] =
4072 "ユニーク", /* "Uniques" */
4073 "乗馬可能なモンスター", /* "Riding" */
4074 "賞金首", /* "Wanted */
4075 "アンバーの王族", /* "Ambertite" */
4104 /* "古代ドラゴン/ワイアーム", */
4165 /* "Ancient Dragon/Wyrm", */
4174 "Multi-Headed Reptile",
4179 "Reptile/Amphibian",
4180 "Spider/Scorpion/Tick",
4182 /* "Major Demon", */
4199 * Symbols of monsters in each group. Note the "Uniques" group
4200 * is handled differently.
4202 static cptr monster_group_char[] =
4259 "!$&()+./=>?[\\]`{|~",
4269 * hook function to sort monsters by level
4271 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4273 u16b *who = (u16b*)(u);
4278 monster_race *r_ptr1 = &r_info[w1];
4279 monster_race *r_ptr2 = &r_info[w2];
4284 if (r_ptr2->level > r_ptr1->level) return TRUE;
4285 if (r_ptr1->level > r_ptr2->level) return FALSE;
4287 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4288 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4293 * Build a list of monster indexes in the given group. Return the number
4294 * of monsters in the group.
4296 * mode & 0x01 : check for non-empty group
4297 * mode & 0x02 : visual operation only
4299 static int collect_monsters(int grp_cur, s16b mon_idx[], byte mode)
4304 /* Get a list of x_char in this group */
4305 cptr group_char = monster_group_char[grp_cur];
4307 /* XXX Hack -- Check if this is the "Uniques" group */
4308 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4310 /* XXX Hack -- Check if this is the "Riding" group */
4311 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4313 /* XXX Hack -- Check if this is the "Wanted" group */
4314 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4316 /* XXX Hack -- Check if this is the "Amberite" group */
4317 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4320 /* Check every race */
4321 for (i = 0; i < max_r_idx; i++)
4323 /* Access the race */
4324 monster_race *r_ptr = &r_info[i];
4326 /* Skip empty race */
4327 if (!r_ptr->name) continue ;
4329 /* Require known monsters */
4330 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4334 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4337 else if (grp_riding)
4339 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4342 else if (grp_wanted)
4344 bool wanted = FALSE;
4346 for (j = 0; j < MAX_KUBI; j++)
4348 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4349 (p_ptr->today_mon && p_ptr->today_mon == i))
4355 if (!wanted) continue;
4358 else if (grp_amberite)
4360 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4365 /* Check for race in the group */
4366 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4370 mon_idx[mon_cnt++] = i;
4372 /* XXX Hack -- Just checking for non-empty group */
4373 if (mode & 0x01) break;
4376 /* Terminate the list */
4377 mon_idx[mon_cnt] = -1;
4379 /* Select the sort method */
4380 ang_sort_comp = ang_sort_comp_monster_level;
4381 ang_sort_swap = ang_sort_swap_hook;
4383 /* Sort by monster level */
4384 ang_sort(mon_idx, &dummy_why, mon_cnt);
4386 /* Return the number of races */
4392 * Description of each monster group.
4394 static cptr object_group_text[] =
4397 "キノコ", /* "Mushrooms" */
4398 "薬", /* "Potions" */
4399 "油つぼ", /* "Flasks" */
4400 "巻物", /* "Scrolls" */
4402 "アミュレット", /* "Amulets" */
4403 "笛", /* "Whistle" */
4404 "光源", /* "Lanterns" */
4405 "魔法棒", /* "Wands" */
4408 "カード", /* "Cards" */
4419 "刀剣類", /* "Swords" */
4420 "鈍器", /* "Blunt Weapons" */
4421 "長柄武器", /* "Polearms" */
4422 "採掘道具", /* "Diggers" */
4423 "飛び道具", /* "Bows" */
4427 "軽装鎧", /* "Soft Armor" */
4428 "重装鎧", /* "Hard Armor" */
4429 "ドラゴン鎧", /* "Dragon Armor" */
4430 "盾", /* "Shields" */
4431 "クローク", /* "Cloaks" */
4432 "籠手", /* "Gloves" */
4433 "ヘルメット", /* "Helms" */
4435 "ブーツ", /* "Boots" */
4488 * TVALs of items in each group
4490 static byte object_group_tval[] =
4531 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4539 * Build a list of object indexes in the given group. Return the number
4540 * of objects in the group.
4542 * mode & 0x01 : check for non-empty group
4543 * mode & 0x02 : visual operation only
4545 static int collect_objects(int grp_cur, int object_idx[], byte mode)
4547 int i, j, k, object_cnt = 0;
4549 /* Get a list of x_char in this group */
4550 byte group_tval = object_group_tval[grp_cur];
4552 /* Check every object */
4553 for (i = 0; i < max_k_idx; i++)
4555 /* Access the object */
4556 object_kind *k_ptr = &k_info[i];
4558 /* Skip empty objects */
4559 if (!k_ptr->name) continue;
4563 /* Any objects will be displayed */
4569 /* Skip non-flavoured objects */
4570 if (!k_ptr->flavor) continue;
4572 /* Require objects ever seen */
4573 if (!k_ptr->aware) continue;
4576 /* Skip items with no distribution (special artifacts) */
4577 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4581 /* Check for objects in the group */
4582 if (TV_LIFE_BOOK == group_tval)
4584 /* Hack -- All spell books */
4585 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4587 /* Add the object */
4588 object_idx[object_cnt++] = i;
4592 else if (k_ptr->tval == group_tval)
4594 /* Add the object */
4595 object_idx[object_cnt++] = i;
4599 /* XXX Hack -- Just checking for non-empty group */
4600 if (mode & 0x01) break;
4603 /* Terminate the list */
4604 object_idx[object_cnt] = -1;
4606 /* Return the number of objects */
4612 * Description of each feature group.
4614 static cptr feature_group_text[] =
4622 * Build a list of feature indexes in the given group. Return the number
4623 * of features in the group.
4625 * mode & 0x01 : check for non-empty group
4627 static int collect_features(int grp_cur, int *feat_idx, byte mode)
4629 int i, feat_cnt = 0;
4631 /* Unused; There is a single group. */
4634 /* Check every feature */
4635 for (i = 0; i < max_f_idx; i++)
4637 /* Access the index */
4638 feature_type *f_ptr = &f_info[i];
4640 /* Skip empty index */
4641 if (!f_ptr->name) continue;
4643 /* Skip mimiccing features */
4644 if (f_ptr->mimic != i) continue;
4647 feat_idx[feat_cnt++] = i;
4649 /* XXX Hack -- Just checking for non-empty group */
4650 if (mode & 0x01) break;
4653 /* Terminate the list */
4654 feat_idx[feat_cnt] = -1;
4656 /* Return the number of races */
4663 * Build a list of monster indexes in the given group. Return the number
4664 * of monsters in the group.
4666 static int collect_artifacts(int grp_cur, int object_idx[])
4668 int i, object_cnt = 0;
4670 /* Get a list of x_char in this group */
4671 byte group_tval = object_group_tval[grp_cur];
4673 /* Check every object */
4674 for (i = 0; i < max_a_idx; i++)
4676 /* Access the artifact */
4677 artifact_type *a_ptr = &a_info[i];
4679 /* Skip empty artifacts */
4680 if (!a_ptr->name) continue;
4682 /* Skip "uncreated" artifacts */
4683 if (!a_ptr->cur_num) continue;
4685 /* Check for race in the group */
4686 if (a_ptr->tval == group_tval)
4689 object_idx[object_cnt++] = i;
4693 /* Terminate the list */
4694 object_idx[object_cnt] = 0;
4696 /* Return the number of races */
4703 * Encode the screen colors
4705 static char hack[17] = "dwsorgbuDWvyRGBU";
4709 * Hack -- load a screen dump from a file
4711 void do_cmd_load_screen(void)
4726 Term_get_size(&wid, &hgt);
4728 /* Build the filename */
4729 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4731 /* Append to the file */
4732 fff = my_fopen(buf, "r");
4736 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4742 /* Save the screen */
4745 /* Clear the screen */
4749 /* Load the screen */
4750 for (y = 0; okay; y++)
4752 /* Get a line of data including control code */
4753 if (!fgets(buf, 1024, fff)) okay = FALSE;
4755 /* Get the blank line */
4756 if (buf[0] == '\n' || buf[0] == '\0') break;
4758 /* Ignore too large screen image */
4759 if (y >= hgt) continue;
4762 for (x = 0; x < wid - 1; x++)
4765 if (buf[x] == '\n' || buf[x] == '\0') break;
4767 /* Put the attr/char */
4768 Term_draw(x, y, TERM_WHITE, buf[x]);
4772 /* Dump the screen */
4773 for (y = 0; okay; y++)
4775 /* Get a line of data including control code */
4776 if (!fgets(buf, 1024, fff)) okay = FALSE;
4778 /* Get the blank line */
4779 if (buf[0] == '\n' || buf[0] == '\0') break;
4781 /* Ignore too large screen image */
4782 if (y >= hgt) continue;
4785 for (x = 0; x < wid - 1; x++)
4788 if (buf[x] == '\n' || buf[x] == '\0') break;
4790 /* Get the attr/char */
4791 (void)(Term_what(x, y, &a, &c));
4793 /* Look up the attr */
4794 for (i = 0; i < 16; i++)
4796 /* Use attr matches */
4797 if (hack[i] == buf[x]) a = i;
4800 /* Put the attr/char */
4801 Term_draw(x, y, a, c);
4811 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4817 /* Restore the screen */
4824 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4825 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4828 #define IM_FLAG_STR _("*", "* ")
4829 #define HAS_FLAG_STR _("+", "+ ")
4830 #define NO_FLAG_STR _("・", ". ")
4832 #define print_im_or_res_flag(IM, RES) \
4834 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4835 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4838 #define print_flag(TR) \
4840 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4844 /* XTRA HACK RESLIST */
4845 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, byte tval, char *where)
4847 char o_name[MAX_NLEN];
4848 u32b flgs[TR_FLAG_SIZE];
4850 if (!o_ptr->k_idx) return;
4851 if (o_ptr->tval != tval) return;
4853 /* Identified items only */
4854 if (!object_is_known(o_ptr)) return;
4857 * HACK:Ring of Lordly protection and Dragon equipment
4858 * have random resistances.
4860 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4861 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4862 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4863 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4864 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4865 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4866 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4867 || object_is_artifact(o_ptr))
4870 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4872 while (o_name[i] && (i < 26))
4875 if (iskanji(o_name[i])) i++;
4884 o_name[i] = ' '; i++;
4889 fprintf(fff, "%s %s", where, o_name);
4891 if (!(o_ptr->ident & (IDENT_MENTAL)))
4893 fputs(_("-------不明--------------- -------不明---------\n",
4894 "-------unknown------------ -------unknown------\n"), fff);
4898 object_flags_known(o_ptr, flgs);
4900 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4901 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4902 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4903 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4904 print_flag(TR_RES_POIS);
4905 print_flag(TR_RES_LITE);
4906 print_flag(TR_RES_DARK);
4907 print_flag(TR_RES_SHARDS);
4908 print_flag(TR_RES_SOUND);
4909 print_flag(TR_RES_NETHER);
4910 print_flag(TR_RES_NEXUS);
4911 print_flag(TR_RES_CHAOS);
4912 print_flag(TR_RES_DISEN);
4916 print_flag(TR_RES_BLIND);
4917 print_flag(TR_RES_FEAR);
4918 print_flag(TR_RES_CONF);
4919 print_flag(TR_FREE_ACT);
4920 print_flag(TR_SEE_INVIS);
4921 print_flag(TR_HOLD_EXP);
4922 print_flag(TR_TELEPATHY);
4923 print_flag(TR_SLOW_DIGEST);
4924 print_flag(TR_REGEN);
4925 print_flag(TR_LEVITATION);
4933 fprintf(fff, "%s\n", inven_res_label);
4939 * Display *ID* ed weapons/armors's resistances
4941 static void do_cmd_knowledge_inven(void)
4945 char file_name[1024];
4955 /* Open a new file */
4956 fff = my_fopen_temp(file_name, 1024);
4959 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4963 fprintf(fff, "%s\n", inven_res_label);
4965 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4969 for (; j < 9; j++) fputc('\n', fff);
4971 fprintf(fff, "%s\n", inven_res_label);
4973 strcpy(where, _("装", "E "));
4974 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4976 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4978 strcpy(where, _("持", "I "));
4979 for (i = 0; i < INVEN_PACK; i++)
4981 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4984 st_ptr = &town[1].store[STORE_HOME];
4985 strcpy(where, _("家", "H "));
4986 for (i = 0; i < st_ptr->stock_num; i++)
4988 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4992 /* Close the file */
4995 /* Display the file contents */
4996 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4998 /* Remove the file */
5003 void do_cmd_save_screen_html_aux(char *filename, int message)
5007 byte a = 0, old_a = 0;
5021 cptr html_head[] = {
5022 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
5026 cptr html_foot[] = {
5028 "</body>\n</html>\n",
5034 Term_get_size(&wid, &hgt);
5036 /* File type is "TEXT" */
5037 FILE_TYPE(FILE_TYPE_TEXT);
5039 /* Append to the file */
5040 fff = my_fopen(filename, "w");
5045 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
5052 /* Save the screen */
5056 /* Build the filename */
5057 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
5058 tmpfff = my_fopen(buf, "r");
5060 for (i = 0; html_head[i]; i++)
5061 fputs(html_head[i], fff);
5065 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
5067 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
5071 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
5073 fprintf(fff, "%s\n", buf);
5078 /* Dump the screen */
5079 for (y = 0; y < hgt; y++)
5086 for (x = 0; x < wid - 1; x++)
5090 /* Get the attr/char */
5091 (void)(Term_what(x, y, &a, &c));
5095 case '&': cc = "&"; break;
5096 case '<': cc = "<"; break;
5097 case '>': cc = ">"; break;
5099 case 0x1f: c = '.'; break;
5100 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
5105 if ((y == 0 && x == 0) || a != old_a) {
5106 rv = angband_color_table[a][1];
5107 gv = angband_color_table[a][2];
5108 bv = angband_color_table[a][3];
5109 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
5110 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
5114 fprintf(fff, "%s", cc);
5116 fprintf(fff, "%c", c);
5119 fprintf(fff, "</font>");
5122 for (i = 0; html_foot[i]; i++)
5123 fputs(html_foot[i], fff);
5128 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
5130 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
5134 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
5136 fprintf(fff, "%s\n", buf);
5150 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5154 /* Restore the screen */
5160 * Hack -- save a screen dump to a file
5162 static void do_cmd_save_screen_html(void)
5164 char buf[1024], tmp[256] = "screen.html";
5166 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
5169 /* Build the filename */
5170 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
5174 do_cmd_save_screen_html_aux(buf, 1);
5179 * Redefinable "save_screen" action
5181 void (*screendump_aux)(void) = NULL;
5185 * Hack -- save a screen dump to a file
5187 void do_cmd_save_screen(void)
5189 bool old_use_graphics = use_graphics;
5190 bool html_dump = FALSE;
5194 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5198 if (c == 'Y' || c == 'y')
5200 else if (c == 'H' || c == 'h')
5212 Term_get_size(&wid, &hgt);
5214 if (old_use_graphics)
5216 use_graphics = FALSE;
5219 /* Redraw everything */
5220 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5222 /* Hack -- update */
5228 do_cmd_save_screen_html();
5232 /* Do we use a special screendump function ? */
5233 else if (screendump_aux)
5235 /* Dump the screen to a graphics file */
5236 (*screendump_aux)();
5238 else /* Dump the screen as text */
5249 /* Build the filename */
5250 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5252 /* File type is "TEXT" */
5253 FILE_TYPE(FILE_TYPE_TEXT);
5255 /* Append to the file */
5256 fff = my_fopen(buf, "w");
5261 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5267 /* Save the screen */
5271 /* Dump the screen */
5272 for (y = 0; y < hgt; y++)
5275 for (x = 0; x < wid - 1; x++)
5277 /* Get the attr/char */
5278 (void)(Term_what(x, y, &a, &c));
5288 fprintf(fff, "%s\n", buf);
5295 /* Dump the screen */
5296 for (y = 0; y < hgt; y++)
5299 for (x = 0; x < wid - 1; x++)
5301 /* Get the attr/char */
5302 (void)(Term_what(x, y, &a, &c));
5305 buf[x] = hack[a&0x0F];
5312 fprintf(fff, "%s\n", buf);
5323 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5326 /* Restore the screen */
5330 if (old_use_graphics)
5332 use_graphics = TRUE;
5335 /* Redraw everything */
5336 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5338 /* Hack -- update */
5345 * Sorting hook -- Comp function -- see below
5347 * We use "u" to point to array of monster indexes,
5348 * and "v" to select the type of sorting to perform on "u".
5350 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5352 u16b *who = (u16b*)(u);
5354 u16b *why = (u16b*)(v);
5361 /* Sort by total kills */
5364 /* Extract total kills */
5365 z1 = a_info[w1].tval;
5366 z2 = a_info[w2].tval;
5368 /* Compare total kills */
5369 if (z1 < z2) return (TRUE);
5370 if (z1 > z2) return (FALSE);
5374 /* Sort by monster level */
5377 /* Extract levels */
5378 z1 = a_info[w1].sval;
5379 z2 = a_info[w2].sval;
5381 /* Compare levels */
5382 if (z1 < z2) return (TRUE);
5383 if (z1 > z2) return (FALSE);
5387 /* Sort by monster experience */
5390 /* Extract experience */
5391 z1 = a_info[w1].level;
5392 z2 = a_info[w2].level;
5394 /* Compare experience */
5395 if (z1 < z2) return (TRUE);
5396 if (z1 > z2) return (FALSE);
5400 /* Compare indexes */
5406 * Sorting hook -- Swap function -- see below
5408 * We use "u" to point to array of monster indexes,
5409 * and "v" to select the type of sorting to perform.
5411 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5413 u16b *who = (u16b*)(u);
5428 * Check the status of "artifacts"
5430 static void do_cmd_knowledge_artifacts(void)
5432 int i, k, z, x, y, n = 0;
5438 char file_name[1024];
5440 char base_name[MAX_NLEN];
5444 /* Open a new file */
5445 fff = my_fopen_temp(file_name, 1024);
5448 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5453 /* Allocate the "who" array */
5454 C_MAKE(who, max_a_idx, s16b);
5456 /* Allocate the "okay" array */
5457 C_MAKE(okay, max_a_idx, bool);
5459 /* Scan the artifacts */
5460 for (k = 0; k < max_a_idx; k++)
5462 artifact_type *a_ptr = &a_info[k];
5467 /* Skip "empty" artifacts */
5468 if (!a_ptr->name) continue;
5470 /* Skip "uncreated" artifacts */
5471 if (!a_ptr->cur_num) continue;
5477 /* Check the dungeon */
5478 for (y = 0; y < cur_hgt; y++)
5480 for (x = 0; x < cur_wid; x++)
5482 cave_type *c_ptr = &cave[y][x];
5484 s16b this_o_idx, next_o_idx = 0;
5486 /* Scan all objects in the grid */
5487 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5491 /* Acquire object */
5492 o_ptr = &o_list[this_o_idx];
5494 /* Acquire next object */
5495 next_o_idx = o_ptr->next_o_idx;
5497 /* Ignore non-artifacts */
5498 if (!object_is_fixed_artifact(o_ptr)) continue;
5500 /* Ignore known items */
5501 if (object_is_known(o_ptr)) continue;
5503 /* Note the artifact */
5504 okay[o_ptr->name1] = FALSE;
5509 /* Check the inventory and equipment */
5510 for (i = 0; i < INVEN_TOTAL; i++)
5512 object_type *o_ptr = &inventory[i];
5514 /* Ignore non-objects */
5515 if (!o_ptr->k_idx) continue;
5517 /* Ignore non-artifacts */
5518 if (!object_is_fixed_artifact(o_ptr)) continue;
5520 /* Ignore known items */
5521 if (object_is_known(o_ptr)) continue;
5523 /* Note the artifact */
5524 okay[o_ptr->name1] = FALSE;
5527 for (k = 0; k < max_a_idx; k++)
5529 if (okay[k]) who[n++] = k;
5532 /* Select the sort method */
5533 ang_sort_comp = ang_sort_art_comp;
5534 ang_sort_swap = ang_sort_art_swap;
5536 /* Sort the array by dungeon depth of monsters */
5537 ang_sort(who, &why, n);
5539 /* Scan the artifacts */
5540 for (k = 0; k < n; k++)
5542 artifact_type *a_ptr = &a_info[who[k]];
5545 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5547 /* Obtain the base object type */
5548 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5556 /* Get local object */
5559 /* Create fake object */
5560 object_prep(q_ptr, z);
5562 /* Make it an artifact */
5563 q_ptr->name1 = (byte)who[k];
5565 /* Display as if known */
5566 q_ptr->ident |= IDENT_STORE;
5568 /* Describe the artifact */
5569 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5572 /* Hack -- Build the artifact name */
5573 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5576 /* Free the "who" array */
5577 C_KILL(who, max_a_idx, s16b);
5579 /* Free the "okay" array */
5580 C_KILL(okay, max_a_idx, bool);
5582 /* Close the file */
5585 /* Display the file contents */
5586 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5588 /* Remove the file */
5594 * Display known uniques
5595 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5597 static void do_cmd_knowledge_uniques(void)
5605 char file_name[1024];
5608 int n_alive_surface = 0;
5609 int n_alive_over100 = 0;
5610 int n_alive_total = 0;
5613 for (i = 0; i < 10; i++) n_alive[i] = 0;
5615 /* Open a new file */
5616 fff = my_fopen_temp(file_name, 1024);
5620 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5625 /* Allocate the "who" array */
5626 C_MAKE(who, max_r_idx, s16b);
5628 /* Scan the monsters */
5629 for (i = 1; i < max_r_idx; i++)
5631 monster_race *r_ptr = &r_info[i];
5634 if (!r_ptr->name) continue;
5636 /* Require unique monsters */
5637 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5639 /* Only display "known" uniques */
5640 if (!cheat_know && !r_ptr->r_sights) continue;
5642 /* Only print rarity <= 100 uniques */
5643 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5645 /* Only "alive" uniques */
5646 if (r_ptr->max_num == 0) continue;
5650 lev = (r_ptr->level - 1) / 10;
5654 if (max_lev < lev) max_lev = lev;
5656 else n_alive_over100++;
5658 else n_alive_surface++;
5660 /* Collect "appropriate" monsters */
5664 /* Select the sort method */
5665 ang_sort_comp = ang_sort_comp_hook;
5666 ang_sort_swap = ang_sort_swap_hook;
5668 /* Sort the array by dungeon depth of monsters */
5669 ang_sort(who, &why, n);
5671 if (n_alive_surface)
5673 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5674 n_alive_total += n_alive_surface;
5676 for (i = 0; i <= max_lev; i++)
5678 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5679 n_alive_total += n_alive[i];
5681 if (n_alive_over100)
5683 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5684 n_alive_total += n_alive_over100;
5689 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5690 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5694 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5697 /* Scan the monster races */
5698 for (k = 0; k < n; k++)
5700 monster_race *r_ptr = &r_info[who[k]];
5702 /* Print a message */
5703 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, r_ptr->level);
5706 /* Free the "who" array */
5707 C_KILL(who, max_r_idx, s16b);
5709 /* Close the file */
5712 /* Display the file contents */
5713 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5715 /* Remove the file */
5721 * Display weapon-exp
5723 static void do_cmd_knowledge_weapon_exp(void)
5725 int i, j, num, weapon_exp;
5729 char file_name[1024];
5732 /* Open a new file */
5733 fff = my_fopen_temp(file_name, 1024);
5735 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5740 for (i = 0; i < 5; i++)
5742 for (num = 0; num < 64; num++)
5744 for (j = 0; j < max_k_idx; j++)
5746 object_kind *k_ptr = &k_info[j];
5748 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5750 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5752 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5754 fprintf(fff, "%-25s ", tmp);
5755 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5756 else fprintf(fff, " ");
5757 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5758 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5766 /* Close the file */
5769 /* Display the file contents */
5770 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5772 /* Remove the file */
5778 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5782 static void do_cmd_knowledge_spell_exp(void)
5784 int i = 0, spell_exp, exp_level;
5787 const magic_type *s_ptr;
5789 char file_name[1024];
5791 /* Open a new file */
5792 fff = my_fopen_temp(file_name, 1024);
5794 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5799 if (p_ptr->realm1 != REALM_NONE)
5801 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5802 for (i = 0; i < 32; i++)
5804 if (!is_magic(p_ptr->realm1))
5806 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5810 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5812 if (s_ptr->slevel >= 99) continue;
5813 spell_exp = p_ptr->spell_exp[i];
5814 exp_level = spell_exp_level(spell_exp);
5815 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5816 if (p_ptr->realm1 == REALM_HISSATSU)
5817 fprintf(fff, "[--]");
5820 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5821 else fprintf(fff, " ");
5822 fprintf(fff, "%s", exp_level_str[exp_level]);
5824 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5829 if (p_ptr->realm2 != REALM_NONE)
5831 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5832 for (i = 0; i < 32; i++)
5834 if (!is_magic(p_ptr->realm1))
5836 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5840 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5842 if (s_ptr->slevel >= 99) continue;
5844 spell_exp = p_ptr->spell_exp[i + 32];
5845 exp_level = spell_exp_level(spell_exp);
5846 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5847 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5848 else fprintf(fff, " ");
5849 fprintf(fff, "%s", exp_level_str[exp_level]);
5850 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5855 /* Close the file */
5858 /* Display the file contents */
5859 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5861 /* Remove the file */
5867 * @brief スキル情報を表示するコマンドのメインルーチン /
5871 static void do_cmd_knowledge_skill_exp(void)
5873 int i = 0, skill_exp;
5877 char file_name[1024];
5878 char skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5879 _("二刀流 ", "Dual Wielding "),
5880 _("乗馬 ", "Riding ")};
5882 /* Open a new file */
5883 fff = my_fopen_temp(file_name, 1024);
5885 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5890 for (i = 0; i < 3; i++)
5892 skill_exp = p_ptr->skill_exp[i];
5893 fprintf(fff, "%-20s ", skill_name[i]);
5894 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5895 else fprintf(fff, " ");
5896 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5897 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5901 /* Close the file */
5904 /* Display the file contents */
5905 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5907 /* Remove the file */
5913 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5914 * @param Name 変換したい文字列の参照ポインタ
5917 void plural_aux(char *Name)
5919 int NameLen = strlen(Name);
5921 if (my_strstr(Name, "Disembodied hand"))
5923 strcpy(Name, "Disembodied hands that strangled people");
5925 else if (my_strstr(Name, "Colour out of space"))
5927 strcpy(Name, "Colours out of space");
5929 else if (my_strstr(Name, "stairway to hell"))
5931 strcpy(Name, "stairways to hell");
5933 else if (my_strstr(Name, "Dweller on the threshold"))
5935 strcpy(Name, "Dwellers on the threshold");
5937 else if (my_strstr(Name, " of "))
5939 cptr aider = my_strstr(Name, " of ");
5950 if (dummy[i-1] == 's')
5952 strcpy(&(dummy[i]), "es");
5957 strcpy(&(dummy[i]), "s");
5960 strcpy(&(dummy[i+1]), aider);
5961 strcpy(Name, dummy);
5963 else if (my_strstr(Name, "coins"))
5966 strcpy(dummy, "piles of ");
5967 strcat(dummy, Name);
5968 strcpy(Name, dummy);
5971 else if (my_strstr(Name, "Manes"))
5975 else if (streq(&(Name[NameLen - 2]), "ey"))
5977 strcpy(&(Name[NameLen - 2]), "eys");
5979 else if (Name[NameLen - 1] == 'y')
5981 strcpy(&(Name[NameLen - 1]), "ies");
5983 else if (streq(&(Name[NameLen - 4]), "ouse"))
5985 strcpy(&(Name[NameLen - 4]), "ice");
5987 else if (streq(&(Name[NameLen - 2]), "us"))
5989 strcpy(&(Name[NameLen - 2]), "i");
5991 else if (streq(&(Name[NameLen - 6]), "kelman"))
5993 strcpy(&(Name[NameLen - 6]), "kelmen");
5995 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5997 strcpy(&(Name[NameLen - 8]), "wordsmen");
5999 else if (streq(&(Name[NameLen - 7]), "oodsman"))
6001 strcpy(&(Name[NameLen - 7]), "oodsmen");
6003 else if (streq(&(Name[NameLen - 7]), "eastman"))
6005 strcpy(&(Name[NameLen - 7]), "eastmen");
6007 else if (streq(&(Name[NameLen - 8]), "izardman"))
6009 strcpy(&(Name[NameLen - 8]), "izardmen");
6011 else if (streq(&(Name[NameLen - 5]), "geist"))
6013 strcpy(&(Name[NameLen - 5]), "geister");
6015 else if (streq(&(Name[NameLen - 2]), "ex"))
6017 strcpy(&(Name[NameLen - 2]), "ices");
6019 else if (streq(&(Name[NameLen - 2]), "lf"))
6021 strcpy(&(Name[NameLen - 2]), "lves");
6023 else if (suffix(Name, "ch") ||
6024 suffix(Name, "sh") ||
6025 suffix(Name, "nx") ||
6026 suffix(Name, "s") ||
6029 strcpy(&(Name[NameLen]), "es");
6033 strcpy(&(Name[NameLen]), "s");
6038 * @brief 現在のペットを表示するコマンドのメインルーチン /
6039 * Display current pets
6042 static void do_cmd_knowledge_pets(void)
6046 monster_type *m_ptr;
6049 int show_upkeep = 0;
6050 char file_name[1024];
6053 /* Open a new file */
6054 fff = my_fopen_temp(file_name, 1024);
6056 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6061 /* Process the monsters (backwards) */
6062 for (i = m_max - 1; i >= 1; i--)
6064 /* Access the monster */
6067 /* Ignore "dead" monsters */
6068 if (!m_ptr->r_idx) continue;
6070 /* Calculate "upkeep" for pets */
6074 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
6075 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
6079 show_upkeep = calculate_upkeep();
6081 fprintf(fff, "----------------------------------------------\n");
6083 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
6084 fprintf(fff, " 維持コスト: %d%% MP\n", show_upkeep);
6086 fprintf(fff, " Total: %d pet%s.\n",
6087 t_friends, (t_friends == 1 ? "" : "s"));
6088 fprintf(fff, " Upkeep: %d%% mana.\n", show_upkeep);
6093 /* Close the file */
6096 /* Display the file contents */
6097 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
6099 /* Remove the file */
6105 * @brief 現在のペットを表示するコマンドのメインルーチン /
6108 * @note the player ghosts are ignored. XXX XXX XXX
6110 static void do_cmd_knowledge_kill_count(void)
6118 char file_name[1024];
6123 /* Open a new file */
6124 fff = my_fopen_temp(file_name, 1024);
6127 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6132 /* Allocate the "who" array */
6133 C_MAKE(who, max_r_idx, s16b);
6136 /* Monsters slain */
6139 for (kk = 1; kk < max_r_idx; kk++)
6141 monster_race *r_ptr = &r_info[kk];
6143 if (r_ptr->flags1 & (RF1_UNIQUE))
6145 bool dead = (r_ptr->max_num == 0);
6154 s16b This = r_ptr->r_pkills;
6164 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
6167 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
6169 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
6175 /* Scan the monsters */
6176 for (i = 1; i < max_r_idx; i++)
6178 monster_race *r_ptr = &r_info[i];
6180 /* Use that monster */
6181 if (r_ptr->name) who[n++] = i;
6184 /* Select the sort method */
6185 ang_sort_comp = ang_sort_comp_hook;
6186 ang_sort_swap = ang_sort_swap_hook;
6188 /* Sort the array by dungeon depth of monsters */
6189 ang_sort(who, &why, n);
6191 /* Scan the monster races */
6192 for (k = 0; k < n; k++)
6194 monster_race *r_ptr = &r_info[who[k]];
6196 if (r_ptr->flags1 & (RF1_UNIQUE))
6198 bool dead = (r_ptr->max_num == 0);
6202 /* Print a message */
6203 fprintf(fff, " %s\n",
6204 (r_name + r_ptr->name));
6210 s16b This = r_ptr->r_pkills;
6215 /* p,tは人と数える by ita */
6216 if (my_strchr("pt", r_ptr->d_char))
6217 fprintf(fff, " %3d 人の %s\n", This, r_name + r_ptr->name);
6219 fprintf(fff, " %3d 体の %s\n", This, r_name + r_ptr->name);
6223 if (my_strstr(r_name + r_ptr->name, "coins"))
6225 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6229 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6235 strcpy(ToPlural, (r_name + r_ptr->name));
6236 plural_aux(ToPlural);
6237 fprintf(fff, " %d %s\n", This, ToPlural);
6247 fprintf(fff,"----------------------------------------------\n");
6249 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6251 fprintf(fff," Total: %lu creature%s killed.\n",
6252 (unsigned long int)Total, (Total == 1 ? "" : "s"));
6256 /* Free the "who" array */
6257 C_KILL(who, max_r_idx, s16b);
6259 /* Close the file */
6262 /* Display the file contents */
6263 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6265 /* Remove the file */
6271 * @brief モンスター情報リスト中のグループを表示する /
6272 * Display the object groups.
6276 * @param per_page リストの表示行
6277 * @param grp_idx グループのID配列
6278 * @param group_text グループ名の文字列配列
6279 * @param grp_cur 現在の選択ID
6280 * @param grp_top 現在の選択リスト最上部ID
6283 static void display_group_list(int col, int row, int wid, int per_page,
6284 int grp_idx[], cptr group_text[], int grp_cur, int grp_top)
6288 /* Display lines until done */
6289 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6291 /* Get the group index */
6292 int grp = grp_idx[grp_top + i];
6294 /* Choose a color */
6295 byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6297 /* Erase the entire line */
6298 Term_erase(col, row + i, wid);
6300 /* Display the group label */
6301 c_put_str(attr, group_text[grp], row + i, col);
6307 * Move the cursor in a browser window
6309 static void browser_cursor(char ch, int *column, int *grp_cur, int grp_cnt,
6310 int *list_cur, int list_cnt)
6315 int list = *list_cur;
6317 /* Extract direction */
6320 /* Hack -- scroll up full screen */
6325 /* Hack -- scroll down full screen */
6330 d = get_keymap_dir(ch);
6335 /* Diagonals - hack */
6336 if ((ddx[d] > 0) && ddy[d])
6342 Term_get_size(&wid, &hgt);
6344 browser_rows = hgt - 8;
6346 /* Browse group list */
6351 /* Move up or down */
6352 grp += ddy[d] * (browser_rows - 1);
6355 if (grp >= grp_cnt) grp = grp_cnt - 1;
6356 if (grp < 0) grp = 0;
6357 if (grp != old_grp) list = 0;
6360 /* Browse sub-list list */
6363 /* Move up or down */
6364 list += ddy[d] * browser_rows;
6367 if (list >= list_cnt) list = list_cnt - 1;
6368 if (list < 0) list = 0;
6380 if (col < 0) col = 0;
6381 if (col > 1) col = 1;
6388 /* Browse group list */
6393 /* Move up or down */
6397 if (grp >= grp_cnt) grp = grp_cnt - 1;
6398 if (grp < 0) grp = 0;
6399 if (grp != old_grp) list = 0;
6402 /* Browse sub-list list */
6405 /* Move up or down */
6409 if (list >= list_cnt) list = list_cnt - 1;
6410 if (list < 0) list = 0;
6421 static void display_visual_list(int col, int row, int height, int width, byte attr_top, byte char_left)
6425 /* Clear the display lines */
6426 for (i = 0; i < height; i++)
6428 Term_erase(col, row + i, width);
6431 /* Bigtile mode uses double width */
6432 if (use_bigtile) width /= 2;
6434 /* Display lines until done */
6435 for (i = 0; i < height; i++)
6437 /* Display columns until done */
6438 for (j = 0; j < width; j++)
6446 /* Bigtile mode uses double width */
6447 if (use_bigtile) x += j;
6452 /* Ignore illegal characters */
6453 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6454 (!use_graphics && ic > 0x7f))
6460 /* Force correct code for both ASCII character and tile */
6461 if (c & 0x80) a |= 0x80;
6463 /* Display symbol */
6464 Term_queue_bigchar(x, y, a, c, 0, 0);
6471 * Place the cursor at the collect position for visual mode
6473 static void place_visual_list_cursor(int col, int row, byte a, byte c, byte attr_top, byte char_left)
6475 int i = (a & 0x7f) - attr_top;
6476 int j = c - char_left;
6481 /* Bigtile mode uses double width */
6482 if (use_bigtile) x += j;
6484 /* Place the cursor */
6490 * Clipboard variables for copy&paste in visual mode
6492 static byte attr_idx = 0;
6493 static byte char_idx = 0;
6495 /* Hack -- for feature lighting */
6496 static byte attr_idx_feat[F_LIT_MAX];
6497 static byte char_idx_feat[F_LIT_MAX];
6500 * Do visual mode command -- Change symbols
6502 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6503 int height, int width,
6504 byte *attr_top_ptr, byte *char_left_ptr,
6505 byte *cur_attr_ptr, byte *cur_char_ptr, bool *need_redraw)
6507 static byte attr_old = 0, char_old = 0;
6512 if (*visual_list_ptr)
6515 *cur_attr_ptr = attr_old;
6516 *cur_char_ptr = char_old;
6517 *visual_list_ptr = FALSE;
6525 if (*visual_list_ptr)
6528 *visual_list_ptr = FALSE;
6529 *need_redraw = TRUE;
6537 if (!*visual_list_ptr)
6539 *visual_list_ptr = TRUE;
6541 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6542 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6544 attr_old = *cur_attr_ptr;
6545 char_old = *cur_char_ptr;
6556 /* Set the visual */
6557 attr_idx = *cur_attr_ptr;
6558 char_idx = *cur_char_ptr;
6560 /* Hack -- for feature lighting */
6561 for (i = 0; i < F_LIT_MAX; i++)
6563 attr_idx_feat[i] = 0;
6564 char_idx_feat[i] = 0;
6571 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6574 *cur_attr_ptr = attr_idx;
6575 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6576 if (!*visual_list_ptr) *need_redraw = TRUE;
6582 *cur_char_ptr = char_idx;
6583 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6584 if (!*visual_list_ptr) *need_redraw = TRUE;
6590 if (*visual_list_ptr)
6593 int d = get_keymap_dir(ch);
6594 byte a = (*cur_attr_ptr & 0x7f);
6595 byte c = *cur_char_ptr;
6597 if (use_bigtile) eff_width = width / 2;
6598 else eff_width = width;
6600 /* Restrict direction */
6601 if ((a == 0) && (ddy[d] < 0)) d = 0;
6602 if ((c == 0) && (ddx[d] < 0)) d = 0;
6603 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6604 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6609 /* Force correct code for both ASCII character and tile */
6610 if (c & 0x80) a |= 0x80;
6612 /* Set the visual */
6617 /* Move the frame */
6618 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6619 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6620 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6621 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6627 /* Visual mode command is not used */
6633 * Display the monsters in a group.
6635 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6636 int mon_cur, int mon_top, bool visual_only)
6640 /* Display lines until done */
6641 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6645 /* Get the race index */
6646 int r_idx = mon_idx[mon_top + i] ;
6648 /* Access the race */
6649 monster_race *r_ptr = &r_info[r_idx];
6651 /* Choose a color */
6652 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6654 /* Display the name */
6655 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6657 /* Hack -- visual_list mode */
6660 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6662 if (p_ptr->wizard || visual_only)
6664 c_prt(attr, format("%d", r_idx), row + i, 62);
6667 /* Erase chars before overwritten by the race letter */
6668 Term_erase(69, row + i, 255);
6670 /* Display symbol */
6671 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6676 if (!(r_ptr->flags1 & RF1_UNIQUE))
6677 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6679 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6680 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6684 /* Clear remaining lines */
6685 for (; i < per_page; i++)
6687 Term_erase(col, row + i, 255);
6693 * Display known monsters.
6695 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx)
6698 int grp_cur, grp_top, old_grp_cur;
6699 int mon_cur, mon_top;
6700 int grp_cnt, grp_idx[100];
6708 bool visual_list = FALSE;
6709 byte attr_top = 0, char_left = 0;
6717 Term_get_size(&wid, &hgt);
6719 browser_rows = hgt - 8;
6721 /* Allocate the "mon_idx" array */
6722 C_MAKE(mon_idx, max_r_idx, s16b);
6727 if (direct_r_idx < 0)
6729 mode = visual_only ? 0x03 : 0x01;
6731 /* Check every group */
6732 for (i = 0; monster_group_text[i] != NULL; i++)
6734 /* Measure the label */
6735 len = strlen(monster_group_text[i]);
6737 /* Save the maximum length */
6738 if (len > max) max = len;
6740 /* See if any monsters are known */
6741 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6743 /* Build a list of groups with known monsters */
6744 grp_idx[grp_cnt++] = i;
6752 mon_idx[0] = direct_r_idx;
6755 /* Terminate the list */
6758 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6759 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6762 /* Terminate the list */
6763 grp_idx[grp_cnt] = -1;
6766 grp_cur = grp_top = 0;
6767 mon_cur = mon_top = 0;
6772 mode = visual_only ? 0x02 : 0x00;
6777 monster_race *r_ptr;
6784 prt(format("%s - モンスター", !visual_only ? "知識" : "表示"), 2, 0);
6785 if (direct_r_idx < 0) prt("グループ", 4, 0);
6786 prt("名前", 4, max + 3);
6787 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6789 if (!visual_only) prt("殺害数", 4, 72);
6791 prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6792 if (direct_r_idx < 0) prt("Group", 4, 0);
6793 prt("Name", 4, max + 3);
6794 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6796 if (!visual_only) prt("Kills", 4, 73);
6799 for (i = 0; i < 78; i++)
6801 Term_putch(i, 5, TERM_WHITE, '=');
6804 if (direct_r_idx < 0)
6806 for (i = 0; i < browser_rows; i++)
6808 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6815 if (direct_r_idx < 0)
6817 /* Scroll group list */
6818 if (grp_cur < grp_top) grp_top = grp_cur;
6819 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6821 /* Display a list of monster groups */
6822 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6824 if (old_grp_cur != grp_cur)
6826 old_grp_cur = grp_cur;
6828 /* Get a list of monsters in the current group */
6829 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6832 /* Scroll monster list */
6833 while (mon_cur < mon_top)
6834 mon_top = MAX(0, mon_top - browser_rows/2);
6835 while (mon_cur >= mon_top + browser_rows)
6836 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6841 /* Display a list of monsters in the current group */
6842 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6848 /* Display a monster name */
6849 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6851 /* Display visual list below first monster */
6852 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6857 prt(format("<方向>%s%s%s, ESC",
6858 (!visual_list && !visual_only) ? ", 'r'で思い出を見る" : "",
6859 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6860 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6863 prt(format("<dir>%s%s%s, ESC",
6864 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6865 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6866 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6870 /* Get the current monster */
6871 r_ptr = &r_info[mon_idx[mon_cur]];
6875 /* Mega Hack -- track this monster race */
6876 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6878 /* Hack -- handle stuff */
6884 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6888 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6892 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6897 /* Do visual mode command if needed */
6898 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))
6900 if (direct_r_idx >= 0)
6925 /* Recall on screen */
6926 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6928 screen_roff(mon_idx[mon_cur], 0);
6939 /* Move the cursor */
6940 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6947 /* Free the "mon_idx" array */
6948 C_KILL(mon_idx, max_r_idx, s16b);
6953 * Display the objects in a group.
6955 static void display_object_list(int col, int row, int per_page, int object_idx[],
6956 int object_cur, int object_top, bool visual_only)
6960 /* Display lines until done */
6961 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6965 object_kind *flavor_k_ptr;
6967 /* Get the object index */
6968 int k_idx = object_idx[object_top + i];
6970 /* Access the object */
6971 object_kind *k_ptr = &k_info[k_idx];
6973 /* Choose a color */
6974 byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6975 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6978 if (!visual_only && k_ptr->flavor)
6980 /* Appearance of this object is shuffled */
6981 flavor_k_ptr = &k_info[k_ptr->flavor];
6985 /* Appearance of this object is very normal */
6986 flavor_k_ptr = k_ptr;
6991 attr = ((i + object_top == object_cur) ? cursor : attr);
6993 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6996 strip_name(o_name, k_idx);
7001 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
7004 /* Display the name */
7005 c_prt(attr, o_name, row + i, col);
7007 /* Hack -- visual_list mode */
7010 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);
7012 if (p_ptr->wizard || visual_only)
7014 c_prt(attr, format("%d", k_idx), row + i, 70);
7017 a = flavor_k_ptr->x_attr;
7018 c = flavor_k_ptr->x_char;
7020 /* Display symbol */
7021 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
7024 /* Clear remaining lines */
7025 for (; i < per_page; i++)
7027 Term_erase(col, row + i, 255);
7032 * Describe fake object
7034 static void desc_obj_fake(int k_idx)
7037 object_type object_type_body;
7039 /* Get local object */
7040 o_ptr = &object_type_body;
7042 /* Wipe the object */
7045 /* Create the artifact */
7046 object_prep(o_ptr, k_idx);
7048 /* It's fully know */
7049 o_ptr->ident |= IDENT_KNOWN;
7051 /* Track the object */
7052 /* object_actual_track(o_ptr); */
7054 /* Hack - mark as fake */
7055 /* term_obj_real = FALSE; */
7057 /* Hack -- Handle stuff */
7060 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
7062 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
7070 * Display known objects
7072 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx)
7075 int grp_cur, grp_top, old_grp_cur;
7076 int object_old, object_cur, object_top;
7077 int grp_cnt, grp_idx[100];
7085 bool visual_list = FALSE;
7086 byte attr_top = 0, char_left = 0;
7094 Term_get_size(&wid, &hgt);
7096 browser_rows = hgt - 8;
7098 /* Allocate the "object_idx" array */
7099 C_MAKE(object_idx, max_k_idx, int);
7104 if (direct_k_idx < 0)
7106 mode = visual_only ? 0x03 : 0x01;
7108 /* Check every group */
7109 for (i = 0; object_group_text[i] != NULL; i++)
7111 /* Measure the label */
7112 len = strlen(object_group_text[i]);
7114 /* Save the maximum length */
7115 if (len > max) max = len;
7117 /* See if any monsters are known */
7118 if (collect_objects(i, object_idx, mode))
7120 /* Build a list of groups with known monsters */
7121 grp_idx[grp_cnt++] = i;
7130 object_kind *k_ptr = &k_info[direct_k_idx];
7131 object_kind *flavor_k_ptr;
7133 if (!visual_only && k_ptr->flavor)
7135 /* Appearance of this object is shuffled */
7136 flavor_k_ptr = &k_info[k_ptr->flavor];
7140 /* Appearance of this object is very normal */
7141 flavor_k_ptr = k_ptr;
7144 object_idx[0] = direct_k_idx;
7145 object_old = direct_k_idx;
7148 /* Terminate the list */
7151 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7152 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
7155 /* Terminate the list */
7156 grp_idx[grp_cnt] = -1;
7159 grp_cur = grp_top = 0;
7160 object_cur = object_top = 0;
7165 mode = visual_only ? 0x02 : 0x00;
7170 object_kind *k_ptr, *flavor_k_ptr;
7177 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
7178 if (direct_k_idx < 0) prt("グループ", 4, 0);
7179 prt("名前", 4, max + 3);
7180 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
7183 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
7184 if (direct_k_idx < 0) prt("Group", 4, 0);
7185 prt("Name", 4, max + 3);
7186 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
7190 for (i = 0; i < 78; i++)
7192 Term_putch(i, 5, TERM_WHITE, '=');
7195 if (direct_k_idx < 0)
7197 for (i = 0; i < browser_rows; i++)
7199 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7206 if (direct_k_idx < 0)
7208 /* Scroll group list */
7209 if (grp_cur < grp_top) grp_top = grp_cur;
7210 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7212 /* Display a list of object groups */
7213 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
7215 if (old_grp_cur != grp_cur)
7217 old_grp_cur = grp_cur;
7219 /* Get a list of objects in the current group */
7220 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
7223 /* Scroll object list */
7224 while (object_cur < object_top)
7225 object_top = MAX(0, object_top - browser_rows/2);
7226 while (object_cur >= object_top + browser_rows)
7227 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
7232 /* Display a list of objects in the current group */
7233 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
7237 object_top = object_cur;
7239 /* Display a list of objects in the current group */
7240 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
7242 /* Display visual list below first object */
7243 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7246 /* Get the current object */
7247 k_ptr = &k_info[object_idx[object_cur]];
7249 if (!visual_only && k_ptr->flavor)
7251 /* Appearance of this object is shuffled */
7252 flavor_k_ptr = &k_info[k_ptr->flavor];
7256 /* Appearance of this object is very normal */
7257 flavor_k_ptr = k_ptr;
7262 prt(format("<方向>%s%s%s, ESC",
7263 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7264 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7265 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7268 prt(format("<dir>%s%s%s, ESC",
7269 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7270 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7271 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7277 /* Mega Hack -- track this object */
7278 if (object_cnt) object_kind_track(object_idx[object_cur]);
7280 /* The "current" object changed */
7281 if (object_old != object_idx[object_cur])
7283 /* Hack -- handle stuff */
7286 /* Remember the "current" object */
7287 object_old = object_idx[object_cur];
7293 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7297 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7301 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7306 /* Do visual mode command if needed */
7307 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))
7309 if (direct_k_idx >= 0)
7334 /* Recall on screen */
7335 if (!visual_list && !visual_only && (grp_cnt > 0))
7337 desc_obj_fake(object_idx[object_cur]);
7345 /* Move the cursor */
7346 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7352 /* Free the "object_idx" array */
7353 C_KILL(object_idx, max_k_idx, int);
7358 * Display the features in a group.
7360 static void display_feature_list(int col, int row, int per_page, int *feat_idx,
7361 int feat_cur, int feat_top, bool visual_only, int lighting_level)
7363 int lit_col[F_LIT_MAX], i, j;
7364 int f_idx_col = use_bigtile ? 62 : 64;
7366 /* Correct columns 1 and 4 */
7367 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7368 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7369 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7371 /* Display lines until done */
7372 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7377 int f_idx = feat_idx[feat_top + i];
7379 /* Access the index */
7380 feature_type *f_ptr = &f_info[f_idx];
7382 int row_i = row + i;
7384 /* Choose a color */
7385 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7387 /* Display the name */
7388 c_prt(attr, f_name + f_ptr->name, row_i, col);
7390 /* Hack -- visual_list mode */
7393 /* Display lighting level */
7394 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7396 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));
7398 if (p_ptr->wizard || visual_only)
7400 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7403 /* Display symbol */
7404 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);
7406 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7407 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7409 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7411 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7413 /* Mega-hack -- Use non-standard colour */
7414 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7416 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7420 /* Clear remaining lines */
7421 for (; i < per_page; i++)
7423 Term_erase(col, row + i, 255);
7429 * Interact with feature visuals.
7431 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level)
7434 int grp_cur, grp_top, old_grp_cur;
7435 int feat_cur, feat_top;
7436 int grp_cnt, grp_idx[100];
7444 bool visual_list = FALSE;
7445 byte attr_top = 0, char_left = 0;
7450 byte attr_old[F_LIT_MAX];
7451 byte char_old[F_LIT_MAX];
7452 byte *cur_attr_ptr, *cur_char_ptr;
7454 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7455 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7458 Term_get_size(&wid, &hgt);
7460 browser_rows = hgt - 8;
7462 /* Allocate the "feat_idx" array */
7463 C_MAKE(feat_idx, max_f_idx, int);
7468 if (direct_f_idx < 0)
7470 /* Check every group */
7471 for (i = 0; feature_group_text[i] != NULL; i++)
7473 /* Measure the label */
7474 len = strlen(feature_group_text[i]);
7476 /* Save the maximum length */
7477 if (len > max) max = len;
7479 /* See if any features are known */
7480 if (collect_features(i, feat_idx, 0x01))
7482 /* Build a list of groups with known features */
7483 grp_idx[grp_cnt++] = i;
7491 feature_type *f_ptr = &f_info[direct_f_idx];
7493 feat_idx[0] = direct_f_idx;
7496 /* Terminate the list */
7499 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7500 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7502 for (i = 0; i < F_LIT_MAX; i++)
7504 attr_old[i] = f_ptr->x_attr[i];
7505 char_old[i] = f_ptr->x_char[i];
7509 /* Terminate the list */
7510 grp_idx[grp_cnt] = -1;
7513 grp_cur = grp_top = 0;
7514 feat_cur = feat_top = 0;
7522 feature_type *f_ptr;
7529 prt("表示 - 地形", 2, 0);
7530 if (direct_f_idx < 0) prt("グループ", 4, 0);
7531 prt("名前", 4, max + 3);
7534 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7535 prt("文字 ( l/ d)", 4, 66);
7539 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7540 prt("文字 (l/d)", 4, 68);
7543 prt("Visuals - features", 2, 0);
7544 if (direct_f_idx < 0) prt("Group", 4, 0);
7545 prt("Name", 4, max + 3);
7548 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7549 prt("Sym ( l/ d)", 4, 67);
7553 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7554 prt("Sym (l/d)", 4, 69);
7558 for (i = 0; i < 78; i++)
7560 Term_putch(i, 5, TERM_WHITE, '=');
7563 if (direct_f_idx < 0)
7565 for (i = 0; i < browser_rows; i++)
7567 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7574 if (direct_f_idx < 0)
7576 /* Scroll group list */
7577 if (grp_cur < grp_top) grp_top = grp_cur;
7578 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7580 /* Display a list of feature groups */
7581 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7583 if (old_grp_cur != grp_cur)
7585 old_grp_cur = grp_cur;
7587 /* Get a list of features in the current group */
7588 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7591 /* Scroll feature list */
7592 while (feat_cur < feat_top)
7593 feat_top = MAX(0, feat_top - browser_rows/2);
7594 while (feat_cur >= feat_top + browser_rows)
7595 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7600 /* Display a list of features in the current group */
7601 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7605 feat_top = feat_cur;
7607 /* Display a list of features in the current group */
7608 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7610 /* Display visual list below first object */
7611 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7616 prt(format("<方向>%s, 'd'で標準光源効果%s, ESC",
7617 visual_list ? ", ENTERで決定, 'a'で対象明度変更" : ", 'v'でシンボル変更",
7618 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7621 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
7622 visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
7623 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7627 /* Get the current feature */
7628 f_ptr = &f_info[feat_idx[feat_cur]];
7629 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7630 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7634 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7638 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7642 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7647 if (visual_list && ((ch == 'A') || (ch == 'a')))
7649 int prev_lighting_level = *lighting_level;
7653 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7654 else (*lighting_level)--;
7658 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7659 else (*lighting_level)++;
7662 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7663 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7665 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7666 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7671 else if ((ch == 'D') || (ch == 'd'))
7673 byte prev_x_attr = f_ptr->x_attr[*lighting_level];
7674 byte prev_x_char = f_ptr->x_char[*lighting_level];
7676 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7680 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7681 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7683 if (prev_x_char != f_ptr->x_char[*lighting_level])
7684 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7686 else *need_redraw = TRUE;
7691 /* Do visual mode command if needed */
7692 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))
7696 /* Restore previous visual settings */
7698 for (i = 0; i < F_LIT_MAX; i++)
7700 f_ptr->x_attr[i] = attr_old[i];
7701 f_ptr->x_char[i] = char_old[i];
7708 if (direct_f_idx >= 0) flag = TRUE;
7709 else *lighting_level = F_LIT_STANDARD;
7712 /* Preserve current visual settings */
7715 for (i = 0; i < F_LIT_MAX; i++)
7717 attr_old[i] = f_ptr->x_attr[i];
7718 char_old[i] = f_ptr->x_char[i];
7720 *lighting_level = F_LIT_STANDARD;
7727 for (i = 0; i < F_LIT_MAX; i++)
7729 attr_idx_feat[i] = f_ptr->x_attr[i];
7730 char_idx_feat[i] = f_ptr->x_char[i];
7739 /* Allow TERM_DARK text */
7740 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7742 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7743 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7761 /* Move the cursor */
7762 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7768 /* Free the "feat_idx" array */
7769 C_KILL(feat_idx, max_f_idx, int);
7774 * List wanted monsters
7776 static void do_cmd_knowledge_kubi(void)
7781 char file_name[1024];
7784 /* Open a new file */
7785 fff = my_fopen_temp(file_name, 1024);
7787 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7794 bool listed = FALSE;
7797 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7799 fprintf(fff, "賞金首リスト\n");
7801 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7803 fprintf(fff, "List of wanted monsters\n");
7805 fprintf(fff, "----------------------------------------------\n");
7807 for (i = 0; i < MAX_KUBI; i++)
7809 if (kubi_r_idx[i] <= 10000)
7811 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7819 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7823 /* Close the file */
7826 /* Display the file contents */
7827 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7829 /* Remove the file */
7834 * List virtues & status
7836 static void do_cmd_knowledge_virtues(void)
7840 char file_name[1024];
7843 /* Open a new file */
7844 fff = my_fopen_temp(file_name, 1024);
7846 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7853 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7857 /* Close the file */
7860 /* Display the file contents */
7861 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7863 /* Remove the file */
7871 static void do_cmd_knowledge_dungeon(void)
7875 char file_name[1024];
7879 /* Open a new file */
7880 fff = my_fopen_temp(file_name, 1024);
7882 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7889 for (i = 1; i < max_d_idx; i++)
7893 if (!d_info[i].maxdepth) continue;
7894 if (!max_dlv[i]) continue;
7895 if (d_info[i].final_guardian)
7897 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7899 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7901 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, max_dlv[i]);
7905 /* Close the file */
7908 /* Display the file contents */
7909 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7911 /* Remove the file */
7916 * List virtues & status
7919 static void do_cmd_knowledge_stat(void)
7923 char file_name[1024];
7926 /* Open a new file */
7927 fff = my_fopen_temp(file_name, 1024);
7929 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7936 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7937 (2 * p_ptr->hitdie +
7938 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7941 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7942 else fprintf(fff, "現在の体力ランク : ???\n\n");
7943 fprintf(fff, "能力の最大値\n\n");
7945 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7946 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7947 fprintf(fff, "Limits of maximum stats\n\n");
7949 for (v_nr = 0; v_nr < 6; v_nr++)
7951 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);
7952 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7958 /* Close the file */
7961 /* Display the file contents */
7962 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7964 /* Remove the file */
7970 * Print all active quests
7972 static void do_cmd_knowledge_quests_current(FILE *fff)
7975 char rand_tmp_str[120] = "\0";
7977 monster_race *r_ptr;
7979 int rand_level = 100;
7982 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7984 for (i = 1; i < max_quests; i++)
7986 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7987 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7988 (quest[i].status == QUEST_STATUS_COMPLETED))
7990 /* Set the quest number temporary */
7991 int old_quest = p_ptr->inside_quest;
7994 /* Clear the text */
7995 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7996 quest_text_line = 0;
7998 p_ptr->inside_quest = i;
8000 /* Get the quest text */
8001 init_flags = INIT_SHOW_TEXT;
8003 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
8005 /* Reset the old quest number */
8006 p_ptr->inside_quest = old_quest;
8008 /* No info from "silent" quests */
8009 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8013 if (quest[i].type != QUEST_TYPE_RANDOM)
8015 char note[80] = "\0";
8017 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
8019 switch (quest[i].type)
8021 case QUEST_TYPE_KILL_LEVEL:
8022 case QUEST_TYPE_KILL_ANY_LEVEL:
8023 r_ptr = &r_info[quest[i].r_idx];
8024 strcpy(name, r_name + r_ptr->name);
8025 if (quest[i].max_num > 1)
8028 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
8029 quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
8032 sprintf(note," - kill %d %s, have killed %d.",
8033 quest[i].max_num, name, quest[i].cur_num);
8037 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
8040 case QUEST_TYPE_FIND_ARTIFACT:
8043 artifact_type *a_ptr = &a_info[quest[i].k_idx];
8045 object_type *q_ptr = &forge;
8046 int k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
8047 object_prep(q_ptr, k_idx);
8048 q_ptr->name1 = quest[i].k_idx;
8049 q_ptr->ident = IDENT_STORE;
8050 object_desc(name, q_ptr, OD_NAME_ONLY);
8052 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
8054 case QUEST_TYPE_FIND_EXIT:
8055 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
8058 case QUEST_TYPE_KILL_NUMBER:
8060 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
8061 quest[i].max_num, quest[i].max_num - quest[i].cur_num);
8063 sprintf(note," - Kill %d monsters, have killed %d.",
8064 quest[i].max_num, quest[i].cur_num);
8068 case QUEST_TYPE_KILL_ALL:
8069 case QUEST_TYPE_TOWER:
8070 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
8075 /* Print the quest info */
8077 sprintf(tmp_str, " %s (危険度:%d階相当)%s\n",
8078 quest[i].name, quest[i].level, note);
8080 sprintf(tmp_str, " %s (Danger level: %d)%s\n",
8081 quest[i].name, quest[i].level, note);
8084 fputs(tmp_str, fff);
8086 if (quest[i].status == QUEST_STATUS_COMPLETED)
8088 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
8089 fputs(tmp_str, fff);
8095 while (quest_text[j][0] && j < 10)
8097 fprintf(fff, " %s\n", quest_text[j]);
8102 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
8105 rand_level = quest[i].level;
8107 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
8109 /* Print the quest info */
8110 r_ptr = &r_info[quest[i].r_idx];
8111 strcpy(name, r_name + r_ptr->name);
8113 if (quest[i].max_num > 1)
8116 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
8117 quest[i].name, quest[i].level,
8118 quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
8122 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
8123 quest[i].name, quest[i].level,
8124 quest[i].max_num, name, quest[i].cur_num);
8130 sprintf(rand_tmp_str," %s (%d 階) - %sを倒す。\n",
8131 quest[i].name, quest[i].level, name);
8133 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %s.\n",
8134 quest[i].name, quest[i].level, name);
8142 /* Print the current random quest */
8143 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
8145 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8149 static bool do_cmd_knowledge_quests_aux(FILE *fff, int q_idx)
8152 char playtime_str[16];
8153 quest_type* const q_ptr = &quest[q_idx];
8155 if (is_fixed_quest_idx(q_idx))
8157 /* Set the quest number temporary */
8158 int old_quest = p_ptr->inside_quest;
8160 p_ptr->inside_quest = q_idx;
8163 init_flags = INIT_NAME_ONLY;
8165 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
8167 /* Reset the old quest number */
8168 p_ptr->inside_quest = old_quest;
8170 /* No info from "silent" quests */
8171 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
8174 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
8175 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
8177 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
8179 /* Print the quest info */
8180 if (q_ptr->complev == 0)
8183 _(" %-35s (%3d階) - 不戦勝 - %s\n",
8184 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
8185 r_name+r_info[q_ptr->r_idx].name,
8186 q_ptr->level, playtime_str);
8191 _(" %-35s (%3d階) - レベル%2d - %s\n",
8192 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
8193 r_name+r_info[q_ptr->r_idx].name,
8201 /* Print the quest info */
8203 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
8204 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
8205 q_ptr->name, q_ptr->level, q_ptr->complev, playtime_str);
8208 fputs(tmp_str, fff);
8214 * Print all finished quests
8216 void do_cmd_knowledge_quests_completed(FILE *fff, int quest_num[])
8221 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
8222 for (i = 1; i < max_quests; i++)
8224 int q_idx = quest_num[i];
8225 quest_type* const q_ptr = &quest[q_idx];
8227 if (q_ptr->status == QUEST_STATUS_FINISHED &&
8228 do_cmd_knowledge_quests_aux(fff, q_idx))
8233 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8238 * Print all failed quests
8240 void do_cmd_knowledge_quests_failed(FILE *fff, int quest_num[])
8245 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
8246 for (i = 1; i < max_quests; i++)
8248 int q_idx = quest_num[i];
8249 quest_type* const q_ptr = &quest[q_idx];
8251 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
8252 do_cmd_knowledge_quests_aux(fff, q_idx))
8257 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8262 * Print all random quests
8264 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
8270 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
8271 for (i = 1; i < max_quests; i++)
8273 /* No info from "silent" quests */
8274 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8276 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
8280 /* Print the quest info */
8282 sprintf(tmp_str, " %s (%d階, %s)\n",
8283 quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
8285 sprintf(tmp_str, " %s (%d, %s)\n",
8286 quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
8288 fputs(tmp_str, fff);
8291 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8295 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8297 int *q_num = (int *)u;
8298 quest_type *qa = &quest[q_num[a]];
8299 quest_type *qb = &quest[q_num[b]];
8304 return (qa->comptime <= qb->comptime);
8307 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8309 int *q_num = (int *)u;
8316 q_num[a] = q_num[b];
8322 * Print quest status of all active quests
8324 static void do_cmd_knowledge_quests(void)
8327 char file_name[1024];
8328 int *quest_num, dummy, i;
8330 /* Open a new file */
8331 fff = my_fopen_temp(file_name, 1024);
8334 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8339 /* Allocate Memory */
8340 C_MAKE(quest_num, max_quests, int);
8342 /* Sort by compete level */
8343 for (i = 1; i < max_quests; i++) quest_num[i] = i;
8344 ang_sort_comp = ang_sort_comp_quest_num;
8345 ang_sort_swap = ang_sort_swap_quest_num;
8346 ang_sort(quest_num, &dummy, max_quests);
8348 /* Dump Quest Information */
8349 do_cmd_knowledge_quests_current(fff);
8351 do_cmd_knowledge_quests_completed(fff, quest_num);
8353 do_cmd_knowledge_quests_failed(fff, quest_num);
8357 do_cmd_knowledge_quests_wiz_random(fff);
8360 /* Close the file */
8363 /* Display the file contents */
8364 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8366 /* Remove the file */
8370 C_KILL(quest_num, max_quests, int);
8377 static void do_cmd_knowledge_home(void)
8382 char file_name[1024];
8384 char o_name[MAX_NLEN];
8387 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8389 /* Open a new file */
8390 fff = my_fopen_temp(file_name, 1024);
8392 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8399 /* Print all homes in the different towns */
8400 st_ptr = &town[1].store[STORE_HOME];
8402 /* Home -- if anything there */
8403 if (st_ptr->stock_num)
8408 /* Header with name of the town */
8409 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8411 /* Dump all available items */
8412 for (i = 0; i < st_ptr->stock_num; i++)
8415 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8416 object_desc(o_name, &st_ptr->stock[i], 0);
8417 if (strlen(o_name) <= 80-3)
8419 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8425 for (n = 0, t = o_name; n < 80-3; n++, t++)
8426 if(iskanji(*t)) {t++; n++;}
8427 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8429 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8430 fprintf(fff, " %.77s\n", o_name+n);
8433 object_desc(o_name, &st_ptr->stock[i], 0);
8434 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8439 /* Add an empty line */
8440 fprintf(fff, "\n\n");
8444 /* Close the file */
8447 /* Display the file contents */
8448 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8450 /* Remove the file */
8456 * Check the status of "autopick"
8458 static void do_cmd_knowledge_autopick(void)
8462 char file_name[1024];
8464 /* Open a new file */
8465 fff = my_fopen_temp(file_name, 1024);
8469 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8476 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8480 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8481 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8484 for (k = 0; k < max_autopick; k++)
8487 byte act = autopick_list[k].action;
8488 if (act & DONT_AUTOPICK)
8490 tmp = _("放置", "Leave");
8492 else if (act & DO_AUTODESTROY)
8494 tmp = _("破壊", "Destroy");
8496 else if (act & DO_AUTOPICK)
8498 tmp = _("拾う", "Pickup");
8500 else /* if (act & DO_QUERY_AUTOPICK) */ /* Obvious */
8502 tmp = _("確認", "Query");
8505 if (act & DO_DISPLAY)
8506 fprintf(fff, "%11s", format("[%s]", tmp));
8508 fprintf(fff, "%11s", format("(%s)", tmp));
8510 tmp = autopick_line_from_entry(&autopick_list[k]);
8511 fprintf(fff, " %s", tmp);
8515 /* Close the file */
8517 /* Display the file contents */
8518 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8520 /* Remove the file */
8526 * Interact with "knowledge"
8528 void do_cmd_knowledge(void)
8531 bool need_redraw = FALSE;
8533 /* File type is "TEXT" */
8534 FILE_TYPE(FILE_TYPE_TEXT);
8536 /* Save the screen */
8539 /* Interact until done */
8545 /* Ask for a choice */
8547 prt(format("%d/2 ページ", (p+1)), 2, 65);
8548 prt("現在の知識を確認する", 3, 0);
8550 prt(format("page %d/2", (p+1)), 2, 65);
8551 prt("Display current knowledge", 3, 0);
8554 /* Give some choices */
8558 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8559 prt("(2) 既知のアイテム の一覧", 7, 5);
8560 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8561 prt("(4) 既知のモンスター の一覧", 9, 5);
8562 prt("(5) 倒した敵の数 の一覧", 10, 5);
8563 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8564 prt("(7) 現在のペット の一覧", 12, 5);
8565 prt("(8) 我が家のアイテム の一覧", 13, 5);
8566 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8567 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8571 prt("(a) 自分に関する情報 の一覧", 6, 5);
8572 prt("(b) 突然変異 の一覧", 7, 5);
8573 prt("(c) 武器の経験値 の一覧", 8, 5);
8574 prt("(d) 魔法の経験値 の一覧", 9, 5);
8575 prt("(e) 技能の経験値 の一覧", 10, 5);
8576 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8577 prt("(g) 入ったダンジョン の一覧", 12, 5);
8578 prt("(h) 実行中のクエスト の一覧", 13, 5);
8579 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8584 prt("(1) Display known artifacts", 6, 5);
8585 prt("(2) Display known objects", 7, 5);
8586 prt("(3) Display remaining uniques", 8, 5);
8587 prt("(4) Display known monster", 9, 5);
8588 prt("(5) Display kill count", 10, 5);
8589 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8590 prt("(7) Display current pets", 12, 5);
8591 prt("(8) Display home inventory", 13, 5);
8592 prt("(9) Display *identified* equip.", 14, 5);
8593 prt("(0) Display terrain symbols.", 15, 5);
8597 prt("(a) Display about yourself", 6, 5);
8598 prt("(b) Display mutations", 7, 5);
8599 prt("(c) Display weapon proficiency", 8, 5);
8600 prt("(d) Display spell proficiency", 9, 5);
8601 prt("(e) Display misc. proficiency", 10, 5);
8602 prt("(f) Display virtues", 11, 5);
8603 prt("(g) Display dungeons", 12, 5);
8604 prt("(h) Display current quests", 13, 5);
8605 prt("(i) Display auto pick/destroy", 14, 5);
8611 prt("ESC) 抜ける", 21, 1);
8612 prt("SPACE) 次ページ", 21, 30);
8613 /*prt("-) 前ページ", 21, 60);*/
8614 prt("コマンド:", 20, 0);
8616 prt("-more-", 17, 8);
8617 prt("ESC) Exit menu", 21, 1);
8618 prt("SPACE) Next page", 21, 30);
8619 /*prt("-) Previous page", 21, 60);*/
8620 prt("Command: ", 20, 0);
8627 if (i == ESCAPE) break;
8630 case ' ': /* Page change */
8634 case '1': /* Artifacts */
8635 do_cmd_knowledge_artifacts();
8637 case '2': /* Objects */
8638 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8640 case '3': /* Uniques */
8641 do_cmd_knowledge_uniques();
8643 case '4': /* Monsters */
8644 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8646 case '5': /* Kill count */
8647 do_cmd_knowledge_kill_count();
8649 case '6': /* wanted */
8650 if (!vanilla_town) do_cmd_knowledge_kubi();
8652 case '7': /* Pets */
8653 do_cmd_knowledge_pets();
8655 case '8': /* Home */
8656 do_cmd_knowledge_home();
8658 case '9': /* Resist list */
8659 do_cmd_knowledge_inven();
8661 case '0': /* Feature list */
8663 int lighting_level = F_LIT_STANDARD;
8664 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8668 case 'a': /* Max stat */
8669 do_cmd_knowledge_stat();
8671 case 'b': /* Mutations */
8672 do_cmd_knowledge_mutations();
8674 case 'c': /* weapon-exp */
8675 do_cmd_knowledge_weapon_exp();
8677 case 'd': /* spell-exp */
8678 do_cmd_knowledge_spell_exp();
8680 case 'e': /* skill-exp */
8681 do_cmd_knowledge_skill_exp();
8683 case 'f': /* Virtues */
8684 do_cmd_knowledge_virtues();
8686 case 'g': /* Dungeon */
8687 do_cmd_knowledge_dungeon();
8689 case 'h': /* Quests */
8690 do_cmd_knowledge_quests();
8692 case 'i': /* Autopick */
8693 do_cmd_knowledge_autopick();
8695 default: /* Unknown option */
8699 /* Flush messages */
8703 /* Restore the screen */
8706 if (need_redraw) do_cmd_redraw();
8711 * Check on the status of an active quest
8713 void do_cmd_checkquest(void)
8715 /* File type is "TEXT" */
8716 FILE_TYPE(FILE_TYPE_TEXT);
8718 /* Save the screen */
8722 do_cmd_knowledge_quests();
8724 /* Restore the screen */
8730 * Display the time and date
8732 void do_cmd_time(void)
8734 int day, hour, min, full, start, end, num;
8742 extract_day_hour_min(&day, &hour, &min);
8744 full = hour * 100 + min;
8751 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8753 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8754 else strcpy(day_buf, "*****");
8758 msg_format("%s日目, 時刻は%d:%02d %sです。",
8759 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8760 min, (hour < 12) ? "AM" : "PM");
8762 msg_format("This is day %s. The time is %d:%02d %s.",
8763 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8764 min, (hour < 12) ? "AM" : "PM");
8769 if (!randint0(10) || p_ptr->image)
8771 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8775 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8778 /* Open this file */
8779 fff = my_fopen(buf, "rt");
8784 /* Find this time */
8785 while (!my_fgets(fff, buf, sizeof(buf)))
8787 /* Ignore comments */
8788 if (!buf[0] || (buf[0] == '#')) continue;
8790 /* Ignore invalid lines */
8791 if (buf[1] != ':') continue;
8793 /* Process 'Start' */
8796 /* Extract the starting time */
8797 start = atoi(buf + 2);
8799 /* Assume valid for an hour */
8809 /* Extract the ending time */
8810 end = atoi(buf + 2);
8816 /* Ignore incorrect range */
8817 if ((start > full) || (full > end)) continue;
8819 /* Process 'Description' */
8824 /* Apply the randomizer */
8825 if (!randint0(num)) strcpy(desc, buf + 2);
8835 /* Close the file */