3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
48 #include "cmd-spell.h"
52 #include "player-effects.h"
53 #include "player-status.h"
54 #include "player-skill.h"
55 #include "player-personality.h"
62 #include "object-flavor.h"
63 #include "object-hook.h"
65 #include "monster-status.h"
67 #include "view-mainwindow.h"
68 #include "dungeon-file.h"
70 #include "player-class.h"
71 #include "player-move.h"
73 #include "objectkind.h"
74 #include "floor-town.h"
80 * Mark strings for auto dump
82 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
83 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
86 * Variables for auto dump
88 static FILE *auto_dump_stream;
89 static concptr auto_dump_mark;
90 static int auto_dump_line_num;
94 * @brief prf出力内容を消去する /
95 * Remove old lines automatically generated before.
96 * @param orig_file 消去を行うファイル名
98 static void remove_auto_dump(concptr orig_file)
100 FILE *tmp_fff, *orig_fff;
104 bool between_mark = FALSE;
105 bool changed = FALSE;
107 long header_location = 0;
108 char header_mark_str[80];
109 char footer_mark_str[80];
112 /* Prepare a header/footer mark string */
113 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
114 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
116 mark_len = strlen(footer_mark_str);
118 /* Open an old dump file in read-only mode */
119 orig_fff = my_fopen(orig_file, "r");
121 /* If original file does not exist, nothing to do */
122 if (!orig_fff) return;
124 /* Open a new (temporary) file */
125 tmp_fff = my_fopen_temp(tmp_file, 1024);
129 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
134 /* Loop for every line */
138 if (my_fgets(orig_fff, buf, sizeof(buf)))
140 /* Read error: Assume End of File */
143 * Was looking for the footer, but not found.
145 * Since automatic dump might be edited by hand,
146 * it's dangerous to kill these lines.
147 * Seek back to the next line of the (pseudo) header,
152 fseek(orig_fff, header_location, SEEK_SET);
153 between_mark = FALSE;
157 /* Success -- End the loop */
164 /* We are looking for the header mark of automatic dump */
167 /* Is this line a header? */
168 if (!strcmp(buf, header_mark_str))
170 /* Memorise seek point of this line */
171 header_location = ftell(orig_fff);
173 /* Initialize counter for number of lines */
176 /* Look for the footer from now */
179 /* There are some changes */
186 /* Copy orginally lines */
187 fprintf(tmp_fff, "%s\n", buf);
191 /* We are looking for the footer mark of automatic dump */
194 /* Is this line a footer? */
195 if (!strncmp(buf, footer_mark_str, mark_len))
200 * Compare the number of lines
202 * If there is an inconsistency between
203 * actual number of lines and the
204 * number here, the automatic dump
205 * might be edited by hand. So it's
206 * dangerous to kill these lines.
207 * Seek back to the next line of the
208 * (pseudo) header, and read again.
210 if (!sscanf(buf + mark_len, " (%d)", &tmp)
213 fseek(orig_fff, header_location, SEEK_SET);
216 /* Look for another header */
217 between_mark = FALSE;
223 /* Ignore old line, and count number of lines */
233 /* If there are some changes, overwrite the original file with new one */
236 /* Copy contents of temporary file */
238 tmp_fff = my_fopen(tmp_file, "r");
239 orig_fff = my_fopen(orig_file, "w");
241 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
242 fprintf(orig_fff, "%s\n", buf);
248 /* Kill the temporary file */
256 * @brief prfファイルのフォーマットに従った内容を出力する /
257 * Dump a formatted line, using "vstrnfmt()".
260 static void auto_dump_printf(concptr fmt, ...)
267 /* Begin the Varargs Stuff */
270 /* Format the args, save the length */
271 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
273 /* End the Varargs Stuff */
276 /* Count number of lines */
277 for (p = buf; *p; p++)
279 if (*p == '\n') auto_dump_line_num++;
283 fprintf(auto_dump_stream, "%s", buf);
288 * @brief prfファイルをファイルオープンする /
289 * Open file to append auto dump.
291 * @param mark 出力するヘッダマーク
292 * @return ファイルポインタを取得できたらTRUEを返す
294 static bool open_auto_dump(concptr buf, concptr mark)
297 char header_mark_str[80];
299 /* Save the mark string */
300 auto_dump_mark = mark;
302 /* Prepare a header mark string */
303 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
305 /* Remove old macro dumps */
306 remove_auto_dump(buf);
308 /* Append to the file */
309 auto_dump_stream = my_fopen(buf, "a");
312 if (!auto_dump_stream) {
313 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
321 fprintf(auto_dump_stream, "%s\n", header_mark_str);
323 /* Initialize counter */
324 auto_dump_line_num = 0;
326 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
327 "# *Warning!* The lines below are an automatic dump.\n"));
328 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
329 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
335 * @brief prfファイルをファイルクローズする /
336 * Append foot part and close auto dump.
339 static void close_auto_dump(void)
341 char footer_mark_str[80];
343 /* Prepare a footer mark string */
344 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
346 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
347 "# *Warning!* The lines below are an automatic dump.\n"));
348 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
349 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
351 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
354 my_fclose(auto_dump_stream);
363 * @brief Return suffix of ordinal number
365 * @return pointer of suffix string.
367 concptr get_ordinal_number_suffix(int num)
369 num = ABS(num) % 100;
373 return (num == 11) ? "th" : "st";
375 return (num == 12) ? "th" : "nd";
377 return (num == 13) ? "th" : "rd";
386 * @brief 日記にメッセージを追加する /
387 * Take note to the diary.
388 * @param type 日記内容のID
389 * @param num 日記内容のIDに応じた数値
390 * @param note 日記内容のIDに応じた文字列参照ポインタ
393 errr do_cmd_write_nikki(int type, int num, concptr note)
397 GAME_TEXT file_name[MAX_NLEN];
399 concptr note_level = "";
400 bool do_level = TRUE;
401 char note_level_buf[40];
404 static bool disable_nikki = FALSE;
406 extract_day_hour_min(&day, &hour, &min);
408 if (disable_nikki) return(-1);
410 if (type == NIKKI_FIX_QUEST_C ||
411 type == NIKKI_FIX_QUEST_F ||
412 type == NIKKI_RAND_QUEST_C ||
413 type == NIKKI_RAND_QUEST_F ||
414 type == NIKKI_TO_QUEST)
418 old_quest = p_ptr->inside_quest;
419 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
421 /* Get the quest text */
422 init_flags = INIT_NAME_ONLY;
424 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
426 /* Reset the old quest number */
427 p_ptr->inside_quest = old_quest;
430 /* different filne name to avoid mixing */
431 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
433 /* Build the filename */
434 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
436 /* File type is "TEXT" */
437 FILE_TYPE(FILE_TYPE_TEXT);
439 fff = my_fopen(buf, "a");
444 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
450 q_idx = quest_number(current_floor_ptr->dun_level);
454 if (p_ptr->inside_arena)
455 note_level = _("アリーナ:", "Arane:");
456 else if (!current_floor_ptr->dun_level)
457 note_level = _("地上:", "Surface:");
458 else if (q_idx && (is_fixed_quest_idx(q_idx)
459 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
460 note_level = _("クエスト:", "Quest:");
464 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
466 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
468 note_level = note_level_buf;
476 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
477 else fputs(_("*****日目\n", "Day *****\n"), fff);
485 fprintf(fff, "%s\n",note);
489 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
494 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
497 case NIKKI_ART_SCROLL:
499 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
504 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
507 case NIKKI_FIX_QUEST_C:
509 if (quest[num].flags & QUEST_FLAG_SILENT) break;
510 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
511 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
514 case NIKKI_FIX_QUEST_F:
516 if (quest[num].flags & QUEST_FLAG_SILENT) break;
517 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
518 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
521 case NIKKI_RAND_QUEST_C:
523 GAME_TEXT name[MAX_NLEN];
524 strcpy(name, r_name+r_info[quest[num].r_idx].name);
525 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
526 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
529 case NIKKI_RAND_QUEST_F:
531 GAME_TEXT name[MAX_NLEN];
532 strcpy(name, r_name+r_info[quest[num].r_idx].name);
533 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
534 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
537 case NIKKI_MAXDEAPTH:
539 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
540 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
541 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
542 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
547 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
548 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
549 _(d_name + d_info[num].name, (int)max_dlv[num]),
550 _((int)max_dlv[num], d_name + d_info[num].name));
556 if (q_idx && (is_fixed_quest_idx(q_idx)
557 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
559 to = _("地上", "the surface");
563 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
564 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
566 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
572 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
573 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
574 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
576 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
581 if (quest[num].flags & QUEST_FLAG_SILENT) break;
582 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
583 hour, min, note_level, quest[num].name);
588 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
589 hour, min, note_level);
594 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
599 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
607 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
608 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
611 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
612 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
614 if (num == MAX_ARENA_MONS)
616 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
617 " won all fight to become a Chanpion.\n"));
624 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
630 if (!current_floor_ptr->dun_level)
631 to = _("地上", "the surface");
633 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
635 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
636 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
642 if (!current_floor_ptr->dun_level)
643 to = _("地上", "the surface");
645 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
647 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
648 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
653 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
656 case NIKKI_GAMESTART:
658 time_t ct = time((time_t*)0);
662 fprintf(fff, "%s %s",note, ctime(&ct));
665 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
668 case NIKKI_NAMED_PET:
670 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
673 case RECORD_NAMED_PET_NAME:
674 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
676 case RECORD_NAMED_PET_UNNAME:
677 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
679 case RECORD_NAMED_PET_DISMISS:
680 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
682 case RECORD_NAMED_PET_DEATH:
683 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
685 case RECORD_NAMED_PET_MOVED:
686 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
688 case RECORD_NAMED_PET_LOST_SIGHT:
689 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
691 case RECORD_NAMED_PET_DESTROY:
692 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
694 case RECORD_NAMED_PET_EARTHQUAKE:
695 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
697 case RECORD_NAMED_PET_GENOCIDE:
698 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
700 case RECORD_NAMED_PET_WIZ_ZAP:
701 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
703 case RECORD_NAMED_PET_TELE_LEVEL:
704 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
706 case RECORD_NAMED_PET_BLAST:
707 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
709 case RECORD_NAMED_PET_HEAL_LEPER:
710 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
712 case RECORD_NAMED_PET_COMPACT:
713 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
715 case RECORD_NAMED_PET_LOSE_PARENT:
716 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
727 case NIKKI_WIZARD_LOG:
728 fprintf(fff, "%s\n", note);
737 if (do_level) write_level = FALSE;
743 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
746 * @brief 日記のタイトル表記と内容出力 /
749 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
751 static void do_cmd_disp_nikki(void)
753 char nikki_title[256];
754 GAME_TEXT file_name[MAX_NLEN];
759 static const char subtitle[][30] = {"最強の肉体を求めて",
790 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
791 "Attack is the best form of defence.",
793 "An unexpected windfall",
794 "A drowning man will catch at a straw",
795 "Don't count your chickens before they are hatched.",
796 "It is no use crying over spilt milk.",
797 "Seeing is believing.",
798 "Strike the iron while it is hot.",
799 "I don't care what follows.",
800 "To dig a well to put out a house on fire.",
801 "Tomorrow is another day.",
802 "Easy come, easy go.",
803 "The more haste, the less speed.",
804 "Where there is life, there is hope.",
805 "There is no royal road to *WINNER*.",
806 "Danger past, God forgotten.",
807 "The best thing to do now is to run away.",
808 "Life is but an empty dream.",
809 "Dead men tell no tales.",
810 "A book that remains shut is but a block.",
811 "Misfortunes never come singly.",
812 "A little knowledge is a dangerous thing.",
813 "History repeats itself.",
814 "*WINNER* was not built in a day.",
815 "Ignorance is bliss.",
816 "To lose is to win?",
817 "No medicine can cure folly.",
818 "All good things come to an end.",
819 "M$ Empire strikes back.",
820 "To see is to believe",
822 "Quest of The World's Greatest Brain"};
824 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
826 /* Build the filename */
827 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
829 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
830 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
831 else if (IS_WIZARD_CLASS())
832 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
833 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
836 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
838 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
841 /* Display the file contents */
842 show_file(FALSE, buf, nikki_title, -1, 0);
846 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
849 static void do_cmd_bunshou(void)
852 char bunshou[80] = "\0";
854 if (get_string(_("内容: ", "diary note: "), tmp, 79))
856 strcpy(bunshou, tmp);
858 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
863 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
866 static void do_cmd_last_get(void)
871 if (record_o_name[0] == '\0') return;
873 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
874 if (!get_check(buf)) return;
876 turn_tmp = current_world_ptr->game_turn;
877 current_world_ptr->game_turn = record_turn;
878 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
879 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
880 current_world_ptr->game_turn = turn_tmp;
884 * @brief ファイル中の全日記記録を消去する /
887 static void do_cmd_erase_nikki(void)
889 GAME_TEXT file_name[MAX_NLEN];
893 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
894 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
896 /* Build the filename */
897 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
900 fff = my_fopen(buf, "w");
903 msg_format(_("記録を消去しました。", "deleted record."));
905 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
914 void do_cmd_nikki(void)
918 /* File type is "TEXT" */
919 FILE_TYPE(FILE_TYPE_TEXT);
922 /* Interact until done */
927 /* Ask for a choice */
928 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
930 /* Give some choices */
931 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
932 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
933 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
934 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
936 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
939 prt(_("コマンド:", "Command: "), 18, 0);
944 if (i == ESCAPE) break;
958 do_cmd_erase_nikki();
962 prepare_movie_hooks();
964 default: /* Unknown option */
974 * @brief 画面を再描画するコマンドのメインルーチン
975 * Hack -- redraw the screen
979 * This command performs various low level updates, clears all the "extra"
980 * windows, does a total redraw of the main window, and requests all of the
981 * interesting updates and redraws that I can think of.
983 * This command is also used to "instantiate" the results of the user
984 * selecting various things, such as graphics mode, so it must call
985 * the "TERM_XTRA_REACT" hook before redrawing the windows.
988 void do_cmd_redraw(void)
994 /* Hack -- react to changes */
995 Term_xtra(TERM_XTRA_REACT, 0);
997 /* Combine and Reorder the pack (later) */
998 p_ptr->update |= (PU_COMBINE | PU_REORDER);
999 p_ptr->update |= (PU_TORCH);
1000 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1001 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1002 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1003 p_ptr->update |= (PU_MONSTERS);
1005 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1007 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1008 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1014 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1017 /* Redraw every window */
1018 for (j = 0; j < 8; j++)
1021 if (!angband_term[j]) continue;
1024 Term_activate(angband_term[j]);
1033 * @brief 名前を変更するコマンドのメインルーチン
1034 * Hack -- change name
1037 void do_cmd_change_name(void)
1052 /* Display the player */
1053 display_player(mode);
1058 display_player(mode);
1063 Term_putstr(2, 23, -1, TERM_WHITE,
1064 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1066 Term_putstr(2, 23, -1, TERM_WHITE,
1067 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1075 if (c == ESCAPE) break;
1082 /* Process the player name */
1083 process_player_name(FALSE);
1089 sprintf(tmp, "%s.txt", player_base);
1090 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1092 if (tmp[0] && (tmp[0] != ' '))
1094 file_character(tmp);
1112 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1119 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1120 * Recall the most recent message
1123 void do_cmd_message_one(void)
1125 /* Recall one message */
1126 prt(format("> %s", message_str(0)), 0, 0);
1131 * @brief メッセージのログを表示するコマンドのメインルーチン
1132 * Recall the most recent message
1136 * Show previous messages to the user -BEN-
1138 * The screen format uses line 0 and 23 for headers and prompts,
1139 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1141 * This command shows you which commands you are viewing, and allows
1142 * you to "search" for strings in the recall.
1144 * Note that messages may be longer than 80 characters, but they are
1145 * displayed using "infinite" length, with a special sub-command to
1146 * "slide" the virtual display to the left or right.
1148 * Attempt to only hilite the matching portions of the string.
1151 void do_cmd_messages(int num_now)
1155 char shower_str[81];
1156 char finder_str[81];
1158 concptr shower = NULL;
1162 Term_get_size(&wid, &hgt);
1164 /* Number of message lines in a screen */
1165 num_lines = hgt - 4;
1168 strcpy(finder_str, "");
1171 strcpy(shower_str, "");
1173 /* Total messages */
1176 /* Start on first message */
1181 /* Process requests until done */
1187 /* Dump up to 20 lines of messages */
1188 for (j = 0; (j < num_lines) && (i + j < n); j++)
1190 concptr msg = message_str(i+j);
1192 /* Dump the messages, bottom to top */
1193 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1195 /* Hilite "shower" */
1196 if (shower && shower[0])
1200 /* Display matches */
1201 while ((str = my_strstr(str, shower)) != NULL)
1203 int len = strlen(shower);
1205 /* Display the match */
1206 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1214 /* Erase remaining lines */
1215 for (; j < num_lines; j++)
1217 Term_erase(0, num_lines + 1 - j, 255);
1220 /* Display header */
1222 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1223 i, i + j - 1, n), 0, 0);
1225 /* Display prompt (not very informative) */
1226 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1227 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1229 skey = inkey_special(TRUE);
1231 /* Exit on Escape */
1232 if (skey == ESCAPE) break;
1234 /* Hack -- Save the old index */
1239 /* Hack -- handle show */
1242 prt(_("強調: ", "Show: "), hgt - 1, 0);
1244 /* Get a "shower" string, or continue */
1245 strcpy(back_str, shower_str);
1246 if (askfor(shower_str, 80))
1249 shower = shower_str[0] ? shower_str : NULL;
1251 else strcpy(shower_str, back_str);
1255 /* Hack -- handle find */
1262 prt(_("検索: ", "Find: "), hgt - 1, 0);
1264 /* Get a "finder" string, or continue */
1265 strcpy(back_str, finder_str);
1266 if (!askfor(finder_str, 80))
1268 strcpy(finder_str, back_str);
1271 else if (!finder_str[0])
1273 shower = NULL; /* Stop showing */
1278 shower = finder_str;
1281 for (z = i + 1; z < n; z++)
1283 concptr msg = message_str(z);
1286 if (my_strstr(msg, finder_str))
1297 /* Recall 1 older message */
1299 /* Go to the oldest line */
1303 /* Recall 1 newer message */
1305 /* Go to the newest line */
1309 /* Recall 1 older message */
1314 /* Go older if legal */
1315 i = MIN(i + 1, n - num_lines);
1318 /* Recall 10 older messages */
1320 /* Go older if legal */
1321 i = MIN(i + 10, n - num_lines);
1324 /* Recall 20 older messages */
1329 /* Go older if legal */
1330 i = MIN(i + num_lines, n - num_lines);
1333 /* Recall 20 newer messages */
1337 /* Go newer (if able) */
1338 i = MAX(0, i - num_lines);
1341 /* Recall 10 newer messages */
1343 /* Go newer (if able) */
1347 /* Recall 1 newer messages */
1350 /* Go newer (if able) */
1355 /* Hack -- Error of some kind */
1363 * @brief チートオプションを変更するコマンドのメインルーチン
1364 * Interact with some options for cheating
1365 * @param info 表示メッセージ
1368 static void do_cmd_options_cheat(concptr info)
1371 int i, k = 0, n = CHEAT_MAX;
1375 /* Interact with the player */
1381 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1386 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1387 prt(" << 注意 >>", 11, 0);
1388 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1389 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1390 prt(" じらないようにして下さい。", 14, 0);
1392 /* Display the options */
1393 for (i = 0; i < n; i++)
1395 byte a = TERM_WHITE;
1397 /* Color current option */
1398 if (i == k) a = TERM_L_BLUE;
1400 /* Display the option text */
1401 sprintf(buf, "%-48s: %s (%s)",
1402 cheat_info[i].o_desc,
1403 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1404 cheat_info[i].o_text);
1405 c_prt(a, buf, i + 2, 0);
1408 /* Hilite current option */
1409 move_cursor(k + 2, 50);
1415 * HACK - Try to translate the key into a direction
1416 * to allow using the roguelike keys for navigation.
1418 dir = get_keymap_dir(ch);
1419 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1433 k = (n + k - 1) % n;
1451 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1452 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1453 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1454 (*cheat_info[k].o_var) = TRUE;
1463 (*cheat_info[k].o_var) = FALSE;
1470 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1471 /* Peruse the help file */
1472 (void)show_file(TRUE, buf, NULL, 0, 0);
1489 * @brief セーブ頻度ターンの次の値を返す
1490 * @param current 現在のセーブ頻度ターン値
1491 * @return 次のセーブ頻度ターン値
1493 static s16b toggle_frequency(s16b current)
1498 case 50: return 100;
1499 case 100: return 250;
1500 case 250: return 500;
1501 case 500: return 1000;
1502 case 1000: return 2500;
1503 case 2500: return 5000;
1504 case 5000: return 10000;
1505 case 10000: return 25000;
1512 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1513 * @param info 表示メッセージ
1516 static void do_cmd_options_autosave(concptr info)
1519 int i, k = 0, n = 2;
1524 /* Interact with the player */
1528 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1529 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1533 /* Display the options */
1534 for (i = 0; i < n; i++)
1536 byte a = TERM_WHITE;
1538 /* Color current option */
1539 if (i == k) a = TERM_L_BLUE;
1541 /* Display the option text */
1542 sprintf(buf, "%-48s: %s (%s)",
1543 autosave_info[i].o_desc,
1544 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1545 autosave_info[i].o_text);
1546 c_prt(a, buf, i + 2, 0);
1548 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1550 /* Hilite current option */
1551 move_cursor(k + 2, 50);
1567 k = (n + k - 1) % n;
1585 (*autosave_info[k].o_var) = TRUE;
1594 (*autosave_info[k].o_var) = FALSE;
1602 autosave_freq = toggle_frequency(autosave_freq);
1603 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1609 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1625 * @brief 標準オプションを変更するコマンドのサブルーチン /
1626 * Interact with some options
1627 * @param page オプションページ番号
1628 * @param info 表示メッセージ
1631 void do_cmd_options_aux(int page, concptr info)
1634 int i, k = 0, n = 0, l;
1637 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1638 (!p_ptr->wizard || !allow_debug_opts);
1641 /* Lookup the options */
1642 for (i = 0; i < 24; i++) opt[i] = 0;
1644 /* Scan the options */
1645 for (i = 0; option_info[i].o_desc; i++)
1647 /* Notice options on this "page" */
1648 if (option_info[i].o_page == page) opt[n++] = i;
1652 /* Interact with the player */
1658 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1659 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1662 /* HACK -- description for easy-auto-destroy options */
1663 if (page == OPT_PAGE_AUTODESTROY)
1664 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1665 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1667 /* Display the options */
1668 for (i = 0; i < n; i++)
1670 byte a = TERM_WHITE;
1672 /* Color current option */
1673 if (i == k) a = TERM_L_BLUE;
1675 /* Display the option text */
1676 sprintf(buf, "%-48s: %s (%.19s)",
1677 option_info[opt[i]].o_desc,
1678 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1679 option_info[opt[i]].o_text);
1680 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1681 else c_prt(a, buf, i + 2, 0);
1684 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1687 /* Hilite current option */
1688 move_cursor(k + 2 + l, 50);
1694 * HACK - Try to translate the key into a direction
1695 * to allow using the roguelike keys for navigation.
1697 dir = get_keymap_dir(ch);
1698 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1712 k = (n + k - 1) % n;
1729 if (browse_only) break;
1730 (*option_info[opt[k]].o_var) = TRUE;
1739 if (browse_only) break;
1740 (*option_info[opt[k]].o_var) = FALSE;
1748 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1754 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1755 /* Peruse the help file */
1756 (void)show_file(TRUE, buf, NULL, 0, 0);
1773 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1774 * Modify the "window" options
1777 static void do_cmd_options_win(void)
1787 /* Memorize old flags */
1788 for (j = 0; j < 8; j++)
1790 /* Acquire current flags */
1791 old_flag[j] = window_flag[j];
1800 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1802 /* Display the windows */
1803 for (j = 0; j < 8; j++)
1805 byte a = TERM_WHITE;
1807 concptr s = angband_term_name[j];
1810 if (j == x) a = TERM_L_BLUE;
1812 /* Window name, staggered, centered */
1813 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1816 /* Display the options */
1817 for (i = 0; i < 16; i++)
1819 byte a = TERM_WHITE;
1821 concptr str = window_flag_desc[i];
1824 if (i == y) a = TERM_L_BLUE;
1827 if (!str) str = _("(未使用)", "(Unused option)");
1830 Term_putstr(0, i + 5, -1, a, str);
1832 /* Display the windows */
1833 for (j = 0; j < 8; j++)
1839 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1842 if (window_flag[j] & (1L << i)) c = 'X';
1845 Term_putch(35 + j * 5, i + 5, a, c);
1850 Term_gotoxy(35 + x * 5, y + 5);
1868 for (j = 0; j < 8; j++)
1870 window_flag[j] &= ~(1L << y);
1874 for (i = 0; i < 16; i++)
1876 window_flag[x] &= ~(1L << i);
1889 window_flag[x] |= (1L << y);
1897 window_flag[x] &= ~(1L << y);
1903 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1911 d = get_keymap_dir(ch);
1913 x = (x + ddx[d] + 8) % 8;
1914 y = (y + ddy[d] + 16) % 16;
1921 /* Notice changes */
1922 for (j = 0; j < 8; j++)
1927 if (!angband_term[j]) continue;
1929 /* Ignore non-changes */
1930 if (window_flag[j] == old_flag[j]) continue;
1933 Term_activate(angband_term[j]);
1950 option_fields[OPT_NUM] =
1953 { '1', " キー入力 オプション", 3 },
1954 { '2', " マップ画面 オプション", 4 },
1955 { '3', " テキスト表示 オプション", 5 },
1956 { '4', " ゲームプレイ オプション", 6 },
1957 { '5', " 行動中止関係 オプション", 7 },
1958 { '6', " 簡易自動破壊 オプション", 8 },
1959 { 'r', " プレイ記録 オプション", 9 },
1961 { 'p', "自動拾いエディタ", 11 },
1962 { 'd', " 基本ウェイト量 ", 12 },
1963 { 'h', "低ヒットポイント", 13 },
1964 { 'm', " 低魔力色閾値 ", 14 },
1965 { 'a', " 自動セーブ オプション", 15 },
1966 { 'w', "ウインドウフラグ", 16 },
1968 { 'b', " 初期 オプション (参照のみ)", 18 },
1969 { 'c', " 詐欺 オプション", 19 },
1971 { '1', "Input Options", 3 },
1972 { '2', "Map Screen Options", 4 },
1973 { '3', "Text Display Options", 5 },
1974 { '4', "Game-Play Options", 6 },
1975 { '5', "Disturbance Options", 7 },
1976 { '6', "Easy Auto-Destroyer Options", 8 },
1977 { 'r', "Play record Options", 9 },
1979 { 'p', "Auto-picker/destroyer editor", 11 },
1980 { 'd', "Base Delay Factor", 12 },
1981 { 'h', "Hitpoint Warning", 13 },
1982 { 'm', "Mana Color Threshold", 14 },
1983 { 'a', "Autosave Options", 15 },
1984 { 'w', "Window Flags", 16 },
1986 { 'b', "Birth Options (Browse Only)", 18 },
1987 { 'c', "Cheat Options", 19 },
1993 * @brief 標準オプションを変更するコマンドのメインルーチン /
1994 * Set or unset various options.
1998 * The user must use the "Ctrl-R" command to "adapt" to changes
1999 * in any options which control "visual" aspects of the game.
2002 void do_cmd_options(void)
2014 /* Does not list cheat option when cheat option is off */
2015 if (!p_ptr->noscore && !allow_debug_opts) n--;
2018 /* Why are we here */
2019 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2023 /* Give some choices */
2024 for (i = 0; i < n; i++)
2026 byte a = TERM_WHITE;
2027 if (i == y) a = TERM_L_BLUE;
2028 Term_putstr(5, option_fields[i].row, -1, a,
2029 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2032 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2035 skey = inkey_special(TRUE);
2036 if (!(skey & SKEY_MASK)) k = (char)skey;
2040 if (k == ESCAPE) break;
2042 if (my_strchr("\n\r ", k))
2044 k = option_fields[y].key;
2048 for (i = 0; i < n; i++)
2050 if (tolower(k) == option_fields[i].key) break;
2053 /* Command is found */
2056 /* Hack -- browse help */
2057 if (k == '?') break;
2061 if (skey == SKEY_UP) d = 8;
2062 if (skey == SKEY_DOWN) d = 2;
2063 y = (y + ddy[d] + n) % n;
2068 if (k == ESCAPE) break;
2075 /* Process the general options */
2076 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2082 /* Process the general options */
2083 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2090 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2097 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2104 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2111 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2115 /* Play-record Options */
2120 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2129 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2130 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2131 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2135 /* Cheating Options */
2138 if (!p_ptr->noscore && !allow_debug_opts)
2140 /* Cheat options are not permitted */
2146 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2153 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2162 do_cmd_options_win();
2163 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2164 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2165 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2166 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2171 /* Auto-picker/destroyer editor */
2175 do_cmd_edit_autopick();
2179 /* Hack -- Delay Speed */
2185 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2187 /* Get a new value */
2190 int msec = delay_factor * delay_factor * delay_factor;
2191 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2192 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2194 if (k == ESCAPE) break;
2197 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2200 else if (isdigit(k)) delay_factor = D2I(k);
2207 /* Hack -- hitpoint warning factor */
2213 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2215 /* Get a new value */
2218 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2219 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2221 if (k == ESCAPE) break;
2224 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2227 else if (isdigit(k)) hitpoint_warn = D2I(k);
2234 /* Hack -- mana color factor */
2240 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2242 /* Get a new value */
2245 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2246 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2248 if (k == ESCAPE) break;
2251 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2254 else if (isdigit(k)) mana_warn = D2I(k);
2262 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2266 /* Unknown option */
2279 /* Hack - Redraw equippy chars */
2280 p_ptr->redraw |= (PR_EQUIPPY);
2286 * @brief prefファイルを選択して処理する /
2287 * Ask for a "user pref line" and process it
2290 * Allow absolute file names?
2292 void do_cmd_pref(void)
2299 /* Ask for a "user pref command" */
2300 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2302 /* Process that pref command */
2303 (void)process_pref_file_command(buf);
2307 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2310 void do_cmd_reload_autopick(void)
2312 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2313 /* Load the file with messages */
2314 autopick_load_pref(TRUE);
2320 * @brief マクロ情報をprefファイルに保存する /
2321 * @param fname ファイル名
2324 static errr macro_dump(concptr fname)
2326 static concptr mark = "Macro Dump";
2332 /* Build the filename */
2333 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2335 /* File type is "TEXT" */
2336 FILE_TYPE(FILE_TYPE_TEXT);
2338 /* Append to the file */
2339 if (!open_auto_dump(buf, mark)) return (-1);
2342 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2345 for (i = 0; i < macro__num; i++)
2347 /* Extract the action */
2348 ascii_to_text(buf, macro__act[i]);
2350 /* Dump the macro */
2351 auto_dump_printf("A:%s\n", buf);
2353 /* Extract the action */
2354 ascii_to_text(buf, macro__pat[i]);
2356 /* Dump normal macros */
2357 auto_dump_printf("P:%s\n", buf);
2360 auto_dump_printf("\n");
2372 * @brief マクロのトリガーキーを取得する /
2373 * Hack -- ask for a "trigger" (see below)
2374 * @param buf キー表記を保管するバッファ
2378 * Note the complex use of the "inkey()" function from "util.c".
2380 * Note that both "flush()" calls are extremely important.
2383 static void do_cmd_macro_aux(char *buf)
2391 /* Do not process macros */
2397 /* Read the pattern */
2403 /* Do not process macros */
2406 /* Do not wait for keys */
2409 /* Attempt to read a key */
2418 /* Convert the trigger */
2419 ascii_to_text(tmp, buf);
2421 /* Hack -- display the trigger */
2422 Term_addstr(-1, TERM_WHITE, tmp);
2428 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2429 * Hack -- ask for a keymap "trigger" (see below)
2430 * @param buf キー表記を取得するバッファ
2434 * Note that both "flush()" calls are extremely important. This may
2435 * no longer be true, since "util.c" is much simpler now.
2438 static void do_cmd_macro_aux_keymap(char *buf)
2448 /* Convert to ascii */
2449 ascii_to_text(tmp, buf);
2451 /* Hack -- display the trigger */
2452 Term_addstr(-1, TERM_WHITE, tmp);
2459 * @brief キーマップをprefファイルにダンプする /
2460 * Hack -- append all keymaps to the given file
2461 * @param fname ファイルネーム
2465 static errr keymap_dump(concptr fname)
2467 static concptr mark = "Keymap Dump";
2476 if (rogue_like_commands)
2478 mode = KEYMAP_MODE_ROGUE;
2484 mode = KEYMAP_MODE_ORIG;
2488 /* Build the filename */
2489 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2491 /* File type is "TEXT" */
2492 FILE_TYPE(FILE_TYPE_TEXT);
2494 /* Append to the file */
2495 if (!open_auto_dump(buf, mark)) return -1;
2498 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2501 for (i = 0; i < 256; i++)
2505 /* Loop up the keymap */
2506 act = keymap_act[mode][i];
2508 /* Skip empty keymaps */
2511 /* Encode the key */
2514 ascii_to_text(key, buf);
2516 /* Encode the action */
2517 ascii_to_text(buf, act);
2519 /* Dump the macro */
2520 auto_dump_printf("A:%s\n", buf);
2521 auto_dump_printf("C:%d:%s\n", mode, key);
2533 * @brief マクロを設定するコマンドのメインルーチン /
2534 * Interact with "macros"
2538 * Note that the macro "action" must be defined before the trigger.
2540 * Could use some helpful instructions on this page.
2543 void do_cmd_macros(void)
2555 if (rogue_like_commands)
2557 mode = KEYMAP_MODE_ROGUE;
2563 mode = KEYMAP_MODE_ORIG;
2566 /* File type is "TEXT" */
2567 FILE_TYPE(FILE_TYPE_TEXT);
2572 /* Process requests until done */
2576 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2578 /* Describe that action */
2579 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2581 /* Analyze the current action */
2582 ascii_to_text(buf, macro__buf);
2584 /* Display the current action */
2589 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2591 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2592 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2593 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2594 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2595 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2596 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2597 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2598 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2599 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2600 #endif /* ALLOW_MACROS */
2603 prt(_("コマンド: ", "Command: "), 16, 0);
2608 if (i == ESCAPE) break;
2610 /* Load a 'macro' file */
2616 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2619 prt(_("ファイル: ", "File: "), 18, 0);
2621 /* Default filename */
2622 sprintf(tmp, "%s.prf", player_base);
2624 /* Ask for a file */
2625 if (!askfor(tmp, 80)) continue;
2627 /* Process the given filename */
2628 err = process_pref_file(tmp);
2631 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2636 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2640 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2650 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2653 prt(_("ファイル: ", "File: "), 18, 0);
2655 /* Default filename */
2656 sprintf(tmp, "%s.prf", player_base);
2658 /* Ask for a file */
2659 if (!askfor(tmp, 80)) continue;
2661 /* Dump the macros */
2662 (void)macro_dump(tmp);
2665 msg_print(_("マクロを追加しました。", "Appended macros."));
2674 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2678 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2680 /* Get a macro trigger */
2681 do_cmd_macro_aux(buf);
2683 /* Acquire action */
2684 k = macro_find_exact(buf);
2690 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2696 /* Obtain the action */
2697 strcpy(macro__buf, macro__act[k]);
2699 /* Analyze the current action */
2700 ascii_to_text(buf, macro__buf);
2702 /* Display the current action */
2706 msg_print(_("マクロを確認しました。", "Found a macro."));
2710 /* Create a macro */
2714 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2717 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2719 /* Get a macro trigger */
2720 do_cmd_macro_aux(buf);
2726 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2727 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2730 prt(_("マクロ行動: ", "Action: "), 20, 0);
2732 /* Convert to text */
2733 ascii_to_text(tmp, macro__buf);
2735 /* Get an encoded action */
2736 if (askfor(tmp, 80))
2738 /* Convert to ascii */
2739 text_to_ascii(macro__buf, tmp);
2741 /* Link the macro */
2742 macro_add(buf, macro__buf);
2745 msg_print(_("マクロを追加しました。", "Added a macro."));
2749 /* Remove a macro */
2753 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2756 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2758 /* Get a macro trigger */
2759 do_cmd_macro_aux(buf);
2761 /* Link the macro */
2762 macro_add(buf, buf);
2765 msg_print(_("マクロを削除しました。", "Removed a macro."));
2772 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2775 prt(_("ファイル: ", "File: "), 18, 0);
2777 /* Default filename */
2778 sprintf(tmp, "%s.prf", player_base);
2780 /* Ask for a file */
2781 if (!askfor(tmp, 80)) continue;
2783 /* Dump the macros */
2784 (void)keymap_dump(tmp);
2787 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2790 /* Query a keymap */
2796 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2799 prt(_("押すキー: ", "Keypress: "), 18, 0);
2801 /* Get a keymap trigger */
2802 do_cmd_macro_aux_keymap(buf);
2804 /* Look up the keymap */
2805 act = keymap_act[mode][(byte)(buf[0])];
2811 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2817 /* Obtain the action */
2818 strcpy(macro__buf, act);
2820 /* Analyze the current action */
2821 ascii_to_text(buf, macro__buf);
2823 /* Display the current action */
2827 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2831 /* Create a keymap */
2835 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2838 prt(_("押すキー: ", "Keypress: "), 18, 0);
2840 /* Get a keymap trigger */
2841 do_cmd_macro_aux_keymap(buf);
2847 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2848 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2851 prt(_("行動: ", "Action: "), 20, 0);
2853 /* Convert to text */
2854 ascii_to_text(tmp, macro__buf);
2856 /* Get an encoded action */
2857 if (askfor(tmp, 80))
2859 /* Convert to ascii */
2860 text_to_ascii(macro__buf, tmp);
2862 /* Free old keymap */
2863 string_free(keymap_act[mode][(byte)(buf[0])]);
2865 /* Make new keymap */
2866 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2869 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2873 /* Remove a keymap */
2877 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2880 prt(_("押すキー: ", "Keypress: "), 18, 0);
2882 /* Get a keymap trigger */
2883 do_cmd_macro_aux_keymap(buf);
2885 /* Free old keymap */
2886 string_free(keymap_act[mode][(byte)(buf[0])]);
2888 /* Make new keymap */
2889 keymap_act[mode][(byte)(buf[0])] = NULL;
2892 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2895 /* Enter a new action */
2899 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2905 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2906 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2909 prt(_("マクロ行動: ", "Action: "), 20, 0);
2911 /* Hack -- limit the value */
2914 /* Get an encoded action */
2915 if (!askfor(buf, 80)) continue;
2917 /* Extract an action */
2918 text_to_ascii(macro__buf, buf);
2921 #endif /* ALLOW_MACROS */
2934 * @brief キャラクタ色の明暗表現
2936 static concptr lighting_level_str[F_LIT_MAX] =
2951 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2952 * @param i 指定対象となるキャラクタコード
2953 * @param num 指定されたビジュアルIDを返す参照ポインタ
2954 * @param max ビジュアルIDの最大数
2955 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2957 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2964 sprintf(str, "%d", *num);
2966 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2969 tmp = (IDX)strtol(str, NULL, 0);
2970 if (tmp >= 0 && tmp < max)
2973 else if (isupper(i))
2974 *num = (*num + max - 1) % max;
2976 *num = (*num + 1) % max;
2982 * @brief キャラクタの変更メニュー表示
2983 * @param choice_msg 選択メッセージ
2986 static void print_visuals_menu(concptr choice_msg)
2988 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2990 /* Give some choices */
2991 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2993 #ifdef ALLOW_VISUALS
2994 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2995 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2996 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2997 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2998 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2999 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
3000 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3001 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3002 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3003 #endif /* ALLOW_VISUALS */
3005 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3008 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3011 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3012 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3013 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3016 * Interact with "visuals"
3018 void do_cmd_visuals(void)
3023 bool need_redraw = FALSE;
3024 concptr empty_symbol = "<< ? >>";
3026 if (use_bigtile) empty_symbol = "<< ?? >>";
3028 /* File type is "TEXT" */
3029 FILE_TYPE(FILE_TYPE_TEXT);
3032 /* Interact until done */
3037 /* Ask for a choice */
3038 print_visuals_menu(NULL);
3043 if (i == ESCAPE) break;
3047 /* Load a 'pref' file */
3050 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3053 prt(_("ファイル: ", "File: "), 17, 0);
3055 /* Default filename */
3056 sprintf(tmp, "%s.prf", player_base);
3059 if (!askfor(tmp, 70)) continue;
3061 /* Process the given filename */
3062 (void)process_pref_file(tmp);
3067 #ifdef ALLOW_VISUALS
3069 /* Dump monster attr/chars */
3072 static concptr mark = "Monster attr/chars";
3075 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3078 prt(_("ファイル: ", "File: "), 17, 0);
3080 /* Default filename */
3081 sprintf(tmp, "%s.prf", player_base);
3083 /* Get a filename */
3084 if (!askfor(tmp, 70)) continue;
3086 /* Build the filename */
3087 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3089 /* Append to the file */
3090 if (!open_auto_dump(buf, mark)) continue;
3093 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3096 for (i = 0; i < max_r_idx; i++)
3098 monster_race *r_ptr = &r_info[i];
3100 /* Skip non-entries */
3101 if (!r_ptr->name) continue;
3103 /* Dump a comment */
3104 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3106 /* Dump the monster attr/char info */
3107 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3108 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3114 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3119 /* Dump object attr/chars */
3122 static concptr mark = "Object attr/chars";
3123 KIND_OBJECT_IDX k_idx;
3126 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3129 prt(_("ファイル: ", "File: "), 17, 0);
3131 /* Default filename */
3132 sprintf(tmp, "%s.prf", player_base);
3134 /* Get a filename */
3135 if (!askfor(tmp, 70)) continue;
3137 /* Build the filename */
3138 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3140 /* Append to the file */
3141 if (!open_auto_dump(buf, mark)) continue;
3144 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3147 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3149 GAME_TEXT o_name[MAX_NLEN];
3150 object_kind *k_ptr = &k_info[k_idx];
3152 /* Skip non-entries */
3153 if (!k_ptr->name) continue;
3158 strip_name(o_name, k_idx);
3164 /* Prepare dummy object */
3165 object_prep(&forge, k_idx);
3167 /* Get un-shuffled flavor name */
3168 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3171 /* Dump a comment */
3172 auto_dump_printf("# %s\n", o_name);
3174 /* Dump the object attr/char info */
3175 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3176 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3182 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3187 /* Dump feature attr/chars */
3190 static concptr mark = "Feature attr/chars";
3193 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3196 prt(_("ファイル: ", "File: "), 17, 0);
3198 /* Default filename */
3199 sprintf(tmp, "%s.prf", player_base);
3201 /* Get a filename */
3202 if (!askfor(tmp, 70)) continue;
3204 /* Build the filename */
3205 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3207 /* Append to the file */
3208 if (!open_auto_dump(buf, mark)) continue;
3211 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3214 for (i = 0; i < max_f_idx; i++)
3216 feature_type *f_ptr = &f_info[i];
3218 /* Skip non-entries */
3219 if (!f_ptr->name) continue;
3221 /* Skip mimiccing features */
3222 if (f_ptr->mimic != i) continue;
3224 /* Dump a comment */
3225 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3227 /* Dump the feature attr/char info */
3228 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3229 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3230 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3231 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3237 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3242 /* Modify monster attr/chars (numeric operation) */
3245 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3246 static MONRACE_IDX r = 0;
3248 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3250 /* Hack -- query until done */
3253 monster_race *r_ptr = &r_info[r];
3257 TERM_COLOR da = r_ptr->d_attr;
3258 byte dc = r_ptr->d_char;
3259 TERM_COLOR ca = r_ptr->x_attr;
3260 byte cc = r_ptr->x_char;
3262 /* Label the object */
3263 Term_putstr(5, 17, -1, TERM_WHITE,
3264 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3266 /* Label the Default values */
3267 Term_putstr(10, 19, -1, TERM_WHITE,
3268 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3270 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3271 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3273 /* Label the Current values */
3274 Term_putstr(10, 20, -1, TERM_WHITE,
3275 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3277 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3278 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3281 Term_putstr(0, 22, -1, TERM_WHITE,
3282 _("コマンド (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): "));
3287 if (i == ESCAPE) break;
3289 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3290 else if (isupper(i)) c = 'a' + i - 'A';
3300 if (!cmd_visuals_aux(i, &r, max_r_idx))
3306 while (!r_info[r].name);
3310 t = (int)r_ptr->x_attr;
3311 (void)cmd_visuals_aux(i, &t, 256);
3312 r_ptr->x_attr = (byte)t;
3316 t = (int)r_ptr->x_char;
3317 (void)cmd_visuals_aux(i, &t, 256);
3318 r_ptr->x_char = (byte)t;
3322 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3324 print_visuals_menu(choice_msg);
3332 /* Modify object attr/chars (numeric operation) */
3335 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3337 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3339 /* Hack -- query until done */
3342 object_kind *k_ptr = &k_info[k];
3346 TERM_COLOR da = k_ptr->d_attr;
3347 SYMBOL_CODE dc = k_ptr->d_char;
3348 TERM_COLOR ca = k_ptr->x_attr;
3349 SYMBOL_CODE cc = k_ptr->x_char;
3351 /* Label the object */
3352 Term_putstr(5, 17, -1, TERM_WHITE,
3353 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3354 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3356 /* Label the Default values */
3357 Term_putstr(10, 19, -1, TERM_WHITE,
3358 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3360 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3361 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3363 /* Label the Current values */
3364 Term_putstr(10, 20, -1, TERM_WHITE,
3365 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3367 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3368 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3371 Term_putstr(0, 22, -1, TERM_WHITE,
3372 _("コマンド (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): "));
3377 if (i == ESCAPE) break;
3379 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3380 else if (isupper(i)) c = 'a' + i - 'A';
3390 if (!cmd_visuals_aux(i, &k, max_k_idx))
3396 while (!k_info[k].name);
3400 t = (int)k_ptr->x_attr;
3401 (void)cmd_visuals_aux(i, &t, 256);
3402 k_ptr->x_attr = (byte)t;
3406 t = (int)k_ptr->x_char;
3407 (void)cmd_visuals_aux(i, &t, 256);
3408 k_ptr->x_char = (byte)t;
3412 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3414 print_visuals_menu(choice_msg);
3422 /* Modify feature attr/chars (numeric operation) */
3425 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3427 static IDX lighting_level = F_LIT_STANDARD;
3428 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3430 /* Hack -- query until done */
3433 feature_type *f_ptr = &f_info[f];
3437 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3438 byte dc = f_ptr->d_char[lighting_level];
3439 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3440 byte cc = f_ptr->x_char[lighting_level];
3442 /* Label the object */
3444 Term_putstr(5, 17, -1, TERM_WHITE,
3445 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3446 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3448 /* Label the Default values */
3449 Term_putstr(10, 19, -1, TERM_WHITE,
3450 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3452 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3453 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3455 /* Label the Current values */
3457 Term_putstr(10, 20, -1, TERM_WHITE,
3458 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3460 Term_putstr(10, 20, -1, TERM_WHITE,
3461 format("Current attr/char = %3d / %3d", ca, cc));
3464 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3465 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3469 Term_putstr(0, 22, -1, TERM_WHITE,
3470 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3472 Term_putstr(0, 22, -1, TERM_WHITE,
3473 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3479 if (i == ESCAPE) break;
3481 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3482 else if (isupper(i)) c = 'a' + i - 'A';
3492 if (!cmd_visuals_aux(i, &f, max_f_idx))
3498 while (!f_info[f].name || (f_info[f].mimic != f));
3502 t = (int)f_ptr->x_attr[lighting_level];
3503 (void)cmd_visuals_aux(i, &t, 256);
3504 f_ptr->x_attr[lighting_level] = (byte)t;
3508 t = (int)f_ptr->x_char[lighting_level];
3509 (void)cmd_visuals_aux(i, &t, 256);
3510 f_ptr->x_char[lighting_level] = (byte)t;
3514 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3517 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3521 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3523 print_visuals_menu(choice_msg);
3531 /* Modify monster attr/chars (visual mode) */
3533 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3536 /* Modify object attr/chars (visual mode) */
3538 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3541 /* Modify feature attr/chars (visual mode) */
3544 IDX lighting_level = F_LIT_STANDARD;
3545 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3549 #endif /* ALLOW_VISUALS */
3557 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3561 /* Unknown option */
3571 if (need_redraw) do_cmd_redraw();
3576 * Interact with "colors"
3578 void do_cmd_colors(void)
3587 /* File type is "TEXT" */
3588 FILE_TYPE(FILE_TYPE_TEXT);
3593 /* Interact until done */
3598 /* Ask for a choice */
3599 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3601 /* Give some choices */
3602 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3605 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3606 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3610 prt(_("コマンド: ", "Command: "), 8, 0);
3614 if (i == ESCAPE) break;
3616 /* Load a 'pref' file */
3620 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3623 prt(_("ファイル: ", "File: "), 10, 0);
3626 sprintf(tmp, "%s.prf", player_base);
3629 if (!askfor(tmp, 70)) continue;
3631 /* Process the given filename */
3632 (void)process_pref_file(tmp);
3634 /* Mega-Hack -- react to changes */
3635 Term_xtra(TERM_XTRA_REACT, 0);
3637 /* Mega-Hack -- redraw */
3646 static concptr mark = "Colors";
3649 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3652 prt(_("ファイル: ", "File: "), 10, 0);
3654 /* Default filename */
3655 sprintf(tmp, "%s.prf", player_base);
3657 /* Get a filename */
3658 if (!askfor(tmp, 70)) continue;
3660 /* Build the filename */
3661 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3663 /* Append to the file */
3664 if (!open_auto_dump(buf, mark)) continue;
3667 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3670 for (i = 0; i < 256; i++)
3672 int kv = angband_color_table[i][0];
3673 int rv = angband_color_table[i][1];
3674 int gv = angband_color_table[i][2];
3675 int bv = angband_color_table[i][3];
3677 concptr name = _("未知", "unknown");
3679 /* Skip non-entries */
3680 if (!kv && !rv && !gv && !bv) continue;
3682 /* Extract the color name */
3683 if (i < 16) name = color_names[i];
3685 /* Dump a comment */
3686 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3688 /* Dump the monster attr/char info */
3689 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3696 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3705 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3707 /* Hack -- query until done */
3716 /* Exhibit the normal colors */
3717 for (j = 0; j < 16; j++)
3719 /* Exhibit this color */
3720 Term_putstr(j*4, 20, -1, a, "###");
3722 /* Exhibit all colors */
3723 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3726 /* Describe the color */
3727 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3729 /* Describe the color */
3730 Term_putstr(5, 10, -1, TERM_WHITE,
3731 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3733 /* Label the Current values */
3734 Term_putstr(5, 12, -1, TERM_WHITE,
3735 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3736 angband_color_table[a][0],
3737 angband_color_table[a][1],
3738 angband_color_table[a][2],
3739 angband_color_table[a][3]));
3742 Term_putstr(0, 14, -1, TERM_WHITE,
3743 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3748 if (i == ESCAPE) break;
3751 if (i == 'n') a = (byte)(a + 1);
3752 if (i == 'N') a = (byte)(a - 1);
3753 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3754 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3755 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3756 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3757 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3758 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3759 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3760 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3762 /* Hack -- react to changes */
3763 Term_xtra(TERM_XTRA_REACT, 0);
3765 /* Hack -- redraw */
3772 /* Unknown option */
3786 * Note something in the message recall
3788 void do_cmd_note(void)
3796 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3798 /* Ignore empty notes */
3799 if (!buf[0] || (buf[0] == ' ')) return;
3801 /* Add the note to the message recall */
3802 msg_format(_("メモ: %s", "Note: %s"), buf);
3807 * Mention the current version
3809 void do_cmd_version(void)
3811 #if FAKE_VER_EXTRA > 0
3812 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3813 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3815 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3816 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3823 * Array of feeling strings
3825 static concptr do_cmd_feeling_text[11] =
3827 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3828 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3829 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3830 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3831 _("とても悪い予感がする...", "You have a very bad feeling..."),
3832 _("悪い予感がする...", "You have a bad feeling..."),
3833 _("何か緊張する。", "You feel nervous."),
3834 _("少し不運な気がする...", "You feel your luck is turning..."),
3835 _("この場所は好きになれない。", "You don't like the look of this place."),
3836 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3837 _("なんて退屈なところだ...", "What a boring place...")
3840 static concptr do_cmd_feeling_text_combat[11] =
3842 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3843 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3844 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3845 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3846 _("とても悪い予感がする...", "You have a very bad feeling..."),
3847 _("悪い予感がする...", "You have a bad feeling..."),
3848 _("何か緊張する。", "You feel nervous."),
3849 _("少し不運な気がする...", "You feel your luck is turning..."),
3850 _("この場所は好きになれない。", "You don't like the look of this place."),
3851 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3852 _("なんて退屈なところだ...", "What a boring place...")
3855 static concptr do_cmd_feeling_text_lucky[11] =
3857 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3858 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3859 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3860 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3861 _("とても良い感じがする...", "You have a very good feeling..."),
3862 _("良い感じがする...", "You have a good feeling..."),
3863 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3864 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3865 _("見た感じ悪くはない...", "You like the look of this place..."),
3866 _("全然駄目ということはないが...", "This level can't be all bad..."),
3867 _("なんて退屈なところだ...", "What a boring place...")
3872 * Note that "feeling" is set to zero unless some time has passed.
3873 * Note that this is done when the level is GENERATED, not entered.
3875 void do_cmd_feeling(void)
3877 if (p_ptr->wild_mode) return;
3879 /* No useful feeling in quests */
3880 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3882 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3886 /* No useful feeling in town */
3887 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3889 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3891 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3896 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3901 /* No useful feeling in the wilderness */
3902 else if (!current_floor_ptr->dun_level)
3904 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3908 /* Display the feeling */
3909 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3910 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3911 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3912 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3913 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3915 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3921 * Description of each monster group.
3923 static concptr monster_group_text[] =
3926 "ユニーク", /* "Uniques" */
3927 "乗馬可能なモンスター", /* "Riding" */
3928 "賞金首", /* "Wanted */
3929 "アンバーの王族", /* "Ambertite" */
3958 /* "古代ドラゴン/ワイアーム", */
4019 /* "Ancient Dragon/Wyrm", */
4028 "Multi-Headed Reptile",
4033 "Reptile/Amphibian",
4034 "Spider/Scorpion/Tick",
4036 /* "Major Demon", */
4053 * Symbols of monsters in each group. Note the "Uniques" group
4054 * is handled differently.
4056 static concptr monster_group_char[] =
4113 "!$&()+./=>?[\\]`{|~",
4123 * Build a list of monster indexes in the given group. Return the number
4124 * of monsters in the group.
4126 * mode & 0x01 : check for non-empty group
4127 * mode & 0x02 : visual operation only
4129 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4135 /* Get a list of x_char in this group */
4136 concptr group_char = monster_group_char[grp_cur];
4138 /* XXX Hack -- Check if this is the "Uniques" group */
4139 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4141 /* XXX Hack -- Check if this is the "Riding" group */
4142 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4144 /* XXX Hack -- Check if this is the "Wanted" group */
4145 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4147 /* XXX Hack -- Check if this is the "Amberite" group */
4148 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4151 /* Check every race */
4152 for (i = 0; i < max_r_idx; i++)
4154 /* Access the race */
4155 monster_race *r_ptr = &r_info[i];
4157 /* Skip empty race */
4158 if (!r_ptr->name) continue ;
4160 /* Require known monsters */
4161 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4165 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4168 else if (grp_riding)
4170 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4173 else if (grp_wanted)
4175 bool wanted = FALSE;
4177 for (j = 0; j < MAX_KUBI; j++)
4179 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4180 (p_ptr->today_mon && p_ptr->today_mon == i))
4186 if (!wanted) continue;
4189 else if (grp_amberite)
4191 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4196 /* Check for race in the group */
4197 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4201 mon_idx[mon_cnt++] = i;
4203 /* XXX Hack -- Just checking for non-empty group */
4204 if (mode & 0x01) break;
4207 /* Terminate the list */
4208 mon_idx[mon_cnt] = -1;
4210 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4212 /* Return the number of races */
4218 * Description of each monster group.
4220 static concptr object_group_text[] =
4223 "キノコ", /* "Mushrooms" */
4224 "薬", /* "Potions" */
4225 "油つぼ", /* "Flasks" */
4226 "巻物", /* "Scrolls" */
4228 "アミュレット", /* "Amulets" */
4229 "笛", /* "Whistle" */
4230 "光源", /* "Lanterns" */
4231 "魔法棒", /* "Wands" */
4234 "カード", /* "Cards" */
4245 "刀剣類", /* "Swords" */
4246 "鈍器", /* "Blunt Weapons" */
4247 "長柄武器", /* "Polearms" */
4248 "採掘道具", /* "Diggers" */
4249 "飛び道具", /* "Bows" */
4253 "軽装鎧", /* "Soft Armor" */
4254 "重装鎧", /* "Hard Armor" */
4255 "ドラゴン鎧", /* "Dragon Armor" */
4256 "盾", /* "Shields" */
4257 "クローク", /* "Cloaks" */
4258 "籠手", /* "Gloves" */
4259 "ヘルメット", /* "Helms" */
4261 "ブーツ", /* "Boots" */
4314 * TVALs of items in each group
4316 static byte object_group_tval[] =
4357 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4365 * Build a list of object indexes in the given group. Return the number
4366 * of objects in the group.
4368 * mode & 0x01 : check for non-empty group
4369 * mode & 0x02 : visual operation only
4371 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4373 KIND_OBJECT_IDX i, object_cnt = 0;
4376 /* Get a list of x_char in this group */
4377 byte group_tval = object_group_tval[grp_cur];
4379 /* Check every object */
4380 for (i = 0; i < max_k_idx; i++)
4382 /* Access the object */
4383 object_kind *k_ptr = &k_info[i];
4385 /* Skip empty objects */
4386 if (!k_ptr->name) continue;
4390 /* Any objects will be displayed */
4396 /* Skip non-flavoured objects */
4397 if (!k_ptr->flavor) continue;
4399 /* Require objects ever seen */
4400 if (!k_ptr->aware) continue;
4403 /* Skip items with no distribution (special artifacts) */
4404 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4408 /* Check for objects in the group */
4409 if (TV_LIFE_BOOK == group_tval)
4411 /* Hack -- All spell books */
4412 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4414 /* Add the object */
4415 object_idx[object_cnt++] = i;
4419 else if (k_ptr->tval == group_tval)
4421 /* Add the object */
4422 object_idx[object_cnt++] = i;
4426 /* XXX Hack -- Just checking for non-empty group */
4427 if (mode & 0x01) break;
4430 /* Terminate the list */
4431 object_idx[object_cnt] = -1;
4433 /* Return the number of objects */
4439 * Description of each feature group.
4441 static concptr feature_group_text[] =
4449 * Build a list of feature indexes in the given group. Return the number
4450 * of features in the group.
4452 * mode & 0x01 : check for non-empty group
4454 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4457 FEAT_IDX feat_cnt = 0;
4459 /* Unused; There is a single group. */
4462 /* Check every feature */
4463 for (i = 0; i < max_f_idx; i++)
4465 feature_type *f_ptr = &f_info[i];
4467 /* Skip empty index */
4468 if (!f_ptr->name) continue;
4470 /* Skip mimiccing features */
4471 if (f_ptr->mimic != i) continue;
4474 feat_idx[feat_cnt++] = i;
4476 /* XXX Hack -- Just checking for non-empty group */
4477 if (mode & 0x01) break;
4480 /* Terminate the list */
4481 feat_idx[feat_cnt] = -1;
4483 /* Return the number of races */
4490 * Build a list of monster indexes in the given group. Return the number
4491 * of monsters in the group.
4493 static int collect_artifacts(int grp_cur, int object_idx[])
4495 int i, object_cnt = 0;
4497 /* Get a list of x_char in this group */
4498 byte group_tval = object_group_tval[grp_cur];
4500 /* Check every object */
4501 for (i = 0; i < max_a_idx; i++)
4503 /* Access the artifact */
4504 artifact_type *a_ptr = &a_info[i];
4506 /* Skip empty artifacts */
4507 if (!a_ptr->name) continue;
4509 /* Skip "uncreated" artifacts */
4510 if (!a_ptr->cur_num) continue;
4512 /* Check for race in the group */
4513 if (a_ptr->tval == group_tval)
4516 object_idx[object_cnt++] = i;
4520 /* Terminate the list */
4521 object_idx[object_cnt] = 0;
4523 /* Return the number of races */
4530 * Encode the screen colors
4532 static char hack[17] = "dwsorgbuDWvyRGBU";
4536 * Hack -- load a screen dump from a file
4538 void do_cmd_load_screen(void)
4543 SYMBOL_CODE c = ' ';
4549 Term_get_size(&wid, &hgt);
4551 /* Build the filename */
4552 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4554 /* Append to the file */
4555 fff = my_fopen(buf, "r");
4558 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4566 /* Load the screen */
4567 for (y = 0; okay; y++)
4569 /* Get a line of data including control code */
4570 if (!fgets(buf, 1024, fff)) okay = FALSE;
4572 /* Get the blank line */
4573 if (buf[0] == '\n' || buf[0] == '\0') break;
4575 /* Ignore too large screen image */
4576 if (y >= hgt) continue;
4579 for (x = 0; x < wid - 1; x++)
4582 if (buf[x] == '\n' || buf[x] == '\0') break;
4584 /* Put the attr/char */
4585 Term_draw(x, y, TERM_WHITE, buf[x]);
4589 /* Dump the screen */
4590 for (y = 0; okay; y++)
4592 /* Get a line of data including control code */
4593 if (!fgets(buf, 1024, fff)) okay = FALSE;
4595 /* Get the blank line */
4596 if (buf[0] == '\n' || buf[0] == '\0') break;
4598 /* Ignore too large screen image */
4599 if (y >= hgt) continue;
4602 for (x = 0; x < wid - 1; x++)
4605 if (buf[x] == '\n' || buf[x] == '\0') break;
4607 /* Get the attr/char */
4608 (void)(Term_what(x, y, &a, &c));
4610 /* Look up the attr */
4611 for (i = 0; i < 16; i++)
4613 /* Use attr matches */
4614 if (hack[i] == buf[x]) a = (byte_hack)i;
4617 /* Put the attr/char */
4618 Term_draw(x, y, a, c);
4623 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4634 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4635 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4638 #define IM_FLAG_STR _("*", "* ")
4639 #define HAS_FLAG_STR _("+", "+ ")
4640 #define NO_FLAG_STR _("・", ". ")
4642 #define print_im_or_res_flag(IM, RES) \
4644 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4645 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4648 #define print_flag(TR) \
4650 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4654 /* XTRA HACK RESLIST */
4655 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4657 GAME_TEXT o_name[MAX_NLEN];
4658 BIT_FLAGS flgs[TR_FLAG_SIZE];
4660 if (!o_ptr->k_idx) return;
4661 if (o_ptr->tval != tval) return;
4663 /* Identified items only */
4664 if (!object_is_known(o_ptr)) return;
4667 * HACK:Ring of Lordly protection and Dragon equipment
4668 * have random resistances.
4670 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4671 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4672 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4673 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4674 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4675 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4676 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4677 || object_is_artifact(o_ptr))
4680 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4682 while (o_name[i] && (i < 26))
4685 if (iskanji(o_name[i])) i++;
4694 o_name[i] = ' '; i++;
4699 fprintf(fff, "%s %s", where, o_name);
4701 if (!(o_ptr->ident & (IDENT_MENTAL)))
4703 fputs(_("-------不明--------------- -------不明---------\n",
4704 "-------unknown------------ -------unknown------\n"), fff);
4708 object_flags_known(o_ptr, flgs);
4710 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4711 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4712 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4713 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4714 print_flag(TR_RES_POIS);
4715 print_flag(TR_RES_LITE);
4716 print_flag(TR_RES_DARK);
4717 print_flag(TR_RES_SHARDS);
4718 print_flag(TR_RES_SOUND);
4719 print_flag(TR_RES_NETHER);
4720 print_flag(TR_RES_NEXUS);
4721 print_flag(TR_RES_CHAOS);
4722 print_flag(TR_RES_DISEN);
4726 print_flag(TR_RES_BLIND);
4727 print_flag(TR_RES_FEAR);
4728 print_flag(TR_RES_CONF);
4729 print_flag(TR_FREE_ACT);
4730 print_flag(TR_SEE_INVIS);
4731 print_flag(TR_HOLD_EXP);
4732 print_flag(TR_TELEPATHY);
4733 print_flag(TR_SLOW_DIGEST);
4734 print_flag(TR_REGEN);
4735 print_flag(TR_LEVITATION);
4743 fprintf(fff, "%s\n", inven_res_label);
4749 * Display *ID* ed weapons/armors's resistances
4751 static void do_cmd_knowledge_inven(void)
4754 GAME_TEXT file_name[1024];
4756 OBJECT_TYPE_VALUE tval;
4762 /* Open a new file */
4763 fff = my_fopen_temp(file_name, 1024);
4766 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4770 fprintf(fff, "%s\n", inven_res_label);
4772 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4776 for (; j < 9; j++) fputc('\n', fff);
4778 fprintf(fff, "%s\n", inven_res_label);
4780 strcpy(where, _("装", "E "));
4781 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4783 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4785 strcpy(where, _("持", "I "));
4786 for (i = 0; i < INVEN_PACK; i++)
4788 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4791 st_ptr = &town_info[1].store[STORE_HOME];
4792 strcpy(where, _("家", "H "));
4793 for (i = 0; i < st_ptr->stock_num; i++)
4795 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4800 /* Display the file contents */
4801 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4806 void do_cmd_save_screen_html_aux(char *filename, int message)
4811 TERM_COLOR a = 0, old_a = 0;
4825 concptr html_head[] = {
4826 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4830 concptr html_foot[] = {
4832 "</body>\n</html>\n",
4838 Term_get_size(&wid, &hgt);
4840 /* File type is "TEXT" */
4841 FILE_TYPE(FILE_TYPE_TEXT);
4843 /* Append to the file */
4844 fff = my_fopen(filename, "w");
4848 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4854 if (message) screen_save();
4856 /* Build the filename */
4857 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4858 tmpfff = my_fopen(buf, "r");
4860 for (i = 0; html_head[i]; i++)
4861 fputs(html_head[i], fff);
4865 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4867 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4871 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4873 fprintf(fff, "%s\n", buf);
4878 /* Dump the screen */
4879 for (y = 0; y < hgt; y++)
4886 for (x = 0; x < wid - 1; x++)
4890 /* Get the attr/char */
4891 (void)(Term_what(x, y, &a, &c));
4895 case '&': cc = "&"; break;
4896 case '<': cc = "<"; break;
4897 case '>': cc = ">"; break;
4899 case 0x1f: c = '.'; break;
4900 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4905 if ((y == 0 && x == 0) || a != old_a) {
4906 rv = angband_color_table[a][1];
4907 gv = angband_color_table[a][2];
4908 bv = angband_color_table[a][3];
4909 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4910 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4914 fprintf(fff, "%s", cc);
4916 fprintf(fff, "%c", c);
4919 fprintf(fff, "</font>");
4922 for (i = 0; html_foot[i]; i++)
4923 fputs(html_foot[i], fff);
4928 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4930 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4934 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4936 fprintf(fff, "%s\n", buf);
4947 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4955 * Hack -- save a screen dump to a file
4957 static void do_cmd_save_screen_html(void)
4959 char buf[1024], tmp[256] = "screen.html";
4961 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4964 /* Build the filename */
4965 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4969 do_cmd_save_screen_html_aux(buf, 1);
4974 * Redefinable "save_screen" action
4976 void (*screendump_aux)(void) = NULL;
4980 * Hack -- save a screen dump to a file
4982 void do_cmd_save_screen(void)
4984 bool old_use_graphics = use_graphics;
4985 bool html_dump = FALSE;
4989 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4993 if (c == 'Y' || c == 'y')
4995 else if (c == 'H' || c == 'h')
5007 Term_get_size(&wid, &hgt);
5009 if (old_use_graphics)
5011 use_graphics = FALSE;
5013 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5019 do_cmd_save_screen_html();
5023 /* Do we use a special screendump function ? */
5024 else if (screendump_aux)
5026 /* Dump the screen to a graphics file */
5027 (*screendump_aux)();
5029 else /* Dump the screen as text */
5033 SYMBOL_CODE c = ' ';
5037 /* Build the filename */
5038 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5040 /* File type is "TEXT" */
5041 FILE_TYPE(FILE_TYPE_TEXT);
5043 /* Append to the file */
5044 fff = my_fopen(buf, "w");
5048 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5056 /* Dump the screen */
5057 for (y = 0; y < hgt; y++)
5060 for (x = 0; x < wid - 1; x++)
5062 /* Get the attr/char */
5063 (void)(Term_what(x, y, &a, &c));
5073 fprintf(fff, "%s\n", buf);
5080 /* Dump the screen */
5081 for (y = 0; y < hgt; y++)
5084 for (x = 0; x < wid - 1; x++)
5086 /* Get the attr/char */
5087 (void)(Term_what(x, y, &a, &c));
5090 buf[x] = hack[a&0x0F];
5097 fprintf(fff, "%s\n", buf);
5104 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5109 if (old_use_graphics)
5111 use_graphics = TRUE;
5113 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5119 * Check the status of "artifacts"
5121 static void do_cmd_knowledge_artifacts(void)
5131 GAME_TEXT file_name[1024];
5132 GAME_TEXT base_name[MAX_NLEN];
5136 /* Open a new file */
5137 fff = my_fopen_temp(file_name, 1024);
5140 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5145 /* Allocate the "who" array */
5146 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5148 /* Allocate the "okay" array */
5149 C_MAKE(okay, max_a_idx, bool);
5151 /* Scan the artifacts */
5152 for (k = 0; k < max_a_idx; k++)
5154 artifact_type *a_ptr = &a_info[k];
5159 /* Skip "empty" artifacts */
5160 if (!a_ptr->name) continue;
5162 /* Skip "uncreated" artifacts */
5163 if (!a_ptr->cur_num) continue;
5169 /* Check the dungeon */
5170 for (y = 0; y < current_floor_ptr->height; y++)
5172 for (x = 0; x < current_floor_ptr->width; x++)
5174 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5176 OBJECT_IDX this_o_idx, next_o_idx = 0;
5178 /* Scan all objects in the grid */
5179 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5182 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5183 next_o_idx = o_ptr->next_o_idx;
5185 /* Ignore non-artifacts */
5186 if (!object_is_fixed_artifact(o_ptr)) continue;
5188 /* Ignore known items */
5189 if (object_is_known(o_ptr)) continue;
5191 /* Note the artifact */
5192 okay[o_ptr->name1] = FALSE;
5197 /* Check the p_ptr->inventory_list and equipment */
5198 for (i = 0; i < INVEN_TOTAL; i++)
5200 object_type *o_ptr = &p_ptr->inventory_list[i];
5202 /* Ignore non-objects */
5203 if (!o_ptr->k_idx) continue;
5205 /* Ignore non-artifacts */
5206 if (!object_is_fixed_artifact(o_ptr)) continue;
5208 /* Ignore known items */
5209 if (object_is_known(o_ptr)) continue;
5211 /* Note the artifact */
5212 okay[o_ptr->name1] = FALSE;
5215 for (k = 0; k < max_a_idx; k++)
5217 if (okay[k]) who[n++] = k;
5220 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5222 /* Scan the artifacts */
5223 for (k = 0; k < n; k++)
5225 artifact_type *a_ptr = &a_info[who[k]];
5226 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5228 /* Obtain the base object type */
5229 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5238 /* Create fake object */
5239 object_prep(q_ptr, z);
5241 /* Make it an artifact */
5242 q_ptr->name1 = (byte)who[k];
5244 /* Display as if known */
5245 q_ptr->ident |= IDENT_STORE;
5247 /* Describe the artifact */
5248 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5251 /* Hack -- Build the artifact name */
5252 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5255 /* Free the "who" array */
5256 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5258 /* Free the "okay" array */
5259 C_KILL(okay, max_a_idx, bool);
5262 /* Display the file contents */
5263 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5269 * Display known uniques
5270 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5272 static void do_cmd_knowledge_uniques(void)
5281 GAME_TEXT file_name[1024];
5284 int n_alive_surface = 0;
5285 int n_alive_over100 = 0;
5286 int n_alive_total = 0;
5289 for (i = 0; i < 10; i++) n_alive[i] = 0;
5291 /* Open a new file */
5292 fff = my_fopen_temp(file_name, 1024);
5296 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5301 /* Allocate the "who" array */
5302 C_MAKE(who, max_r_idx, MONRACE_IDX);
5304 /* Scan the monsters */
5305 for (i = 1; i < max_r_idx; i++)
5307 monster_race *r_ptr = &r_info[i];
5310 if (!r_ptr->name) continue;
5312 /* Require unique monsters */
5313 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5315 /* Only display "known" uniques */
5316 if (!cheat_know && !r_ptr->r_sights) continue;
5318 /* Only print rarity <= 100 uniques */
5319 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5321 /* Only "alive" uniques */
5322 if (r_ptr->max_num == 0) continue;
5326 lev = (r_ptr->level - 1) / 10;
5330 if (max_lev < lev) max_lev = lev;
5332 else n_alive_over100++;
5334 else n_alive_surface++;
5336 /* Collect "appropriate" monsters */
5340 /* Sort the array by dungeon depth of monsters */
5341 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5343 if (n_alive_surface)
5345 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5346 n_alive_total += n_alive_surface;
5348 for (i = 0; i <= max_lev; i++)
5350 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5351 n_alive_total += n_alive[i];
5353 if (n_alive_over100)
5355 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5356 n_alive_total += n_alive_over100;
5361 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5362 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5366 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5369 /* Scan the monster races */
5370 for (k = 0; k < n; k++)
5372 monster_race *r_ptr = &r_info[who[k]];
5374 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5377 /* Free the "who" array */
5378 C_KILL(who, max_r_idx, s16b);
5381 /* Display the file contents */
5382 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5388 * Display weapon-exp
5390 static void do_cmd_knowledge_weapon_exp(void)
5398 GAME_TEXT file_name[1024];
5401 /* Open a new file */
5402 fff = my_fopen_temp(file_name, 1024);
5404 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5409 for (i = 0; i < 5; i++)
5411 for (num = 0; num < 64; num++)
5413 for (j = 0; j < max_k_idx; j++)
5415 object_kind *k_ptr = &k_info[j];
5417 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5419 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5421 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5423 fprintf(fff, "%-25s ", tmp);
5424 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5425 else fprintf(fff, " ");
5426 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5427 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5436 /* Display the file contents */
5437 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5443 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5447 static void do_cmd_knowledge_spell_exp(void)
5454 const magic_type *s_ptr;
5456 GAME_TEXT file_name[1024];
5458 /* Open a new file */
5459 fff = my_fopen_temp(file_name, 1024);
5461 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5466 if (p_ptr->realm1 != REALM_NONE)
5468 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5469 for (i = 0; i < 32; i++)
5471 if (!is_magic(p_ptr->realm1))
5473 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5477 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5479 if (s_ptr->slevel >= 99) continue;
5480 spell_exp = p_ptr->spell_exp[i];
5481 exp_level = spell_exp_level(spell_exp);
5482 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5483 if (p_ptr->realm1 == REALM_HISSATSU)
5484 fprintf(fff, "[--]");
5487 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5488 else fprintf(fff, " ");
5489 fprintf(fff, "%s", exp_level_str[exp_level]);
5491 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5496 if (p_ptr->realm2 != REALM_NONE)
5498 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5499 for (i = 0; i < 32; i++)
5501 if (!is_magic(p_ptr->realm1))
5503 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5507 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5509 if (s_ptr->slevel >= 99) continue;
5511 spell_exp = p_ptr->spell_exp[i + 32];
5512 exp_level = spell_exp_level(spell_exp);
5513 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5514 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5515 else fprintf(fff, " ");
5516 fprintf(fff, "%s", exp_level_str[exp_level]);
5517 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5523 /* Display the file contents */
5524 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5530 * @brief スキル情報を表示するコマンドのメインルーチン /
5534 static void do_cmd_knowledge_skill_exp(void)
5536 int i = 0, skill_exp;
5540 char file_name[1024];
5541 char skill_name[GINOU_TEMPMAX][20] =
5543 _("マーシャルアーツ", "Martial Arts "),
5544 _("二刀流 ", "Dual Wielding "),
5545 _("乗馬 ", "Riding "),
5549 /* Open a new file */
5550 fff = my_fopen_temp(file_name, 1024);
5552 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5557 for (i = 0; i < GINOU_TEMPMAX; i++)
5559 skill_exp = p_ptr->skill_exp[i];
5560 fprintf(fff, "%-20s ", skill_name[i]);
5561 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5562 else fprintf(fff, " ");
5563 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5564 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5569 /* Display the file contents */
5570 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5576 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5577 * @param Name 変換したい文字列の参照ポインタ
5580 void plural_aux(char *Name)
5582 int NameLen = strlen(Name);
5584 if (my_strstr(Name, "Disembodied hand"))
5586 strcpy(Name, "Disembodied hands that strangled people");
5588 else if (my_strstr(Name, "Colour out of space"))
5590 strcpy(Name, "Colours out of space");
5592 else if (my_strstr(Name, "stairway to hell"))
5594 strcpy(Name, "stairways to hell");
5596 else if (my_strstr(Name, "Dweller on the threshold"))
5598 strcpy(Name, "Dwellers on the threshold");
5600 else if (my_strstr(Name, " of "))
5602 concptr aider = my_strstr(Name, " of ");
5613 if (dummy[i-1] == 's')
5615 strcpy(&(dummy[i]), "es");
5620 strcpy(&(dummy[i]), "s");
5623 strcpy(&(dummy[i+1]), aider);
5624 strcpy(Name, dummy);
5626 else if (my_strstr(Name, "coins"))
5629 strcpy(dummy, "piles of ");
5630 strcat(dummy, Name);
5631 strcpy(Name, dummy);
5634 else if (my_strstr(Name, "Manes"))
5638 else if (streq(&(Name[NameLen - 2]), "ey"))
5640 strcpy(&(Name[NameLen - 2]), "eys");
5642 else if (Name[NameLen - 1] == 'y')
5644 strcpy(&(Name[NameLen - 1]), "ies");
5646 else if (streq(&(Name[NameLen - 4]), "ouse"))
5648 strcpy(&(Name[NameLen - 4]), "ice");
5650 else if (streq(&(Name[NameLen - 2]), "us"))
5652 strcpy(&(Name[NameLen - 2]), "i");
5654 else if (streq(&(Name[NameLen - 6]), "kelman"))
5656 strcpy(&(Name[NameLen - 6]), "kelmen");
5658 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5660 strcpy(&(Name[NameLen - 8]), "wordsmen");
5662 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5664 strcpy(&(Name[NameLen - 7]), "oodsmen");
5666 else if (streq(&(Name[NameLen - 7]), "eastman"))
5668 strcpy(&(Name[NameLen - 7]), "eastmen");
5670 else if (streq(&(Name[NameLen - 8]), "izardman"))
5672 strcpy(&(Name[NameLen - 8]), "izardmen");
5674 else if (streq(&(Name[NameLen - 5]), "geist"))
5676 strcpy(&(Name[NameLen - 5]), "geister");
5678 else if (streq(&(Name[NameLen - 2]), "ex"))
5680 strcpy(&(Name[NameLen - 2]), "ices");
5682 else if (streq(&(Name[NameLen - 2]), "lf"))
5684 strcpy(&(Name[NameLen - 2]), "lves");
5686 else if (suffix(Name, "ch") ||
5687 suffix(Name, "sh") ||
5688 suffix(Name, "nx") ||
5689 suffix(Name, "s") ||
5692 strcpy(&(Name[NameLen]), "es");
5696 strcpy(&(Name[NameLen]), "s");
5701 * @brief 現在のペットを表示するコマンドのメインルーチン /
5702 * Display current pets
5705 static void do_cmd_knowledge_pets(void)
5709 monster_type *m_ptr;
5710 GAME_TEXT pet_name[MAX_NLEN];
5712 int show_upkeep = 0;
5713 GAME_TEXT file_name[1024];
5716 /* Open a new file */
5717 fff = my_fopen_temp(file_name, 1024);
5719 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5724 /* Process the monsters (backwards) */
5725 for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
5727 /* Access the monster */
5728 m_ptr = ¤t_floor_ptr->m_list[i];
5730 /* Ignore "dead" monsters */
5731 if (!monster_is_valid(m_ptr)) continue;
5733 /* Calculate "upkeep" for pets */
5737 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5738 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5742 show_upkeep = calculate_upkeep();
5744 fprintf(fff, "----------------------------------------------\n");
5746 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5748 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5750 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5755 /* Display the file contents */
5756 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5762 * @brief 現在のペットを表示するコマンドのメインルーチン /
5765 * @note the player ghosts are ignored.
5767 static void do_cmd_knowledge_kill_count(void)
5774 GAME_TEXT file_name[1024];
5779 /* Open a new file */
5780 fff = my_fopen_temp(file_name, 1024);
5783 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5788 /* Allocate the "who" array */
5789 C_MAKE(who, max_r_idx, MONRACE_IDX);
5792 /* Monsters slain */
5795 for (kk = 1; kk < max_r_idx; kk++)
5797 monster_race *r_ptr = &r_info[kk];
5799 if (r_ptr->flags1 & (RF1_UNIQUE))
5801 bool dead = (r_ptr->max_num == 0);
5810 MONSTER_NUMBER This = r_ptr->r_pkills;
5820 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5823 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5825 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5831 /* Scan the monsters */
5832 for (i = 1; i < max_r_idx; i++)
5834 monster_race *r_ptr = &r_info[i];
5836 /* Use that monster */
5837 if (r_ptr->name) who[n++] = i;
5840 /* Sort the array by dungeon depth of monsters */
5841 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5843 /* Scan the monster races */
5844 for (k = 0; k < n; k++)
5846 monster_race *r_ptr = &r_info[who[k]];
5848 if (r_ptr->flags1 & (RF1_UNIQUE))
5850 bool dead = (r_ptr->max_num == 0);
5854 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5860 MONSTER_NUMBER This = r_ptr->r_pkills;
5865 /* p,tは人と数える by ita */
5866 if (my_strchr("pt", r_ptr->d_char))
5867 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5869 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5873 if (my_strstr(r_name + r_ptr->name, "coins"))
5875 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5879 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5885 strcpy(ToPlural, (r_name + r_ptr->name));
5886 plural_aux(ToPlural);
5887 fprintf(fff, " %d %s\n", This, ToPlural);
5897 fprintf(fff,"----------------------------------------------\n");
5899 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5901 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5905 /* Free the "who" array */
5906 C_KILL(who, max_r_idx, s16b);
5909 /* Display the file contents */
5910 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5916 * @brief モンスター情報リスト中のグループを表示する /
5917 * Display the object groups.
5921 * @param per_page リストの表示行
5922 * @param grp_idx グループのID配列
5923 * @param group_text グループ名の文字列配列
5924 * @param grp_cur 現在の選択ID
5925 * @param grp_top 現在の選択リスト最上部ID
5928 static void display_group_list(int col, int row, int wid, int per_page, IDX grp_idx[], concptr group_text[], int grp_cur, int grp_top)
5932 /* Display lines until done */
5933 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5935 /* Get the group index */
5936 int grp = grp_idx[grp_top + i];
5938 /* Choose a color */
5939 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5941 /* Erase the entire line */
5942 Term_erase(col, row + i, wid);
5944 /* Display the group label */
5945 c_put_str(attr, group_text[grp], row + i, col);
5951 * Move the cursor in a browser window
5953 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5954 IDX *list_cur, int list_cnt)
5959 IDX list = *list_cur;
5961 /* Extract direction */
5964 /* Hack -- scroll up full screen */
5969 /* Hack -- scroll down full screen */
5974 d = get_keymap_dir(ch);
5979 /* Diagonals - hack */
5980 if ((ddx[d] > 0) && ddy[d])
5985 Term_get_size(&wid, &hgt);
5987 browser_rows = hgt - 8;
5989 /* Browse group list */
5994 /* Move up or down */
5995 grp += ddy[d] * (browser_rows - 1);
5998 if (grp >= grp_cnt) grp = grp_cnt - 1;
5999 if (grp < 0) grp = 0;
6000 if (grp != old_grp) list = 0;
6003 /* Browse sub-list list */
6006 /* Move up or down */
6007 list += ddy[d] * browser_rows;
6010 if (list >= list_cnt) list = list_cnt - 1;
6011 if (list < 0) list = 0;
6023 if (col < 0) col = 0;
6024 if (col > 1) col = 1;
6031 /* Browse group list */
6036 /* Move up or down */
6040 if (grp >= grp_cnt) grp = grp_cnt - 1;
6041 if (grp < 0) grp = 0;
6042 if (grp != old_grp) list = 0;
6045 /* Browse sub-list list */
6048 /* Move up or down */
6049 list += (IDX)ddy[d];
6052 if (list >= list_cnt) list = list_cnt - 1;
6053 if (list < 0) list = 0;
6064 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6068 /* Clear the display lines */
6069 for (i = 0; i < height; i++)
6071 Term_erase(col, row + i, width);
6074 /* Bigtile mode uses double width */
6075 if (use_bigtile) width /= 2;
6077 /* Display lines until done */
6078 for (i = 0; i < height; i++)
6080 /* Display columns until done */
6081 for (j = 0; j < width; j++)
6085 TERM_LEN x = col + j;
6086 TERM_LEN y = row + i;
6088 /* Bigtile mode uses double width */
6089 if (use_bigtile) x += j;
6094 /* Ignore illegal characters */
6095 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6096 (!use_graphics && ic > 0x7f))
6102 /* Force correct code for both ASCII character and tile */
6103 if (c & 0x80) a |= 0x80;
6105 /* Display symbol */
6106 Term_queue_bigchar(x, y, a, c, 0, 0);
6113 * Place the cursor at the collect position for visual mode
6115 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6117 int i = (a & 0x7f) - attr_top;
6118 int j = c - char_left;
6120 TERM_LEN x = col + j;
6121 TERM_LEN y = row + i;
6123 /* Bigtile mode uses double width */
6124 if (use_bigtile) x += j;
6126 /* Place the cursor */
6132 * Clipboard variables for copy&paste in visual mode
6134 static TERM_COLOR attr_idx = 0;
6135 static SYMBOL_CODE char_idx = 0;
6137 /* Hack -- for feature lighting */
6138 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6139 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6142 * Do visual mode command -- Change symbols
6144 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6145 int height, int width,
6146 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6147 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6149 static TERM_COLOR attr_old = 0;
6150 static SYMBOL_CODE char_old = 0;
6155 if (*visual_list_ptr)
6158 *cur_attr_ptr = attr_old;
6159 *cur_char_ptr = char_old;
6160 *visual_list_ptr = FALSE;
6168 if (*visual_list_ptr)
6171 *visual_list_ptr = FALSE;
6172 *need_redraw = TRUE;
6180 if (!*visual_list_ptr)
6182 *visual_list_ptr = TRUE;
6184 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6185 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6187 attr_old = *cur_attr_ptr;
6188 char_old = *cur_char_ptr;
6199 /* Set the visual */
6200 attr_idx = *cur_attr_ptr;
6201 char_idx = *cur_char_ptr;
6203 /* Hack -- for feature lighting */
6204 for (i = 0; i < F_LIT_MAX; i++)
6206 attr_idx_feat[i] = 0;
6207 char_idx_feat[i] = 0;
6214 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6217 *cur_attr_ptr = attr_idx;
6218 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6219 if (!*visual_list_ptr) *need_redraw = TRUE;
6225 *cur_char_ptr = char_idx;
6226 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6227 if (!*visual_list_ptr) *need_redraw = TRUE;
6233 if (*visual_list_ptr)
6236 int d = get_keymap_dir(ch);
6237 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6238 SYMBOL_CODE c = *cur_char_ptr;
6240 if (use_bigtile) eff_width = width / 2;
6241 else eff_width = width;
6243 /* Restrict direction */
6244 if ((a == 0) && (ddy[d] < 0)) d = 0;
6245 if ((c == 0) && (ddx[d] < 0)) d = 0;
6246 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6247 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6249 a += (TERM_COLOR)ddy[d];
6250 c += (SYMBOL_CODE)ddx[d];
6252 /* Force correct code for both ASCII character and tile */
6253 if (c & 0x80) a |= 0x80;
6255 /* Set the visual */
6260 /* Move the frame */
6261 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6262 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6263 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6264 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6270 /* Visual mode command is not used */
6276 * Display the monsters in a group.
6278 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6279 int mon_cur, int mon_top, bool visual_only)
6283 /* Display lines until done */
6284 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6288 /* Get the race index */
6289 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6291 /* Access the race */
6292 monster_race *r_ptr = &r_info[r_idx];
6294 /* Choose a color */
6295 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6297 /* Display the name */
6298 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6300 /* Hack -- visual_list mode */
6303 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6305 if (p_ptr->wizard || visual_only)
6307 c_prt(attr, format("%d", r_idx), row + i, 62);
6310 /* Erase chars before overwritten by the race letter */
6311 Term_erase(69, row + i, 255);
6313 /* Display symbol */
6314 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6319 if (!(r_ptr->flags1 & RF1_UNIQUE))
6320 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6322 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6323 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6327 /* Clear remaining lines */
6328 for (; i < per_page; i++)
6330 Term_erase(col, row + i, 255);
6336 * Display known monsters.
6338 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6342 IDX grp_cur, grp_top, old_grp_cur;
6343 IDX mon_cur, mon_top;
6344 IDX grp_cnt, grp_idx[100];
6352 bool visual_list = FALSE;
6353 TERM_COLOR attr_top = 0;
6361 Term_get_size(&wid, &hgt);
6363 browser_rows = hgt - 8;
6365 /* Allocate the "mon_idx" array */
6366 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6371 if (direct_r_idx < 0)
6373 mode = visual_only ? 0x03 : 0x01;
6375 /* Check every group */
6376 for (i = 0; monster_group_text[i] != NULL; i++)
6378 /* Measure the label */
6379 len = strlen(monster_group_text[i]);
6381 /* Save the maximum length */
6382 if (len > max) max = len;
6384 /* See if any monsters are known */
6385 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6387 /* Build a list of groups with known monsters */
6388 grp_idx[grp_cnt++] = i;
6396 mon_idx[0] = direct_r_idx;
6399 /* Terminate the list */
6402 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6403 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6406 /* Terminate the list */
6407 grp_idx[grp_cnt] = -1;
6410 grp_cur = grp_top = 0;
6411 mon_cur = mon_top = 0;
6416 mode = visual_only ? 0x02 : 0x00;
6421 monster_race *r_ptr;
6426 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6427 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6428 prt(_("名前", "Name"), 4, max + 3);
6429 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6430 prt(_("文字", "Sym"), 4, 67);
6431 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6433 for (i = 0; i < 78; i++)
6435 Term_putch(i, 5, TERM_WHITE, '=');
6438 if (direct_r_idx < 0)
6440 for (i = 0; i < browser_rows; i++)
6442 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6449 if (direct_r_idx < 0)
6451 /* Scroll group list */
6452 if (grp_cur < grp_top) grp_top = grp_cur;
6453 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6455 /* Display a list of monster groups */
6456 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6458 if (old_grp_cur != grp_cur)
6460 old_grp_cur = grp_cur;
6462 /* Get a list of monsters in the current group */
6463 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6466 /* Scroll monster list */
6467 while (mon_cur < mon_top)
6468 mon_top = MAX(0, mon_top - browser_rows/2);
6469 while (mon_cur >= mon_top + browser_rows)
6470 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6475 /* Display a list of monsters in the current group */
6476 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6482 /* Display a monster name */
6483 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6485 /* Display visual list below first monster */
6486 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6490 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6491 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6492 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6493 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6496 /* Get the current monster */
6497 r_ptr = &r_info[mon_idx[mon_cur]];
6501 /* Mega Hack -- track this monster race */
6502 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6508 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6512 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6516 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6521 /* Do visual mode command if needed */
6522 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))
6524 if (direct_r_idx >= 0)
6549 /* Recall on screen */
6550 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6552 screen_roff(mon_idx[mon_cur], 0);
6563 /* Move the cursor */
6564 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6571 /* Free the "mon_idx" array */
6572 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6577 * Display the objects in a group.
6579 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6580 int object_cur, int object_top, bool visual_only)
6584 /* Display lines until done */
6585 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6587 GAME_TEXT o_name[MAX_NLEN];
6590 object_kind *flavor_k_ptr;
6592 /* Get the object index */
6593 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6595 /* Access the object */
6596 object_kind *k_ptr = &k_info[k_idx];
6598 /* Choose a color */
6599 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6600 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6603 if (!visual_only && k_ptr->flavor)
6605 /* Appearance of this object is shuffled */
6606 flavor_k_ptr = &k_info[k_ptr->flavor];
6610 /* Appearance of this object is very normal */
6611 flavor_k_ptr = k_ptr;
6616 attr = ((i + object_top == object_cur) ? cursor : attr);
6618 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6621 strip_name(o_name, k_idx);
6626 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6629 /* Display the name */
6630 c_prt(attr, o_name, row + i, col);
6632 /* Hack -- visual_list mode */
6635 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);
6637 if (p_ptr->wizard || visual_only)
6639 c_prt(attr, format("%d", k_idx), row + i, 70);
6642 a = flavor_k_ptr->x_attr;
6643 c = flavor_k_ptr->x_char;
6645 /* Display symbol */
6646 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6649 /* Clear remaining lines */
6650 for (; i < per_page; i++)
6652 Term_erase(col, row + i, 255);
6657 * Describe fake object
6659 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6662 object_type object_type_body;
6663 o_ptr = &object_type_body;
6665 object_prep(o_ptr, k_idx);
6667 /* It's fully know */
6668 o_ptr->ident |= IDENT_KNOWN;
6670 /* Track the object */
6671 /* object_actual_track(o_ptr); */
6673 /* Hack - mark as fake */
6674 /* term_obj_real = FALSE; */
6677 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6679 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6687 * Display known objects
6689 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6693 IDX grp_cur, grp_top, old_grp_cur;
6694 IDX object_old, object_cur, object_top;
6698 OBJECT_IDX *object_idx;
6704 bool visual_list = FALSE;
6705 TERM_COLOR attr_top = 0;
6713 Term_get_size(&wid, &hgt);
6715 browser_rows = hgt - 8;
6717 /* Allocate the "object_idx" array */
6718 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6723 if (direct_k_idx < 0)
6725 mode = visual_only ? 0x03 : 0x01;
6727 /* Check every group */
6728 for (i = 0; object_group_text[i] != NULL; i++)
6730 /* Measure the label */
6731 len = strlen(object_group_text[i]);
6733 /* Save the maximum length */
6734 if (len > max) max = len;
6736 /* See if any monsters are known */
6737 if (collect_objects(i, object_idx, mode))
6739 /* Build a list of groups with known monsters */
6740 grp_idx[grp_cnt++] = i;
6749 object_kind *k_ptr = &k_info[direct_k_idx];
6750 object_kind *flavor_k_ptr;
6752 if (!visual_only && k_ptr->flavor)
6754 /* Appearance of this object is shuffled */
6755 flavor_k_ptr = &k_info[k_ptr->flavor];
6759 /* Appearance of this object is very normal */
6760 flavor_k_ptr = k_ptr;
6763 object_idx[0] = direct_k_idx;
6764 object_old = direct_k_idx;
6767 /* Terminate the list */
6770 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6771 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6774 /* Terminate the list */
6775 grp_idx[grp_cnt] = -1;
6778 grp_cur = grp_top = 0;
6779 object_cur = object_top = 0;
6784 mode = visual_only ? 0x02 : 0x00;
6789 object_kind *k_ptr, *flavor_k_ptr;
6796 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6797 if (direct_k_idx < 0) prt("グループ", 4, 0);
6798 prt("名前", 4, max + 3);
6799 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6802 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6803 if (direct_k_idx < 0) prt("Group", 4, 0);
6804 prt("Name", 4, max + 3);
6805 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6809 for (i = 0; i < 78; i++)
6811 Term_putch(i, 5, TERM_WHITE, '=');
6814 if (direct_k_idx < 0)
6816 for (i = 0; i < browser_rows; i++)
6818 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6825 if (direct_k_idx < 0)
6827 /* Scroll group list */
6828 if (grp_cur < grp_top) grp_top = grp_cur;
6829 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6831 /* Display a list of object groups */
6832 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6834 if (old_grp_cur != grp_cur)
6836 old_grp_cur = grp_cur;
6838 /* Get a list of objects in the current group */
6839 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6842 /* Scroll object list */
6843 while (object_cur < object_top)
6844 object_top = MAX(0, object_top - browser_rows/2);
6845 while (object_cur >= object_top + browser_rows)
6846 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6851 /* Display a list of objects in the current group */
6852 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6856 object_top = object_cur;
6858 /* Display a list of objects in the current group */
6859 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6861 /* Display visual list below first object */
6862 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6865 /* Get the current object */
6866 k_ptr = &k_info[object_idx[object_cur]];
6868 if (!visual_only && k_ptr->flavor)
6870 /* Appearance of this object is shuffled */
6871 flavor_k_ptr = &k_info[k_ptr->flavor];
6875 /* Appearance of this object is very normal */
6876 flavor_k_ptr = k_ptr;
6881 prt(format("<方向>%s%s%s, ESC",
6882 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6883 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6884 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6887 prt(format("<dir>%s%s%s, ESC",
6888 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6889 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6890 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6896 /* Mega Hack -- track this object */
6897 if (object_cnt) object_kind_track(object_idx[object_cur]);
6899 /* The "current" object changed */
6900 if (object_old != object_idx[object_cur])
6904 /* Remember the "current" object */
6905 object_old = object_idx[object_cur];
6911 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6915 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6919 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6924 /* Do visual mode command if needed */
6925 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))
6927 if (direct_k_idx >= 0)
6952 /* Recall on screen */
6953 if (!visual_list && !visual_only && (grp_cnt > 0))
6955 desc_obj_fake(object_idx[object_cur]);
6963 /* Move the cursor */
6964 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6970 /* Free the "object_idx" array */
6971 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6976 * Display the features in a group.
6978 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6979 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6981 int lit_col[F_LIT_MAX], i, j;
6982 int f_idx_col = use_bigtile ? 62 : 64;
6984 /* Correct columns 1 and 4 */
6985 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6986 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6987 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6989 /* Display lines until done */
6990 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6993 FEAT_IDX f_idx = feat_idx[feat_top + i];
6994 feature_type *f_ptr = &f_info[f_idx];
6995 int row_i = row + i;
6997 /* Choose a color */
6998 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7000 /* Display the name */
7001 c_prt(attr, f_name + f_ptr->name, row_i, col);
7003 /* Hack -- visual_list mode */
7006 /* Display lighting level */
7007 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7009 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));
7011 if (p_ptr->wizard || visual_only)
7013 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7016 /* Display symbol */
7017 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);
7019 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7020 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7022 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7024 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7026 /* Mega-hack -- Use non-standard colour */
7027 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7029 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7033 /* Clear remaining lines */
7034 for (; i < per_page; i++)
7036 Term_erase(col, row + i, 255);
7042 * Interact with feature visuals.
7044 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7048 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7049 FEAT_IDX feat_cur, feat_top;
7051 FEAT_IDX grp_idx[100];
7055 TERM_LEN column = 0;
7059 bool visual_list = FALSE;
7060 TERM_COLOR attr_top = 0;
7063 TERM_LEN browser_rows;
7066 TERM_COLOR attr_old[F_LIT_MAX];
7067 SYMBOL_CODE char_old[F_LIT_MAX];
7068 TERM_COLOR *cur_attr_ptr;
7069 SYMBOL_CODE *cur_char_ptr;
7071 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7072 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7074 Term_get_size(&wid, &hgt);
7076 browser_rows = hgt - 8;
7078 /* Allocate the "feat_idx" array */
7079 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7084 if (direct_f_idx < 0)
7086 /* Check every group */
7087 for (i = 0; feature_group_text[i] != NULL; i++)
7089 /* Measure the label */
7090 len = strlen(feature_group_text[i]);
7092 /* Save the maximum length */
7093 if (len > max) max = len;
7095 /* See if any features are known */
7096 if (collect_features(i, feat_idx, 0x01))
7098 /* Build a list of groups with known features */
7099 grp_idx[grp_cnt++] = i;
7107 feature_type *f_ptr = &f_info[direct_f_idx];
7109 feat_idx[0] = direct_f_idx;
7112 /* Terminate the list */
7115 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7116 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7118 for (i = 0; i < F_LIT_MAX; i++)
7120 attr_old[i] = f_ptr->x_attr[i];
7121 char_old[i] = f_ptr->x_char[i];
7125 /* Terminate the list */
7126 grp_idx[grp_cnt] = -1;
7129 grp_cur = grp_top = 0;
7130 feat_cur = feat_top = 0;
7138 feature_type *f_ptr;
7144 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7145 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7146 prt(_("名前", "Name"), 4, max + 3);
7149 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7150 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7154 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7155 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7158 for (i = 0; i < 78; i++)
7160 Term_putch(i, 5, TERM_WHITE, '=');
7163 if (direct_f_idx < 0)
7165 for (i = 0; i < browser_rows; i++)
7167 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7174 if (direct_f_idx < 0)
7176 /* Scroll group list */
7177 if (grp_cur < grp_top) grp_top = grp_cur;
7178 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7180 /* Display a list of feature groups */
7181 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7183 if (old_grp_cur != grp_cur)
7185 old_grp_cur = grp_cur;
7187 /* Get a list of features in the current group */
7188 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7191 /* Scroll feature list */
7192 while (feat_cur < feat_top)
7193 feat_top = MAX(0, feat_top - browser_rows/2);
7194 while (feat_cur >= feat_top + browser_rows)
7195 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7200 /* Display a list of features in the current group */
7201 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7205 feat_top = feat_cur;
7207 /* Display a list of features in the current group */
7208 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7210 /* Display visual list below first object */
7211 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7215 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7216 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7217 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7220 /* Get the current feature */
7221 f_ptr = &f_info[feat_idx[feat_cur]];
7222 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7223 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7227 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7231 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7235 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7240 if (visual_list && ((ch == 'A') || (ch == 'a')))
7242 int prev_lighting_level = *lighting_level;
7246 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7247 else (*lighting_level)--;
7251 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7252 else (*lighting_level)++;
7255 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7256 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7258 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7259 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7264 else if ((ch == 'D') || (ch == 'd'))
7266 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7267 byte prev_x_char = f_ptr->x_char[*lighting_level];
7269 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7273 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7274 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7276 if (prev_x_char != f_ptr->x_char[*lighting_level])
7277 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7279 else *need_redraw = TRUE;
7284 /* Do visual mode command if needed */
7285 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))
7289 /* Restore previous visual settings */
7291 for (i = 0; i < F_LIT_MAX; i++)
7293 f_ptr->x_attr[i] = attr_old[i];
7294 f_ptr->x_char[i] = char_old[i];
7301 if (direct_f_idx >= 0) flag = TRUE;
7302 else *lighting_level = F_LIT_STANDARD;
7305 /* Preserve current visual settings */
7308 for (i = 0; i < F_LIT_MAX; i++)
7310 attr_old[i] = f_ptr->x_attr[i];
7311 char_old[i] = f_ptr->x_char[i];
7313 *lighting_level = F_LIT_STANDARD;
7320 for (i = 0; i < F_LIT_MAX; i++)
7322 attr_idx_feat[i] = f_ptr->x_attr[i];
7323 char_idx_feat[i] = f_ptr->x_char[i];
7332 /* Allow TERM_DARK text */
7333 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7335 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7336 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7354 /* Move the cursor */
7355 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7361 /* Free the "feat_idx" array */
7362 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7367 * List wanted monsters
7369 static void do_cmd_knowledge_kubi(void)
7374 GAME_TEXT file_name[1024];
7377 /* Open a new file */
7378 fff = my_fopen_temp(file_name, 1024);
7380 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7387 bool listed = FALSE;
7389 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7390 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7392 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7393 fprintf(fff, "----------------------------------------------\n");
7395 for (i = 0; i < MAX_KUBI; i++)
7397 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7399 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7407 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7412 /* Display the file contents */
7413 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7418 * List virtues & status
7420 static void do_cmd_knowledge_virtues(void)
7423 GAME_TEXT file_name[1024];
7425 /* Open a new file */
7426 fff = my_fopen_temp(file_name, 1024);
7428 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7435 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7440 /* Display the file contents */
7441 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7448 static void do_cmd_knowledge_dungeon(void)
7452 GAME_TEXT file_name[1024];
7455 /* Open a new file */
7456 fff = my_fopen_temp(file_name, 1024);
7458 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7465 for (i = 1; i < max_d_idx; i++)
7469 if (!d_info[i].maxdepth) continue;
7470 if (!max_dlv[i]) continue;
7471 if (d_info[i].final_guardian)
7473 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7475 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7477 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7482 /* Display the file contents */
7483 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7488 * List virtues & status
7491 static void do_cmd_knowledge_stat(void)
7495 GAME_TEXT file_name[1024];
7498 /* Open a new file */
7499 fff = my_fopen_temp(file_name, 1024);
7501 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7508 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7509 (2 * p_ptr->hitdie +
7510 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7512 if (p_ptr->knowledge & KNOW_HPRATE)
7513 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7514 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7516 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7517 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7519 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);
7520 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7527 /* Display the file contents */
7528 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7534 * Print all active quests
7536 static void do_cmd_knowledge_quests_current(FILE *fff)
7539 char rand_tmp_str[120] = "\0";
7540 GAME_TEXT name[MAX_NLEN];
7541 monster_race *r_ptr;
7543 int rand_level = 100;
7546 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7548 for (i = 1; i < max_q_idx; i++)
7550 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7551 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7552 (quest[i].status == QUEST_STATUS_COMPLETED))
7554 /* Set the quest number temporary */
7555 QUEST_IDX old_quest = p_ptr->inside_quest;
7558 /* Clear the text */
7559 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7560 quest_text_line = 0;
7562 p_ptr->inside_quest = i;
7564 /* Get the quest text */
7565 init_flags = INIT_SHOW_TEXT;
7567 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7569 /* Reset the old quest number */
7570 p_ptr->inside_quest = old_quest;
7572 /* No info from "silent" quests */
7573 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7577 if (quest[i].type != QUEST_TYPE_RANDOM)
7579 char note[80] = "\0";
7581 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7583 switch (quest[i].type)
7585 case QUEST_TYPE_KILL_LEVEL:
7586 case QUEST_TYPE_KILL_ANY_LEVEL:
7587 r_ptr = &r_info[quest[i].r_idx];
7588 strcpy(name, r_name + r_ptr->name);
7589 if (quest[i].max_num > 1)
7592 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7593 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7596 sprintf(note," - kill %d %s, have killed %d.",
7597 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7601 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7604 case QUEST_TYPE_FIND_ARTIFACT:
7607 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7609 object_type *q_ptr = &forge;
7610 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7611 object_prep(q_ptr, k_idx);
7612 q_ptr->name1 = quest[i].k_idx;
7613 q_ptr->ident = IDENT_STORE;
7614 object_desc(name, q_ptr, OD_NAME_ONLY);
7616 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7618 case QUEST_TYPE_FIND_EXIT:
7619 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7622 case QUEST_TYPE_KILL_NUMBER:
7624 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7625 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7627 sprintf(note," - Kill %d monsters, have killed %d.",
7628 (int)quest[i].max_num, (int)quest[i].cur_num);
7632 case QUEST_TYPE_KILL_ALL:
7633 case QUEST_TYPE_TOWER:
7634 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7639 /* Print the quest info */
7640 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7641 quest[i].name, (int)quest[i].level, note);
7643 fputs(tmp_str, fff);
7645 if (quest[i].status == QUEST_STATUS_COMPLETED)
7647 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7648 fputs(tmp_str, fff);
7654 while (quest_text[j][0] && j < 10)
7656 fprintf(fff, " %s\n", quest_text[j]);
7661 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7664 rand_level = quest[i].level;
7666 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7668 /* Print the quest info */
7669 r_ptr = &r_info[quest[i].r_idx];
7670 strcpy(name, r_name + r_ptr->name);
7672 if (quest[i].max_num > 1)
7675 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7676 quest[i].name, (int)quest[i].level,
7677 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7681 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7682 quest[i].name, (int)quest[i].level,
7683 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7688 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7689 quest[i].name, (int)quest[i].level, name);
7696 /* Print the current random quest */
7697 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7699 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7703 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7706 char playtime_str[16];
7707 quest_type* const q_ptr = &quest[q_idx];
7709 if (is_fixed_quest_idx(q_idx))
7711 /* Set the quest number temporary */
7712 IDX old_quest = p_ptr->inside_quest;
7714 p_ptr->inside_quest = q_idx;
7717 init_flags = INIT_NAME_ONLY;
7719 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7721 /* Reset the old quest number */
7722 p_ptr->inside_quest = old_quest;
7724 /* No info from "silent" quests */
7725 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7728 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7729 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7731 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7733 /* Print the quest info */
7734 if (q_ptr->complev == 0)
7737 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7738 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7739 r_name+r_info[q_ptr->r_idx].name,
7740 (int)q_ptr->level, playtime_str);
7745 _(" %-35s (%3d階) - レベル%2d - %s\n",
7746 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7747 r_name+r_info[q_ptr->r_idx].name,
7755 /* Print the quest info */
7757 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7758 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7759 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7762 fputs(tmp_str, fff);
7768 * Print all finished quests
7770 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7773 QUEST_IDX total = 0;
7775 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7776 for (i = 1; i < max_q_idx; i++)
7778 QUEST_IDX q_idx = quest_num[i];
7779 quest_type* const q_ptr = &quest[q_idx];
7781 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7786 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7791 * Print all failed quests
7793 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7796 QUEST_IDX total = 0;
7798 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7799 for (i = 1; i < max_q_idx; i++)
7801 QUEST_IDX q_idx = quest_num[i];
7802 quest_type* const q_ptr = &quest[q_idx];
7804 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7805 do_cmd_knowledge_quests_aux(fff, q_idx))
7810 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7815 * Print all random quests
7817 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7819 GAME_TEXT tmp_str[120];
7821 QUEST_IDX total = 0;
7823 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7824 for (i = 1; i < max_q_idx; i++)
7826 /* No info from "silent" quests */
7827 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7829 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7833 /* Print the quest info */
7834 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7835 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7836 fputs(tmp_str, fff);
7839 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7843 * Print quest status of all active quests
7845 static void do_cmd_knowledge_quests(void)
7848 GAME_TEXT file_name[1024];
7853 /* Open a new file */
7854 fff = my_fopen_temp(file_name, 1024);
7857 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7862 /* Allocate Memory */
7863 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7865 /* Sort by compete level */
7866 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7867 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7869 /* Dump Quest Information */
7870 do_cmd_knowledge_quests_current(fff);
7872 do_cmd_knowledge_quests_completed(fff, quest_num);
7874 do_cmd_knowledge_quests_failed(fff, quest_num);
7878 do_cmd_knowledge_quests_wiz_random(fff);
7882 /* Display the file contents */
7883 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7887 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7894 static void do_cmd_knowledge_home(void)
7899 GAME_TEXT file_name[1024];
7901 GAME_TEXT o_name[MAX_NLEN];
7902 concptr paren = ")";
7904 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7906 /* Open a new file */
7907 fff = my_fopen_temp(file_name, 1024);
7909 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7916 /* Print all homes in the different towns */
7917 st_ptr = &town_info[1].store[STORE_HOME];
7919 /* Home -- if anything there */
7920 if (st_ptr->stock_num)
7925 /* Header with name of the town */
7926 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7928 /* Dump all available items */
7929 for (i = 0; i < st_ptr->stock_num; i++)
7932 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7933 object_desc(o_name, &st_ptr->stock[i], 0);
7934 if (strlen(o_name) <= 80-3)
7936 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7942 for (n = 0, t = o_name; n < 80-3; n++, t++)
7943 if(iskanji(*t)) {t++; n++;}
7944 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7946 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7947 fprintf(fff, " %.77s\n", o_name+n);
7950 object_desc(o_name, &st_ptr->stock[i], 0);
7951 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7956 /* Add an empty line */
7957 fprintf(fff, "\n\n");
7962 /* Display the file contents */
7963 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7969 * Check the status of "autopick"
7971 static void do_cmd_knowledge_autopick(void)
7975 GAME_TEXT file_name[1024];
7977 /* Open a new file */
7978 fff = my_fopen_temp(file_name, 1024);
7982 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7989 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7993 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7994 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
7997 for (k = 0; k < max_autopick; k++)
8000 byte act = autopick_list[k].action;
8001 if (act & DONT_AUTOPICK)
8003 tmp = _("放置", "Leave");
8005 else if (act & DO_AUTODESTROY)
8007 tmp = _("破壊", "Destroy");
8009 else if (act & DO_AUTOPICK)
8011 tmp = _("拾う", "Pickup");
8015 tmp = _("確認", "Query");
8018 if (act & DO_DISPLAY)
8019 fprintf(fff, "%11s", format("[%s]", tmp));
8021 fprintf(fff, "%11s", format("(%s)", tmp));
8023 tmp = autopick_line_from_entry(&autopick_list[k]);
8024 fprintf(fff, " %s", tmp);
8029 /* Display the file contents */
8030 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8036 * Interact with "knowledge"
8038 void do_cmd_knowledge(void)
8041 bool need_redraw = FALSE;
8043 /* File type is "TEXT" */
8044 FILE_TYPE(FILE_TYPE_TEXT);
8047 /* Interact until done */
8052 /* Ask for a choice */
8053 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8054 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8056 /* Give some choices */
8060 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8061 prt("(2) 既知のアイテム の一覧", 7, 5);
8062 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8063 prt("(4) 既知のモンスター の一覧", 9, 5);
8064 prt("(5) 倒した敵の数 の一覧", 10, 5);
8065 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8066 prt("(7) 現在のペット の一覧", 12, 5);
8067 prt("(8) 我が家のアイテム の一覧", 13, 5);
8068 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8069 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8073 prt("(a) 自分に関する情報 の一覧", 6, 5);
8074 prt("(b) 突然変異 の一覧", 7, 5);
8075 prt("(c) 武器の経験値 の一覧", 8, 5);
8076 prt("(d) 魔法の経験値 の一覧", 9, 5);
8077 prt("(e) 技能の経験値 の一覧", 10, 5);
8078 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8079 prt("(g) 入ったダンジョン の一覧", 12, 5);
8080 prt("(h) 実行中のクエスト の一覧", 13, 5);
8081 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8086 prt("(1) Display known artifacts", 6, 5);
8087 prt("(2) Display known objects", 7, 5);
8088 prt("(3) Display remaining uniques", 8, 5);
8089 prt("(4) Display known monster", 9, 5);
8090 prt("(5) Display kill count", 10, 5);
8091 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8092 prt("(7) Display current pets", 12, 5);
8093 prt("(8) Display home p_ptr->inventory_list", 13, 5);
8094 prt("(9) Display *identified* equip.", 14, 5);
8095 prt("(0) Display terrain symbols.", 15, 5);
8099 prt("(a) Display about yourself", 6, 5);
8100 prt("(b) Display mutations", 7, 5);
8101 prt("(c) Display weapon proficiency", 8, 5);
8102 prt("(d) Display spell proficiency", 9, 5);
8103 prt("(e) Display misc. proficiency", 10, 5);
8104 prt("(f) Display virtues", 11, 5);
8105 prt("(g) Display dungeons", 12, 5);
8106 prt("(h) Display current quests", 13, 5);
8107 prt("(i) Display auto pick/destroy", 14, 5);
8111 prt(_("-続く-", "-more-"), 17, 8);
8112 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8113 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8114 /*prt("-) 前ページ", 21, 60);*/
8115 prt(_("コマンド:", "Command: "), 20, 0);
8118 if (i == ESCAPE) break;
8121 case ' ': /* Page change */
8125 case '1': /* Artifacts */
8126 do_cmd_knowledge_artifacts();
8128 case '2': /* Objects */
8129 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8131 case '3': /* Uniques */
8132 do_cmd_knowledge_uniques();
8134 case '4': /* Monsters */
8135 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8137 case '5': /* Kill count */
8138 do_cmd_knowledge_kill_count();
8140 case '6': /* wanted */
8141 if (!vanilla_town) do_cmd_knowledge_kubi();
8143 case '7': /* Pets */
8144 do_cmd_knowledge_pets();
8146 case '8': /* Home */
8147 do_cmd_knowledge_home();
8149 case '9': /* Resist list */
8150 do_cmd_knowledge_inven();
8152 case '0': /* Feature list */
8154 IDX lighting_level = F_LIT_STANDARD;
8155 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8159 case 'a': /* Max stat */
8160 do_cmd_knowledge_stat();
8162 case 'b': /* Mutations */
8163 do_cmd_knowledge_mutations();
8165 case 'c': /* weapon-exp */
8166 do_cmd_knowledge_weapon_exp();
8168 case 'd': /* spell-exp */
8169 do_cmd_knowledge_spell_exp();
8171 case 'e': /* skill-exp */
8172 do_cmd_knowledge_skill_exp();
8174 case 'f': /* Virtues */
8175 do_cmd_knowledge_virtues();
8177 case 'g': /* Dungeon */
8178 do_cmd_knowledge_dungeon();
8180 case 'h': /* Quests */
8181 do_cmd_knowledge_quests();
8183 case 'i': /* Autopick */
8184 do_cmd_knowledge_autopick();
8186 default: /* Unknown option */
8194 if (need_redraw) do_cmd_redraw();
8199 * Check on the status of an active quest
8201 void do_cmd_checkquest(void)
8203 /* File type is "TEXT" */
8204 FILE_TYPE(FILE_TYPE_TEXT);
8208 do_cmd_knowledge_quests();
8214 * Display the time and date
8216 void do_cmd_time(void)
8218 int day, hour, min, full, start, end, num;
8226 extract_day_hour_min(&day, &hour, &min);
8228 full = hour * 100 + min;
8235 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8237 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8238 else strcpy(day_buf, "*****");
8240 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8241 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8244 if (!randint0(10) || p_ptr->image)
8246 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8250 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8253 /* Open this file */
8254 fff = my_fopen(buf, "rt");
8258 /* Find this time */
8259 while (!my_fgets(fff, buf, sizeof(buf)))
8261 /* Ignore comments */
8262 if (!buf[0] || (buf[0] == '#')) continue;
8264 /* Ignore invalid lines */
8265 if (buf[1] != ':') continue;
8267 /* Process 'Start' */
8270 /* Extract the starting time */
8271 start = atoi(buf + 2);
8273 /* Assume valid for an hour */
8283 /* Extract the ending time */
8284 end = atoi(buf + 2);
8290 /* Ignore incorrect range */
8291 if ((start > full) || (full > end)) continue;
8293 /* Process 'Description' */
8298 /* Apply the randomizer */
8299 if (!randint0(num)) strcpy(desc, buf + 2);