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.
52 #include "cmd-spell.h"
56 #include "player-effects.h"
57 #include "player-status.h"
58 #include "player-skill.h"
59 #include "player-personality.h"
66 #include "object-flavor.h"
67 #include "object-hook.h"
69 #include "monster-status.h"
71 #include "view-mainwindow.h"
72 #include "dungeon-file.h"
74 #include "player-class.h"
75 #include "player-move.h"
77 #include "objectkind.h"
78 #include "floor-town.h"
82 * Mark strings for auto dump
84 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
85 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
88 * Variables for auto dump
90 static FILE *auto_dump_stream;
91 static concptr auto_dump_mark;
92 static int auto_dump_line_num;
98 * @brief prf出力内容を消去する /
99 * Remove old lines automatically generated before.
100 * @param orig_file 消去を行うファイル名
102 static void remove_auto_dump(concptr orig_file)
104 FILE *tmp_fff, *orig_fff;
108 bool between_mark = FALSE;
109 bool changed = FALSE;
111 long header_location = 0;
112 char header_mark_str[80];
113 char footer_mark_str[80];
116 /* Prepare a header/footer mark string */
117 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
118 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
120 mark_len = strlen(footer_mark_str);
122 /* Open an old dump file in read-only mode */
123 orig_fff = my_fopen(orig_file, "r");
125 /* If original file does not exist, nothing to do */
126 if (!orig_fff) return;
128 /* Open a new (temporary) file */
129 tmp_fff = my_fopen_temp(tmp_file, 1024);
133 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
138 /* Loop for every line */
142 if (my_fgets(orig_fff, buf, sizeof(buf)))
144 /* Read error: Assume End of File */
147 * Was looking for the footer, but not found.
149 * Since automatic dump might be edited by hand,
150 * it's dangerous to kill these lines.
151 * Seek back to the next line of the (pseudo) header,
156 fseek(orig_fff, header_location, SEEK_SET);
157 between_mark = FALSE;
161 /* Success -- End the loop */
168 /* We are looking for the header mark of automatic dump */
171 /* Is this line a header? */
172 if (!strcmp(buf, header_mark_str))
174 /* Memorise seek point of this line */
175 header_location = ftell(orig_fff);
177 /* Initialize counter for number of lines */
180 /* Look for the footer from now */
183 /* There are some changes */
190 /* Copy orginally lines */
191 fprintf(tmp_fff, "%s\n", buf);
195 /* We are looking for the footer mark of automatic dump */
198 /* Is this line a footer? */
199 if (!strncmp(buf, footer_mark_str, mark_len))
204 * Compare the number of lines
206 * If there is an inconsistency between
207 * actual number of lines and the
208 * number here, the automatic dump
209 * might be edited by hand. So it's
210 * dangerous to kill these lines.
211 * Seek back to the next line of the
212 * (pseudo) header, and read again.
214 if (!sscanf(buf + mark_len, " (%d)", &tmp)
217 fseek(orig_fff, header_location, SEEK_SET);
220 /* Look for another header */
221 between_mark = FALSE;
227 /* Ignore old line, and count number of lines */
237 /* If there are some changes, overwrite the original file with new one */
240 /* Copy contents of temporary file */
242 tmp_fff = my_fopen(tmp_file, "r");
243 orig_fff = my_fopen(orig_file, "w");
245 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
246 fprintf(orig_fff, "%s\n", buf);
252 /* Kill the temporary file */
260 * @brief prfファイルのフォーマットに従った内容を出力する /
261 * Dump a formatted line, using "vstrnfmt()".
264 static void auto_dump_printf(concptr fmt, ...)
271 /* Begin the Varargs Stuff */
274 /* Format the args, save the length */
275 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
277 /* End the Varargs Stuff */
280 /* Count number of lines */
281 for (p = buf; *p; p++)
283 if (*p == '\n') auto_dump_line_num++;
287 fprintf(auto_dump_stream, "%s", buf);
292 * @brief prfファイルをファイルオープンする /
293 * Open file to append auto dump.
295 * @param mark 出力するヘッダマーク
296 * @return ファイルポインタを取得できたらTRUEを返す
298 static bool open_auto_dump(concptr buf, concptr mark)
301 char header_mark_str[80];
303 /* Save the mark string */
304 auto_dump_mark = mark;
306 /* Prepare a header mark string */
307 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
309 /* Remove old macro dumps */
310 remove_auto_dump(buf);
312 /* Append to the file */
313 auto_dump_stream = my_fopen(buf, "a");
316 if (!auto_dump_stream) {
317 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
325 fprintf(auto_dump_stream, "%s\n", header_mark_str);
327 /* Initialize counter */
328 auto_dump_line_num = 0;
330 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
331 "# *Warning!* The lines below are an automatic dump.\n"));
332 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
333 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
339 * @brief prfファイルをファイルクローズする /
340 * Append foot part and close auto dump.
343 static void close_auto_dump(void)
345 char footer_mark_str[80];
347 /* Prepare a footer mark string */
348 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
350 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
351 "# *Warning!* The lines below are an automatic dump.\n"));
352 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
353 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
355 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
358 my_fclose(auto_dump_stream);
367 * @brief Return suffix of ordinal number
369 * @return pointer of suffix string.
371 concptr get_ordinal_number_suffix(int num)
373 num = ABS(num) % 100;
377 return (num == 11) ? "th" : "st";
379 return (num == 12) ? "th" : "nd";
381 return (num == 13) ? "th" : "rd";
390 * @brief 日記にメッセージを追加する /
391 * Take note to the diary.
392 * @param type 日記内容のID
393 * @param num 日記内容のIDに応じた数値
394 * @param note 日記内容のIDに応じた文字列参照ポインタ
397 errr do_cmd_write_nikki(int type, int num, concptr note)
401 GAME_TEXT file_name[MAX_NLEN];
403 concptr note_level = "";
404 bool do_level = TRUE;
405 char note_level_buf[40];
408 static bool disable_nikki = FALSE;
410 extract_day_hour_min(&day, &hour, &min);
412 if (disable_nikki) return(-1);
414 if (type == NIKKI_FIX_QUEST_C ||
415 type == NIKKI_FIX_QUEST_F ||
416 type == NIKKI_RAND_QUEST_C ||
417 type == NIKKI_RAND_QUEST_F ||
418 type == NIKKI_TO_QUEST)
422 old_quest = p_ptr->inside_quest;
423 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
425 /* Get the quest text */
426 init_flags = INIT_NAME_ONLY;
428 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
430 /* Reset the old quest number */
431 p_ptr->inside_quest = old_quest;
434 /* different filne name to avoid mixing */
435 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
437 /* Build the filename */
438 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
440 /* File type is "TEXT" */
441 FILE_TYPE(FILE_TYPE_TEXT);
443 fff = my_fopen(buf, "a");
448 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
454 q_idx = quest_number(current_floor_ptr->dun_level);
458 if (p_ptr->inside_arena)
459 note_level = _("アリーナ:", "Arane:");
460 else if (!current_floor_ptr->dun_level)
461 note_level = _("地上:", "Surface:");
462 else if (q_idx && (is_fixed_quest_idx(q_idx)
463 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
464 note_level = _("クエスト:", "Quest:");
468 sprintf(note_level_buf, "%d階(%s):", (int)current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
470 sprintf(note_level_buf, "%s L%d:", d_name+d_info[p_ptr->dungeon_idx].name, (int)current_floor_ptr->dun_level);
472 note_level = note_level_buf;
480 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
481 else fputs(_("*****日目\n", "Day *****\n"), fff);
489 fprintf(fff, "%s\n",note);
493 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
498 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
501 case NIKKI_ART_SCROLL:
503 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
508 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
511 case NIKKI_FIX_QUEST_C:
513 if (quest[num].flags & QUEST_FLAG_SILENT) break;
514 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
515 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
518 case NIKKI_FIX_QUEST_F:
520 if (quest[num].flags & QUEST_FLAG_SILENT) break;
521 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
522 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
525 case NIKKI_RAND_QUEST_C:
527 GAME_TEXT name[MAX_NLEN];
528 strcpy(name, r_name+r_info[quest[num].r_idx].name);
529 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
530 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
533 case NIKKI_RAND_QUEST_F:
535 GAME_TEXT name[MAX_NLEN];
536 strcpy(name, r_name+r_info[quest[num].r_idx].name);
537 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
538 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
541 case NIKKI_MAXDEAPTH:
543 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
544 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
545 _(d_name+d_info[p_ptr->dungeon_idx].name, num),
546 _(num, d_name+d_info[p_ptr->dungeon_idx].name));
551 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
552 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
553 _(d_name + d_info[num].name, (int)max_dlv[num]),
554 _((int)max_dlv[num], d_name + d_info[num].name));
560 if (q_idx && (is_fixed_quest_idx(q_idx)
561 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
563 to = _("地上", "the surface");
567 if (!(current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
568 else to = format(_("%d階", "level %d"), current_floor_ptr->dun_level+num);
570 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
576 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
577 hour, min, note_level, _(d_name+d_info[p_ptr->dungeon_idx].name, (int)max_dlv[p_ptr->dungeon_idx]),
578 _((int)max_dlv[p_ptr->dungeon_idx], d_name+d_info[p_ptr->dungeon_idx].name));
580 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
585 if (quest[num].flags & QUEST_FLAG_SILENT) break;
586 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
587 hour, min, note_level, quest[num].name);
592 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
593 hour, min, note_level);
598 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
603 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
611 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
612 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
615 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
616 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
618 if (num == MAX_ARENA_MONS)
620 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
621 " won all fight to become a Chanpion.\n"));
628 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
634 if (!current_floor_ptr->dun_level)
635 to = _("地上", "the surface");
637 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
639 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
640 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
646 if (!current_floor_ptr->dun_level)
647 to = _("地上", "the surface");
649 to = format(_("%d階(%s)", "level %d of %s"), current_floor_ptr->dun_level, d_name+d_info[p_ptr->dungeon_idx].name);
651 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
652 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
657 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
660 case NIKKI_GAMESTART:
662 time_t ct = time((time_t*)0);
666 fprintf(fff, "%s %s",note, ctime(&ct));
669 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
672 case NIKKI_NAMED_PET:
674 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
677 case RECORD_NAMED_PET_NAME:
678 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
680 case RECORD_NAMED_PET_UNNAME:
681 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
683 case RECORD_NAMED_PET_DISMISS:
684 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
686 case RECORD_NAMED_PET_DEATH:
687 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
689 case RECORD_NAMED_PET_MOVED:
690 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
692 case RECORD_NAMED_PET_LOST_SIGHT:
693 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
695 case RECORD_NAMED_PET_DESTROY:
696 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
698 case RECORD_NAMED_PET_EARTHQUAKE:
699 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
701 case RECORD_NAMED_PET_GENOCIDE:
702 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
704 case RECORD_NAMED_PET_WIZ_ZAP:
705 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
707 case RECORD_NAMED_PET_TELE_LEVEL:
708 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
710 case RECORD_NAMED_PET_BLAST:
711 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
713 case RECORD_NAMED_PET_HEAL_LEPER:
714 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
716 case RECORD_NAMED_PET_COMPACT:
717 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
719 case RECORD_NAMED_PET_LOSE_PARENT:
720 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
731 case NIKKI_WIZARD_LOG:
732 fprintf(fff, "%s\n", note);
741 if (do_level) write_level = FALSE;
747 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
750 * @brief 日記のタイトル表記と内容出力 /
753 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
755 static void do_cmd_disp_nikki(void)
757 char nikki_title[256];
758 GAME_TEXT file_name[MAX_NLEN];
763 static const char subtitle[][30] = {"最強の肉体を求めて",
794 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
795 "Attack is the best form of defence.",
797 "An unexpected windfall",
798 "A drowning man will catch at a straw",
799 "Don't count your chickens before they are hatched.",
800 "It is no use crying over spilt milk.",
801 "Seeing is believing.",
802 "Strike the iron while it is hot.",
803 "I don't care what follows.",
804 "To dig a well to put out a house on fire.",
805 "Tomorrow is another day.",
806 "Easy come, easy go.",
807 "The more haste, the less speed.",
808 "Where there is life, there is hope.",
809 "There is no royal road to *WINNER*.",
810 "Danger past, God forgotten.",
811 "The best thing to do now is to run away.",
812 "Life is but an empty dream.",
813 "Dead men tell no tales.",
814 "A book that remains shut is but a block.",
815 "Misfortunes never come singly.",
816 "A little knowledge is a dangerous thing.",
817 "History repeats itself.",
818 "*WINNER* was not built in a day.",
819 "Ignorance is bliss.",
820 "To lose is to win?",
821 "No medicine can cure folly.",
822 "All good things come to an end.",
823 "M$ Empire strikes back.",
824 "To see is to believe",
826 "Quest of The World's Greatest Brain"};
828 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
830 /* Build the filename */
831 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
833 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
834 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
835 else if (IS_WIZARD_CLASS())
836 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
837 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
840 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
842 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
845 /* Display the file contents */
846 show_file(FALSE, buf, nikki_title, -1, 0);
850 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
853 static void do_cmd_bunshou(void)
856 char bunshou[80] = "\0";
858 if (get_string(_("内容: ", "diary note: "), tmp, 79))
860 strcpy(bunshou, tmp);
862 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
867 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
870 static void do_cmd_last_get(void)
875 if (record_o_name[0] == '\0') return;
877 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
878 if (!get_check(buf)) return;
880 turn_tmp = current_world_ptr->game_turn;
881 current_world_ptr->game_turn = record_turn;
882 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
883 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
884 current_world_ptr->game_turn = turn_tmp;
888 * @brief ファイル中の全日記記録を消去する /
891 static void do_cmd_erase_nikki(void)
893 GAME_TEXT file_name[MAX_NLEN];
897 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
898 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
900 /* Build the filename */
901 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
904 fff = my_fopen(buf, "w");
907 msg_format(_("記録を消去しました。", "deleted record."));
909 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
918 void do_cmd_nikki(void)
922 /* File type is "TEXT" */
923 FILE_TYPE(FILE_TYPE_TEXT);
926 /* Interact until done */
931 /* Ask for a choice */
932 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
934 /* Give some choices */
935 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
936 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
937 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
938 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
940 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
943 prt(_("コマンド:", "Command: "), 18, 0);
948 if (i == ESCAPE) break;
962 do_cmd_erase_nikki();
966 prepare_movie_hooks();
968 default: /* Unknown option */
978 * @brief 画面を再描画するコマンドのメインルーチン
979 * Hack -- redraw the screen
983 * This command performs various low level updates, clears all the "extra"
984 * windows, does a total redraw of the main window, and requests all of the
985 * interesting updates and redraws that I can think of.
987 * This command is also used to "instantiate" the results of the user
988 * selecting various things, such as graphics mode, so it must call
989 * the "TERM_XTRA_REACT" hook before redrawing the windows.
992 void do_cmd_redraw(void)
998 /* Hack -- react to changes */
999 Term_xtra(TERM_XTRA_REACT, 0);
1001 /* Combine and Reorder the pack (later) */
1002 p_ptr->update |= (PU_COMBINE | PU_REORDER);
1003 p_ptr->update |= (PU_TORCH);
1004 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1005 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1006 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1007 p_ptr->update |= (PU_MONSTERS);
1009 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1011 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1012 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1018 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
1021 /* Redraw every window */
1022 for (j = 0; j < 8; j++)
1025 if (!angband_term[j]) continue;
1028 Term_activate(angband_term[j]);
1037 * @brief 名前を変更するコマンドのメインルーチン
1038 * Hack -- change name
1041 void do_cmd_change_name(void)
1056 /* Display the player */
1057 display_player(mode);
1062 display_player(mode);
1067 Term_putstr(2, 23, -1, TERM_WHITE,
1068 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1070 Term_putstr(2, 23, -1, TERM_WHITE,
1071 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1079 if (c == ESCAPE) break;
1086 /* Process the player name */
1087 process_player_name(FALSE);
1093 sprintf(tmp, "%s.txt", player_base);
1094 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1096 if (tmp[0] && (tmp[0] != ' '))
1098 file_character(tmp);
1116 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1123 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1124 * Recall the most recent message
1127 void do_cmd_message_one(void)
1129 /* Recall one message */
1130 prt(format("> %s", message_str(0)), 0, 0);
1135 * @brief メッセージのログを表示するコマンドのメインルーチン
1136 * Recall the most recent message
1140 * Show previous messages to the user -BEN-
1142 * The screen format uses line 0 and 23 for headers and prompts,
1143 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1145 * This command shows you which commands you are viewing, and allows
1146 * you to "search" for strings in the recall.
1148 * Note that messages may be longer than 80 characters, but they are
1149 * displayed using "infinite" length, with a special sub-command to
1150 * "slide" the virtual display to the left or right.
1152 * Attempt to only hilite the matching portions of the string.
1155 void do_cmd_messages(int num_now)
1159 char shower_str[81];
1160 char finder_str[81];
1162 concptr shower = NULL;
1166 Term_get_size(&wid, &hgt);
1168 /* Number of message lines in a screen */
1169 num_lines = hgt - 4;
1172 strcpy(finder_str, "");
1175 strcpy(shower_str, "");
1177 /* Total messages */
1180 /* Start on first message */
1185 /* Process requests until done */
1191 /* Dump up to 20 lines of messages */
1192 for (j = 0; (j < num_lines) && (i + j < n); j++)
1194 concptr msg = message_str(i+j);
1196 /* Dump the messages, bottom to top */
1197 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1199 /* Hilite "shower" */
1200 if (shower && shower[0])
1204 /* Display matches */
1205 while ((str = my_strstr(str, shower)) != NULL)
1207 int len = strlen(shower);
1209 /* Display the match */
1210 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1218 /* Erase remaining lines */
1219 for (; j < num_lines; j++)
1221 Term_erase(0, num_lines + 1 - j, 255);
1224 /* Display header */
1226 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1227 i, i + j - 1, n), 0, 0);
1229 /* Display prompt (not very informative) */
1230 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1231 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1233 skey = inkey_special(TRUE);
1235 /* Exit on Escape */
1236 if (skey == ESCAPE) break;
1238 /* Hack -- Save the old index */
1243 /* Hack -- handle show */
1246 prt(_("強調: ", "Show: "), hgt - 1, 0);
1248 /* Get a "shower" string, or continue */
1249 strcpy(back_str, shower_str);
1250 if (askfor(shower_str, 80))
1253 shower = shower_str[0] ? shower_str : NULL;
1255 else strcpy(shower_str, back_str);
1259 /* Hack -- handle find */
1266 prt(_("検索: ", "Find: "), hgt - 1, 0);
1268 /* Get a "finder" string, or continue */
1269 strcpy(back_str, finder_str);
1270 if (!askfor(finder_str, 80))
1272 strcpy(finder_str, back_str);
1275 else if (!finder_str[0])
1277 shower = NULL; /* Stop showing */
1282 shower = finder_str;
1285 for (z = i + 1; z < n; z++)
1287 concptr msg = message_str(z);
1290 if (my_strstr(msg, finder_str))
1301 /* Recall 1 older message */
1303 /* Go to the oldest line */
1307 /* Recall 1 newer message */
1309 /* Go to the newest line */
1313 /* Recall 1 older message */
1318 /* Go older if legal */
1319 i = MIN(i + 1, n - num_lines);
1322 /* Recall 10 older messages */
1324 /* Go older if legal */
1325 i = MIN(i + 10, n - num_lines);
1328 /* Recall 20 older messages */
1333 /* Go older if legal */
1334 i = MIN(i + num_lines, n - num_lines);
1337 /* Recall 20 newer messages */
1341 /* Go newer (if able) */
1342 i = MAX(0, i - num_lines);
1345 /* Recall 10 newer messages */
1347 /* Go newer (if able) */
1351 /* Recall 1 newer messages */
1354 /* Go newer (if able) */
1359 /* Hack -- Error of some kind */
1367 * @brief チートオプションを変更するコマンドのメインルーチン
1368 * Interact with some options for cheating
1369 * @param info 表示メッセージ
1372 static void do_cmd_options_cheat(concptr info)
1375 int i, k = 0, n = CHEAT_MAX;
1379 /* Interact with the player */
1385 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1390 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1391 prt(" << 注意 >>", 11, 0);
1392 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1393 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1394 prt(" じらないようにして下さい。", 14, 0);
1396 /* Display the options */
1397 for (i = 0; i < n; i++)
1399 byte a = TERM_WHITE;
1401 /* Color current option */
1402 if (i == k) a = TERM_L_BLUE;
1404 /* Display the option text */
1405 sprintf(buf, "%-48s: %s (%s)",
1406 cheat_info[i].o_desc,
1407 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1408 cheat_info[i].o_text);
1409 c_prt(a, buf, i + 2, 0);
1412 /* Hilite current option */
1413 move_cursor(k + 2, 50);
1419 * HACK - Try to translate the key into a direction
1420 * to allow using the roguelike keys for navigation.
1422 dir = get_keymap_dir(ch);
1423 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1437 k = (n + k - 1) % n;
1455 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1456 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1457 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1458 (*cheat_info[k].o_var) = TRUE;
1467 (*cheat_info[k].o_var) = FALSE;
1474 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1475 /* Peruse the help file */
1476 (void)show_file(TRUE, buf, NULL, 0, 0);
1493 * @brief セーブ頻度ターンの次の値を返す
1494 * @param current 現在のセーブ頻度ターン値
1495 * @return 次のセーブ頻度ターン値
1497 static s16b toggle_frequency(s16b current)
1502 case 50: return 100;
1503 case 100: return 250;
1504 case 250: return 500;
1505 case 500: return 1000;
1506 case 1000: return 2500;
1507 case 2500: return 5000;
1508 case 5000: return 10000;
1509 case 10000: return 25000;
1516 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1517 * @param info 表示メッセージ
1520 static void do_cmd_options_autosave(concptr info)
1523 int i, k = 0, n = 2;
1528 /* Interact with the player */
1532 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1533 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1537 /* Display the options */
1538 for (i = 0; i < n; i++)
1540 byte a = TERM_WHITE;
1542 /* Color current option */
1543 if (i == k) a = TERM_L_BLUE;
1545 /* Display the option text */
1546 sprintf(buf, "%-48s: %s (%s)",
1547 autosave_info[i].o_desc,
1548 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1549 autosave_info[i].o_text);
1550 c_prt(a, buf, i + 2, 0);
1552 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1554 /* Hilite current option */
1555 move_cursor(k + 2, 50);
1571 k = (n + k - 1) % n;
1589 (*autosave_info[k].o_var) = TRUE;
1598 (*autosave_info[k].o_var) = FALSE;
1606 autosave_freq = toggle_frequency(autosave_freq);
1607 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1613 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1629 * @brief 標準オプションを変更するコマンドのサブルーチン /
1630 * Interact with some options
1631 * @param page オプションページ番号
1632 * @param info 表示メッセージ
1635 void do_cmd_options_aux(int page, concptr info)
1638 int i, k = 0, n = 0, l;
1641 bool browse_only = (page == OPT_PAGE_BIRTH) && current_world_ptr->character_generated &&
1642 (!p_ptr->wizard || !allow_debug_opts);
1645 /* Lookup the options */
1646 for (i = 0; i < 24; i++) opt[i] = 0;
1648 /* Scan the options */
1649 for (i = 0; option_info[i].o_desc; i++)
1651 /* Notice options on this "page" */
1652 if (option_info[i].o_page == page) opt[n++] = i;
1656 /* Interact with the player */
1662 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1663 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1666 /* HACK -- description for easy-auto-destroy options */
1667 if (page == OPT_PAGE_AUTODESTROY)
1668 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1669 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1671 /* Display the options */
1672 for (i = 0; i < n; i++)
1674 byte a = TERM_WHITE;
1676 /* Color current option */
1677 if (i == k) a = TERM_L_BLUE;
1679 /* Display the option text */
1680 sprintf(buf, "%-48s: %s (%.19s)",
1681 option_info[opt[i]].o_desc,
1682 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1683 option_info[opt[i]].o_text);
1684 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1685 else c_prt(a, buf, i + 2, 0);
1688 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1691 /* Hilite current option */
1692 move_cursor(k + 2 + l, 50);
1698 * HACK - Try to translate the key into a direction
1699 * to allow using the roguelike keys for navigation.
1701 dir = get_keymap_dir(ch);
1702 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1716 k = (n + k - 1) % n;
1733 if (browse_only) break;
1734 (*option_info[opt[k]].o_var) = TRUE;
1743 if (browse_only) break;
1744 (*option_info[opt[k]].o_var) = FALSE;
1752 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1758 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1759 /* Peruse the help file */
1760 (void)show_file(TRUE, buf, NULL, 0, 0);
1777 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1778 * Modify the "window" options
1781 static void do_cmd_options_win(void)
1791 /* Memorize old flags */
1792 for (j = 0; j < 8; j++)
1794 /* Acquire current flags */
1795 old_flag[j] = window_flag[j];
1804 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1806 /* Display the windows */
1807 for (j = 0; j < 8; j++)
1809 byte a = TERM_WHITE;
1811 concptr s = angband_term_name[j];
1814 if (j == x) a = TERM_L_BLUE;
1816 /* Window name, staggered, centered */
1817 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1820 /* Display the options */
1821 for (i = 0; i < 16; i++)
1823 byte a = TERM_WHITE;
1825 concptr str = window_flag_desc[i];
1828 if (i == y) a = TERM_L_BLUE;
1831 if (!str) str = _("(未使用)", "(Unused option)");
1834 Term_putstr(0, i + 5, -1, a, str);
1836 /* Display the windows */
1837 for (j = 0; j < 8; j++)
1843 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1846 if (window_flag[j] & (1L << i)) c = 'X';
1849 Term_putch(35 + j * 5, i + 5, a, c);
1854 Term_gotoxy(35 + x * 5, y + 5);
1872 for (j = 0; j < 8; j++)
1874 window_flag[j] &= ~(1L << y);
1878 for (i = 0; i < 16; i++)
1880 window_flag[x] &= ~(1L << i);
1893 window_flag[x] |= (1L << y);
1901 window_flag[x] &= ~(1L << y);
1907 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1915 d = get_keymap_dir(ch);
1917 x = (x + ddx[d] + 8) % 8;
1918 y = (y + ddy[d] + 16) % 16;
1925 /* Notice changes */
1926 for (j = 0; j < 8; j++)
1931 if (!angband_term[j]) continue;
1933 /* Ignore non-changes */
1934 if (window_flag[j] == old_flag[j]) continue;
1937 Term_activate(angband_term[j]);
1954 option_fields[OPT_NUM] =
1957 { '1', " キー入力 オプション", 3 },
1958 { '2', " マップ画面 オプション", 4 },
1959 { '3', " テキスト表示 オプション", 5 },
1960 { '4', " ゲームプレイ オプション", 6 },
1961 { '5', " 行動中止関係 オプション", 7 },
1962 { '6', " 簡易自動破壊 オプション", 8 },
1963 { 'r', " プレイ記録 オプション", 9 },
1965 { 'p', "自動拾いエディタ", 11 },
1966 { 'd', " 基本ウェイト量 ", 12 },
1967 { 'h', "低ヒットポイント", 13 },
1968 { 'm', " 低魔力色閾値 ", 14 },
1969 { 'a', " 自動セーブ オプション", 15 },
1970 { 'w', "ウインドウフラグ", 16 },
1972 { 'b', " 初期 オプション (参照のみ)", 18 },
1973 { 'c', " 詐欺 オプション", 19 },
1975 { '1', "Input Options", 3 },
1976 { '2', "Map Screen Options", 4 },
1977 { '3', "Text Display Options", 5 },
1978 { '4', "Game-Play Options", 6 },
1979 { '5', "Disturbance Options", 7 },
1980 { '6', "Easy Auto-Destroyer Options", 8 },
1981 { 'r', "Play record Options", 9 },
1983 { 'p', "Auto-picker/destroyer editor", 11 },
1984 { 'd', "Base Delay Factor", 12 },
1985 { 'h', "Hitpoint Warning", 13 },
1986 { 'm', "Mana Color Threshold", 14 },
1987 { 'a', "Autosave Options", 15 },
1988 { 'w', "Window Flags", 16 },
1990 { 'b', "Birth Options (Browse Only)", 18 },
1991 { 'c', "Cheat Options", 19 },
1997 * @brief 標準オプションを変更するコマンドのメインルーチン /
1998 * Set or unset various options.
2002 * The user must use the "Ctrl-R" command to "adapt" to changes
2003 * in any options which control "visual" aspects of the game.
2006 void do_cmd_options(void)
2018 /* Does not list cheat option when cheat option is off */
2019 if (!p_ptr->noscore && !allow_debug_opts) n--;
2022 /* Why are we here */
2023 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2027 /* Give some choices */
2028 for (i = 0; i < n; i++)
2030 byte a = TERM_WHITE;
2031 if (i == y) a = TERM_L_BLUE;
2032 Term_putstr(5, option_fields[i].row, -1, a,
2033 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2036 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2039 skey = inkey_special(TRUE);
2040 if (!(skey & SKEY_MASK)) k = (char)skey;
2044 if (k == ESCAPE) break;
2046 if (my_strchr("\n\r ", k))
2048 k = option_fields[y].key;
2052 for (i = 0; i < n; i++)
2054 if (tolower(k) == option_fields[i].key) break;
2057 /* Command is found */
2060 /* Hack -- browse help */
2061 if (k == '?') break;
2065 if (skey == SKEY_UP) d = 8;
2066 if (skey == SKEY_DOWN) d = 2;
2067 y = (y + ddy[d] + n) % n;
2072 if (k == ESCAPE) break;
2079 /* Process the general options */
2080 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2086 /* Process the general options */
2087 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2094 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2101 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2108 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2115 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2119 /* Play-record Options */
2124 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2133 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2134 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2135 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2139 /* Cheating Options */
2142 if (!p_ptr->noscore && !allow_debug_opts)
2144 /* Cheat options are not permitted */
2150 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2157 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2166 do_cmd_options_win();
2167 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2168 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2169 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2170 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2175 /* Auto-picker/destroyer editor */
2179 do_cmd_edit_autopick();
2183 /* Hack -- Delay Speed */
2189 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2191 /* Get a new value */
2194 int msec = delay_factor * delay_factor * delay_factor;
2195 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2196 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2198 if (k == ESCAPE) break;
2201 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2204 else if (isdigit(k)) delay_factor = D2I(k);
2211 /* Hack -- hitpoint warning factor */
2217 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2219 /* Get a new value */
2222 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2223 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2225 if (k == ESCAPE) break;
2228 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2231 else if (isdigit(k)) hitpoint_warn = D2I(k);
2238 /* Hack -- mana color factor */
2244 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2246 /* Get a new value */
2249 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2250 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2252 if (k == ESCAPE) break;
2255 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2258 else if (isdigit(k)) mana_warn = D2I(k);
2266 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2270 /* Unknown option */
2283 /* Hack - Redraw equippy chars */
2284 p_ptr->redraw |= (PR_EQUIPPY);
2290 * @brief prefファイルを選択して処理する /
2291 * Ask for a "user pref line" and process it
2294 * Allow absolute file names?
2296 void do_cmd_pref(void)
2303 /* Ask for a "user pref command" */
2304 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2306 /* Process that pref command */
2307 (void)process_pref_file_command(buf);
2311 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2314 void do_cmd_reload_autopick(void)
2316 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2317 /* Load the file with messages */
2318 autopick_load_pref(TRUE);
2324 * @brief マクロ情報をprefファイルに保存する /
2325 * @param fname ファイル名
2328 static errr macro_dump(concptr fname)
2330 static concptr mark = "Macro Dump";
2336 /* Build the filename */
2337 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2339 /* File type is "TEXT" */
2340 FILE_TYPE(FILE_TYPE_TEXT);
2342 /* Append to the file */
2343 if (!open_auto_dump(buf, mark)) return (-1);
2346 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2349 for (i = 0; i < macro__num; i++)
2351 /* Extract the action */
2352 ascii_to_text(buf, macro__act[i]);
2354 /* Dump the macro */
2355 auto_dump_printf("A:%s\n", buf);
2357 /* Extract the action */
2358 ascii_to_text(buf, macro__pat[i]);
2360 /* Dump normal macros */
2361 auto_dump_printf("P:%s\n", buf);
2364 auto_dump_printf("\n");
2376 * @brief マクロのトリガーキーを取得する /
2377 * Hack -- ask for a "trigger" (see below)
2378 * @param buf キー表記を保管するバッファ
2382 * Note the complex use of the "inkey()" function from "util.c".
2384 * Note that both "flush()" calls are extremely important.
2387 static void do_cmd_macro_aux(char *buf)
2395 /* Do not process macros */
2401 /* Read the pattern */
2407 /* Do not process macros */
2410 /* Do not wait for keys */
2413 /* Attempt to read a key */
2422 /* Convert the trigger */
2423 ascii_to_text(tmp, buf);
2425 /* Hack -- display the trigger */
2426 Term_addstr(-1, TERM_WHITE, tmp);
2432 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2433 * Hack -- ask for a keymap "trigger" (see below)
2434 * @param buf キー表記を取得するバッファ
2438 * Note that both "flush()" calls are extremely important. This may
2439 * no longer be true, since "util.c" is much simpler now.
2442 static void do_cmd_macro_aux_keymap(char *buf)
2452 /* Convert to ascii */
2453 ascii_to_text(tmp, buf);
2455 /* Hack -- display the trigger */
2456 Term_addstr(-1, TERM_WHITE, tmp);
2463 * @brief キーマップをprefファイルにダンプする /
2464 * Hack -- append all keymaps to the given file
2465 * @param fname ファイルネーム
2469 static errr keymap_dump(concptr fname)
2471 static concptr mark = "Keymap Dump";
2480 if (rogue_like_commands)
2482 mode = KEYMAP_MODE_ROGUE;
2488 mode = KEYMAP_MODE_ORIG;
2492 /* Build the filename */
2493 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2495 /* File type is "TEXT" */
2496 FILE_TYPE(FILE_TYPE_TEXT);
2498 /* Append to the file */
2499 if (!open_auto_dump(buf, mark)) return -1;
2502 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2505 for (i = 0; i < 256; i++)
2509 /* Loop up the keymap */
2510 act = keymap_act[mode][i];
2512 /* Skip empty keymaps */
2515 /* Encode the key */
2518 ascii_to_text(key, buf);
2520 /* Encode the action */
2521 ascii_to_text(buf, act);
2523 /* Dump the macro */
2524 auto_dump_printf("A:%s\n", buf);
2525 auto_dump_printf("C:%d:%s\n", mode, key);
2537 * @brief マクロを設定するコマンドのメインルーチン /
2538 * Interact with "macros"
2542 * Note that the macro "action" must be defined before the trigger.
2544 * Could use some helpful instructions on this page.
2547 void do_cmd_macros(void)
2559 if (rogue_like_commands)
2561 mode = KEYMAP_MODE_ROGUE;
2567 mode = KEYMAP_MODE_ORIG;
2570 /* File type is "TEXT" */
2571 FILE_TYPE(FILE_TYPE_TEXT);
2576 /* Process requests until done */
2580 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2582 /* Describe that action */
2583 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2585 /* Analyze the current action */
2586 ascii_to_text(buf, macro__buf);
2588 /* Display the current action */
2593 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2595 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2596 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2597 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2598 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2599 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2600 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2601 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2602 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2603 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2604 #endif /* ALLOW_MACROS */
2607 prt(_("コマンド: ", "Command: "), 16, 0);
2612 if (i == ESCAPE) break;
2614 /* Load a 'macro' file */
2620 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2623 prt(_("ファイル: ", "File: "), 18, 0);
2625 /* Default filename */
2626 sprintf(tmp, "%s.prf", player_base);
2628 /* Ask for a file */
2629 if (!askfor(tmp, 80)) continue;
2631 /* Process the given filename */
2632 err = process_pref_file(tmp);
2635 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2640 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2644 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2654 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2657 prt(_("ファイル: ", "File: "), 18, 0);
2659 /* Default filename */
2660 sprintf(tmp, "%s.prf", player_base);
2662 /* Ask for a file */
2663 if (!askfor(tmp, 80)) continue;
2665 /* Dump the macros */
2666 (void)macro_dump(tmp);
2669 msg_print(_("マクロを追加しました。", "Appended macros."));
2678 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2682 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2684 /* Get a macro trigger */
2685 do_cmd_macro_aux(buf);
2687 /* Acquire action */
2688 k = macro_find_exact(buf);
2694 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2700 /* Obtain the action */
2701 strcpy(macro__buf, macro__act[k]);
2703 /* Analyze the current action */
2704 ascii_to_text(buf, macro__buf);
2706 /* Display the current action */
2710 msg_print(_("マクロを確認しました。", "Found a macro."));
2714 /* Create a macro */
2718 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2721 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2723 /* Get a macro trigger */
2724 do_cmd_macro_aux(buf);
2730 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2731 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2734 prt(_("マクロ行動: ", "Action: "), 20, 0);
2736 /* Convert to text */
2737 ascii_to_text(tmp, macro__buf);
2739 /* Get an encoded action */
2740 if (askfor(tmp, 80))
2742 /* Convert to ascii */
2743 text_to_ascii(macro__buf, tmp);
2745 /* Link the macro */
2746 macro_add(buf, macro__buf);
2749 msg_print(_("マクロを追加しました。", "Added a macro."));
2753 /* Remove a macro */
2757 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2760 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2762 /* Get a macro trigger */
2763 do_cmd_macro_aux(buf);
2765 /* Link the macro */
2766 macro_add(buf, buf);
2769 msg_print(_("マクロを削除しました。", "Removed a macro."));
2776 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2779 prt(_("ファイル: ", "File: "), 18, 0);
2781 /* Default filename */
2782 sprintf(tmp, "%s.prf", player_base);
2784 /* Ask for a file */
2785 if (!askfor(tmp, 80)) continue;
2787 /* Dump the macros */
2788 (void)keymap_dump(tmp);
2791 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2794 /* Query a keymap */
2800 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2803 prt(_("押すキー: ", "Keypress: "), 18, 0);
2805 /* Get a keymap trigger */
2806 do_cmd_macro_aux_keymap(buf);
2808 /* Look up the keymap */
2809 act = keymap_act[mode][(byte)(buf[0])];
2815 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2821 /* Obtain the action */
2822 strcpy(macro__buf, act);
2824 /* Analyze the current action */
2825 ascii_to_text(buf, macro__buf);
2827 /* Display the current action */
2831 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2835 /* Create a keymap */
2839 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2842 prt(_("押すキー: ", "Keypress: "), 18, 0);
2844 /* Get a keymap trigger */
2845 do_cmd_macro_aux_keymap(buf);
2851 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2852 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2855 prt(_("行動: ", "Action: "), 20, 0);
2857 /* Convert to text */
2858 ascii_to_text(tmp, macro__buf);
2860 /* Get an encoded action */
2861 if (askfor(tmp, 80))
2863 /* Convert to ascii */
2864 text_to_ascii(macro__buf, tmp);
2866 /* Free old keymap */
2867 string_free(keymap_act[mode][(byte)(buf[0])]);
2869 /* Make new keymap */
2870 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2873 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2877 /* Remove a keymap */
2881 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2884 prt(_("押すキー: ", "Keypress: "), 18, 0);
2886 /* Get a keymap trigger */
2887 do_cmd_macro_aux_keymap(buf);
2889 /* Free old keymap */
2890 string_free(keymap_act[mode][(byte)(buf[0])]);
2892 /* Make new keymap */
2893 keymap_act[mode][(byte)(buf[0])] = NULL;
2896 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2899 /* Enter a new action */
2903 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2909 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2910 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2913 prt(_("マクロ行動: ", "Action: "), 20, 0);
2915 /* Hack -- limit the value */
2918 /* Get an encoded action */
2919 if (!askfor(buf, 80)) continue;
2921 /* Extract an action */
2922 text_to_ascii(macro__buf, buf);
2925 #endif /* ALLOW_MACROS */
2938 * @brief キャラクタ色の明暗表現
2940 static concptr lighting_level_str[F_LIT_MAX] =
2955 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2956 * @param i 指定対象となるキャラクタコード
2957 * @param num 指定されたビジュアルIDを返す参照ポインタ
2958 * @param max ビジュアルIDの最大数
2959 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2961 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2968 sprintf(str, "%d", *num);
2970 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2973 tmp = (IDX)strtol(str, NULL, 0);
2974 if (tmp >= 0 && tmp < max)
2977 else if (isupper(i))
2978 *num = (*num + max - 1) % max;
2980 *num = (*num + 1) % max;
2986 * @brief キャラクタの変更メニュー表示
2987 * @param choice_msg 選択メッセージ
2990 static void print_visuals_menu(concptr choice_msg)
2992 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2994 /* Give some choices */
2995 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2997 #ifdef ALLOW_VISUALS
2998 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2999 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
3000 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
3001 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
3002 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
3003 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
3004 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
3005 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
3006 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
3007 #endif /* ALLOW_VISUALS */
3009 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
3012 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
3015 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
3016 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3017 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3020 * Interact with "visuals"
3022 void do_cmd_visuals(void)
3027 bool need_redraw = FALSE;
3028 concptr empty_symbol = "<< ? >>";
3030 if (use_bigtile) empty_symbol = "<< ?? >>";
3032 /* File type is "TEXT" */
3033 FILE_TYPE(FILE_TYPE_TEXT);
3036 /* Interact until done */
3041 /* Ask for a choice */
3042 print_visuals_menu(NULL);
3047 if (i == ESCAPE) break;
3051 /* Load a 'pref' file */
3054 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3057 prt(_("ファイル: ", "File: "), 17, 0);
3059 /* Default filename */
3060 sprintf(tmp, "%s.prf", player_base);
3063 if (!askfor(tmp, 70)) continue;
3065 /* Process the given filename */
3066 (void)process_pref_file(tmp);
3071 #ifdef ALLOW_VISUALS
3073 /* Dump monster attr/chars */
3076 static concptr mark = "Monster attr/chars";
3079 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3082 prt(_("ファイル: ", "File: "), 17, 0);
3084 /* Default filename */
3085 sprintf(tmp, "%s.prf", player_base);
3087 /* Get a filename */
3088 if (!askfor(tmp, 70)) continue;
3090 /* Build the filename */
3091 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3093 /* Append to the file */
3094 if (!open_auto_dump(buf, mark)) continue;
3097 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3100 for (i = 0; i < max_r_idx; i++)
3102 monster_race *r_ptr = &r_info[i];
3104 /* Skip non-entries */
3105 if (!r_ptr->name) continue;
3107 /* Dump a comment */
3108 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3110 /* Dump the monster attr/char info */
3111 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3112 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3118 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3123 /* Dump object attr/chars */
3126 static concptr mark = "Object attr/chars";
3127 KIND_OBJECT_IDX k_idx;
3130 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3133 prt(_("ファイル: ", "File: "), 17, 0);
3135 /* Default filename */
3136 sprintf(tmp, "%s.prf", player_base);
3138 /* Get a filename */
3139 if (!askfor(tmp, 70)) continue;
3141 /* Build the filename */
3142 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3144 /* Append to the file */
3145 if (!open_auto_dump(buf, mark)) continue;
3148 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3151 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3153 GAME_TEXT o_name[MAX_NLEN];
3154 object_kind *k_ptr = &k_info[k_idx];
3156 /* Skip non-entries */
3157 if (!k_ptr->name) continue;
3162 strip_name(o_name, k_idx);
3168 /* Prepare dummy object */
3169 object_prep(&forge, k_idx);
3171 /* Get un-shuffled flavor name */
3172 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3175 /* Dump a comment */
3176 auto_dump_printf("# %s\n", o_name);
3178 /* Dump the object attr/char info */
3179 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3180 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3186 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3191 /* Dump feature attr/chars */
3194 static concptr mark = "Feature attr/chars";
3197 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3200 prt(_("ファイル: ", "File: "), 17, 0);
3202 /* Default filename */
3203 sprintf(tmp, "%s.prf", player_base);
3205 /* Get a filename */
3206 if (!askfor(tmp, 70)) continue;
3208 /* Build the filename */
3209 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3211 /* Append to the file */
3212 if (!open_auto_dump(buf, mark)) continue;
3215 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3218 for (i = 0; i < max_f_idx; i++)
3220 feature_type *f_ptr = &f_info[i];
3222 /* Skip non-entries */
3223 if (!f_ptr->name) continue;
3225 /* Skip mimiccing features */
3226 if (f_ptr->mimic != i) continue;
3228 /* Dump a comment */
3229 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3231 /* Dump the feature attr/char info */
3232 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3233 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3234 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3235 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3241 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3246 /* Modify monster attr/chars (numeric operation) */
3249 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3250 static MONRACE_IDX r = 0;
3252 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3254 /* Hack -- query until done */
3257 monster_race *r_ptr = &r_info[r];
3261 TERM_COLOR da = r_ptr->d_attr;
3262 byte dc = r_ptr->d_char;
3263 TERM_COLOR ca = r_ptr->x_attr;
3264 byte cc = r_ptr->x_char;
3266 /* Label the object */
3267 Term_putstr(5, 17, -1, TERM_WHITE,
3268 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3270 /* Label the Default values */
3271 Term_putstr(10, 19, -1, TERM_WHITE,
3272 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3274 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3275 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3277 /* Label the Current values */
3278 Term_putstr(10, 20, -1, TERM_WHITE,
3279 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3281 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3282 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3285 Term_putstr(0, 22, -1, TERM_WHITE,
3286 _("コマンド (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): "));
3291 if (i == ESCAPE) break;
3293 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3294 else if (isupper(i)) c = 'a' + i - 'A';
3304 if (!cmd_visuals_aux(i, &r, max_r_idx))
3310 while (!r_info[r].name);
3314 t = (int)r_ptr->x_attr;
3315 (void)cmd_visuals_aux(i, &t, 256);
3316 r_ptr->x_attr = (byte)t;
3320 t = (int)r_ptr->x_char;
3321 (void)cmd_visuals_aux(i, &t, 256);
3322 r_ptr->x_char = (byte)t;
3326 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3328 print_visuals_menu(choice_msg);
3336 /* Modify object attr/chars (numeric operation) */
3339 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3341 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3343 /* Hack -- query until done */
3346 object_kind *k_ptr = &k_info[k];
3350 TERM_COLOR da = k_ptr->d_attr;
3351 SYMBOL_CODE dc = k_ptr->d_char;
3352 TERM_COLOR ca = k_ptr->x_attr;
3353 SYMBOL_CODE cc = k_ptr->x_char;
3355 /* Label the object */
3356 Term_putstr(5, 17, -1, TERM_WHITE,
3357 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3358 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3360 /* Label the Default values */
3361 Term_putstr(10, 19, -1, TERM_WHITE,
3362 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3364 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3365 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3367 /* Label the Current values */
3368 Term_putstr(10, 20, -1, TERM_WHITE,
3369 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3371 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3372 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3375 Term_putstr(0, 22, -1, TERM_WHITE,
3376 _("コマンド (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): "));
3381 if (i == ESCAPE) break;
3383 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3384 else if (isupper(i)) c = 'a' + i - 'A';
3394 if (!cmd_visuals_aux(i, &k, max_k_idx))
3400 while (!k_info[k].name);
3404 t = (int)k_ptr->x_attr;
3405 (void)cmd_visuals_aux(i, &t, 256);
3406 k_ptr->x_attr = (byte)t;
3410 t = (int)k_ptr->x_char;
3411 (void)cmd_visuals_aux(i, &t, 256);
3412 k_ptr->x_char = (byte)t;
3416 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3418 print_visuals_menu(choice_msg);
3426 /* Modify feature attr/chars (numeric operation) */
3429 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3431 static IDX lighting_level = F_LIT_STANDARD;
3432 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3434 /* Hack -- query until done */
3437 feature_type *f_ptr = &f_info[f];
3441 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3442 byte dc = f_ptr->d_char[lighting_level];
3443 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3444 byte cc = f_ptr->x_char[lighting_level];
3446 /* Label the object */
3448 Term_putstr(5, 17, -1, TERM_WHITE,
3449 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3450 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3452 /* Label the Default values */
3453 Term_putstr(10, 19, -1, TERM_WHITE,
3454 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3456 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3457 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3459 /* Label the Current values */
3461 Term_putstr(10, 20, -1, TERM_WHITE,
3462 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3464 Term_putstr(10, 20, -1, TERM_WHITE,
3465 format("Current attr/char = %3d / %3d", ca, cc));
3468 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3469 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3473 Term_putstr(0, 22, -1, TERM_WHITE,
3474 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3476 Term_putstr(0, 22, -1, TERM_WHITE,
3477 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3483 if (i == ESCAPE) break;
3485 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3486 else if (isupper(i)) c = 'a' + i - 'A';
3496 if (!cmd_visuals_aux(i, &f, max_f_idx))
3502 while (!f_info[f].name || (f_info[f].mimic != f));
3506 t = (int)f_ptr->x_attr[lighting_level];
3507 (void)cmd_visuals_aux(i, &t, 256);
3508 f_ptr->x_attr[lighting_level] = (byte)t;
3512 t = (int)f_ptr->x_char[lighting_level];
3513 (void)cmd_visuals_aux(i, &t, 256);
3514 f_ptr->x_char[lighting_level] = (byte)t;
3518 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3521 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3525 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3527 print_visuals_menu(choice_msg);
3535 /* Modify monster attr/chars (visual mode) */
3537 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3540 /* Modify object attr/chars (visual mode) */
3542 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3545 /* Modify feature attr/chars (visual mode) */
3548 IDX lighting_level = F_LIT_STANDARD;
3549 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3553 #endif /* ALLOW_VISUALS */
3561 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3565 /* Unknown option */
3575 if (need_redraw) do_cmd_redraw();
3580 * Interact with "colors"
3582 void do_cmd_colors(void)
3591 /* File type is "TEXT" */
3592 FILE_TYPE(FILE_TYPE_TEXT);
3597 /* Interact until done */
3602 /* Ask for a choice */
3603 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3605 /* Give some choices */
3606 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3609 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3610 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3614 prt(_("コマンド: ", "Command: "), 8, 0);
3618 if (i == ESCAPE) break;
3620 /* Load a 'pref' file */
3624 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3627 prt(_("ファイル: ", "File: "), 10, 0);
3630 sprintf(tmp, "%s.prf", player_base);
3633 if (!askfor(tmp, 70)) continue;
3635 /* Process the given filename */
3636 (void)process_pref_file(tmp);
3638 /* Mega-Hack -- react to changes */
3639 Term_xtra(TERM_XTRA_REACT, 0);
3641 /* Mega-Hack -- redraw */
3650 static concptr mark = "Colors";
3653 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3656 prt(_("ファイル: ", "File: "), 10, 0);
3658 /* Default filename */
3659 sprintf(tmp, "%s.prf", player_base);
3661 /* Get a filename */
3662 if (!askfor(tmp, 70)) continue;
3664 /* Build the filename */
3665 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3667 /* Append to the file */
3668 if (!open_auto_dump(buf, mark)) continue;
3671 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3674 for (i = 0; i < 256; i++)
3676 int kv = angband_color_table[i][0];
3677 int rv = angband_color_table[i][1];
3678 int gv = angband_color_table[i][2];
3679 int bv = angband_color_table[i][3];
3681 concptr name = _("未知", "unknown");
3683 /* Skip non-entries */
3684 if (!kv && !rv && !gv && !bv) continue;
3686 /* Extract the color name */
3687 if (i < 16) name = color_names[i];
3689 /* Dump a comment */
3690 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3692 /* Dump the monster attr/char info */
3693 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3700 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3709 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3711 /* Hack -- query until done */
3720 /* Exhibit the normal colors */
3721 for (j = 0; j < 16; j++)
3723 /* Exhibit this color */
3724 Term_putstr(j*4, 20, -1, a, "###");
3726 /* Exhibit all colors */
3727 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3730 /* Describe the color */
3731 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3733 /* Describe the color */
3734 Term_putstr(5, 10, -1, TERM_WHITE,
3735 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3737 /* Label the Current values */
3738 Term_putstr(5, 12, -1, TERM_WHITE,
3739 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3740 angband_color_table[a][0],
3741 angband_color_table[a][1],
3742 angband_color_table[a][2],
3743 angband_color_table[a][3]));
3746 Term_putstr(0, 14, -1, TERM_WHITE,
3747 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3752 if (i == ESCAPE) break;
3755 if (i == 'n') a = (byte)(a + 1);
3756 if (i == 'N') a = (byte)(a - 1);
3757 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3758 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3759 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3760 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3761 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3762 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3763 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3764 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3766 /* Hack -- react to changes */
3767 Term_xtra(TERM_XTRA_REACT, 0);
3769 /* Hack -- redraw */
3776 /* Unknown option */
3790 * Note something in the message recall
3792 void do_cmd_note(void)
3800 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3802 /* Ignore empty notes */
3803 if (!buf[0] || (buf[0] == ' ')) return;
3805 /* Add the note to the message recall */
3806 msg_format(_("メモ: %s", "Note: %s"), buf);
3811 * Mention the current version
3813 void do_cmd_version(void)
3815 #if FAKE_VER_EXTRA > 0
3816 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3817 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3819 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3820 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3827 * Array of feeling strings
3829 static concptr do_cmd_feeling_text[11] =
3831 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3832 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3833 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3834 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3835 _("とても悪い予感がする...", "You have a very bad feeling..."),
3836 _("悪い予感がする...", "You have a bad feeling..."),
3837 _("何か緊張する。", "You feel nervous."),
3838 _("少し不運な気がする...", "You feel your luck is turning..."),
3839 _("この場所は好きになれない。", "You don't like the look of this place."),
3840 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3841 _("なんて退屈なところだ...", "What a boring place...")
3844 static concptr do_cmd_feeling_text_combat[11] =
3846 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3847 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3848 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3849 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3850 _("とても悪い予感がする...", "You have a very bad feeling..."),
3851 _("悪い予感がする...", "You have a bad feeling..."),
3852 _("何か緊張する。", "You feel nervous."),
3853 _("少し不運な気がする...", "You feel your luck is turning..."),
3854 _("この場所は好きになれない。", "You don't like the look of this place."),
3855 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3856 _("なんて退屈なところだ...", "What a boring place...")
3859 static concptr do_cmd_feeling_text_lucky[11] =
3861 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3862 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3863 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3864 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3865 _("とても良い感じがする...", "You have a very good feeling..."),
3866 _("良い感じがする...", "You have a good feeling..."),
3867 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3868 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3869 _("見た感じ悪くはない...", "You like the look of this place..."),
3870 _("全然駄目ということはないが...", "This level can't be all bad..."),
3871 _("なんて退屈なところだ...", "What a boring place...")
3876 * Note that "feeling" is set to zero unless some time has passed.
3877 * Note that this is done when the level is GENERATED, not entered.
3879 void do_cmd_feeling(void)
3881 if (p_ptr->wild_mode) return;
3883 /* No useful feeling in quests */
3884 if (p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level))
3886 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3890 /* No useful feeling in town */
3891 else if (p_ptr->town_num && !current_floor_ptr->dun_level)
3893 if (!strcmp(town_info[p_ptr->town_num].name, _("荒野", "wilderness")))
3895 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3900 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3905 /* No useful feeling in the wilderness */
3906 else if (!current_floor_ptr->dun_level)
3908 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3912 /* Display the feeling */
3913 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3914 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3915 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3916 p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
3917 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3919 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3925 * Description of each monster group.
3927 static concptr monster_group_text[] =
3930 "ユニーク", /* "Uniques" */
3931 "乗馬可能なモンスター", /* "Riding" */
3932 "賞金首", /* "Wanted */
3933 "アンバーの王族", /* "Ambertite" */
3962 /* "古代ドラゴン/ワイアーム", */
4023 /* "Ancient Dragon/Wyrm", */
4032 "Multi-Headed Reptile",
4037 "Reptile/Amphibian",
4038 "Spider/Scorpion/Tick",
4040 /* "Major Demon", */
4057 * Symbols of monsters in each group. Note the "Uniques" group
4058 * is handled differently.
4060 static concptr monster_group_char[] =
4117 "!$&()+./=>?[\\]`{|~",
4127 * Build a list of monster indexes in the given group. Return the number
4128 * of monsters in the group.
4130 * mode & 0x01 : check for non-empty group
4131 * mode & 0x02 : visual operation only
4133 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4139 /* Get a list of x_char in this group */
4140 concptr group_char = monster_group_char[grp_cur];
4142 /* XXX Hack -- Check if this is the "Uniques" group */
4143 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4145 /* XXX Hack -- Check if this is the "Riding" group */
4146 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4148 /* XXX Hack -- Check if this is the "Wanted" group */
4149 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4151 /* XXX Hack -- Check if this is the "Amberite" group */
4152 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4155 /* Check every race */
4156 for (i = 0; i < max_r_idx; i++)
4158 /* Access the race */
4159 monster_race *r_ptr = &r_info[i];
4161 /* Skip empty race */
4162 if (!r_ptr->name) continue ;
4164 /* Require known monsters */
4165 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4169 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4172 else if (grp_riding)
4174 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4177 else if (grp_wanted)
4179 bool wanted = FALSE;
4181 for (j = 0; j < MAX_KUBI; j++)
4183 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
4184 (p_ptr->today_mon && p_ptr->today_mon == i))
4190 if (!wanted) continue;
4193 else if (grp_amberite)
4195 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4200 /* Check for race in the group */
4201 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4205 mon_idx[mon_cnt++] = i;
4207 /* XXX Hack -- Just checking for non-empty group */
4208 if (mode & 0x01) break;
4211 /* Terminate the list */
4212 mon_idx[mon_cnt] = -1;
4214 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
4216 /* Return the number of races */
4222 * Description of each monster group.
4224 static concptr object_group_text[] =
4227 "キノコ", /* "Mushrooms" */
4228 "薬", /* "Potions" */
4229 "油つぼ", /* "Flasks" */
4230 "巻物", /* "Scrolls" */
4232 "アミュレット", /* "Amulets" */
4233 "笛", /* "Whistle" */
4234 "光源", /* "Lanterns" */
4235 "魔法棒", /* "Wands" */
4238 "カード", /* "Cards" */
4249 "刀剣類", /* "Swords" */
4250 "鈍器", /* "Blunt Weapons" */
4251 "長柄武器", /* "Polearms" */
4252 "採掘道具", /* "Diggers" */
4253 "飛び道具", /* "Bows" */
4257 "軽装鎧", /* "Soft Armor" */
4258 "重装鎧", /* "Hard Armor" */
4259 "ドラゴン鎧", /* "Dragon Armor" */
4260 "盾", /* "Shields" */
4261 "クローク", /* "Cloaks" */
4262 "籠手", /* "Gloves" */
4263 "ヘルメット", /* "Helms" */
4265 "ブーツ", /* "Boots" */
4318 * TVALs of items in each group
4320 static byte object_group_tval[] =
4361 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4369 * Build a list of object indexes in the given group. Return the number
4370 * of objects in the group.
4372 * mode & 0x01 : check for non-empty group
4373 * mode & 0x02 : visual operation only
4375 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4377 KIND_OBJECT_IDX i, object_cnt = 0;
4380 /* Get a list of x_char in this group */
4381 byte group_tval = object_group_tval[grp_cur];
4383 /* Check every object */
4384 for (i = 0; i < max_k_idx; i++)
4386 /* Access the object */
4387 object_kind *k_ptr = &k_info[i];
4389 /* Skip empty objects */
4390 if (!k_ptr->name) continue;
4394 /* Any objects will be displayed */
4400 /* Skip non-flavoured objects */
4401 if (!k_ptr->flavor) continue;
4403 /* Require objects ever seen */
4404 if (!k_ptr->aware) continue;
4407 /* Skip items with no distribution (special artifacts) */
4408 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4412 /* Check for objects in the group */
4413 if (TV_LIFE_BOOK == group_tval)
4415 /* Hack -- All spell books */
4416 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4418 /* Add the object */
4419 object_idx[object_cnt++] = i;
4423 else if (k_ptr->tval == group_tval)
4425 /* Add the object */
4426 object_idx[object_cnt++] = i;
4430 /* XXX Hack -- Just checking for non-empty group */
4431 if (mode & 0x01) break;
4434 /* Terminate the list */
4435 object_idx[object_cnt] = -1;
4437 /* Return the number of objects */
4443 * Description of each feature group.
4445 static concptr feature_group_text[] =
4453 * Build a list of feature indexes in the given group. Return the number
4454 * of features in the group.
4456 * mode & 0x01 : check for non-empty group
4458 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4461 FEAT_IDX feat_cnt = 0;
4463 /* Unused; There is a single group. */
4466 /* Check every feature */
4467 for (i = 0; i < max_f_idx; i++)
4469 feature_type *f_ptr = &f_info[i];
4471 /* Skip empty index */
4472 if (!f_ptr->name) continue;
4474 /* Skip mimiccing features */
4475 if (f_ptr->mimic != i) continue;
4478 feat_idx[feat_cnt++] = i;
4480 /* XXX Hack -- Just checking for non-empty group */
4481 if (mode & 0x01) break;
4484 /* Terminate the list */
4485 feat_idx[feat_cnt] = -1;
4487 /* Return the number of races */
4494 * Build a list of monster indexes in the given group. Return the number
4495 * of monsters in the group.
4497 static int collect_artifacts(int grp_cur, int object_idx[])
4499 int i, object_cnt = 0;
4501 /* Get a list of x_char in this group */
4502 byte group_tval = object_group_tval[grp_cur];
4504 /* Check every object */
4505 for (i = 0; i < max_a_idx; i++)
4507 /* Access the artifact */
4508 artifact_type *a_ptr = &a_info[i];
4510 /* Skip empty artifacts */
4511 if (!a_ptr->name) continue;
4513 /* Skip "uncreated" artifacts */
4514 if (!a_ptr->cur_num) continue;
4516 /* Check for race in the group */
4517 if (a_ptr->tval == group_tval)
4520 object_idx[object_cnt++] = i;
4524 /* Terminate the list */
4525 object_idx[object_cnt] = 0;
4527 /* Return the number of races */
4534 * Encode the screen colors
4536 static char hack[17] = "dwsorgbuDWvyRGBU";
4540 * Hack -- load a screen dump from a file
4542 void do_cmd_load_screen(void)
4547 SYMBOL_CODE c = ' ';
4553 Term_get_size(&wid, &hgt);
4555 /* Build the filename */
4556 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4558 /* Append to the file */
4559 fff = my_fopen(buf, "r");
4562 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4570 /* Load the screen */
4571 for (y = 0; okay; y++)
4573 /* Get a line of data including control code */
4574 if (!fgets(buf, 1024, fff)) okay = FALSE;
4576 /* Get the blank line */
4577 if (buf[0] == '\n' || buf[0] == '\0') break;
4579 /* Ignore too large screen image */
4580 if (y >= hgt) continue;
4583 for (x = 0; x < wid - 1; x++)
4586 if (buf[x] == '\n' || buf[x] == '\0') break;
4588 /* Put the attr/char */
4589 Term_draw(x, y, TERM_WHITE, buf[x]);
4593 /* Dump the screen */
4594 for (y = 0; okay; y++)
4596 /* Get a line of data including control code */
4597 if (!fgets(buf, 1024, fff)) okay = FALSE;
4599 /* Get the blank line */
4600 if (buf[0] == '\n' || buf[0] == '\0') break;
4602 /* Ignore too large screen image */
4603 if (y >= hgt) continue;
4606 for (x = 0; x < wid - 1; x++)
4609 if (buf[x] == '\n' || buf[x] == '\0') break;
4611 /* Get the attr/char */
4612 (void)(Term_what(x, y, &a, &c));
4614 /* Look up the attr */
4615 for (i = 0; i < 16; i++)
4617 /* Use attr matches */
4618 if (hack[i] == buf[x]) a = (byte_hack)i;
4621 /* Put the attr/char */
4622 Term_draw(x, y, a, c);
4627 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4638 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4639 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4642 #define IM_FLAG_STR _("*", "* ")
4643 #define HAS_FLAG_STR _("+", "+ ")
4644 #define NO_FLAG_STR _("・", ". ")
4646 #define print_im_or_res_flag(IM, RES) \
4648 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4649 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4652 #define print_flag(TR) \
4654 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4658 /* XTRA HACK RESLIST */
4659 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4661 GAME_TEXT o_name[MAX_NLEN];
4662 BIT_FLAGS flgs[TR_FLAG_SIZE];
4664 if (!o_ptr->k_idx) return;
4665 if (o_ptr->tval != tval) return;
4667 /* Identified items only */
4668 if (!object_is_known(o_ptr)) return;
4671 * HACK:Ring of Lordly protection and Dragon equipment
4672 * have random resistances.
4674 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4675 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4676 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4677 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4678 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4679 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4680 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4681 || object_is_artifact(o_ptr))
4684 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4686 while (o_name[i] && (i < 26))
4689 if (iskanji(o_name[i])) i++;
4698 o_name[i] = ' '; i++;
4703 fprintf(fff, "%s %s", where, o_name);
4705 if (!(o_ptr->ident & (IDENT_MENTAL)))
4707 fputs(_("-------不明--------------- -------不明---------\n",
4708 "-------unknown------------ -------unknown------\n"), fff);
4712 object_flags_known(o_ptr, flgs);
4714 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4715 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4716 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4717 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4718 print_flag(TR_RES_POIS);
4719 print_flag(TR_RES_LITE);
4720 print_flag(TR_RES_DARK);
4721 print_flag(TR_RES_SHARDS);
4722 print_flag(TR_RES_SOUND);
4723 print_flag(TR_RES_NETHER);
4724 print_flag(TR_RES_NEXUS);
4725 print_flag(TR_RES_CHAOS);
4726 print_flag(TR_RES_DISEN);
4730 print_flag(TR_RES_BLIND);
4731 print_flag(TR_RES_FEAR);
4732 print_flag(TR_RES_CONF);
4733 print_flag(TR_FREE_ACT);
4734 print_flag(TR_SEE_INVIS);
4735 print_flag(TR_HOLD_EXP);
4736 print_flag(TR_TELEPATHY);
4737 print_flag(TR_SLOW_DIGEST);
4738 print_flag(TR_REGEN);
4739 print_flag(TR_LEVITATION);
4747 fprintf(fff, "%s\n", inven_res_label);
4753 * Display *ID* ed weapons/armors's resistances
4755 static void do_cmd_knowledge_inven(void)
4758 GAME_TEXT file_name[1024];
4760 OBJECT_TYPE_VALUE tval;
4766 /* Open a new file */
4767 fff = my_fopen_temp(file_name, 1024);
4770 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4774 fprintf(fff, "%s\n", inven_res_label);
4776 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4780 for (; j < 9; j++) fputc('\n', fff);
4782 fprintf(fff, "%s\n", inven_res_label);
4784 strcpy(where, _("装", "E "));
4785 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4787 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4789 strcpy(where, _("持", "I "));
4790 for (i = 0; i < INVEN_PACK; i++)
4792 do_cmd_knowledge_inven_aux(fff, &p_ptr->inventory_list[i], &j, tval, where);
4795 st_ptr = &town_info[1].store[STORE_HOME];
4796 strcpy(where, _("家", "H "));
4797 for (i = 0; i < st_ptr->stock_num; i++)
4799 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4804 /* Display the file contents */
4805 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4810 void do_cmd_save_screen_html_aux(char *filename, int message)
4815 TERM_COLOR a = 0, old_a = 0;
4829 concptr html_head[] = {
4830 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4834 concptr html_foot[] = {
4836 "</body>\n</html>\n",
4842 Term_get_size(&wid, &hgt);
4844 /* File type is "TEXT" */
4845 FILE_TYPE(FILE_TYPE_TEXT);
4847 /* Append to the file */
4848 fff = my_fopen(filename, "w");
4852 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4858 if (message) screen_save();
4860 /* Build the filename */
4861 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4862 tmpfff = my_fopen(buf, "r");
4864 for (i = 0; html_head[i]; i++)
4865 fputs(html_head[i], fff);
4869 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4871 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4875 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4877 fprintf(fff, "%s\n", buf);
4882 /* Dump the screen */
4883 for (y = 0; y < hgt; y++)
4890 for (x = 0; x < wid - 1; x++)
4894 /* Get the attr/char */
4895 (void)(Term_what(x, y, &a, &c));
4899 case '&': cc = "&"; break;
4900 case '<': cc = "<"; break;
4901 case '>': cc = ">"; break;
4903 case 0x1f: c = '.'; break;
4904 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4909 if ((y == 0 && x == 0) || a != old_a) {
4910 rv = angband_color_table[a][1];
4911 gv = angband_color_table[a][2];
4912 bv = angband_color_table[a][3];
4913 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4914 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4918 fprintf(fff, "%s", cc);
4920 fprintf(fff, "%c", c);
4923 fprintf(fff, "</font>");
4926 for (i = 0; html_foot[i]; i++)
4927 fputs(html_foot[i], fff);
4932 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4934 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4938 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4940 fprintf(fff, "%s\n", buf);
4951 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4959 * Hack -- save a screen dump to a file
4961 static void do_cmd_save_screen_html(void)
4963 char buf[1024], tmp[256] = "screen.html";
4965 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4968 /* Build the filename */
4969 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4973 do_cmd_save_screen_html_aux(buf, 1);
4978 * Redefinable "save_screen" action
4980 void (*screendump_aux)(void) = NULL;
4984 * Hack -- save a screen dump to a file
4986 void do_cmd_save_screen(void)
4988 bool old_use_graphics = use_graphics;
4989 bool html_dump = FALSE;
4993 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4997 if (c == 'Y' || c == 'y')
4999 else if (c == 'H' || c == 'h')
5011 Term_get_size(&wid, &hgt);
5013 if (old_use_graphics)
5015 use_graphics = FALSE;
5017 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5023 do_cmd_save_screen_html();
5027 /* Do we use a special screendump function ? */
5028 else if (screendump_aux)
5030 /* Dump the screen to a graphics file */
5031 (*screendump_aux)();
5033 else /* Dump the screen as text */
5037 SYMBOL_CODE c = ' ';
5041 /* Build the filename */
5042 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5044 /* File type is "TEXT" */
5045 FILE_TYPE(FILE_TYPE_TEXT);
5047 /* Append to the file */
5048 fff = my_fopen(buf, "w");
5052 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5060 /* Dump the screen */
5061 for (y = 0; y < hgt; y++)
5064 for (x = 0; x < wid - 1; x++)
5066 /* Get the attr/char */
5067 (void)(Term_what(x, y, &a, &c));
5077 fprintf(fff, "%s\n", buf);
5084 /* Dump the screen */
5085 for (y = 0; y < hgt; y++)
5088 for (x = 0; x < wid - 1; x++)
5090 /* Get the attr/char */
5091 (void)(Term_what(x, y, &a, &c));
5094 buf[x] = hack[a&0x0F];
5101 fprintf(fff, "%s\n", buf);
5108 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5113 if (old_use_graphics)
5115 use_graphics = TRUE;
5117 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5123 * Check the status of "artifacts"
5125 static void do_cmd_knowledge_artifacts(void)
5135 GAME_TEXT file_name[1024];
5136 GAME_TEXT base_name[MAX_NLEN];
5140 /* Open a new file */
5141 fff = my_fopen_temp(file_name, 1024);
5144 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5149 /* Allocate the "who" array */
5150 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5152 /* Allocate the "okay" array */
5153 C_MAKE(okay, max_a_idx, bool);
5155 /* Scan the artifacts */
5156 for (k = 0; k < max_a_idx; k++)
5158 artifact_type *a_ptr = &a_info[k];
5163 /* Skip "empty" artifacts */
5164 if (!a_ptr->name) continue;
5166 /* Skip "uncreated" artifacts */
5167 if (!a_ptr->cur_num) continue;
5173 /* Check the dungeon */
5174 for (y = 0; y < current_floor_ptr->height; y++)
5176 for (x = 0; x < current_floor_ptr->width; x++)
5178 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
5180 OBJECT_IDX this_o_idx, next_o_idx = 0;
5182 /* Scan all objects in the grid */
5183 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5186 o_ptr = ¤t_floor_ptr->o_list[this_o_idx];
5187 next_o_idx = o_ptr->next_o_idx;
5189 /* Ignore non-artifacts */
5190 if (!object_is_fixed_artifact(o_ptr)) continue;
5192 /* Ignore known items */
5193 if (object_is_known(o_ptr)) continue;
5195 /* Note the artifact */
5196 okay[o_ptr->name1] = FALSE;
5201 /* Check the p_ptr->inventory_list and equipment */
5202 for (i = 0; i < INVEN_TOTAL; i++)
5204 object_type *o_ptr = &p_ptr->inventory_list[i];
5206 /* Ignore non-objects */
5207 if (!o_ptr->k_idx) continue;
5209 /* Ignore non-artifacts */
5210 if (!object_is_fixed_artifact(o_ptr)) continue;
5212 /* Ignore known items */
5213 if (object_is_known(o_ptr)) continue;
5215 /* Note the artifact */
5216 okay[o_ptr->name1] = FALSE;
5219 for (k = 0; k < max_a_idx; k++)
5221 if (okay[k]) who[n++] = k;
5224 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
5226 /* Scan the artifacts */
5227 for (k = 0; k < n; k++)
5229 artifact_type *a_ptr = &a_info[who[k]];
5230 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5232 /* Obtain the base object type */
5233 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5242 /* Create fake object */
5243 object_prep(q_ptr, z);
5245 /* Make it an artifact */
5246 q_ptr->name1 = (byte)who[k];
5248 /* Display as if known */
5249 q_ptr->ident |= IDENT_STORE;
5251 /* Describe the artifact */
5252 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5255 /* Hack -- Build the artifact name */
5256 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5259 /* Free the "who" array */
5260 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5262 /* Free the "okay" array */
5263 C_KILL(okay, max_a_idx, bool);
5266 /* Display the file contents */
5267 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5273 * Display known uniques
5274 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5276 static void do_cmd_knowledge_uniques(void)
5285 GAME_TEXT file_name[1024];
5288 int n_alive_surface = 0;
5289 int n_alive_over100 = 0;
5290 int n_alive_total = 0;
5293 for (i = 0; i < 10; i++) n_alive[i] = 0;
5295 /* Open a new file */
5296 fff = my_fopen_temp(file_name, 1024);
5300 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5305 /* Allocate the "who" array */
5306 C_MAKE(who, max_r_idx, MONRACE_IDX);
5308 /* Scan the monsters */
5309 for (i = 1; i < max_r_idx; i++)
5311 monster_race *r_ptr = &r_info[i];
5314 if (!r_ptr->name) continue;
5316 /* Require unique monsters */
5317 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5319 /* Only display "known" uniques */
5320 if (!cheat_know && !r_ptr->r_sights) continue;
5322 /* Only print rarity <= 100 uniques */
5323 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5325 /* Only "alive" uniques */
5326 if (r_ptr->max_num == 0) continue;
5330 lev = (r_ptr->level - 1) / 10;
5334 if (max_lev < lev) max_lev = lev;
5336 else n_alive_over100++;
5338 else n_alive_surface++;
5340 /* Collect "appropriate" monsters */
5344 /* Sort the array by dungeon depth of monsters */
5345 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5347 if (n_alive_surface)
5349 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5350 n_alive_total += n_alive_surface;
5352 for (i = 0; i <= max_lev; i++)
5354 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5355 n_alive_total += n_alive[i];
5357 if (n_alive_over100)
5359 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5360 n_alive_total += n_alive_over100;
5365 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5366 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5370 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5373 /* Scan the monster races */
5374 for (k = 0; k < n; k++)
5376 monster_race *r_ptr = &r_info[who[k]];
5378 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5381 /* Free the "who" array */
5382 C_KILL(who, max_r_idx, s16b);
5385 /* Display the file contents */
5386 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5392 * Display weapon-exp
5394 static void do_cmd_knowledge_weapon_exp(void)
5402 GAME_TEXT file_name[1024];
5405 /* Open a new file */
5406 fff = my_fopen_temp(file_name, 1024);
5408 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5413 for (i = 0; i < 5; i++)
5415 for (num = 0; num < 64; num++)
5417 for (j = 0; j < max_k_idx; j++)
5419 object_kind *k_ptr = &k_info[j];
5421 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5423 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5425 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5427 fprintf(fff, "%-25s ", tmp);
5428 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5429 else fprintf(fff, " ");
5430 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5431 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5440 /* Display the file contents */
5441 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5447 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5451 static void do_cmd_knowledge_spell_exp(void)
5458 const magic_type *s_ptr;
5460 GAME_TEXT file_name[1024];
5462 /* Open a new file */
5463 fff = my_fopen_temp(file_name, 1024);
5465 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5470 if (p_ptr->realm1 != REALM_NONE)
5472 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5473 for (i = 0; i < 32; i++)
5475 if (!is_magic(p_ptr->realm1))
5477 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5481 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5483 if (s_ptr->slevel >= 99) continue;
5484 spell_exp = p_ptr->spell_exp[i];
5485 exp_level = spell_exp_level(spell_exp);
5486 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5487 if (p_ptr->realm1 == REALM_HISSATSU)
5488 fprintf(fff, "[--]");
5491 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5492 else fprintf(fff, " ");
5493 fprintf(fff, "%s", exp_level_str[exp_level]);
5495 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5500 if (p_ptr->realm2 != REALM_NONE)
5502 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5503 for (i = 0; i < 32; i++)
5505 if (!is_magic(p_ptr->realm1))
5507 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5511 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5513 if (s_ptr->slevel >= 99) continue;
5515 spell_exp = p_ptr->spell_exp[i + 32];
5516 exp_level = spell_exp_level(spell_exp);
5517 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5518 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5519 else fprintf(fff, " ");
5520 fprintf(fff, "%s", exp_level_str[exp_level]);
5521 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5527 /* Display the file contents */
5528 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5534 * @brief スキル情報を表示するコマンドのメインルーチン /
5538 static void do_cmd_knowledge_skill_exp(void)
5540 int i = 0, skill_exp;
5544 char file_name[1024];
5545 char skill_name[GINOU_TEMPMAX][20] =
5547 _("マーシャルアーツ", "Martial Arts "),
5548 _("二刀流 ", "Dual Wielding "),
5549 _("乗馬 ", "Riding "),
5553 /* Open a new file */
5554 fff = my_fopen_temp(file_name, 1024);
5556 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5561 for (i = 0; i < GINOU_TEMPMAX; i++)
5563 skill_exp = p_ptr->skill_exp[i];
5564 fprintf(fff, "%-20s ", skill_name[i]);
5565 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5566 else fprintf(fff, " ");
5567 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5568 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5573 /* Display the file contents */
5574 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5580 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5581 * @param Name 変換したい文字列の参照ポインタ
5584 void plural_aux(char *Name)
5586 int NameLen = strlen(Name);
5588 if (my_strstr(Name, "Disembodied hand"))
5590 strcpy(Name, "Disembodied hands that strangled people");
5592 else if (my_strstr(Name, "Colour out of space"))
5594 strcpy(Name, "Colours out of space");
5596 else if (my_strstr(Name, "stairway to hell"))
5598 strcpy(Name, "stairways to hell");
5600 else if (my_strstr(Name, "Dweller on the threshold"))
5602 strcpy(Name, "Dwellers on the threshold");
5604 else if (my_strstr(Name, " of "))
5606 concptr aider = my_strstr(Name, " of ");
5617 if (dummy[i-1] == 's')
5619 strcpy(&(dummy[i]), "es");
5624 strcpy(&(dummy[i]), "s");
5627 strcpy(&(dummy[i+1]), aider);
5628 strcpy(Name, dummy);
5630 else if (my_strstr(Name, "coins"))
5633 strcpy(dummy, "piles of ");
5634 strcat(dummy, Name);
5635 strcpy(Name, dummy);
5638 else if (my_strstr(Name, "Manes"))
5642 else if (streq(&(Name[NameLen - 2]), "ey"))
5644 strcpy(&(Name[NameLen - 2]), "eys");
5646 else if (Name[NameLen - 1] == 'y')
5648 strcpy(&(Name[NameLen - 1]), "ies");
5650 else if (streq(&(Name[NameLen - 4]), "ouse"))
5652 strcpy(&(Name[NameLen - 4]), "ice");
5654 else if (streq(&(Name[NameLen - 2]), "us"))
5656 strcpy(&(Name[NameLen - 2]), "i");
5658 else if (streq(&(Name[NameLen - 6]), "kelman"))
5660 strcpy(&(Name[NameLen - 6]), "kelmen");
5662 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5664 strcpy(&(Name[NameLen - 8]), "wordsmen");
5666 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5668 strcpy(&(Name[NameLen - 7]), "oodsmen");
5670 else if (streq(&(Name[NameLen - 7]), "eastman"))
5672 strcpy(&(Name[NameLen - 7]), "eastmen");
5674 else if (streq(&(Name[NameLen - 8]), "izardman"))
5676 strcpy(&(Name[NameLen - 8]), "izardmen");
5678 else if (streq(&(Name[NameLen - 5]), "geist"))
5680 strcpy(&(Name[NameLen - 5]), "geister");
5682 else if (streq(&(Name[NameLen - 2]), "ex"))
5684 strcpy(&(Name[NameLen - 2]), "ices");
5686 else if (streq(&(Name[NameLen - 2]), "lf"))
5688 strcpy(&(Name[NameLen - 2]), "lves");
5690 else if (suffix(Name, "ch") ||
5691 suffix(Name, "sh") ||
5692 suffix(Name, "nx") ||
5693 suffix(Name, "s") ||
5696 strcpy(&(Name[NameLen]), "es");
5700 strcpy(&(Name[NameLen]), "s");
5705 * @brief 現在のペットを表示するコマンドのメインルーチン /
5706 * Display current pets
5709 static void do_cmd_knowledge_pets(void)
5713 monster_type *m_ptr;
5714 GAME_TEXT pet_name[MAX_NLEN];
5716 int show_upkeep = 0;
5717 GAME_TEXT file_name[1024];
5720 /* Open a new file */
5721 fff = my_fopen_temp(file_name, 1024);
5723 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5728 /* Process the monsters (backwards) */
5729 for (i = current_floor_ptr->m_max - 1; i >= 1; i--)
5731 /* Access the monster */
5732 m_ptr = ¤t_floor_ptr->m_list[i];
5734 /* Ignore "dead" monsters */
5735 if (!monster_is_valid(m_ptr)) continue;
5737 /* Calculate "upkeep" for pets */
5741 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5742 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5746 show_upkeep = calculate_upkeep();
5748 fprintf(fff, "----------------------------------------------\n");
5750 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5752 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5754 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5759 /* Display the file contents */
5760 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5766 * @brief 現在のペットを表示するコマンドのメインルーチン /
5769 * @note the player ghosts are ignored.
5771 static void do_cmd_knowledge_kill_count(void)
5778 GAME_TEXT file_name[1024];
5783 /* Open a new file */
5784 fff = my_fopen_temp(file_name, 1024);
5787 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5792 /* Allocate the "who" array */
5793 C_MAKE(who, max_r_idx, MONRACE_IDX);
5796 /* Monsters slain */
5799 for (kk = 1; kk < max_r_idx; kk++)
5801 monster_race *r_ptr = &r_info[kk];
5803 if (r_ptr->flags1 & (RF1_UNIQUE))
5805 bool dead = (r_ptr->max_num == 0);
5814 MONSTER_NUMBER This = r_ptr->r_pkills;
5824 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5827 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5829 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5835 /* Scan the monsters */
5836 for (i = 1; i < max_r_idx; i++)
5838 monster_race *r_ptr = &r_info[i];
5840 /* Use that monster */
5841 if (r_ptr->name) who[n++] = i;
5844 /* Sort the array by dungeon depth of monsters */
5845 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
5847 /* Scan the monster races */
5848 for (k = 0; k < n; k++)
5850 monster_race *r_ptr = &r_info[who[k]];
5852 if (r_ptr->flags1 & (RF1_UNIQUE))
5854 bool dead = (r_ptr->max_num == 0);
5858 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5864 MONSTER_NUMBER This = r_ptr->r_pkills;
5869 /* p,tは人と数える by ita */
5870 if (my_strchr("pt", r_ptr->d_char))
5871 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5873 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
5877 if (my_strstr(r_name + r_ptr->name, "coins"))
5879 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
5883 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
5889 strcpy(ToPlural, (r_name + r_ptr->name));
5890 plural_aux(ToPlural);
5891 fprintf(fff, " %d %s\n", This, ToPlural);
5901 fprintf(fff,"----------------------------------------------\n");
5903 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
5905 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
5909 /* Free the "who" array */
5910 C_KILL(who, max_r_idx, s16b);
5913 /* Display the file contents */
5914 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
5920 * @brief モンスター情報リスト中のグループを表示する /
5921 * Display the object groups.
5925 * @param per_page リストの表示行
5926 * @param grp_idx グループのID配列
5927 * @param group_text グループ名の文字列配列
5928 * @param grp_cur 現在の選択ID
5929 * @param grp_top 現在の選択リスト最上部ID
5932 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)
5936 /* Display lines until done */
5937 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
5939 /* Get the group index */
5940 int grp = grp_idx[grp_top + i];
5942 /* Choose a color */
5943 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
5945 /* Erase the entire line */
5946 Term_erase(col, row + i, wid);
5948 /* Display the group label */
5949 c_put_str(attr, group_text[grp], row + i, col);
5955 * Move the cursor in a browser window
5957 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
5958 IDX *list_cur, int list_cnt)
5963 IDX list = *list_cur;
5965 /* Extract direction */
5968 /* Hack -- scroll up full screen */
5973 /* Hack -- scroll down full screen */
5978 d = get_keymap_dir(ch);
5983 /* Diagonals - hack */
5984 if ((ddx[d] > 0) && ddy[d])
5989 Term_get_size(&wid, &hgt);
5991 browser_rows = hgt - 8;
5993 /* Browse group list */
5998 /* Move up or down */
5999 grp += ddy[d] * (browser_rows - 1);
6002 if (grp >= grp_cnt) grp = grp_cnt - 1;
6003 if (grp < 0) grp = 0;
6004 if (grp != old_grp) list = 0;
6007 /* Browse sub-list list */
6010 /* Move up or down */
6011 list += ddy[d] * browser_rows;
6014 if (list >= list_cnt) list = list_cnt - 1;
6015 if (list < 0) list = 0;
6027 if (col < 0) col = 0;
6028 if (col > 1) col = 1;
6035 /* Browse group list */
6040 /* Move up or down */
6044 if (grp >= grp_cnt) grp = grp_cnt - 1;
6045 if (grp < 0) grp = 0;
6046 if (grp != old_grp) list = 0;
6049 /* Browse sub-list list */
6052 /* Move up or down */
6053 list += (IDX)ddy[d];
6056 if (list >= list_cnt) list = list_cnt - 1;
6057 if (list < 0) list = 0;
6068 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6072 /* Clear the display lines */
6073 for (i = 0; i < height; i++)
6075 Term_erase(col, row + i, width);
6078 /* Bigtile mode uses double width */
6079 if (use_bigtile) width /= 2;
6081 /* Display lines until done */
6082 for (i = 0; i < height; i++)
6084 /* Display columns until done */
6085 for (j = 0; j < width; j++)
6089 TERM_LEN x = col + j;
6090 TERM_LEN y = row + i;
6092 /* Bigtile mode uses double width */
6093 if (use_bigtile) x += j;
6098 /* Ignore illegal characters */
6099 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6100 (!use_graphics && ic > 0x7f))
6106 /* Force correct code for both ASCII character and tile */
6107 if (c & 0x80) a |= 0x80;
6109 /* Display symbol */
6110 Term_queue_bigchar(x, y, a, c, 0, 0);
6117 * Place the cursor at the collect position for visual mode
6119 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6121 int i = (a & 0x7f) - attr_top;
6122 int j = c - char_left;
6124 TERM_LEN x = col + j;
6125 TERM_LEN y = row + i;
6127 /* Bigtile mode uses double width */
6128 if (use_bigtile) x += j;
6130 /* Place the cursor */
6136 * Clipboard variables for copy&paste in visual mode
6138 static TERM_COLOR attr_idx = 0;
6139 static SYMBOL_CODE char_idx = 0;
6141 /* Hack -- for feature lighting */
6142 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6143 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6146 * Do visual mode command -- Change symbols
6148 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6149 int height, int width,
6150 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6151 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6153 static TERM_COLOR attr_old = 0;
6154 static SYMBOL_CODE char_old = 0;
6159 if (*visual_list_ptr)
6162 *cur_attr_ptr = attr_old;
6163 *cur_char_ptr = char_old;
6164 *visual_list_ptr = FALSE;
6172 if (*visual_list_ptr)
6175 *visual_list_ptr = FALSE;
6176 *need_redraw = TRUE;
6184 if (!*visual_list_ptr)
6186 *visual_list_ptr = TRUE;
6188 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6189 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6191 attr_old = *cur_attr_ptr;
6192 char_old = *cur_char_ptr;
6203 /* Set the visual */
6204 attr_idx = *cur_attr_ptr;
6205 char_idx = *cur_char_ptr;
6207 /* Hack -- for feature lighting */
6208 for (i = 0; i < F_LIT_MAX; i++)
6210 attr_idx_feat[i] = 0;
6211 char_idx_feat[i] = 0;
6218 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6221 *cur_attr_ptr = attr_idx;
6222 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6223 if (!*visual_list_ptr) *need_redraw = TRUE;
6229 *cur_char_ptr = char_idx;
6230 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6231 if (!*visual_list_ptr) *need_redraw = TRUE;
6237 if (*visual_list_ptr)
6240 int d = get_keymap_dir(ch);
6241 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6242 SYMBOL_CODE c = *cur_char_ptr;
6244 if (use_bigtile) eff_width = width / 2;
6245 else eff_width = width;
6247 /* Restrict direction */
6248 if ((a == 0) && (ddy[d] < 0)) d = 0;
6249 if ((c == 0) && (ddx[d] < 0)) d = 0;
6250 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6251 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6253 a += (TERM_COLOR)ddy[d];
6254 c += (SYMBOL_CODE)ddx[d];
6256 /* Force correct code for both ASCII character and tile */
6257 if (c & 0x80) a |= 0x80;
6259 /* Set the visual */
6264 /* Move the frame */
6265 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6266 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6267 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6268 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6274 /* Visual mode command is not used */
6280 * Display the monsters in a group.
6282 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6283 int mon_cur, int mon_top, bool visual_only)
6287 /* Display lines until done */
6288 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6292 /* Get the race index */
6293 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6295 /* Access the race */
6296 monster_race *r_ptr = &r_info[r_idx];
6298 /* Choose a color */
6299 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6301 /* Display the name */
6302 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6304 /* Hack -- visual_list mode */
6307 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6309 if (p_ptr->wizard || visual_only)
6311 c_prt(attr, format("%d", r_idx), row + i, 62);
6314 /* Erase chars before overwritten by the race letter */
6315 Term_erase(69, row + i, 255);
6317 /* Display symbol */
6318 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6323 if (!(r_ptr->flags1 & RF1_UNIQUE))
6324 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6326 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6327 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6331 /* Clear remaining lines */
6332 for (; i < per_page; i++)
6334 Term_erase(col, row + i, 255);
6340 * Display known monsters.
6342 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6346 IDX grp_cur, grp_top, old_grp_cur;
6347 IDX mon_cur, mon_top;
6348 IDX grp_cnt, grp_idx[100];
6356 bool visual_list = FALSE;
6357 TERM_COLOR attr_top = 0;
6365 Term_get_size(&wid, &hgt);
6367 browser_rows = hgt - 8;
6369 /* Allocate the "mon_idx" array */
6370 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6375 if (direct_r_idx < 0)
6377 mode = visual_only ? 0x03 : 0x01;
6379 /* Check every group */
6380 for (i = 0; monster_group_text[i] != NULL; i++)
6382 /* Measure the label */
6383 len = strlen(monster_group_text[i]);
6385 /* Save the maximum length */
6386 if (len > max) max = len;
6388 /* See if any monsters are known */
6389 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6391 /* Build a list of groups with known monsters */
6392 grp_idx[grp_cnt++] = i;
6400 mon_idx[0] = direct_r_idx;
6403 /* Terminate the list */
6406 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6407 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6410 /* Terminate the list */
6411 grp_idx[grp_cnt] = -1;
6414 grp_cur = grp_top = 0;
6415 mon_cur = mon_top = 0;
6420 mode = visual_only ? 0x02 : 0x00;
6425 monster_race *r_ptr;
6430 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6431 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6432 prt(_("名前", "Name"), 4, max + 3);
6433 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6434 prt(_("文字", "Sym"), 4, 67);
6435 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6437 for (i = 0; i < 78; i++)
6439 Term_putch(i, 5, TERM_WHITE, '=');
6442 if (direct_r_idx < 0)
6444 for (i = 0; i < browser_rows; i++)
6446 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6453 if (direct_r_idx < 0)
6455 /* Scroll group list */
6456 if (grp_cur < grp_top) grp_top = grp_cur;
6457 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6459 /* Display a list of monster groups */
6460 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6462 if (old_grp_cur != grp_cur)
6464 old_grp_cur = grp_cur;
6466 /* Get a list of monsters in the current group */
6467 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6470 /* Scroll monster list */
6471 while (mon_cur < mon_top)
6472 mon_top = MAX(0, mon_top - browser_rows/2);
6473 while (mon_cur >= mon_top + browser_rows)
6474 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6479 /* Display a list of monsters in the current group */
6480 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6486 /* Display a monster name */
6487 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6489 /* Display visual list below first monster */
6490 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6494 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6495 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6496 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6497 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6500 /* Get the current monster */
6501 r_ptr = &r_info[mon_idx[mon_cur]];
6505 /* Mega Hack -- track this monster race */
6506 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6512 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6516 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6520 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6525 /* Do visual mode command if needed */
6526 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))
6528 if (direct_r_idx >= 0)
6553 /* Recall on screen */
6554 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6556 screen_roff(mon_idx[mon_cur], 0);
6567 /* Move the cursor */
6568 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6575 /* Free the "mon_idx" array */
6576 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6581 * Display the objects in a group.
6583 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6584 int object_cur, int object_top, bool visual_only)
6588 /* Display lines until done */
6589 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6591 GAME_TEXT o_name[MAX_NLEN];
6594 object_kind *flavor_k_ptr;
6596 /* Get the object index */
6597 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6599 /* Access the object */
6600 object_kind *k_ptr = &k_info[k_idx];
6602 /* Choose a color */
6603 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6604 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6607 if (!visual_only && k_ptr->flavor)
6609 /* Appearance of this object is shuffled */
6610 flavor_k_ptr = &k_info[k_ptr->flavor];
6614 /* Appearance of this object is very normal */
6615 flavor_k_ptr = k_ptr;
6620 attr = ((i + object_top == object_cur) ? cursor : attr);
6622 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6625 strip_name(o_name, k_idx);
6630 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6633 /* Display the name */
6634 c_prt(attr, o_name, row + i, col);
6636 /* Hack -- visual_list mode */
6639 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);
6641 if (p_ptr->wizard || visual_only)
6643 c_prt(attr, format("%d", k_idx), row + i, 70);
6646 a = flavor_k_ptr->x_attr;
6647 c = flavor_k_ptr->x_char;
6649 /* Display symbol */
6650 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6653 /* Clear remaining lines */
6654 for (; i < per_page; i++)
6656 Term_erase(col, row + i, 255);
6661 * Describe fake object
6663 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6666 object_type object_type_body;
6667 o_ptr = &object_type_body;
6669 object_prep(o_ptr, k_idx);
6671 /* It's fully know */
6672 o_ptr->ident |= IDENT_KNOWN;
6674 /* Track the object */
6675 /* object_actual_track(o_ptr); */
6677 /* Hack - mark as fake */
6678 /* term_obj_real = FALSE; */
6681 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6683 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6691 * Display known objects
6693 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6697 IDX grp_cur, grp_top, old_grp_cur;
6698 IDX object_old, object_cur, object_top;
6702 OBJECT_IDX *object_idx;
6708 bool visual_list = FALSE;
6709 TERM_COLOR attr_top = 0;
6717 Term_get_size(&wid, &hgt);
6719 browser_rows = hgt - 8;
6721 /* Allocate the "object_idx" array */
6722 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6727 if (direct_k_idx < 0)
6729 mode = visual_only ? 0x03 : 0x01;
6731 /* Check every group */
6732 for (i = 0; object_group_text[i] != NULL; i++)
6734 /* Measure the label */
6735 len = strlen(object_group_text[i]);
6737 /* Save the maximum length */
6738 if (len > max) max = len;
6740 /* See if any monsters are known */
6741 if (collect_objects(i, object_idx, mode))
6743 /* Build a list of groups with known monsters */
6744 grp_idx[grp_cnt++] = i;
6753 object_kind *k_ptr = &k_info[direct_k_idx];
6754 object_kind *flavor_k_ptr;
6756 if (!visual_only && k_ptr->flavor)
6758 /* Appearance of this object is shuffled */
6759 flavor_k_ptr = &k_info[k_ptr->flavor];
6763 /* Appearance of this object is very normal */
6764 flavor_k_ptr = k_ptr;
6767 object_idx[0] = direct_k_idx;
6768 object_old = direct_k_idx;
6771 /* Terminate the list */
6774 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6775 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6778 /* Terminate the list */
6779 grp_idx[grp_cnt] = -1;
6782 grp_cur = grp_top = 0;
6783 object_cur = object_top = 0;
6788 mode = visual_only ? 0x02 : 0x00;
6793 object_kind *k_ptr, *flavor_k_ptr;
6800 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6801 if (direct_k_idx < 0) prt("グループ", 4, 0);
6802 prt("名前", 4, max + 3);
6803 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6806 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6807 if (direct_k_idx < 0) prt("Group", 4, 0);
6808 prt("Name", 4, max + 3);
6809 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6813 for (i = 0; i < 78; i++)
6815 Term_putch(i, 5, TERM_WHITE, '=');
6818 if (direct_k_idx < 0)
6820 for (i = 0; i < browser_rows; i++)
6822 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6829 if (direct_k_idx < 0)
6831 /* Scroll group list */
6832 if (grp_cur < grp_top) grp_top = grp_cur;
6833 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6835 /* Display a list of object groups */
6836 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6838 if (old_grp_cur != grp_cur)
6840 old_grp_cur = grp_cur;
6842 /* Get a list of objects in the current group */
6843 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6846 /* Scroll object list */
6847 while (object_cur < object_top)
6848 object_top = MAX(0, object_top - browser_rows/2);
6849 while (object_cur >= object_top + browser_rows)
6850 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6855 /* Display a list of objects in the current group */
6856 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6860 object_top = object_cur;
6862 /* Display a list of objects in the current group */
6863 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6865 /* Display visual list below first object */
6866 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6869 /* Get the current object */
6870 k_ptr = &k_info[object_idx[object_cur]];
6872 if (!visual_only && k_ptr->flavor)
6874 /* Appearance of this object is shuffled */
6875 flavor_k_ptr = &k_info[k_ptr->flavor];
6879 /* Appearance of this object is very normal */
6880 flavor_k_ptr = k_ptr;
6885 prt(format("<方向>%s%s%s, ESC",
6886 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
6887 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6888 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6891 prt(format("<dir>%s%s%s, ESC",
6892 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6893 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6894 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6900 /* Mega Hack -- track this object */
6901 if (object_cnt) object_kind_track(object_idx[object_cur]);
6903 /* The "current" object changed */
6904 if (object_old != object_idx[object_cur])
6908 /* Remember the "current" object */
6909 object_old = object_idx[object_cur];
6915 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
6919 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6923 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
6928 /* Do visual mode command if needed */
6929 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))
6931 if (direct_k_idx >= 0)
6956 /* Recall on screen */
6957 if (!visual_list && !visual_only && (grp_cnt > 0))
6959 desc_obj_fake(object_idx[object_cur]);
6967 /* Move the cursor */
6968 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
6974 /* Free the "object_idx" array */
6975 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
6980 * Display the features in a group.
6982 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
6983 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
6985 int lit_col[F_LIT_MAX], i, j;
6986 int f_idx_col = use_bigtile ? 62 : 64;
6988 /* Correct columns 1 and 4 */
6989 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
6990 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6991 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
6993 /* Display lines until done */
6994 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
6997 FEAT_IDX f_idx = feat_idx[feat_top + i];
6998 feature_type *f_ptr = &f_info[f_idx];
6999 int row_i = row + i;
7001 /* Choose a color */
7002 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7004 /* Display the name */
7005 c_prt(attr, f_name + f_ptr->name, row_i, col);
7007 /* Hack -- visual_list mode */
7010 /* Display lighting level */
7011 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7013 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));
7015 if (p_ptr->wizard || visual_only)
7017 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7020 /* Display symbol */
7021 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);
7023 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7024 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7026 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7028 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7030 /* Mega-hack -- Use non-standard colour */
7031 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7033 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7037 /* Clear remaining lines */
7038 for (; i < per_page; i++)
7040 Term_erase(col, row + i, 255);
7046 * Interact with feature visuals.
7048 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7052 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7053 FEAT_IDX feat_cur, feat_top;
7055 FEAT_IDX grp_idx[100];
7059 TERM_LEN column = 0;
7063 bool visual_list = FALSE;
7064 TERM_COLOR attr_top = 0;
7067 TERM_LEN browser_rows;
7070 TERM_COLOR attr_old[F_LIT_MAX];
7071 SYMBOL_CODE char_old[F_LIT_MAX];
7072 TERM_COLOR *cur_attr_ptr;
7073 SYMBOL_CODE *cur_char_ptr;
7075 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7076 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7078 Term_get_size(&wid, &hgt);
7080 browser_rows = hgt - 8;
7082 /* Allocate the "feat_idx" array */
7083 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7088 if (direct_f_idx < 0)
7090 /* Check every group */
7091 for (i = 0; feature_group_text[i] != NULL; i++)
7093 /* Measure the label */
7094 len = strlen(feature_group_text[i]);
7096 /* Save the maximum length */
7097 if (len > max) max = len;
7099 /* See if any features are known */
7100 if (collect_features(i, feat_idx, 0x01))
7102 /* Build a list of groups with known features */
7103 grp_idx[grp_cnt++] = i;
7111 feature_type *f_ptr = &f_info[direct_f_idx];
7113 feat_idx[0] = direct_f_idx;
7116 /* Terminate the list */
7119 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7120 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7122 for (i = 0; i < F_LIT_MAX; i++)
7124 attr_old[i] = f_ptr->x_attr[i];
7125 char_old[i] = f_ptr->x_char[i];
7129 /* Terminate the list */
7130 grp_idx[grp_cnt] = -1;
7133 grp_cur = grp_top = 0;
7134 feat_cur = feat_top = 0;
7142 feature_type *f_ptr;
7148 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7149 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7150 prt(_("名前", "Name"), 4, max + 3);
7153 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7154 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7158 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7159 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7162 for (i = 0; i < 78; i++)
7164 Term_putch(i, 5, TERM_WHITE, '=');
7167 if (direct_f_idx < 0)
7169 for (i = 0; i < browser_rows; i++)
7171 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7178 if (direct_f_idx < 0)
7180 /* Scroll group list */
7181 if (grp_cur < grp_top) grp_top = grp_cur;
7182 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7184 /* Display a list of feature groups */
7185 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7187 if (old_grp_cur != grp_cur)
7189 old_grp_cur = grp_cur;
7191 /* Get a list of features in the current group */
7192 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7195 /* Scroll feature list */
7196 while (feat_cur < feat_top)
7197 feat_top = MAX(0, feat_top - browser_rows/2);
7198 while (feat_cur >= feat_top + browser_rows)
7199 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7204 /* Display a list of features in the current group */
7205 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7209 feat_top = feat_cur;
7211 /* Display a list of features in the current group */
7212 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7214 /* Display visual list below first object */
7215 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7219 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7220 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7221 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7224 /* Get the current feature */
7225 f_ptr = &f_info[feat_idx[feat_cur]];
7226 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7227 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7231 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7235 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7239 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7244 if (visual_list && ((ch == 'A') || (ch == 'a')))
7246 int prev_lighting_level = *lighting_level;
7250 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7251 else (*lighting_level)--;
7255 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7256 else (*lighting_level)++;
7259 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7260 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7262 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7263 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7268 else if ((ch == 'D') || (ch == 'd'))
7270 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7271 byte prev_x_char = f_ptr->x_char[*lighting_level];
7273 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7277 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7278 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7280 if (prev_x_char != f_ptr->x_char[*lighting_level])
7281 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7283 else *need_redraw = TRUE;
7288 /* Do visual mode command if needed */
7289 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))
7293 /* Restore previous visual settings */
7295 for (i = 0; i < F_LIT_MAX; i++)
7297 f_ptr->x_attr[i] = attr_old[i];
7298 f_ptr->x_char[i] = char_old[i];
7305 if (direct_f_idx >= 0) flag = TRUE;
7306 else *lighting_level = F_LIT_STANDARD;
7309 /* Preserve current visual settings */
7312 for (i = 0; i < F_LIT_MAX; i++)
7314 attr_old[i] = f_ptr->x_attr[i];
7315 char_old[i] = f_ptr->x_char[i];
7317 *lighting_level = F_LIT_STANDARD;
7324 for (i = 0; i < F_LIT_MAX; i++)
7326 attr_idx_feat[i] = f_ptr->x_attr[i];
7327 char_idx_feat[i] = f_ptr->x_char[i];
7336 /* Allow TERM_DARK text */
7337 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7339 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7340 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7358 /* Move the cursor */
7359 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7365 /* Free the "feat_idx" array */
7366 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7371 * List wanted monsters
7373 static void do_cmd_knowledge_kubi(void)
7378 GAME_TEXT file_name[1024];
7381 /* Open a new file */
7382 fff = my_fopen_temp(file_name, 1024);
7384 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7391 bool listed = FALSE;
7393 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7394 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7396 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7397 fprintf(fff, "----------------------------------------------\n");
7399 for (i = 0; i < MAX_KUBI; i++)
7401 if (current_world_ptr->bounty_r_idx[i] <= 10000)
7403 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
7411 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7416 /* Display the file contents */
7417 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7422 * List virtues & status
7424 static void do_cmd_knowledge_virtues(void)
7427 GAME_TEXT file_name[1024];
7429 /* Open a new file */
7430 fff = my_fopen_temp(file_name, 1024);
7432 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7439 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7444 /* Display the file contents */
7445 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7452 static void do_cmd_knowledge_dungeon(void)
7456 GAME_TEXT file_name[1024];
7459 /* Open a new file */
7460 fff = my_fopen_temp(file_name, 1024);
7462 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7469 for (i = 1; i < max_d_idx; i++)
7473 if (!d_info[i].maxdepth) continue;
7474 if (!max_dlv[i]) continue;
7475 if (d_info[i].final_guardian)
7477 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7479 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7481 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7486 /* Display the file contents */
7487 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7492 * List virtues & status
7495 static void do_cmd_knowledge_stat(void)
7499 GAME_TEXT file_name[1024];
7502 /* Open a new file */
7503 fff = my_fopen_temp(file_name, 1024);
7505 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7512 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7513 (2 * p_ptr->hitdie +
7514 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7516 if (p_ptr->knowledge & KNOW_HPRATE)
7517 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7518 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7520 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7521 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7523 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);
7524 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7531 /* Display the file contents */
7532 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7538 * Print all active quests
7540 static void do_cmd_knowledge_quests_current(FILE *fff)
7543 char rand_tmp_str[120] = "\0";
7544 GAME_TEXT name[MAX_NLEN];
7545 monster_race *r_ptr;
7547 int rand_level = 100;
7550 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7552 for (i = 1; i < max_q_idx; i++)
7554 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7555 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7556 (quest[i].status == QUEST_STATUS_COMPLETED))
7558 /* Set the quest number temporary */
7559 QUEST_IDX old_quest = p_ptr->inside_quest;
7562 /* Clear the text */
7563 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7564 quest_text_line = 0;
7566 p_ptr->inside_quest = i;
7568 /* Get the quest text */
7569 init_flags = INIT_SHOW_TEXT;
7571 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7573 /* Reset the old quest number */
7574 p_ptr->inside_quest = old_quest;
7576 /* No info from "silent" quests */
7577 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7581 if (quest[i].type != QUEST_TYPE_RANDOM)
7583 char note[80] = "\0";
7585 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7587 switch (quest[i].type)
7589 case QUEST_TYPE_KILL_LEVEL:
7590 case QUEST_TYPE_KILL_ANY_LEVEL:
7591 r_ptr = &r_info[quest[i].r_idx];
7592 strcpy(name, r_name + r_ptr->name);
7593 if (quest[i].max_num > 1)
7596 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7597 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7600 sprintf(note," - kill %d %s, have killed %d.",
7601 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7605 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7608 case QUEST_TYPE_FIND_ARTIFACT:
7611 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7613 object_type *q_ptr = &forge;
7614 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7615 object_prep(q_ptr, k_idx);
7616 q_ptr->name1 = quest[i].k_idx;
7617 q_ptr->ident = IDENT_STORE;
7618 object_desc(name, q_ptr, OD_NAME_ONLY);
7620 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7622 case QUEST_TYPE_FIND_EXIT:
7623 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7626 case QUEST_TYPE_KILL_NUMBER:
7628 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7629 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7631 sprintf(note," - Kill %d monsters, have killed %d.",
7632 (int)quest[i].max_num, (int)quest[i].cur_num);
7636 case QUEST_TYPE_KILL_ALL:
7637 case QUEST_TYPE_TOWER:
7638 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7643 /* Print the quest info */
7644 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7645 quest[i].name, (int)quest[i].level, note);
7647 fputs(tmp_str, fff);
7649 if (quest[i].status == QUEST_STATUS_COMPLETED)
7651 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7652 fputs(tmp_str, fff);
7658 while (quest_text[j][0] && j < 10)
7660 fprintf(fff, " %s\n", quest_text[j]);
7665 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7668 rand_level = quest[i].level;
7670 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7672 /* Print the quest info */
7673 r_ptr = &r_info[quest[i].r_idx];
7674 strcpy(name, r_name + r_ptr->name);
7676 if (quest[i].max_num > 1)
7679 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7680 quest[i].name, (int)quest[i].level,
7681 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7685 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7686 quest[i].name, (int)quest[i].level,
7687 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7692 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7693 quest[i].name, (int)quest[i].level, name);
7700 /* Print the current random quest */
7701 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7703 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7707 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7710 char playtime_str[16];
7711 quest_type* const q_ptr = &quest[q_idx];
7713 if (is_fixed_quest_idx(q_idx))
7715 /* Set the quest number temporary */
7716 IDX old_quest = p_ptr->inside_quest;
7718 p_ptr->inside_quest = q_idx;
7721 init_flags = INIT_NAME_ONLY;
7723 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7725 /* Reset the old quest number */
7726 p_ptr->inside_quest = old_quest;
7728 /* No info from "silent" quests */
7729 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7732 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7733 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7735 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7737 /* Print the quest info */
7738 if (q_ptr->complev == 0)
7741 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7742 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7743 r_name+r_info[q_ptr->r_idx].name,
7744 (int)q_ptr->level, playtime_str);
7749 _(" %-35s (%3d階) - レベル%2d - %s\n",
7750 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7751 r_name+r_info[q_ptr->r_idx].name,
7759 /* Print the quest info */
7761 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7762 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7763 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7766 fputs(tmp_str, fff);
7772 * Print all finished quests
7774 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7777 QUEST_IDX total = 0;
7779 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7780 for (i = 1; i < max_q_idx; i++)
7782 QUEST_IDX q_idx = quest_num[i];
7783 quest_type* const q_ptr = &quest[q_idx];
7785 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7790 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7795 * Print all failed quests
7797 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7800 QUEST_IDX total = 0;
7802 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7803 for (i = 1; i < max_q_idx; i++)
7805 QUEST_IDX q_idx = quest_num[i];
7806 quest_type* const q_ptr = &quest[q_idx];
7808 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7809 do_cmd_knowledge_quests_aux(fff, q_idx))
7814 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7819 * Print all random quests
7821 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7823 GAME_TEXT tmp_str[120];
7825 QUEST_IDX total = 0;
7827 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7828 for (i = 1; i < max_q_idx; i++)
7830 /* No info from "silent" quests */
7831 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7833 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7837 /* Print the quest info */
7838 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7839 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7840 fputs(tmp_str, fff);
7843 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7847 * Print quest status of all active quests
7849 static void do_cmd_knowledge_quests(void)
7852 GAME_TEXT file_name[1024];
7857 /* Open a new file */
7858 fff = my_fopen_temp(file_name, 1024);
7861 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7866 /* Allocate Memory */
7867 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
7869 /* Sort by compete level */
7870 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
7871 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
7873 /* Dump Quest Information */
7874 do_cmd_knowledge_quests_current(fff);
7876 do_cmd_knowledge_quests_completed(fff, quest_num);
7878 do_cmd_knowledge_quests_failed(fff, quest_num);
7882 do_cmd_knowledge_quests_wiz_random(fff);
7886 /* Display the file contents */
7887 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
7891 C_KILL(quest_num, max_q_idx, QUEST_IDX);
7898 static void do_cmd_knowledge_home(void)
7903 GAME_TEXT file_name[1024];
7905 GAME_TEXT o_name[MAX_NLEN];
7906 concptr paren = ")";
7908 process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
7910 /* Open a new file */
7911 fff = my_fopen_temp(file_name, 1024);
7913 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7920 /* Print all homes in the different towns */
7921 st_ptr = &town_info[1].store[STORE_HOME];
7923 /* Home -- if anything there */
7924 if (st_ptr->stock_num)
7929 /* Header with name of the town */
7930 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
7932 /* Dump all available items */
7933 for (i = 0; i < st_ptr->stock_num; i++)
7936 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
7937 object_desc(o_name, &st_ptr->stock[i], 0);
7938 if (strlen(o_name) <= 80-3)
7940 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7946 for (n = 0, t = o_name; n < 80-3; n++, t++)
7947 if(iskanji(*t)) {t++; n++;}
7948 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
7950 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
7951 fprintf(fff, " %.77s\n", o_name+n);
7954 object_desc(o_name, &st_ptr->stock[i], 0);
7955 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
7960 /* Add an empty line */
7961 fprintf(fff, "\n\n");
7966 /* Display the file contents */
7967 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
7973 * Check the status of "autopick"
7975 static void do_cmd_knowledge_autopick(void)
7979 GAME_TEXT file_name[1024];
7981 /* Open a new file */
7982 fff = my_fopen_temp(file_name, 1024);
7986 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7993 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
7997 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
7998 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8001 for (k = 0; k < max_autopick; k++)
8004 byte act = autopick_list[k].action;
8005 if (act & DONT_AUTOPICK)
8007 tmp = _("放置", "Leave");
8009 else if (act & DO_AUTODESTROY)
8011 tmp = _("破壊", "Destroy");
8013 else if (act & DO_AUTOPICK)
8015 tmp = _("拾う", "Pickup");
8019 tmp = _("確認", "Query");
8022 if (act & DO_DISPLAY)
8023 fprintf(fff, "%11s", format("[%s]", tmp));
8025 fprintf(fff, "%11s", format("(%s)", tmp));
8027 tmp = autopick_line_from_entry(&autopick_list[k]);
8028 fprintf(fff, " %s", tmp);
8033 /* Display the file contents */
8034 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8040 * Interact with "knowledge"
8042 void do_cmd_knowledge(void)
8045 bool need_redraw = FALSE;
8047 /* File type is "TEXT" */
8048 FILE_TYPE(FILE_TYPE_TEXT);
8051 /* Interact until done */
8056 /* Ask for a choice */
8057 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8058 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8060 /* Give some choices */
8064 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8065 prt("(2) 既知のアイテム の一覧", 7, 5);
8066 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8067 prt("(4) 既知のモンスター の一覧", 9, 5);
8068 prt("(5) 倒した敵の数 の一覧", 10, 5);
8069 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8070 prt("(7) 現在のペット の一覧", 12, 5);
8071 prt("(8) 我が家のアイテム の一覧", 13, 5);
8072 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8073 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8077 prt("(a) 自分に関する情報 の一覧", 6, 5);
8078 prt("(b) 突然変異 の一覧", 7, 5);
8079 prt("(c) 武器の経験値 の一覧", 8, 5);
8080 prt("(d) 魔法の経験値 の一覧", 9, 5);
8081 prt("(e) 技能の経験値 の一覧", 10, 5);
8082 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8083 prt("(g) 入ったダンジョン の一覧", 12, 5);
8084 prt("(h) 実行中のクエスト の一覧", 13, 5);
8085 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8090 prt("(1) Display known artifacts", 6, 5);
8091 prt("(2) Display known objects", 7, 5);
8092 prt("(3) Display remaining uniques", 8, 5);
8093 prt("(4) Display known monster", 9, 5);
8094 prt("(5) Display kill count", 10, 5);
8095 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8096 prt("(7) Display current pets", 12, 5);
8097 prt("(8) Display home inventory", 13, 5);
8098 prt("(9) Display *identified* equip.", 14, 5);
8099 prt("(0) Display terrain symbols.", 15, 5);
8103 prt("(a) Display about yourself", 6, 5);
8104 prt("(b) Display mutations", 7, 5);
8105 prt("(c) Display weapon proficiency", 8, 5);
8106 prt("(d) Display spell proficiency", 9, 5);
8107 prt("(e) Display misc. proficiency", 10, 5);
8108 prt("(f) Display virtues", 11, 5);
8109 prt("(g) Display dungeons", 12, 5);
8110 prt("(h) Display current quests", 13, 5);
8111 prt("(i) Display auto pick/destroy", 14, 5);
8115 prt(_("-続く-", "-more-"), 17, 8);
8116 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8117 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8118 /*prt("-) 前ページ", 21, 60);*/
8119 prt(_("コマンド:", "Command: "), 20, 0);
8122 if (i == ESCAPE) break;
8125 case ' ': /* Page change */
8129 case '1': /* Artifacts */
8130 do_cmd_knowledge_artifacts();
8132 case '2': /* Objects */
8133 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8135 case '3': /* Uniques */
8136 do_cmd_knowledge_uniques();
8138 case '4': /* Monsters */
8139 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8141 case '5': /* Kill count */
8142 do_cmd_knowledge_kill_count();
8144 case '6': /* wanted */
8145 if (!vanilla_town) do_cmd_knowledge_kubi();
8147 case '7': /* Pets */
8148 do_cmd_knowledge_pets();
8150 case '8': /* Home */
8151 do_cmd_knowledge_home();
8153 case '9': /* Resist list */
8154 do_cmd_knowledge_inven();
8156 case '0': /* Feature list */
8158 IDX lighting_level = F_LIT_STANDARD;
8159 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8163 case 'a': /* Max stat */
8164 do_cmd_knowledge_stat();
8166 case 'b': /* Mutations */
8167 do_cmd_knowledge_mutations();
8169 case 'c': /* weapon-exp */
8170 do_cmd_knowledge_weapon_exp();
8172 case 'd': /* spell-exp */
8173 do_cmd_knowledge_spell_exp();
8175 case 'e': /* skill-exp */
8176 do_cmd_knowledge_skill_exp();
8178 case 'f': /* Virtues */
8179 do_cmd_knowledge_virtues();
8181 case 'g': /* Dungeon */
8182 do_cmd_knowledge_dungeon();
8184 case 'h': /* Quests */
8185 do_cmd_knowledge_quests();
8187 case 'i': /* Autopick */
8188 do_cmd_knowledge_autopick();
8190 default: /* Unknown option */
8198 if (need_redraw) do_cmd_redraw();
8203 * Check on the status of an active quest
8205 void do_cmd_checkquest(void)
8207 /* File type is "TEXT" */
8208 FILE_TYPE(FILE_TYPE_TEXT);
8212 do_cmd_knowledge_quests();
8218 * Display the time and date
8220 void do_cmd_time(void)
8222 int day, hour, min, full, start, end, num;
8230 extract_day_hour_min(&day, &hour, &min);
8232 full = hour * 100 + min;
8239 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8241 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8242 else strcpy(day_buf, "*****");
8244 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8245 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8248 if (!randint0(10) || p_ptr->image)
8250 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8254 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8257 /* Open this file */
8258 fff = my_fopen(buf, "rt");
8262 /* Find this time */
8263 while (!my_fgets(fff, buf, sizeof(buf)))
8265 /* Ignore comments */
8266 if (!buf[0] || (buf[0] == '#')) continue;
8268 /* Ignore invalid lines */
8269 if (buf[1] != ':') continue;
8271 /* Process 'Start' */
8274 /* Extract the starting time */
8275 start = atoi(buf + 2);
8277 /* Assume valid for an hour */
8287 /* Extract the ending time */
8288 end = atoi(buf + 2);
8294 /* Ignore incorrect range */
8295 if ((start > full) || (full > end)) continue;
8297 /* Process 'Description' */
8302 /* Apply the randomizer */
8303 if (!randint0(num)) strcpy(desc, buf + 2);