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.
54 #include "view/display-player.h"
55 #include "player-effects.h"
56 #include "player-status.h"
57 #include "player-skill.h"
58 #include "player-personality.h"
65 #include "object-flavor.h"
66 #include "object-hook.h"
68 #include "monster-status.h"
69 #include "view-mainwindow.h"
70 #include "dungeon-file.h"
71 #include "io/process-pref-file.h"
74 #include "objectkind.h"
75 #include "floor-town.h"
76 #include "view-mainwindow.h" // 暫定。後で消す
80 // Mark strings for auto dump
81 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
82 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
84 // Variables for auto dump
85 static FILE *auto_dump_stream;
86 static concptr auto_dump_mark;
87 static int auto_dump_line_num;
89 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
90 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
91 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
93 // Clipboard variables for copy&paste in visual mode
94 static TERM_COLOR attr_idx = 0;
95 static SYMBOL_CODE char_idx = 0;
97 /* Hack -- for feature lighting */
98 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
99 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
101 // Encode the screen colors
102 static char hack[17] = "dwsorgbuDWvyRGBU";
108 * @brief prf出力内容を消去する /
109 * Remove old lines automatically generated before.
110 * @param orig_file 消去を行うファイル名
112 static void remove_auto_dump(concptr orig_file)
114 FILE *tmp_fff, *orig_fff;
118 bool between_mark = FALSE;
119 bool changed = FALSE;
121 long header_location = 0;
122 char header_mark_str[80];
123 char footer_mark_str[80];
126 /* Prepare a header/footer mark string */
127 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
128 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
130 mark_len = strlen(footer_mark_str);
132 /* Open an old dump file in read-only mode */
133 orig_fff = my_fopen(orig_file, "r");
135 /* If original file does not exist, nothing to do */
136 if (!orig_fff) return;
138 /* Open a new (temporary) file */
139 tmp_fff = my_fopen_temp(tmp_file, 1024);
143 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
148 /* Loop for every line */
152 if (my_fgets(orig_fff, buf, sizeof(buf)))
154 /* Read error: Assume End of File */
157 * Was looking for the footer, but not found.
159 * Since automatic dump might be edited by hand,
160 * it's dangerous to kill these lines.
161 * Seek back to the next line of the (pseudo) header,
166 fseek(orig_fff, header_location, SEEK_SET);
167 between_mark = FALSE;
171 /* Success -- End the loop */
178 /* We are looking for the header mark of automatic dump */
181 /* Is this line a header? */
182 if (!strcmp(buf, header_mark_str))
184 /* Memorise seek point of this line */
185 header_location = ftell(orig_fff);
187 /* Initialize counter for number of lines */
190 /* Look for the footer from now */
193 /* There are some changes */
200 /* Copy orginally lines */
201 fprintf(tmp_fff, "%s\n", buf);
207 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
208 /* We are looking for the footer mark of automatic dump */
209 /* Is this line a footer? */
210 if (!strncmp(buf, footer_mark_str, mark_len))
215 * Compare the number of lines
217 * If there is an inconsistency between
218 * actual number of lines and the
219 * number here, the automatic dump
220 * might be edited by hand. So it's
221 * dangerous to kill these lines.
222 * Seek back to the next line of the
223 * (pseudo) header, and read again.
225 if (!sscanf(buf + mark_len, " (%d)", &tmp)
228 fseek(orig_fff, header_location, SEEK_SET);
231 /* Look for another header */
232 between_mark = FALSE;
237 /* Ignore old line, and count number of lines */
245 /* If there are some changes, overwrite the original file with new one */
248 /* Copy contents of temporary file */
249 tmp_fff = my_fopen(tmp_file, "r");
250 orig_fff = my_fopen(orig_file, "w");
252 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
253 fprintf(orig_fff, "%s\n", buf);
264 * @brief prfファイルのフォーマットに従った内容を出力する /
265 * Dump a formatted line, using "vstrnfmt()".
268 static void auto_dump_printf(concptr fmt, ...)
275 /* Begin the Varargs Stuff */
278 /* Format the args, save the length */
279 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
281 /* End the Varargs Stuff */
284 /* Count number of lines */
285 for (p = buf; *p; p++)
287 if (*p == '\n') auto_dump_line_num++;
291 fprintf(auto_dump_stream, "%s", buf);
296 * @brief prfファイルをファイルオープンする /
297 * Open file to append auto dump.
299 * @param mark 出力するヘッダマーク
300 * @return ファイルポインタを取得できたらTRUEを返す
302 static bool open_auto_dump(concptr buf, concptr mark)
304 char header_mark_str[80];
306 /* Save the mark string */
307 auto_dump_mark = mark;
309 /* Prepare a header mark string */
310 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
312 /* Remove old macro dumps */
313 remove_auto_dump(buf);
315 /* Append to the file */
316 auto_dump_stream = my_fopen(buf, "a");
319 if (!auto_dump_stream)
321 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
329 fprintf(auto_dump_stream, "%s\n", header_mark_str);
331 /* Initialize counter */
332 auto_dump_line_num = 0;
334 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
335 "# *Warning!* The lines below are an automatic dump.\n"));
336 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
337 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
342 * @brief prfファイルをファイルクローズする /
343 * Append foot part and close auto dump.
346 static void close_auto_dump(void)
348 char footer_mark_str[80];
350 /* Prepare a footer mark string */
351 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
353 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
354 "# *Warning!* The lines below are an automatic dump.\n"));
355 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
356 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
358 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
360 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 exe_write_diary(player_type *creature_ptr, 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_diary = FALSE;
410 extract_day_hour_min(creature_ptr, &day, &hour, &min);
412 if (disable_diary) return(-1);
414 if (type == DIARY_FIX_QUEST_C ||
415 type == DIARY_FIX_QUEST_F ||
416 type == DIARY_RAND_QUEST_C ||
417 type == DIARY_RAND_QUEST_F ||
418 type == DIARY_TO_QUEST)
422 old_quest = creature_ptr->current_floor_ptr->inside_quest;
423 creature_ptr->current_floor_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(creature_ptr, "q_info.txt", 0, 0, 0, 0);
430 /* Reset the old quest number */
431 creature_ptr->current_floor_ptr->inside_quest = old_quest;
434 /* different filne name to avoid mixing */
435 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
436 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
438 /* File type is "TEXT" */
439 FILE_TYPE(FILE_TYPE_TEXT);
441 fff = my_fopen(buf, "a");
446 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
448 disable_diary = TRUE;
452 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
456 if (creature_ptr->current_floor_ptr->inside_arena)
457 note_level = _("アリーナ:", "Arane:");
458 else if (!creature_ptr->current_floor_ptr->dun_level)
459 note_level = _("地上:", "Surface:");
460 else if (q_idx && (is_fixed_quest_idx(q_idx)
461 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
462 note_level = _("クエスト:", "Quest:");
466 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
468 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
470 note_level = note_level_buf;
478 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
479 else fputs(_("*****日目\n", "Day *****\n"), fff);
483 case DIARY_DESCRIPTION:
487 fprintf(fff, "%s\n", note);
491 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
496 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
499 case DIARY_ART_SCROLL:
501 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
506 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
509 case DIARY_FIX_QUEST_C:
511 if (quest[num].flags & QUEST_FLAG_SILENT) break;
512 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
513 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
516 case DIARY_FIX_QUEST_F:
518 if (quest[num].flags & QUEST_FLAG_SILENT) break;
519 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
520 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
523 case DIARY_RAND_QUEST_C:
525 GAME_TEXT name[MAX_NLEN];
526 strcpy(name, r_name + r_info[quest[num].r_idx].name);
527 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
528 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
531 case DIARY_RAND_QUEST_F:
533 GAME_TEXT name[MAX_NLEN];
534 strcpy(name, r_name + r_info[quest[num].r_idx].name);
535 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
536 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
539 case DIARY_MAXDEAPTH:
541 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
542 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
543 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
544 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
549 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
550 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
551 _(d_name + d_info[num].name, (int)max_dlv[num]),
552 _((int)max_dlv[num], d_name + d_info[num].name));
558 if (q_idx && (is_fixed_quest_idx(q_idx)
559 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
561 to = _("地上", "the surface");
565 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
566 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
568 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
574 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
575 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
576 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
578 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
583 if (quest[num].flags & QUEST_FLAG_SILENT) break;
584 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
585 hour, min, note_level, quest[num].name);
588 case DIARY_TELEPORT_LEVEL:
590 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
591 hour, min, note_level);
596 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
601 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
609 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
610 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
613 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
614 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
616 if (num == MAX_ARENA_MONS)
618 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
619 " won all fights to become a Champion.\n"));
626 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
632 if (!creature_ptr->current_floor_ptr->dun_level)
633 to = _("地上", "the surface");
635 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
637 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
638 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
644 if (!creature_ptr->current_floor_ptr->dun_level)
645 to = _("地上", "the surface");
647 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
649 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
650 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
655 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
658 case DIARY_GAMESTART:
660 time_t ct = time((time_t*)0);
664 fprintf(fff, "%s %s", note, ctime(&ct));
667 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
670 case DIARY_NAMED_PET:
672 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
675 case RECORD_NAMED_PET_NAME:
676 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
678 case RECORD_NAMED_PET_UNNAME:
679 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
681 case RECORD_NAMED_PET_DISMISS:
682 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
684 case RECORD_NAMED_PET_DEATH:
685 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
687 case RECORD_NAMED_PET_MOVED:
688 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
690 case RECORD_NAMED_PET_LOST_SIGHT:
691 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
693 case RECORD_NAMED_PET_DESTROY:
694 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
696 case RECORD_NAMED_PET_EARTHQUAKE:
697 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
699 case RECORD_NAMED_PET_GENOCIDE:
700 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
702 case RECORD_NAMED_PET_WIZ_ZAP:
703 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
705 case RECORD_NAMED_PET_TELE_LEVEL:
706 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
708 case RECORD_NAMED_PET_BLAST:
709 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
711 case RECORD_NAMED_PET_HEAL_LEPER:
712 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
714 case RECORD_NAMED_PET_COMPACT:
715 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
717 case RECORD_NAMED_PET_LOSE_PARENT:
718 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
728 case DIARY_WIZARD_LOG:
729 fprintf(fff, "%s\n", note);
738 if (do_level) write_level = FALSE;
744 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
747 * @brief 日記のタイトル表記と内容出力 /
750 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
752 static void display_diary(player_type *creature_ptr)
754 char diary_title[256];
755 GAME_TEXT file_name[MAX_NLEN];
759 static const char subtitle[][30] = {
792 static const char subtitle[][51] = {
793 "Quest of The World's Toughest Body",
794 "Attack is the best form of defence.",
796 "An unexpected windfall",
797 "A drowning man will catch at a straw",
798 "Don't count your chickens before they are hatched.",
799 "It is no use crying over spilt milk.",
800 "Seeing is believing.",
801 "Strike the iron while it is hot.",
802 "I don't care what follows.",
803 "To dig a well to put out a house on fire.",
804 "Tomorrow is another day.",
805 "Easy come, easy go.",
806 "The more haste, the less speed.",
807 "Where there is life, there is hope.",
808 "There is no royal road to *WINNER*.",
809 "Danger past, God forgotten.",
810 "The best thing to do now is to run away.",
811 "Life is but an empty dream.",
812 "Dead men tell no tales.",
813 "A book that remains shut is but a block.",
814 "Misfortunes never come singly.",
815 "A little knowledge is a dangerous thing.",
816 "History repeats itself.",
817 "*WINNER* was not built in a day.",
818 "Ignorance is bliss.",
819 "To lose is to win?",
820 "No medicine can cure folly.",
821 "All good things come to an end.",
822 "M$ Empire strikes back.",
823 "To see is to believe",
825 "Quest of The World's Greatest Brain"
828 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
829 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
831 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
832 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
833 else if (IS_WIZARD_CLASS(creature_ptr))
834 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
835 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
838 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
840 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
843 /* Display the file contents */
844 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
849 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
852 static void add_diary_note(player_type *creature_ptr)
855 char bunshou[80] = "\0";
857 if (get_string(_("内容: ", "diary note: "), tmp, 79))
859 strcpy(bunshou, tmp);
860 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
865 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
868 static void do_cmd_last_get(player_type *creaute_ptr)
870 if (record_o_name[0] == '\0') return;
873 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
874 if (!get_check(buf)) return;
876 GAME_TURN turn_tmp = current_world_ptr->game_turn;
877 current_world_ptr->game_turn = record_turn;
878 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
879 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
880 current_world_ptr->game_turn = turn_tmp;
885 * @brief ファイル中の全日記記録を消去する /
888 static void do_cmd_erase_diary(void)
890 GAME_TEXT file_name[MAX_NLEN];
894 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
895 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
896 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
899 fff = my_fopen(buf, "w");
903 msg_format(_("記録を消去しました。", "deleted record."));
907 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
916 * @param crerature_ptr プレーヤーへの参照ポインタ
919 void do_cmd_diary(player_type *creature_ptr)
921 /* File type is "TEXT" */
922 FILE_TYPE(FILE_TYPE_TEXT);
925 /* 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 the last item you got or identified"), 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;
953 display_diary(creature_ptr);
956 add_diary_note(creature_ptr);
959 do_cmd_last_get(creature_ptr);
962 do_cmd_erase_diary();
966 prepare_movie_hooks();
968 default: /* Unknown option */
980 * @brief 画面を再描画するコマンドのメインルーチン
981 * Hack -- redraw the screen
982 * @param creature_ptr プレーヤーへの参照ポインタ
986 * This command performs various low level updates, clears all the "extra"
987 * windows, does a total redraw of the main window, and requests all of the
988 * interesting updates and redraws that I can think of.
990 * This command is also used to "instantiate" the results of the user
991 * selecting various things, such as graphics mode, so it must call
992 * the "TERM_XTRA_REACT" hook before redrawing the windows.
995 void do_cmd_redraw(player_type *creature_ptr)
997 Term_xtra(TERM_XTRA_REACT, 0);
999 /* Combine and Reorder the pack (later) */
1000 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1001 creature_ptr->update |= (PU_TORCH);
1002 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1003 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1004 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1005 creature_ptr->update |= (PU_MONSTERS);
1007 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1009 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1010 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1013 handle_stuff(creature_ptr);
1015 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1017 /* Redraw every window */
1019 for (int j = 0; j < 8; j++)
1022 if (!angband_term[j]) continue;
1025 Term_activate(angband_term[j]);
1034 * @brief プレイヤーのステータス表示
1037 void do_cmd_player_status(player_type *creature_ptr)
1048 display_player(creature_ptr, mode, map_name);
1053 display_player(creature_ptr, mode, map_name);
1057 Term_putstr(2, 23, -1, TERM_WHITE,
1058 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1062 if (c == ESCAPE) break;
1067 get_name(creature_ptr);
1069 /* Process the player name */
1070 process_player_name(creature_ptr, FALSE);
1076 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1077 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1079 if (tmp[0] && (tmp[0] != ' '))
1081 file_character(creature_ptr, tmp, display_player, map_name);
1099 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1101 handle_stuff(creature_ptr);
1106 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1107 * Recall the most recent message
1110 void do_cmd_message_one(void)
1112 /* Recall one message */
1113 prt(format("> %s", message_str(0)), 0, 0);
1118 * @brief メッセージのログを表示するコマンドのメインルーチン
1119 * Recall the most recent message
1123 * Show previous messages to the user -BEN-
1125 * The screen format uses line 0 and 23 for headers and prompts,
1126 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1128 * This command shows you which commands you are viewing, and allows
1129 * you to "search" for strings in the recall.
1131 * Note that messages may be longer than 80 characters, but they are
1132 * displayed using "infinite" length, with a special sub-command to
1133 * "slide" the virtual display to the left or right.
1135 * Attempt to only hilite the matching portions of the string.
1138 void do_cmd_messages(int num_now)
1140 char shower_str[81];
1141 char finder_str[81];
1143 concptr shower = NULL;
1147 Term_get_size(&wid, &hgt);
1149 /* Number of message lines in a screen */
1150 num_lines = hgt - 4;
1153 strcpy(finder_str, "");
1156 strcpy(shower_str, "");
1158 /* Total messages */
1159 int n = message_num();
1161 /* Start on first message */
1166 /* Process requests until done */
1172 /* Dump up to 20 lines of messages */
1173 for (j = 0; (j < num_lines) && (i + j < n); j++)
1175 concptr msg = message_str(i + j);
1177 /* Dump the messages, bottom to top */
1178 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1180 if (!shower || !shower[0]) continue;
1182 /* Hilite "shower" */
1185 /* Display matches */
1186 while ((str = my_strstr(str, shower)) != NULL)
1188 int len = strlen(shower);
1190 /* Display the match */
1191 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1198 /* Erase remaining lines */
1199 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1201 /* Display header */
1203 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1204 i, i + j - 1, n), 0, 0);
1206 /* Display prompt (not very informative) */
1207 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1208 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1210 skey = inkey_special(TRUE);
1212 /* Exit on Escape */
1213 if (skey == ESCAPE) break;
1215 /* Hack -- Save the old index */
1220 /* Hack -- handle show */
1223 prt(_("強調: ", "Show: "), hgt - 1, 0);
1225 /* Get a "shower" string, or continue */
1226 strcpy(back_str, shower_str);
1227 if (askfor(shower_str, 80))
1230 shower = shower_str[0] ? shower_str : NULL;
1232 else strcpy(shower_str, back_str);
1236 /* Hack -- handle find */
1243 prt(_("検索: ", "Find: "), hgt - 1, 0);
1245 /* Get a "finder" string, or continue */
1246 strcpy(back_str, finder_str);
1247 if (!askfor(finder_str, 80))
1249 strcpy(finder_str, back_str);
1252 else if (!finder_str[0])
1254 shower = NULL; /* Stop showing */
1259 shower = finder_str;
1262 for (z = i + 1; z < n; z++)
1264 concptr msg = message_str(z);
1267 if (my_strstr(msg, finder_str))
1278 /* Recall 1 older message */
1280 /* Go to the oldest line */
1284 /* Recall 1 newer message */
1286 /* Go to the newest line */
1290 /* Recall 1 older message */
1295 /* Go older if legal */
1296 i = MIN(i + 1, n - num_lines);
1299 /* Recall 10 older messages */
1301 /* Go older if legal */
1302 i = MIN(i + 10, n - num_lines);
1305 /* Recall 20 older messages */
1310 /* Go older if legal */
1311 i = MIN(i + num_lines, n - num_lines);
1314 /* Recall 20 newer messages */
1318 /* Go newer (if able) */
1319 i = MAX(0, i - num_lines);
1322 /* Recall 10 newer messages */
1324 /* Go newer (if able) */
1328 /* Recall 1 newer messages */
1331 /* Go newer (if able) */
1336 /* Hack -- Error of some kind */
1345 * @brief prefファイルを選択して処理する /
1346 * Ask for a "user pref line" and process it
1347 * @param creature_ptr プレーヤーへの参照ポインタ
1350 * Allow absolute file names?
1352 void do_cmd_pref(player_type *creature_ptr)
1357 /* Ask for a "user pref command" */
1358 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1360 /* Process that pref command */
1361 (void)process_pref_file_command(creature_ptr, buf);
1366 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1367 * @param creature_ptr プレーヤーへの参照ポインタ
1370 void do_cmd_reload_autopick(player_type *creature_ptr)
1372 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1373 /* Load the file with messages */
1374 autopick_load_pref(creature_ptr, TRUE);
1379 * @brief マクロ情報をprefファイルに保存する /
1380 * @param fname ファイル名
1383 static errr macro_dump(concptr fname)
1385 static concptr mark = "Macro Dump";
1387 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1389 /* File type is "TEXT" */
1390 FILE_TYPE(FILE_TYPE_TEXT);
1392 /* Append to the file */
1393 if (!open_auto_dump(buf, mark)) return -1;
1396 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1399 for (int i = 0; i < macro__num; i++)
1401 /* Extract the action */
1402 ascii_to_text(buf, macro__act[i]);
1404 /* Dump the macro */
1405 auto_dump_printf("A:%s\n", buf);
1407 /* Extract the action */
1408 ascii_to_text(buf, macro__pat[i]);
1410 /* Dump normal macros */
1411 auto_dump_printf("P:%s\n", buf);
1414 auto_dump_printf("\n");
1423 * @brief マクロのトリガーキーを取得する /
1424 * Hack -- ask for a "trigger" (see below)
1425 * @param buf キー表記を保管するバッファ
1429 * Note the complex use of the "inkey()" function from "util.c".
1431 * Note that both "flush()" calls are extremely important.
1434 static void do_cmd_macro_aux(char *buf)
1438 /* Do not process macros */
1444 /* Read the pattern */
1451 /* Do not process macros */
1454 /* Do not wait for keys */
1457 /* Attempt to read a key */
1466 /* Convert the trigger */
1468 ascii_to_text(tmp, buf);
1470 /* Hack -- display the trigger */
1471 Term_addstr(-1, TERM_WHITE, tmp);
1476 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1477 * Hack -- ask for a keymap "trigger" (see below)
1478 * @param buf キー表記を取得するバッファ
1482 * Note that both "flush()" calls are extremely important. This may
1483 * no longer be true, since "util.c" is much simpler now.
1486 static void do_cmd_macro_aux_keymap(char *buf)
1496 /* Convert to ascii */
1497 ascii_to_text(tmp, buf);
1499 /* Hack -- display the trigger */
1500 Term_addstr(-1, TERM_WHITE, tmp);
1507 * @brief キーマップをprefファイルにダンプする /
1508 * Hack -- append all keymaps to the given file
1509 * @param fname ファイルネーム
1513 static errr keymap_dump(concptr fname)
1515 static concptr mark = "Keymap Dump";
1522 if (rogue_like_commands)
1524 mode = KEYMAP_MODE_ROGUE;
1530 mode = KEYMAP_MODE_ORIG;
1533 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1535 /* File type is "TEXT" */
1536 FILE_TYPE(FILE_TYPE_TEXT);
1538 /* Append to the file */
1539 if (!open_auto_dump(buf, mark)) return -1;
1542 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1545 for (int i = 0; i < 256; i++)
1549 /* Loop up the keymap */
1550 act = keymap_act[mode][i];
1552 /* Skip empty keymaps */
1555 /* Encode the key */
1558 ascii_to_text(key, buf);
1560 /* Encode the action */
1561 ascii_to_text(buf, act);
1563 /* Dump the macro */
1564 auto_dump_printf("A:%s\n", buf);
1565 auto_dump_printf("C:%d:%s\n", mode, key);
1574 * @brief マクロを設定するコマンドのメインルーチン /
1575 * Interact with "macros"
1579 * Note that the macro "action" must be defined before the trigger.
1581 * Could use some helpful instructions on this page.
1584 void do_cmd_macros(player_type *creature_ptr)
1592 if (rogue_like_commands)
1594 mode = KEYMAP_MODE_ROGUE;
1600 mode = KEYMAP_MODE_ORIG;
1603 /* File type is "TEXT" */
1604 FILE_TYPE(FILE_TYPE_TEXT);
1608 /* Process requests until done */
1612 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1614 /* Describe that action */
1615 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1617 /* Analyze the current action */
1618 ascii_to_text(buf, macro__buf);
1620 /* Display the current action */
1625 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1626 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1627 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1628 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1629 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1630 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1631 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1632 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1633 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1634 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1637 prt(_("コマンド: ", "Command: "), 16, 0);
1642 if (i == ESCAPE) break;
1644 /* Load a 'macro' file */
1650 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1653 prt(_("ファイル: ", "File: "), 18, 0);
1655 /* Default filename */
1656 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1658 /* Ask for a file */
1659 if (!askfor(tmp, 80)) continue;
1661 /* Process the given filename */
1662 err = process_pref_file(creature_ptr, tmp);
1665 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1670 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1674 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1682 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1685 prt(_("ファイル: ", "File: "), 18, 0);
1687 /* Default filename */
1688 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1690 /* Ask for a file */
1691 if (!askfor(tmp, 80)) continue;
1693 /* Dump the macros */
1694 (void)macro_dump(tmp);
1697 msg_print(_("マクロを追加しました。", "Appended macros."));
1706 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1710 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1712 /* Get a macro trigger */
1713 do_cmd_macro_aux(buf);
1715 /* Acquire action */
1716 k = macro_find_exact(buf);
1722 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1728 /* Obtain the action */
1729 strcpy(macro__buf, macro__act[k]);
1731 /* Analyze the current action */
1732 ascii_to_text(buf, macro__buf);
1734 /* Display the current action */
1738 msg_print(_("マクロを確認しました。", "Found a macro."));
1742 /* Create a macro */
1746 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1749 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1751 /* Get a macro trigger */
1752 do_cmd_macro_aux(buf);
1756 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1757 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1760 prt(_("マクロ行動: ", "Action: "), 20, 0);
1762 /* Convert to text */
1763 ascii_to_text(tmp, macro__buf);
1765 /* Get an encoded action */
1766 if (askfor(tmp, 80))
1768 /* Convert to ascii */
1769 text_to_ascii(macro__buf, tmp);
1771 /* Link the macro */
1772 macro_add(buf, macro__buf);
1775 msg_print(_("マクロを追加しました。", "Added a macro."));
1779 /* Remove a macro */
1783 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1786 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1788 /* Get a macro trigger */
1789 do_cmd_macro_aux(buf);
1791 /* Link the macro */
1792 macro_add(buf, buf);
1795 msg_print(_("マクロを削除しました。", "Removed a macro."));
1802 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1805 prt(_("ファイル: ", "File: "), 18, 0);
1807 /* Default filename */
1808 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1810 /* Ask for a file */
1811 if (!askfor(tmp, 80)) continue;
1813 /* Dump the macros */
1814 (void)keymap_dump(tmp);
1817 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1820 /* Query a keymap */
1826 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1829 prt(_("押すキー: ", "Keypress: "), 18, 0);
1831 /* Get a keymap trigger */
1832 do_cmd_macro_aux_keymap(buf);
1834 /* Look up the keymap */
1835 act = keymap_act[mode][(byte)(buf[0])];
1841 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1847 /* Obtain the action */
1848 strcpy(macro__buf, act);
1850 /* Analyze the current action */
1851 ascii_to_text(buf, macro__buf);
1853 /* Display the current action */
1857 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1861 /* Create a keymap */
1865 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1868 prt(_("押すキー: ", "Keypress: "), 18, 0);
1870 /* Get a keymap trigger */
1871 do_cmd_macro_aux_keymap(buf);
1875 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1876 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1879 prt(_("行動: ", "Action: "), 20, 0);
1881 /* Convert to text */
1882 ascii_to_text(tmp, macro__buf);
1884 /* Get an encoded action */
1885 if (askfor(tmp, 80))
1887 /* Convert to ascii */
1888 text_to_ascii(macro__buf, tmp);
1890 /* Free old keymap */
1891 string_free(keymap_act[mode][(byte)(buf[0])]);
1893 /* Make new keymap */
1894 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1897 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1901 /* Remove a keymap */
1905 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1908 prt(_("押すキー: ", "Keypress: "), 18, 0);
1910 /* Get a keymap trigger */
1911 do_cmd_macro_aux_keymap(buf);
1913 /* Free old keymap */
1914 string_free(keymap_act[mode][(byte)(buf[0])]);
1916 /* Make new keymap */
1917 keymap_act[mode][(byte)(buf[0])] = NULL;
1920 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1923 /* Enter a new action */
1927 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1931 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1932 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1935 prt(_("マクロ行動: ", "Action: "), 20, 0);
1937 /* Hack -- limit the value */
1940 /* Get an encoded action */
1941 if (!askfor(buf, 80)) continue;
1943 /* Extract an action */
1944 text_to_ascii(macro__buf, buf);
1960 * @brief キャラクタ色の明暗表現
1962 static concptr lighting_level_str[F_LIT_MAX] =
1977 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1978 * @param i 指定対象となるキャラクタコード
1979 * @param num 指定されたビジュアルIDを返す参照ポインタ
1980 * @param max ビジュアルIDの最大数
1981 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1983 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1990 sprintf(str, "%d", *num);
1992 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1995 tmp = (IDX)strtol(str, NULL, 0);
1996 if (tmp >= 0 && tmp < max)
1999 else if (isupper(i))
2000 *num = (*num + max - 1) % max;
2002 *num = (*num + 1) % max;
2008 * @brief キャラクタの変更メニュー表示
2009 * @param choice_msg 選択メッセージ
2012 static void print_visuals_menu(concptr choice_msg)
2014 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2016 /* Give some choices */
2017 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2018 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2019 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2020 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2021 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2022 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2023 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2024 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2025 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2026 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2027 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2030 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2035 * Interact with "visuals"
2037 void do_cmd_visuals(player_type *creature_ptr)
2042 bool need_redraw = FALSE;
2043 concptr empty_symbol = "<< ? >>";
2045 if (use_bigtile) empty_symbol = "<< ?? >>";
2047 /* File type is "TEXT" */
2048 FILE_TYPE(FILE_TYPE_TEXT);
2051 /* Interact until done */
2056 /* Ask for a choice */
2057 print_visuals_menu(NULL);
2062 if (i == ESCAPE) break;
2066 /* Load a 'pref' file */
2069 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2072 prt(_("ファイル: ", "File: "), 17, 0);
2074 /* Default filename */
2075 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2078 if (!askfor(tmp, 70)) continue;
2080 /* Process the given filename */
2081 (void)process_pref_file(creature_ptr, tmp);
2086 /* Dump monster attr/chars */
2089 static concptr mark = "Monster attr/chars";
2092 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2095 prt(_("ファイル: ", "File: "), 17, 0);
2097 /* Default filename */
2098 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2100 /* Get a filename */
2101 if (!askfor(tmp, 70)) continue;
2102 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2104 /* Append to the file */
2105 if (!open_auto_dump(buf, mark)) continue;
2108 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2111 for (i = 0; i < max_r_idx; i++)
2113 monster_race *r_ptr = &r_info[i];
2115 /* Skip non-entries */
2116 if (!r_ptr->name) continue;
2118 /* Dump a comment */
2119 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2121 /* Dump the monster attr/char info */
2122 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2123 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2129 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2134 /* Dump object attr/chars */
2137 static concptr mark = "Object attr/chars";
2138 KIND_OBJECT_IDX k_idx;
2141 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2144 prt(_("ファイル: ", "File: "), 17, 0);
2146 /* Default filename */
2147 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2149 /* Get a filename */
2150 if (!askfor(tmp, 70)) continue;
2151 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2153 /* Append to the file */
2154 if (!open_auto_dump(buf, mark)) continue;
2157 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2160 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2162 GAME_TEXT o_name[MAX_NLEN];
2163 object_kind *k_ptr = &k_info[k_idx];
2165 /* Skip non-entries */
2166 if (!k_ptr->name) continue;
2171 strip_name(o_name, k_idx);
2177 /* Prepare dummy object */
2178 object_prep(&forge, k_idx);
2180 /* Get un-shuffled flavor name */
2181 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2184 /* Dump a comment */
2185 auto_dump_printf("# %s\n", o_name);
2187 /* Dump the object attr/char info */
2188 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2189 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2195 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2200 /* Dump feature attr/chars */
2203 static concptr mark = "Feature attr/chars";
2206 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2209 prt(_("ファイル: ", "File: "), 17, 0);
2211 /* Default filename */
2212 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2214 /* Get a filename */
2215 if (!askfor(tmp, 70)) continue;
2216 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2218 /* Append to the file */
2219 if (!open_auto_dump(buf, mark)) continue;
2222 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2225 for (i = 0; i < max_f_idx; i++)
2227 feature_type *f_ptr = &f_info[i];
2229 /* Skip non-entries */
2230 if (!f_ptr->name) continue;
2232 /* Skip mimiccing features */
2233 if (f_ptr->mimic != i) continue;
2235 /* Dump a comment */
2236 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2238 /* Dump the feature attr/char info */
2239 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2240 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2241 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2242 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2248 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2253 /* Modify monster attr/chars (numeric operation) */
2256 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2257 static MONRACE_IDX r = 0;
2259 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2261 /* Hack -- query until done */
2264 monster_race *r_ptr = &r_info[r];
2268 TERM_COLOR da = r_ptr->d_attr;
2269 byte dc = r_ptr->d_char;
2270 TERM_COLOR ca = r_ptr->x_attr;
2271 byte cc = r_ptr->x_char;
2273 /* Label the object */
2274 Term_putstr(5, 17, -1, TERM_WHITE,
2275 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2277 /* Label the Default values */
2278 Term_putstr(10, 19, -1, TERM_WHITE,
2279 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2281 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2282 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2284 /* Label the Current values */
2285 Term_putstr(10, 20, -1, TERM_WHITE,
2286 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2288 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2289 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2292 Term_putstr(0, 22, -1, TERM_WHITE,
2293 _("コマンド (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): "));
2298 if (i == ESCAPE) break;
2300 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2301 else if (isupper(i)) c = 'a' + i - 'A';
2311 if (!cmd_visuals_aux(i, &r, max_r_idx))
2316 } while (!r_info[r].name);
2320 t = (int)r_ptr->x_attr;
2321 (void)cmd_visuals_aux(i, &t, 256);
2322 r_ptr->x_attr = (byte)t;
2326 t = (int)r_ptr->x_char;
2327 (void)cmd_visuals_aux(i, &t, 256);
2328 r_ptr->x_char = (byte)t;
2332 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2334 print_visuals_menu(choice_msg);
2342 /* Modify object attr/chars (numeric operation) */
2345 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2347 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2349 /* Hack -- query until done */
2352 object_kind *k_ptr = &k_info[k];
2356 TERM_COLOR da = k_ptr->d_attr;
2357 SYMBOL_CODE dc = k_ptr->d_char;
2358 TERM_COLOR ca = k_ptr->x_attr;
2359 SYMBOL_CODE cc = k_ptr->x_char;
2361 /* Label the object */
2362 Term_putstr(5, 17, -1, TERM_WHITE,
2363 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2364 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2366 /* Label the Default values */
2367 Term_putstr(10, 19, -1, TERM_WHITE,
2368 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2370 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2371 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2373 /* Label the Current values */
2374 Term_putstr(10, 20, -1, TERM_WHITE,
2375 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2377 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2378 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2381 Term_putstr(0, 22, -1, TERM_WHITE,
2382 _("コマンド (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): "));
2387 if (i == ESCAPE) break;
2389 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2390 else if (isupper(i)) c = 'a' + i - 'A';
2400 if (!cmd_visuals_aux(i, &k, max_k_idx))
2405 } while (!k_info[k].name);
2409 t = (int)k_ptr->x_attr;
2410 (void)cmd_visuals_aux(i, &t, 256);
2411 k_ptr->x_attr = (byte)t;
2415 t = (int)k_ptr->x_char;
2416 (void)cmd_visuals_aux(i, &t, 256);
2417 k_ptr->x_char = (byte)t;
2421 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2423 print_visuals_menu(choice_msg);
2431 /* Modify feature attr/chars (numeric operation) */
2434 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2436 static IDX lighting_level = F_LIT_STANDARD;
2437 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2439 /* Hack -- query until done */
2442 feature_type *f_ptr = &f_info[f];
2446 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2447 byte dc = f_ptr->d_char[lighting_level];
2448 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2449 byte cc = f_ptr->x_char[lighting_level];
2451 /* Label the object */
2453 Term_putstr(5, 17, -1, TERM_WHITE,
2454 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2455 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2457 /* Label the Default values */
2458 Term_putstr(10, 19, -1, TERM_WHITE,
2459 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2461 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2462 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2464 /* Label the Current values */
2466 Term_putstr(10, 20, -1, TERM_WHITE,
2467 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2469 Term_putstr(10, 20, -1, TERM_WHITE,
2470 format("Current attr/char = %3d / %3d", ca, cc));
2473 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2474 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2478 Term_putstr(0, 22, -1, TERM_WHITE,
2479 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2481 Term_putstr(0, 22, -1, TERM_WHITE,
2482 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2488 if (i == ESCAPE) break;
2490 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2491 else if (isupper(i)) c = 'a' + i - 'A';
2501 if (!cmd_visuals_aux(i, &f, max_f_idx))
2506 } while (!f_info[f].name || (f_info[f].mimic != f));
2510 t = (int)f_ptr->x_attr[lighting_level];
2511 (void)cmd_visuals_aux(i, &t, 256);
2512 f_ptr->x_attr[lighting_level] = (byte)t;
2516 t = (int)f_ptr->x_char[lighting_level];
2517 (void)cmd_visuals_aux(i, &t, 256);
2518 f_ptr->x_char[lighting_level] = (byte)t;
2522 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2525 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2529 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2531 print_visuals_menu(choice_msg);
2539 /* Modify monster attr/chars (visual mode) */
2541 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2544 /* Modify object attr/chars (visual mode) */
2546 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2549 /* Modify feature attr/chars (visual mode) */
2552 IDX lighting_level = F_LIT_STANDARD;
2553 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2561 reset_visuals(creature_ptr);
2563 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2567 /* Unknown option */
2578 if (need_redraw) do_cmd_redraw(creature_ptr);
2583 * Interact with "colors"
2585 void do_cmd_colors(player_type *creature_ptr)
2591 /* File type is "TEXT" */
2592 FILE_TYPE(FILE_TYPE_TEXT);
2596 /* Interact until done */
2601 /* Ask for a choice */
2602 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2604 /* Give some choices */
2605 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2606 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2607 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2610 prt(_("コマンド: ", "Command: "), 8, 0);
2614 if (i == ESCAPE) break;
2616 /* Load a 'pref' file */
2620 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2623 prt(_("ファイル: ", "File: "), 10, 0);
2626 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2629 if (!askfor(tmp, 70)) continue;
2631 /* Process the given filename */
2632 (void)process_pref_file(creature_ptr, tmp);
2634 /* Mega-Hack -- react to changes */
2635 Term_xtra(TERM_XTRA_REACT, 0);
2637 /* Mega-Hack -- redraw */
2644 static concptr mark = "Colors";
2647 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2650 prt(_("ファイル: ", "File: "), 10, 0);
2652 /* Default filename */
2653 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2655 /* Get a filename */
2656 if (!askfor(tmp, 70)) continue;
2657 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2659 /* Append to the file */
2660 if (!open_auto_dump(buf, mark)) continue;
2663 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2666 for (i = 0; i < 256; i++)
2668 int kv = angband_color_table[i][0];
2669 int rv = angband_color_table[i][1];
2670 int gv = angband_color_table[i][2];
2671 int bv = angband_color_table[i][3];
2673 concptr name = _("未知", "unknown");
2675 /* Skip non-entries */
2676 if (!kv && !rv && !gv && !bv) continue;
2678 /* Extract the color name */
2679 if (i < 16) name = color_names[i];
2681 /* Dump a comment */
2682 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2684 /* Dump the monster attr/char info */
2685 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2692 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2701 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2703 /* Hack -- query until done */
2710 /* Exhibit the normal colors */
2711 for (j = 0; j < 16; j++)
2713 /* Exhibit this color */
2714 Term_putstr(j * 4, 20, -1, a, "###");
2716 /* Exhibit all colors */
2717 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2720 /* Describe the color */
2721 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2723 /* Describe the color */
2724 Term_putstr(5, 10, -1, TERM_WHITE,
2725 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2727 /* Label the Current values */
2728 Term_putstr(5, 12, -1, TERM_WHITE,
2729 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2730 angband_color_table[a][0],
2731 angband_color_table[a][1],
2732 angband_color_table[a][2],
2733 angband_color_table[a][3]));
2736 Term_putstr(0, 14, -1, TERM_WHITE,
2737 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2742 if (i == ESCAPE) break;
2745 if (i == 'n') a = (byte)(a + 1);
2746 if (i == 'N') a = (byte)(a - 1);
2747 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2748 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2749 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2750 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2751 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2752 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2753 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2754 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2756 /* Hack -- react to changes */
2757 Term_xtra(TERM_XTRA_REACT, 0);
2759 /* Hack -- redraw */
2764 /* Unknown option */
2778 * Note something in the message recall
2780 void do_cmd_note(void)
2788 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2790 /* Ignore empty notes */
2791 if (!buf[0] || (buf[0] == ' ')) return;
2793 /* Add the note to the message recall */
2794 msg_format(_("メモ: %s", "Note: %s"), buf);
2799 * Mention the current version
2801 void do_cmd_version(void)
2803 #if FAKE_VER_EXTRA > 0
2804 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2805 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2807 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2808 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2814 * Array of feeling strings
2816 static concptr do_cmd_feeling_text[11] =
2818 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2819 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2820 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2821 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2822 _("とても悪い予感がする...", "You have a very bad feeling..."),
2823 _("悪い予感がする...", "You have a bad feeling..."),
2824 _("何か緊張する。", "You feel nervous."),
2825 _("少し不運な気がする...", "You feel your luck is turning..."),
2826 _("この場所は好きになれない。", "You don't like the look of this place."),
2827 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2828 _("なんて退屈なところだ...", "What a boring place...")
2831 static concptr do_cmd_feeling_text_combat[11] =
2833 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2834 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2835 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2836 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2837 _("とても悪い予感がする...", "You have a very bad feeling..."),
2838 _("悪い予感がする...", "You have a bad feeling..."),
2839 _("何か緊張する。", "You feel nervous."),
2840 _("少し不運な気がする...", "You feel your luck is turning..."),
2841 _("この場所は好きになれない。", "You don't like the look of this place."),
2842 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2843 _("なんて退屈なところだ...", "What a boring place...")
2846 static concptr do_cmd_feeling_text_lucky[11] =
2848 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2849 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2850 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2851 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2852 _("とても良い感じがする...", "You have a very good feeling..."),
2853 _("良い感じがする...", "You have a good feeling..."),
2854 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2855 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2856 _("見た感じ悪くはない...", "You like the look of this place..."),
2857 _("全然駄目ということはないが...", "This level can't be all bad..."),
2858 _("なんて退屈なところだ...", "What a boring place...")
2863 * Note that "feeling" is set to zero unless some time has passed.
2864 * Note that this is done when the level is GENERATED, not entered.
2866 void do_cmd_feeling(player_type *creature_ptr)
2868 if (creature_ptr->wild_mode) return;
2870 /* No useful feeling in quests */
2871 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2873 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2877 /* No useful feeling in town */
2878 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2880 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2882 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2886 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2890 /* No useful feeling in the wilderness */
2891 if (!creature_ptr->current_floor_ptr->dun_level)
2893 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2897 /* Display the feeling */
2898 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2899 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2900 else if (IS_ECHIZEN(creature_ptr))
2901 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2903 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2908 * Description of each monster group.
2910 static concptr monster_group_text[] =
2913 "ユニーク", /* "Uniques" */
2914 "乗馬可能なモンスター", /* "Riding" */
2915 "賞金首", /* "Wanted */
2916 "アンバーの王族", /* "Amberite" */
2945 /* "古代ドラゴン/ワイアーム", */
3006 /* "Ancient Dragon/Wyrm", */
3015 "Multi-Headed Reptile",
3020 "Reptile/Amphibian",
3021 "Spider/Scorpion/Tick",
3023 /* "Major Demon", */
3040 * Symbols of monsters in each group. Note the "Uniques" group
3041 * is handled differently.
3043 static concptr monster_group_char[] =
3100 "!$&()+./=>?[\\]`{|~",
3110 * todo 引数と戻り値について追記求む
3111 * Build a list of monster indexes in the given group.
3113 * mode & 0x01 : check for non-empty group
3114 * mode & 0x02 : visual operation only
3116 * @param creature_ptr プレーヤーへの参照ポインタ
3117 * @param grp_cur ???
3118 * @param mon_idx[] ???
3120 * @return The number of monsters in the group
3122 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3124 /* Get a list of x_char in this group */
3125 concptr group_char = monster_group_char[grp_cur];
3127 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3128 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3129 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3130 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3132 /* Check every race */
3134 for (IDX i = 0; i < max_r_idx; i++)
3136 /* Access the race */
3137 monster_race *r_ptr = &r_info[i];
3139 /* Skip empty race */
3140 if (!r_ptr->name) continue;
3142 /* Require known monsters */
3143 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3147 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3150 else if (grp_riding)
3152 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3155 else if (grp_wanted)
3157 bool wanted = FALSE;
3159 for (j = 0; j < MAX_BOUNTY; j++)
3161 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3162 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3168 if (!wanted) continue;
3171 else if (grp_amberite)
3173 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3178 /* Check for race in the group */
3179 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3183 mon_idx[mon_cnt++] = i;
3185 /* XXX Hack -- Just checking for non-empty group */
3186 if (mode & 0x01) break;
3189 /* Terminate the list */
3190 mon_idx[mon_cnt] = -1;
3193 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3195 /* Return the number of races */
3201 * Description of each monster group.
3203 static concptr object_group_text[] =
3206 "キノコ", /* "Mushrooms" */
3207 "薬", /* "Potions" */
3208 "油つぼ", /* "Flasks" */
3209 "巻物", /* "Scrolls" */
3211 "アミュレット", /* "Amulets" */
3212 "笛", /* "Whistle" */
3213 "光源", /* "Lanterns" */
3214 "魔法棒", /* "Wands" */
3217 "カード", /* "Cards" */
3228 "刀剣類", /* "Swords" */
3229 "鈍器", /* "Blunt Weapons" */
3230 "長柄武器", /* "Polearms" */
3231 "採掘道具", /* "Diggers" */
3232 "飛び道具", /* "Bows" */
3236 "軽装鎧", /* "Soft Armor" */
3237 "重装鎧", /* "Hard Armor" */
3238 "ドラゴン鎧", /* "Dragon Armor" */
3239 "盾", /* "Shields" */
3240 "クローク", /* "Cloaks" */
3241 "籠手", /* "Gloves" */
3242 "ヘルメット", /* "Helms" */
3244 "ブーツ", /* "Boots" */
3297 * TVALs of items in each group
3299 static byte object_group_tval[] =
3340 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3348 * Build a list of object indexes in the given group. Return the number
3349 * of objects in the group.
3351 * mode & 0x01 : check for non-empty group
3352 * mode & 0x02 : visual operation only
3354 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3356 KIND_OBJECT_IDX i, object_cnt = 0;
3359 /* Get a list of x_char in this group */
3360 byte group_tval = object_group_tval[grp_cur];
3362 /* Check every object */
3363 for (i = 0; i < max_k_idx; i++)
3365 /* Access the object */
3366 object_kind *k_ptr = &k_info[i];
3368 /* Skip empty objects */
3369 if (!k_ptr->name) continue;
3373 if (!current_world_ptr->wizard)
3375 /* Skip non-flavoured objects */
3376 if (!k_ptr->flavor) continue;
3378 /* Require objects ever seen */
3379 if (!k_ptr->aware) continue;
3382 /* Skip items with no distribution (special artifacts) */
3383 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3387 /* Check for objects in the group */
3388 if (TV_LIFE_BOOK == group_tval)
3390 /* Hack -- All spell books */
3391 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3393 /* Add the object */
3394 object_idx[object_cnt++] = i;
3398 else if (k_ptr->tval == group_tval)
3400 /* Add the object */
3401 object_idx[object_cnt++] = i;
3405 /* XXX Hack -- Just checking for non-empty group */
3406 if (mode & 0x01) break;
3409 /* Terminate the list */
3410 object_idx[object_cnt] = -1;
3412 /* Return the number of objects */
3418 * Description of each feature group.
3420 static concptr feature_group_text[] =
3428 * Build a list of feature indexes in the given group. Return the number
3429 * of features in the group.
3431 * mode & 0x01 : check for non-empty group
3433 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3435 /* Check every feature */
3436 FEAT_IDX feat_cnt = 0;
3437 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3439 feature_type *f_ptr = &f_info[i];
3441 /* Skip empty index */
3442 if (!f_ptr->name) continue;
3444 /* Skip mimiccing features */
3445 if (f_ptr->mimic != i) continue;
3448 feat_idx[feat_cnt++] = i;
3450 /* XXX Hack -- Just checking for non-empty group */
3451 if (mode & 0x01) break;
3454 /* Terminate the list */
3455 feat_idx[feat_cnt] = -1;
3457 /* Return the number of races */
3463 * Hack -- load a screen dump from a file
3465 void do_cmd_load_screen(void)
3469 SYMBOL_CODE c = ' ';
3475 Term_get_size(&wid, &hgt);
3476 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3478 /* Append to the file */
3479 fff = my_fopen(buf, "r");
3483 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3491 /* Load the screen */
3492 for (y = 0; okay; y++)
3494 /* Get a line of data including control code */
3495 if (!fgets(buf, 1024, fff)) okay = FALSE;
3497 /* Get the blank line */
3498 if (buf[0] == '\n' || buf[0] == '\0') break;
3500 /* Ignore too large screen image */
3501 if (y >= hgt) continue;
3504 for (x = 0; x < wid - 1; x++)
3507 if (buf[x] == '\n' || buf[x] == '\0') break;
3509 /* Put the attr/char */
3510 Term_draw(x, y, TERM_WHITE, buf[x]);
3514 /* Dump the screen */
3515 for (y = 0; okay; y++)
3517 /* Get a line of data including control code */
3518 if (!fgets(buf, 1024, fff)) okay = FALSE;
3520 /* Get the blank line */
3521 if (buf[0] == '\n' || buf[0] == '\0') break;
3523 /* Ignore too large screen image */
3524 if (y >= hgt) continue;
3527 for (x = 0; x < wid - 1; x++)
3530 if (buf[x] == '\n' || buf[x] == '\0') break;
3532 /* Get the attr/char */
3533 (void)(Term_what(x, y, &a, &c));
3535 /* Look up the attr */
3536 for (int i = 0; i < 16; i++)
3538 /* Use attr matches */
3539 if (hack[i] == buf[x]) a = (byte)i;
3542 /* Put the attr/char */
3543 Term_draw(x, y, a, c);
3549 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3557 // todo なぜこんな中途半端なところに? defineも…
3558 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3559 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3561 #define IM_FLAG_STR _("*", "* ")
3562 #define HAS_FLAG_STR _("+", "+ ")
3563 #define NO_FLAG_STR _("・", ". ")
3565 #define print_im_or_res_flag(IM, RES) \
3567 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3568 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3571 #define print_flag(TR) \
3573 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3577 /* XTRA HACK RESLIST */
3578 static void do_cmd_knowledge_inven_aux(player_type *creature_ptr, FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
3580 GAME_TEXT o_name[MAX_NLEN];
3581 BIT_FLAGS flgs[TR_FLAG_SIZE];
3583 if (!o_ptr->k_idx) return;
3584 if (o_ptr->tval != tval) return;
3586 /* Identified items only */
3587 if (!object_is_known(o_ptr)) return;
3590 * HACK:Ring of Lordly protection and Dragon equipment
3591 * have random resistances.
3593 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3594 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3595 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3596 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3597 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3598 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3599 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3600 || object_is_artifact(o_ptr);
3601 if (!is_special_item_type)
3607 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3609 while (o_name[i] && (i < 26))
3612 if (iskanji(o_name[i])) i++;
3621 o_name[i] = ' '; i++;
3627 fprintf(fff, "%s %s", where, o_name);
3629 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
3631 fputs(_("-------不明--------------- -------不明---------\n",
3632 "-------unknown------------ -------unknown------\n"), fff);
3636 object_flags_known(o_ptr, flgs);
3638 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3639 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3640 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3641 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3642 print_flag(TR_RES_POIS);
3643 print_flag(TR_RES_LITE);
3644 print_flag(TR_RES_DARK);
3645 print_flag(TR_RES_SHARDS);
3646 print_flag(TR_RES_SOUND);
3647 print_flag(TR_RES_NETHER);
3648 print_flag(TR_RES_NEXUS);
3649 print_flag(TR_RES_CHAOS);
3650 print_flag(TR_RES_DISEN);
3654 print_flag(TR_RES_BLIND);
3655 print_flag(TR_RES_FEAR);
3656 print_flag(TR_RES_CONF);
3657 print_flag(TR_FREE_ACT);
3658 print_flag(TR_SEE_INVIS);
3659 print_flag(TR_HOLD_EXP);
3660 print_flag(TR_TELEPATHY);
3661 print_flag(TR_SLOW_DIGEST);
3662 print_flag(TR_REGEN);
3663 print_flag(TR_LEVITATION);
3672 fprintf(fff, "%s\n", inven_res_label);
3677 * Display *ID* ed weapons/armors's resistances
3679 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3682 GAME_TEXT file_name[1024];
3684 OBJECT_TYPE_VALUE tval;
3690 /* Open a new file */
3691 fff = my_fopen_temp(file_name, 1024);
3694 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3699 fprintf(fff, "%s\n", inven_res_label);
3701 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3705 for (; j < 9; j++) fputc('\n', fff);
3707 fprintf(fff, "%s\n", inven_res_label);
3710 strcpy(where, _("装", "E "));
3711 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3713 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3716 strcpy(where, _("持", "I "));
3717 for (i = 0; i < INVEN_PACK; i++)
3719 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3722 st_ptr = &town_info[1].store[STORE_HOME];
3723 strcpy(where, _("家", "H "));
3724 for (i = 0; i < st_ptr->stock_num; i++)
3726 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3732 /* Display the file contents */
3733 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3738 void do_cmd_save_screen_html_aux(char *filename, int message)
3746 concptr html_head[] = {
3747 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3751 concptr html_foot[] = {
3753 "</body>\n</html>\n",
3758 Term_get_size(&wid, &hgt);
3760 /* File type is "TEXT" */
3761 FILE_TYPE(FILE_TYPE_TEXT);
3763 /* Append to the file */
3765 fff = my_fopen(filename, "w");
3771 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3778 if (message) screen_save();
3780 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3782 tmpfff = my_fopen(buf, "r");
3785 for (int i = 0; html_head[i]; i++)
3786 fputs(html_head[i], fff);
3790 bool is_first_line = TRUE;
3791 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3795 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3796 is_first_line = FALSE;
3800 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3802 fprintf(fff, "%s\n", buf);
3807 /* Dump the screen */
3808 for (TERM_LEN y = 0; y < hgt; y++)
3811 if (y != 0) fprintf(fff, "\n");
3814 TERM_COLOR a = 0, old_a = 0;
3816 for (TERM_LEN x = 0; x < wid - 1; x++)
3819 /* Get the attr/char */
3820 (void)(Term_what(x, y, &a, &c));
3824 case '&': cc = "&"; break;
3825 case '<': cc = "<"; break;
3826 case '>': cc = ">"; break;
3828 case 0x1f: c = '.'; break;
3829 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3834 if ((y == 0 && x == 0) || a != old_a)
3836 int rv = angband_color_table[a][1];
3837 int gv = angband_color_table[a][2];
3838 int bv = angband_color_table[a][3];
3839 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3840 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3845 fprintf(fff, "%s", cc);
3847 fprintf(fff, "%c", c);
3851 fprintf(fff, "</font>");
3855 for (int i = 0; html_foot[i]; i++)
3856 fputs(html_foot[i], fff);
3861 bool is_first_line = TRUE;
3862 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3866 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3867 is_first_line = FALSE;
3871 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3873 fprintf(fff, "%s\n", buf);
3886 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3895 * Hack -- save a screen dump to a file
3897 static void do_cmd_save_screen_html(void)
3899 char buf[1024], tmp[256] = "screen.html";
3901 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3903 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3907 do_cmd_save_screen_html_aux(buf, 1);
3912 * Redefinable "save_screen" action
3914 void(*screendump_aux)(void) = NULL;
3918 * Save a screen dump to a file
3919 * @param creature_ptr プレーヤーへの参照ポインタ
3922 void do_cmd_save_screen(player_type *creature_ptr)
3924 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3925 bool html_dump = FALSE;
3929 if (c == 'Y' || c == 'y')
3931 else if (c == 'H' || c == 'h')
3944 Term_get_size(&wid, &hgt);
3946 bool old_use_graphics = use_graphics;
3947 if (old_use_graphics)
3949 use_graphics = FALSE;
3950 reset_visuals(creature_ptr);
3951 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3952 handle_stuff(creature_ptr);
3957 do_cmd_save_screen_html();
3958 do_cmd_redraw(creature_ptr);
3961 /* Do we use a special screendump function ? */
3962 else if (screendump_aux)
3964 /* Dump the screen to a graphics file */
3965 (*screendump_aux)();
3967 else /* Dump the screen as text */
3971 SYMBOL_CODE c = ' ';
3974 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3976 /* File type is "TEXT" */
3977 FILE_TYPE(FILE_TYPE_TEXT);
3979 /* Append to the file */
3980 fff = my_fopen(buf, "w");
3984 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3991 /* Dump the screen */
3992 for (y = 0; y < hgt; y++)
3995 for (x = 0; x < wid - 1; x++)
3997 /* Get the attr/char */
3998 (void)(Term_what(x, y, &a, &c));
4008 fprintf(fff, "%s\n", buf);
4015 /* Dump the screen */
4016 for (y = 0; y < hgt; y++)
4019 for (x = 0; x < wid - 1; x++)
4021 /* Get the attr/char */
4022 (void)(Term_what(x, y, &a, &c));
4025 buf[x] = hack[a & 0x0F];
4032 fprintf(fff, "%s\n", buf);
4039 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4044 if (!old_use_graphics) return;
4046 use_graphics = TRUE;
4047 reset_visuals(creature_ptr);
4048 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4049 handle_stuff(creature_ptr);
4054 * todo okay = 既知のアーティファクト? と思われるが確証がない
4055 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4056 * Check the status of "artifacts"
4057 * @param player_ptr プレーヤーへの参照ポインタ
4060 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4062 /* Open a new file */
4064 GAME_TEXT file_name[1024];
4065 fff = my_fopen_temp(file_name, 1024);
4068 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4073 /* Allocate the "who" array */
4075 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4077 /* Allocate the "okay" array */
4079 C_MAKE(okay, max_a_idx, bool);
4081 /* Scan the artifacts */
4082 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4084 artifact_type *a_ptr = &a_info[k];
4089 /* Skip "empty" artifacts */
4090 if (!a_ptr->name) continue;
4092 /* Skip "uncreated" artifacts */
4093 if (!a_ptr->cur_num) continue;
4099 /* Check the dungeon */
4100 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4102 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4104 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4106 OBJECT_IDX this_o_idx, next_o_idx = 0;
4108 /* Scan all objects in the grid */
4109 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4112 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4113 next_o_idx = o_ptr->next_o_idx;
4115 /* Ignore non-artifacts */
4116 if (!object_is_fixed_artifact(o_ptr)) continue;
4118 /* Ignore known items */
4119 if (object_is_known(o_ptr)) continue;
4121 /* Note the artifact */
4122 okay[o_ptr->name1] = FALSE;
4127 /* Check the player_ptr->inventory_list and equipment */
4128 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4130 object_type *o_ptr = &player_ptr->inventory_list[i];
4132 /* Ignore non-objects */
4133 if (!o_ptr->k_idx) continue;
4135 /* Ignore non-artifacts */
4136 if (!object_is_fixed_artifact(o_ptr)) continue;
4138 /* Ignore known items */
4139 if (object_is_known(o_ptr)) continue;
4141 /* Note the artifact */
4142 okay[o_ptr->name1] = FALSE;
4146 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4148 if (okay[k]) who[n++] = k;
4152 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4154 /* Scan the artifacts */
4155 for (ARTIFACT_IDX k = 0; k < n; k++)
4157 artifact_type *a_ptr = &a_info[who[k]];
4158 GAME_TEXT base_name[MAX_NLEN];
4159 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4161 /* Obtain the base object type */
4162 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4171 /* Create fake object */
4172 object_prep(q_ptr, z);
4174 /* Make it an artifact */
4175 q_ptr->name1 = (byte)who[k];
4177 /* Display as if known */
4178 q_ptr->ident |= IDENT_STORE;
4180 /* Describe the artifact */
4181 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4184 /* Hack -- Build the artifact name */
4185 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4188 /* Free the "who" array */
4189 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4191 /* Free the "okay" array */
4192 C_KILL(okay, max_a_idx, bool);
4195 /* Display the file contents */
4196 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4202 * Display known uniques
4203 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4205 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4212 GAME_TEXT file_name[1024];
4215 int n_alive_surface = 0;
4216 int n_alive_over100 = 0;
4217 int n_alive_total = 0;
4220 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4222 /* Open a new file */
4223 fff = my_fopen_temp(file_name, 1024);
4227 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4232 /* Allocate the "who" array */
4233 C_MAKE(who, max_r_idx, MONRACE_IDX);
4235 /* Scan the monsters */
4237 for (IDX i = 1; i < max_r_idx; i++)
4239 monster_race *r_ptr = &r_info[i];
4242 if (!r_ptr->name) continue;
4244 /* Require unique monsters */
4245 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4247 /* Only display "known" uniques */
4248 if (!cheat_know && !r_ptr->r_sights) continue;
4250 /* Only print rarity <= 100 uniques */
4251 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4253 /* Only "alive" uniques */
4254 if (r_ptr->max_num == 0) continue;
4258 lev = (r_ptr->level - 1) / 10;
4262 if (max_lev < lev) max_lev = lev;
4264 else n_alive_over100++;
4266 else n_alive_surface++;
4268 /* Collect "appropriate" monsters */
4272 /* Sort the array by dungeon depth of monsters */
4273 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4275 if (n_alive_surface)
4277 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4278 n_alive_total += n_alive_surface;
4281 for (IDX i = 0; i <= max_lev; i++)
4283 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4284 n_alive_total += n_alive[i];
4287 if (n_alive_over100)
4289 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4290 n_alive_total += n_alive_over100;
4295 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4296 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4300 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4303 /* Scan the monster races */
4304 for (int k = 0; k < n; k++)
4306 monster_race *r_ptr = &r_info[who[k]];
4307 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4310 /* Free the "who" array */
4311 C_KILL(who, max_r_idx, s16b);
4314 /* Display the file contents */
4315 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4321 * Display weapon-exp
4323 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4325 /* Open a new file */
4327 GAME_TEXT file_name[1024];
4328 fff = my_fopen_temp(file_name, 1024);
4331 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4336 for (int i = 0; i < 5; i++)
4338 for (int num = 0; num < 64; num++)
4342 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4344 object_kind *k_ptr = &k_info[j];
4346 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4347 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4349 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4351 fprintf(fff, "%-25s ", tmp);
4352 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4353 else fprintf(fff, " ");
4354 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4355 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4364 /* Display the file contents */
4365 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4371 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4375 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4377 /* Open a new file */
4379 GAME_TEXT file_name[1024];
4380 fff = my_fopen_temp(file_name, 1024);
4383 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4388 if (creature_ptr->realm1 != REALM_NONE)
4390 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4391 for (SPELL_IDX i = 0; i < 32; i++)
4393 const magic_type *s_ptr;
4394 if (!is_magic(creature_ptr->realm1))
4396 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4400 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4403 if (s_ptr->slevel >= 99) continue;
4404 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4405 int exp_level = spell_exp_level(spell_exp);
4406 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4407 if (creature_ptr->realm1 == REALM_HISSATSU)
4408 fprintf(fff, "[--]");
4411 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4412 else fprintf(fff, " ");
4413 fprintf(fff, "%s", exp_level_str[exp_level]);
4416 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4421 if (creature_ptr->realm2 != REALM_NONE)
4423 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4424 for (SPELL_IDX i = 0; i < 32; i++)
4426 const magic_type *s_ptr;
4427 if (!is_magic(creature_ptr->realm1))
4429 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4433 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4436 if (s_ptr->slevel >= 99) continue;
4438 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4439 int exp_level = spell_exp_level(spell_exp);
4440 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4441 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4442 else fprintf(fff, " ");
4443 fprintf(fff, "%s", exp_level_str[exp_level]);
4444 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4451 /* Display the file contents */
4452 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4458 * @brief スキル情報を表示するコマンドのメインルーチン /
4462 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4464 char skill_name[GINOU_TEMPMAX][20] =
4466 _("マーシャルアーツ", "Martial Arts "),
4467 _("二刀流 ", "Dual Wielding "),
4468 _("乗馬 ", "Riding "),
4472 /* Open a new file */
4474 char file_name[1024];
4475 fff = my_fopen_temp(file_name, 1024);
4478 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4483 for (int i = 0; i < GINOU_TEMPMAX; i++)
4485 int skill_exp = creature_ptr->skill_exp[i];
4486 fprintf(fff, "%-20s ", skill_name[i]);
4487 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4488 else fprintf(fff, " ");
4489 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4490 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4496 /* Display the file contents */
4497 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4503 * @brief 現在のペットを表示するコマンドのメインルーチン /
4504 * Display current pets
4505 * @param creature_ptr プレーヤーへの参照ポインタ
4508 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4510 /* Open a new file */
4511 GAME_TEXT file_name[1024];
4513 fff = my_fopen_temp(file_name, 1024);
4516 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4521 /* Process the monsters (backwards) */
4522 monster_type *m_ptr;
4523 GAME_TEXT pet_name[MAX_NLEN];
4525 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4527 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4529 /* Ignore "dead" monsters */
4530 if (!monster_is_valid(m_ptr)) continue;
4532 /* Calculate "upkeep" for pets */
4533 if (!is_pet(m_ptr)) continue;
4536 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4537 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4540 int show_upkeep = calculate_upkeep(creature_ptr);
4542 fprintf(fff, "----------------------------------------------\n");
4544 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4546 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4548 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4552 /* Display the file contents */
4553 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4559 * @brief 現在のペットを表示するコマンドのメインルーチン /
4560 * @param creature_ptr プレーヤーへの参照ポインタ
4563 * @note the player ghosts are ignored.
4565 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4567 /* Open a new file */
4569 GAME_TEXT file_name[1024];
4570 fff = my_fopen_temp(file_name, 1024);
4573 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4578 /* Allocate the "who" array */
4580 C_MAKE(who, max_r_idx, MONRACE_IDX);
4584 /* Monsters slain */
4585 for (int kk = 1; kk < max_r_idx; kk++)
4587 monster_race *r_ptr = &r_info[kk];
4589 if (r_ptr->flags1 & (RF1_UNIQUE))
4591 bool dead = (r_ptr->max_num == 0);
4600 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4602 if (this_monster > 0)
4604 total += this_monster;
4610 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4613 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4615 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4621 /* Scan the monsters */
4623 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4625 monster_race *r_ptr = &r_info[i];
4627 /* Use that monster */
4628 if (r_ptr->name) who[n++] = i;
4631 /* Sort the array by dungeon depth of monsters */
4633 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4635 /* Scan the monster races */
4636 for (int k = 0; k < n; k++)
4638 monster_race *r_ptr = &r_info[who[k]];
4640 if (r_ptr->flags1 & (RF1_UNIQUE))
4642 bool dead = (r_ptr->max_num == 0);
4646 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4653 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4655 if (this_monster <= 0) continue;
4658 /* p,tは人と数える by ita */
4659 if (my_strchr("pt", r_ptr->d_char))
4660 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4662 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4664 if (this_monster < 2)
4666 if (my_strstr(r_name + r_ptr->name, "coins"))
4668 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4672 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4678 strcpy(ToPlural, (r_name + r_ptr->name));
4679 plural_aux(ToPlural);
4680 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4683 total += this_monster;
4686 fprintf(fff, "----------------------------------------------\n");
4688 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4690 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4693 /* Free the "who" array */
4694 C_KILL(who, max_r_idx, s16b);
4697 /* Display the file contents */
4698 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4704 * @brief モンスター情報リスト中のグループを表示する /
4705 * Display the object groups.
4709 * @param per_page リストの表示行
4710 * @param grp_idx グループのID配列
4711 * @param group_text グループ名の文字列配列
4712 * @param grp_cur 現在の選択ID
4713 * @param grp_top 現在の選択リスト最上部ID
4716 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)
4718 /* Display lines until done */
4719 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4721 /* Get the group index */
4722 int grp = grp_idx[grp_top + i];
4724 /* Choose a color */
4725 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4727 /* Erase the entire line */
4728 Term_erase(col, row + i, wid);
4730 /* Display the group label */
4731 c_put_str(attr, group_text[grp], row + i, col);
4737 * Move the cursor in a browser window
4739 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4740 IDX *list_cur, int list_cnt)
4745 IDX list = *list_cur;
4747 /* Extract direction */
4750 /* Hack -- scroll up full screen */
4755 /* Hack -- scroll down full screen */
4760 d = get_keymap_dir(ch);
4765 /* Diagonals - hack */
4766 if ((ddx[d] > 0) && ddy[d])
4771 Term_get_size(&wid, &hgt);
4773 browser_rows = hgt - 8;
4775 /* Browse group list */
4780 /* Move up or down */
4781 grp += ddy[d] * (browser_rows - 1);
4784 if (grp >= grp_cnt) grp = grp_cnt - 1;
4785 if (grp < 0) grp = 0;
4786 if (grp != old_grp) list = 0;
4789 /* Browse sub-list list */
4792 /* Move up or down */
4793 list += ddy[d] * browser_rows;
4796 if (list >= list_cnt) list = list_cnt - 1;
4797 if (list < 0) list = 0;
4809 if (col < 0) col = 0;
4810 if (col > 1) col = 1;
4817 /* Browse group list */
4822 /* Move up or down */
4826 if (grp >= grp_cnt) grp = grp_cnt - 1;
4827 if (grp < 0) grp = 0;
4828 if (grp != old_grp) list = 0;
4831 /* Browse sub-list list */
4834 /* Move up or down */
4835 list += (IDX)ddy[d];
4838 if (list >= list_cnt) list = list_cnt - 1;
4839 if (list < 0) list = 0;
4850 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4852 /* Clear the display lines */
4853 for (int i = 0; i < height; i++)
4855 Term_erase(col, row + i, width);
4858 /* Bigtile mode uses double width */
4859 if (use_bigtile) width /= 2;
4861 /* Display lines until done */
4862 for (int i = 0; i < height; i++)
4864 /* Display columns until done */
4865 for (int j = 0; j < width; j++)
4867 TERM_LEN x = col + j;
4868 TERM_LEN y = row + i;
4870 /* Bigtile mode uses double width */
4871 if (use_bigtile) x += j;
4873 TERM_COLOR ia = attr_top + i;
4874 SYMBOL_CODE ic = char_left + j;
4876 /* Ignore illegal characters */
4877 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4878 (!use_graphics && ic > 0x7f))
4884 /* Force correct code for both ASCII character and tile */
4885 if (c & 0x80) a |= 0x80;
4887 /* Display symbol */
4888 Term_queue_bigchar(x, y, a, c, 0, 0);
4895 * Place the cursor at the collect position for visual mode
4897 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4899 int i = (a & 0x7f) - attr_top;
4900 int j = c - char_left;
4902 TERM_LEN x = col + j;
4903 TERM_LEN y = row + i;
4905 /* Bigtile mode uses double width */
4906 if (use_bigtile) x += j;
4908 /* Place the cursor */
4914 * Do visual mode command -- Change symbols
4916 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4917 int height, int width,
4918 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4919 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4921 static TERM_COLOR attr_old = 0;
4922 static SYMBOL_CODE char_old = 0;
4927 if (*visual_list_ptr)
4930 *cur_attr_ptr = attr_old;
4931 *cur_char_ptr = char_old;
4932 *visual_list_ptr = FALSE;
4940 if (*visual_list_ptr)
4943 *visual_list_ptr = FALSE;
4944 *need_redraw = TRUE;
4952 if (!*visual_list_ptr)
4954 *visual_list_ptr = TRUE;
4956 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4957 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4959 attr_old = *cur_attr_ptr;
4960 char_old = *cur_char_ptr;
4971 /* Set the visual */
4972 attr_idx = *cur_attr_ptr;
4973 char_idx = *cur_char_ptr;
4975 /* Hack -- for feature lighting */
4976 for (i = 0; i < F_LIT_MAX; i++)
4978 attr_idx_feat[i] = 0;
4979 char_idx_feat[i] = 0;
4986 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4989 *cur_attr_ptr = attr_idx;
4990 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4991 if (!*visual_list_ptr) *need_redraw = TRUE;
4997 *cur_char_ptr = char_idx;
4998 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4999 if (!*visual_list_ptr) *need_redraw = TRUE;
5005 if (*visual_list_ptr)
5008 int d = get_keymap_dir(ch);
5009 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5010 SYMBOL_CODE c = *cur_char_ptr;
5012 if (use_bigtile) eff_width = width / 2;
5013 else eff_width = width;
5015 /* Restrict direction */
5016 if ((a == 0) && (ddy[d] < 0)) d = 0;
5017 if ((c == 0) && (ddx[d] < 0)) d = 0;
5018 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5019 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5021 a += (TERM_COLOR)ddy[d];
5022 c += (SYMBOL_CODE)ddx[d];
5024 /* Force correct code for both ASCII character and tile */
5025 if (c & 0x80) a |= 0x80;
5027 /* Set the visual */
5032 /* Move the frame */
5033 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5034 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5035 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5036 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5042 /* Visual mode command is not used */
5048 * Display the monsters in a group.
5050 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5051 int mon_cur, int mon_top, bool visual_only)
5053 /* Display lines until done */
5055 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5059 /* Get the race index */
5060 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5062 /* Access the race */
5063 monster_race *r_ptr = &r_info[r_idx];
5065 /* Choose a color */
5066 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5068 /* Display the name */
5069 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5071 /* Hack -- visual_list mode */
5074 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5077 if (current_world_ptr->wizard || visual_only)
5079 c_prt(attr, format("%d", r_idx), row + i, 62);
5082 /* Erase chars before overwritten by the race letter */
5083 Term_erase(69, row + i, 255);
5085 /* Display symbol */
5086 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5091 if (!(r_ptr->flags1 & RF1_UNIQUE))
5092 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5094 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5095 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5099 /* Clear remaining lines */
5100 for (; i < per_page; i++)
5102 Term_erase(col, row + i, 255);
5108 * todo 引数の詳細について加筆求む
5109 * Display known monsters.
5110 * @param creature_ptr プレーヤーへの参照ポインタ
5111 * @param need_redraw 画面の再描画が必要な時TRUE
5112 * @param visual_only ???
5113 * @param direct_r_idx モンスターID
5116 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5119 Term_get_size(&wid, &hgt);
5121 /* Allocate the "mon_idx" array */
5123 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5129 bool visual_list = FALSE;
5130 TERM_COLOR attr_top = 0;
5133 int browser_rows = hgt - 8;
5134 if (direct_r_idx < 0)
5136 mode = visual_only ? 0x03 : 0x01;
5138 /* Check every group */
5140 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5142 /* Measure the label */
5143 len = strlen(monster_group_text[i]);
5145 /* Save the maximum length */
5146 if (len > max) max = len;
5148 /* See if any monsters are known */
5149 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5151 /* Build a list of groups with known monsters */
5152 grp_idx[grp_cnt++] = i;
5160 mon_idx[0] = direct_r_idx;
5163 /* Terminate the list */
5166 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5167 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5170 /* Terminate the list */
5171 grp_idx[grp_cnt] = -1;
5173 mode = visual_only ? 0x02 : 0x00;
5174 IDX old_grp_cur = -1;
5187 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5188 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5189 prt(_("名前", "Name"), 4, max + 3);
5190 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5191 prt(_("文字", "Sym"), 4, 67);
5192 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5194 for (IDX i = 0; i < 78; i++)
5196 Term_putch(i, 5, TERM_WHITE, '=');
5199 if (direct_r_idx < 0)
5201 for (IDX i = 0; i < browser_rows; i++)
5203 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5210 if (direct_r_idx < 0)
5212 /* Scroll group list */
5213 if (grp_cur < grp_top) grp_top = grp_cur;
5214 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5216 /* Display a list of monster groups */
5217 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5219 if (old_grp_cur != grp_cur)
5221 old_grp_cur = grp_cur;
5223 /* Get a list of monsters in the current group */
5224 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5227 /* Scroll monster list */
5228 while (mon_cur < mon_top)
5229 mon_top = MAX(0, mon_top - browser_rows / 2);
5230 while (mon_cur >= mon_top + browser_rows)
5231 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5236 /* Display a list of monsters in the current group */
5237 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5243 /* Display a monster name */
5244 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5246 /* Display visual list below first monster */
5247 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5251 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5252 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5253 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5254 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5257 /* Get the current monster */
5258 monster_race *r_ptr;
5259 r_ptr = &r_info[mon_idx[mon_cur]];
5263 /* Mega Hack -- track this monster race */
5264 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5265 handle_stuff(creature_ptr);
5270 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5274 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5278 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5283 /* Do visual mode command if needed */
5284 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))
5286 if (direct_r_idx >= 0)
5312 /* Recall on screen */
5313 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5315 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5327 /* Move the cursor */
5328 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5335 /* Free the "mon_idx" array */
5336 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5341 * Display the objects in a group.
5343 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5344 int object_cur, int object_top, bool visual_only)
5346 /* Display lines until done */
5348 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5350 GAME_TEXT o_name[MAX_NLEN];
5353 object_kind *flavor_k_ptr;
5355 /* Get the object index */
5356 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5358 /* Access the object */
5359 object_kind *k_ptr = &k_info[k_idx];
5361 /* Choose a color */
5362 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5363 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5365 if (!visual_only && k_ptr->flavor)
5367 /* Appearance of this object is shuffled */
5368 flavor_k_ptr = &k_info[k_ptr->flavor];
5372 /* Appearance of this object is very normal */
5373 flavor_k_ptr = k_ptr;
5376 attr = ((i + object_top == object_cur) ? cursor : attr);
5378 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5381 strip_name(o_name, k_idx);
5386 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5389 /* Display the name */
5390 c_prt(attr, o_name, row + i, col);
5392 /* Hack -- visual_list mode */
5395 c_prt(attr, format("%02x/%02x", flavor_k_ptr->x_attr, flavor_k_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 64 : 68);
5398 if (current_world_ptr->wizard || visual_only)
5400 c_prt(attr, format("%d", k_idx), row + i, 70);
5403 a = flavor_k_ptr->x_attr;
5404 c = flavor_k_ptr->x_char;
5406 /* Display symbol */
5407 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5410 /* Clear remaining lines */
5411 for (; i < per_page; i++)
5413 Term_erase(col, row + i, 255);
5419 * Describe fake object
5421 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5424 object_type object_type_body;
5425 o_ptr = &object_type_body;
5427 object_prep(o_ptr, k_idx);
5429 /* It's fully know */
5430 o_ptr->ident |= IDENT_KNOWN;
5431 handle_stuff(creature_ptr);
5433 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5435 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5441 * Display known objects
5443 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5445 IDX object_old, object_top;
5448 OBJECT_IDX *object_idx;
5450 bool visual_list = FALSE;
5451 TERM_COLOR attr_top = 0;
5456 Term_get_size(&wid, &hgt);
5458 int browser_rows = hgt - 8;
5460 /* Allocate the "object_idx" array */
5461 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5466 if (direct_k_idx < 0)
5468 mode = visual_only ? 0x03 : 0x01;
5470 /* Check every group */
5471 for (IDX i = 0; object_group_text[i] != NULL; i++)
5473 /* Measure the label */
5474 len = strlen(object_group_text[i]);
5476 /* Save the maximum length */
5477 if (len > max) max = len;
5479 /* See if any monsters are known */
5480 if (collect_objects(i, object_idx, mode))
5482 /* Build a list of groups with known monsters */
5483 grp_idx[grp_cnt++] = i;
5492 object_kind *k_ptr = &k_info[direct_k_idx];
5493 object_kind *flavor_k_ptr;
5495 if (!visual_only && k_ptr->flavor)
5497 /* Appearance of this object is shuffled */
5498 flavor_k_ptr = &k_info[k_ptr->flavor];
5502 /* Appearance of this object is very normal */
5503 flavor_k_ptr = k_ptr;
5506 object_idx[0] = direct_k_idx;
5507 object_old = direct_k_idx;
5510 /* Terminate the list */
5513 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5514 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5517 /* Terminate the list */
5518 grp_idx[grp_cnt] = -1;
5520 mode = visual_only ? 0x02 : 0x00;
5521 IDX old_grp_cur = -1;
5524 IDX object_cur = object_top = 0;
5530 object_kind *k_ptr, *flavor_k_ptr;
5537 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5538 if (direct_k_idx < 0) prt("グループ", 4, 0);
5539 prt("名前", 4, max + 3);
5540 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5543 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5544 if (direct_k_idx < 0) prt("Group", 4, 0);
5545 prt("Name", 4, max + 3);
5546 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5550 for (IDX i = 0; i < 78; i++)
5552 Term_putch(i, 5, TERM_WHITE, '=');
5555 if (direct_k_idx < 0)
5557 for (IDX i = 0; i < browser_rows; i++)
5559 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5566 if (direct_k_idx < 0)
5568 /* Scroll group list */
5569 if (grp_cur < grp_top) grp_top = grp_cur;
5570 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5572 /* Display a list of object groups */
5573 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5575 if (old_grp_cur != grp_cur)
5577 old_grp_cur = grp_cur;
5579 /* Get a list of objects in the current group */
5580 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5583 /* Scroll object list */
5584 while (object_cur < object_top)
5585 object_top = MAX(0, object_top - browser_rows / 2);
5586 while (object_cur >= object_top + browser_rows)
5587 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5592 /* Display a list of objects in the current group */
5593 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5597 object_top = object_cur;
5599 /* Display a list of objects in the current group */
5600 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5602 /* Display visual list below first object */
5603 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5606 /* Get the current object */
5607 k_ptr = &k_info[object_idx[object_cur]];
5609 if (!visual_only && k_ptr->flavor)
5611 /* Appearance of this object is shuffled */
5612 flavor_k_ptr = &k_info[k_ptr->flavor];
5616 /* Appearance of this object is very normal */
5617 flavor_k_ptr = k_ptr;
5622 prt(format("<方向>%s%s%s, ESC",
5623 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5624 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5625 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5628 prt(format("<dir>%s%s%s, ESC",
5629 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5630 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5631 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5637 /* Mega Hack -- track this object */
5638 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5640 /* The "current" object changed */
5641 if (object_old != object_idx[object_cur])
5643 handle_stuff(creature_ptr);
5645 /* Remember the "current" object */
5646 object_old = object_idx[object_cur];
5652 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5656 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5660 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5665 /* Do visual mode command if needed */
5666 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))
5668 if (direct_k_idx >= 0)
5693 /* Recall on screen */
5694 if (!visual_list && !visual_only && (grp_cnt > 0))
5696 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5704 /* Move the cursor */
5705 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5711 /* Free the "object_idx" array */
5712 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5717 * Display the features in a group.
5719 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5720 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5722 int lit_col[F_LIT_MAX], i;
5723 int f_idx_col = use_bigtile ? 62 : 64;
5725 /* Correct columns 1 and 4 */
5726 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5727 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5728 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5730 /* Display lines until done */
5731 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5734 FEAT_IDX f_idx = feat_idx[feat_top + i];
5735 feature_type *f_ptr = &f_info[f_idx];
5736 int row_i = row + i;
5738 /* Choose a color */
5739 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5741 /* Display the name */
5742 c_prt(attr, f_name + f_ptr->name, row_i, col);
5744 /* Hack -- visual_list mode */
5747 /* Display lighting level */
5748 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5750 c_prt(attr, format("%02x/%02x", f_ptr->x_attr[lighting_level], f_ptr->x_char[lighting_level]), row_i, f_idx_col - ((current_world_ptr->wizard || visual_only) ? 6 : 2));
5752 if (current_world_ptr->wizard || visual_only)
5754 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5757 /* Display symbol */
5758 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);
5760 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5761 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5763 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5765 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5767 /* Mega-hack -- Use non-standard colour */
5768 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5770 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5774 /* Clear remaining lines */
5775 for (; i < per_page; i++)
5777 Term_erase(col, row + i, 255);
5783 * Interact with feature visuals.
5785 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5787 TERM_COLOR attr_old[F_LIT_MAX];
5788 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5789 SYMBOL_CODE char_old[F_LIT_MAX];
5790 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5793 Term_get_size(&wid, &hgt);
5795 /* Allocate the "feat_idx" array */
5797 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5803 FEAT_IDX grp_idx[100];
5804 TERM_COLOR attr_top = 0;
5805 bool visual_list = FALSE;
5807 TERM_LEN browser_rows = hgt - 8;
5808 if (direct_f_idx < 0)
5810 /* Check every group */
5811 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5813 /* Measure the label */
5814 len = strlen(feature_group_text[i]);
5816 /* Save the maximum length */
5817 if (len > max) max = len;
5819 /* See if any features are known */
5820 if (collect_features(feat_idx, 0x01))
5822 /* Build a list of groups with known features */
5823 grp_idx[grp_cnt++] = i;
5831 feature_type *f_ptr = &f_info[direct_f_idx];
5833 feat_idx[0] = direct_f_idx;
5836 /* Terminate the list */
5839 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5840 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5842 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5844 attr_old[i] = f_ptr->x_attr[i];
5845 char_old[i] = f_ptr->x_char[i];
5849 /* Terminate the list */
5850 grp_idx[grp_cnt] = -1;
5852 FEAT_IDX old_grp_cur = -1;
5853 FEAT_IDX grp_cur = 0;
5854 FEAT_IDX grp_top = 0;
5855 FEAT_IDX feat_cur = 0;
5856 FEAT_IDX feat_top = 0;
5857 TERM_LEN column = 0;
5860 TERM_COLOR *cur_attr_ptr;
5861 SYMBOL_CODE *cur_char_ptr;
5865 feature_type *f_ptr;
5871 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5872 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5873 prt(_("名前", "Name"), 4, max + 3);
5876 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5877 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5881 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5882 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5885 for (FEAT_IDX i = 0; i < 78; i++)
5887 Term_putch(i, 5, TERM_WHITE, '=');
5890 if (direct_f_idx < 0)
5892 for (FEAT_IDX i = 0; i < browser_rows; i++)
5894 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5901 if (direct_f_idx < 0)
5903 /* Scroll group list */
5904 if (grp_cur < grp_top) grp_top = grp_cur;
5905 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5907 /* Display a list of feature groups */
5908 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5910 if (old_grp_cur != grp_cur)
5912 old_grp_cur = grp_cur;
5914 /* Get a list of features in the current group */
5915 feat_cnt = collect_features(feat_idx, 0x00);
5918 /* Scroll feature list */
5919 while (feat_cur < feat_top)
5920 feat_top = MAX(0, feat_top - browser_rows / 2);
5921 while (feat_cur >= feat_top + browser_rows)
5922 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5927 /* Display a list of features in the current group */
5928 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5932 feat_top = feat_cur;
5934 /* Display a list of features in the current group */
5935 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5937 /* Display visual list below first object */
5938 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5942 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5943 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5944 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5947 /* Get the current feature */
5948 f_ptr = &f_info[feat_idx[feat_cur]];
5949 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5950 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5954 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5958 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5962 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5967 if (visual_list && ((ch == 'A') || (ch == 'a')))
5969 int prev_lighting_level = *lighting_level;
5973 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5974 else (*lighting_level)--;
5978 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5979 else (*lighting_level)++;
5982 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5983 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5985 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5986 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5991 else if ((ch == 'D') || (ch == 'd'))
5993 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5994 byte prev_x_char = f_ptr->x_char[*lighting_level];
5996 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6000 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6001 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6003 if (prev_x_char != f_ptr->x_char[*lighting_level])
6004 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6006 else *need_redraw = TRUE;
6011 /* Do visual mode command if needed */
6012 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))
6016 /* Restore previous visual settings */
6018 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6020 f_ptr->x_attr[i] = attr_old[i];
6021 f_ptr->x_char[i] = char_old[i];
6028 if (direct_f_idx >= 0) flag = TRUE;
6029 else *lighting_level = F_LIT_STANDARD;
6032 /* Preserve current visual settings */
6035 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6037 attr_old[i] = f_ptr->x_attr[i];
6038 char_old[i] = f_ptr->x_char[i];
6040 *lighting_level = F_LIT_STANDARD;
6047 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6049 attr_idx_feat[i] = f_ptr->x_attr[i];
6050 char_idx_feat[i] = f_ptr->x_char[i];
6059 /* Allow TERM_DARK text */
6060 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6062 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6063 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6081 /* Move the cursor */
6082 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6088 /* Free the "feat_idx" array */
6089 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6094 * List wanted monsters
6095 * @param creature_ptr プレーヤーへの参照ポインタ
6098 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6100 /* Open a new file */
6102 GAME_TEXT file_name[1024];
6103 fff = my_fopen_temp(file_name, 1024);
6106 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6111 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
6112 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6114 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6115 fprintf(fff, "----------------------------------------------\n");
6117 bool listed = FALSE;
6118 for (int i = 0; i < MAX_BOUNTY; i++)
6120 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6122 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6129 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
6134 /* Display the file contents */
6135 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6140 * List virtues & status
6142 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6144 /* Open a new file */
6146 GAME_TEXT file_name[1024];
6147 fff = my_fopen_temp(file_name, 1024);
6150 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6155 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6156 dump_virtues(creature_ptr, fff);
6159 /* Display the file contents */
6160 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6167 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6169 /* Open a new file */
6171 GAME_TEXT file_name[1024];
6172 fff = my_fopen_temp(file_name, 1024);
6175 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6180 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6184 if (!d_info[i].maxdepth) continue;
6185 if (!max_dlv[i]) continue;
6186 if (d_info[i].final_guardian)
6188 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6190 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6192 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6197 /* Display the file contents */
6198 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6204 * List virtues & status
6207 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6209 /* Open a new file */
6211 GAME_TEXT file_name[1024];
6212 fff = my_fopen_temp(file_name, 1024);
6215 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6220 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6221 (2 * creature_ptr->hitdie +
6222 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6224 if (creature_ptr->knowledge & KNOW_HPRATE)
6225 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6226 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6228 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6229 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6231 if ((creature_ptr->knowledge & KNOW_STAT) || creature_ptr->stat_max[v_nr] == creature_ptr->stat_max_max[v_nr]) fprintf(fff, "%s 18/%d\n", stat_names[v_nr], creature_ptr->stat_max_max[v_nr] - 18);
6232 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6235 dump_yourself(creature_ptr, fff);
6238 /* Display the file contents */
6239 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6245 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6246 * Print all active quests
6247 * @param creature_ptr プレーヤーへの参照ポインタ
6250 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6253 char rand_tmp_str[120] = "\0";
6254 GAME_TEXT name[MAX_NLEN];
6255 monster_race *r_ptr;
6256 int rand_level = 100;
6259 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6261 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6263 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6264 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6265 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6269 /* Set the quest number temporary */
6270 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6272 /* Clear the text */
6273 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6274 quest_text_line = 0;
6276 creature_ptr->current_floor_ptr->inside_quest = i;
6278 /* Get the quest text */
6279 init_flags = INIT_SHOW_TEXT;
6281 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6283 /* Reset the old quest number */
6284 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6286 /* No info from "silent" quests */
6287 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6291 if (quest[i].type != QUEST_TYPE_RANDOM)
6293 char note[80] = "\0";
6295 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6297 switch (quest[i].type)
6299 case QUEST_TYPE_KILL_LEVEL:
6300 case QUEST_TYPE_KILL_ANY_LEVEL:
6301 r_ptr = &r_info[quest[i].r_idx];
6302 strcpy(name, r_name + r_ptr->name);
6303 if (quest[i].max_num > 1)
6306 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6307 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6310 sprintf(note, " - kill %d %s, have killed %d.",
6311 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6315 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6318 case QUEST_TYPE_FIND_ARTIFACT:
6321 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6323 object_type *q_ptr = &forge;
6324 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6325 object_prep(q_ptr, k_idx);
6326 q_ptr->name1 = quest[i].k_idx;
6327 q_ptr->ident = IDENT_STORE;
6328 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6330 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
6332 case QUEST_TYPE_FIND_EXIT:
6333 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
6336 case QUEST_TYPE_KILL_NUMBER:
6338 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6339 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6341 sprintf(note, " - Kill %d monsters, have killed %d.",
6342 (int)quest[i].max_num, (int)quest[i].cur_num);
6346 case QUEST_TYPE_KILL_ALL:
6347 case QUEST_TYPE_TOWER:
6348 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6353 /* Print the quest info */
6354 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6355 quest[i].name, (int)quest[i].level, note);
6357 fputs(tmp_str, fff);
6359 if (quest[i].status == QUEST_STATUS_COMPLETED)
6361 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6362 fputs(tmp_str, fff);
6367 while (quest_text[k][0] && k < 10)
6369 fprintf(fff, " %s\n", quest_text[k]);
6376 /* QUEST_TYPE_RANDOM */
6377 if (quest[i].level >= rand_level)
6381 rand_level = quest[i].level;
6383 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6385 /* Print the quest info */
6386 r_ptr = &r_info[quest[i].r_idx];
6387 strcpy(name, r_name + r_ptr->name);
6389 if (quest[i].max_num <= 1)
6391 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6392 quest[i].name, (int)quest[i].level, name);
6397 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6398 quest[i].name, (int)quest[i].level,
6399 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6403 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6404 quest[i].name, (int)quest[i].level,
6405 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6409 /* Print the current random quest */
6410 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6412 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6416 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6419 char playtime_str[16];
6420 quest_type* const q_ptr = &quest[q_idx];
6422 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6423 if (is_fixed_quest_idx(q_idx))
6425 /* Set the quest number temporary */
6426 IDX old_quest = floor_ptr->inside_quest;
6428 floor_ptr->inside_quest = q_idx;
6431 init_flags = INIT_NAME_ONLY;
6433 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6435 /* Reset the old quest number */
6436 floor_ptr->inside_quest = old_quest;
6438 /* No info from "silent" quests */
6439 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6442 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6443 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6445 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
6447 /* Print the quest info */
6449 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6450 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6451 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6452 fputs(tmp_str, fff);
6456 /* Print the quest info */
6457 if (q_ptr->complev == 0)
6460 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6461 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6462 r_name + r_info[q_ptr->r_idx].name,
6463 (int)q_ptr->level, playtime_str);
6464 fputs(tmp_str, fff);
6469 _(" %-35s (%3d階) - レベル%2d - %s\n",
6470 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6471 r_name + r_info[q_ptr->r_idx].name,
6475 fputs(tmp_str, fff);
6481 * Print all finished quests
6482 * @param creature_ptr プレーヤーへの参照ポインタ
6483 * @param fff セーブファイル (展開済?)
6484 * @param quest_num[] 受注したことのあるクエスト群
6487 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6489 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6490 QUEST_IDX total = 0;
6491 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6493 QUEST_IDX q_idx = quest_num[i];
6494 quest_type* const q_ptr = &quest[q_idx];
6496 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6502 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6507 * Print all failed quests
6508 * @param creature_ptr プレーヤーへの参照ポインタ
6509 * @param fff セーブファイル (展開済?)
6510 * @param quest_num[] 受注したことのあるクエスト群
6513 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6515 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6516 QUEST_IDX total = 0;
6517 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6519 QUEST_IDX q_idx = quest_num[i];
6520 quest_type* const q_ptr = &quest[q_idx];
6522 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6523 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6529 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6534 * Print all random quests
6536 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6538 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6539 GAME_TEXT tmp_str[120];
6540 QUEST_IDX total = 0;
6541 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6543 /* No info from "silent" quests */
6544 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6546 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6550 /* Print the quest info */
6551 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6552 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6553 fputs(tmp_str, fff);
6557 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6561 * Print quest status of all active quests
6562 * @param creature_ptr プレーヤーへの参照ポインタ
6565 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6567 /* Open a new file */
6569 GAME_TEXT file_name[1024];
6570 fff = my_fopen_temp(file_name, 1024);
6573 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6578 /* Allocate Memory */
6580 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6582 /* Sort by compete level */
6583 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6585 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6587 /* Dump Quest Information */
6588 do_cmd_knowledge_quests_current(creature_ptr, fff);
6590 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6592 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6593 if (current_world_ptr->wizard)
6596 do_cmd_knowledge_quests_wiz_random(fff);
6601 /* Display the file contents */
6602 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6606 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6612 * @param player_ptr プレーヤーへの参照ポインタ
6615 static void do_cmd_knowledge_home(player_type *player_ptr)
6617 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6619 /* Open a new file */
6621 GAME_TEXT file_name[1024];
6622 fff = my_fopen_temp(file_name, 1024);
6625 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6630 /* Print all homes in the different towns */
6632 st_ptr = &town_info[1].store[STORE_HOME];
6634 /* Home -- if anything there */
6635 if (st_ptr->stock_num)
6640 /* Header with name of the town */
6641 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6643 /* Dump all available items */
6644 concptr paren = ")";
6645 GAME_TEXT o_name[MAX_NLEN];
6646 for (int i = 0; i < st_ptr->stock_num; i++)
6649 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6650 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6651 if (strlen(o_name) <= 80 - 3)
6653 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6659 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6660 if (iskanji(*t)) { t++; n++; }
6661 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6663 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6664 fprintf(fff, " %.77s\n", o_name + n);
6667 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6668 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6672 /* Add an empty line */
6673 fprintf(fff, "\n\n");
6678 /* Display the file contents */
6679 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6685 * Check the status of "autopick"
6687 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6689 /* Open a new file */
6691 GAME_TEXT file_name[1024];
6692 fff = my_fopen_temp(file_name, 1024);
6695 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6702 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6706 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6707 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6710 for (int k = 0; k < max_autopick; k++)
6713 byte act = autopick_list[k].action;
6714 if (act & DONT_AUTOPICK)
6716 tmp = _("放置", "Leave");
6718 else if (act & DO_AUTODESTROY)
6720 tmp = _("破壊", "Destroy");
6722 else if (act & DO_AUTOPICK)
6724 tmp = _("拾う", "Pickup");
6728 tmp = _("確認", "Query");
6731 if (act & DO_DISPLAY)
6732 fprintf(fff, "%11s", format("[%s]", tmp));
6734 fprintf(fff, "%11s", format("(%s)", tmp));
6736 tmp = autopick_line_from_entry(&autopick_list[k]);
6737 fprintf(fff, " %s", tmp);
6744 /* Display the file contents */
6745 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6751 * Interact with "knowledge"
6753 void do_cmd_knowledge(player_type *creature_ptr)
6756 bool need_redraw = FALSE;
6758 /* File type is "TEXT" */
6759 FILE_TYPE(FILE_TYPE_TEXT);
6762 /* Interact until done */
6767 /* Ask for a choice */
6768 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6769 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6771 /* Give some choices */
6775 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6776 prt("(2) 既知のアイテム の一覧", 7, 5);
6777 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6778 prt("(4) 既知のモンスター の一覧", 9, 5);
6779 prt("(5) 倒した敵の数 の一覧", 10, 5);
6780 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6781 prt("(7) 現在のペット の一覧", 12, 5);
6782 prt("(8) 我が家のアイテム の一覧", 13, 5);
6783 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6784 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6788 prt("(a) 自分に関する情報 の一覧", 6, 5);
6789 prt("(b) 突然変異 の一覧", 7, 5);
6790 prt("(c) 武器の経験値 の一覧", 8, 5);
6791 prt("(d) 魔法の経験値 の一覧", 9, 5);
6792 prt("(e) 技能の経験値 の一覧", 10, 5);
6793 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6794 prt("(g) 入ったダンジョン の一覧", 12, 5);
6795 prt("(h) 実行中のクエスト の一覧", 13, 5);
6796 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6801 prt("(1) Display known artifacts", 6, 5);
6802 prt("(2) Display known objects", 7, 5);
6803 prt("(3) Display remaining uniques", 8, 5);
6804 prt("(4) Display known monster", 9, 5);
6805 prt("(5) Display kill count", 10, 5);
6806 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6807 prt("(7) Display current pets", 12, 5);
6808 prt("(8) Display home inventory", 13, 5);
6809 prt("(9) Display *identified* equip.", 14, 5);
6810 prt("(0) Display terrain symbols.", 15, 5);
6814 prt("(a) Display about yourself", 6, 5);
6815 prt("(b) Display mutations", 7, 5);
6816 prt("(c) Display weapon proficiency", 8, 5);
6817 prt("(d) Display spell proficiency", 9, 5);
6818 prt("(e) Display misc. proficiency", 10, 5);
6819 prt("(f) Display virtues", 11, 5);
6820 prt("(g) Display dungeons", 12, 5);
6821 prt("(h) Display current quests", 13, 5);
6822 prt("(i) Display auto pick/destroy", 14, 5);
6826 prt(_("-続く-", "-more-"), 17, 8);
6827 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6828 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6829 /*prt("-) 前ページ", 21, 60);*/
6830 prt(_("コマンド:", "Command: "), 20, 0);
6833 if (i == ESCAPE) break;
6836 case ' ': /* Page change */
6840 case '1': /* Artifacts */
6841 do_cmd_knowledge_artifacts(creature_ptr);
6843 case '2': /* Objects */
6844 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6846 case '3': /* Uniques */
6847 do_cmd_knowledge_uniques(creature_ptr);
6849 case '4': /* Monsters */
6850 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6852 case '5': /* Kill count */
6853 do_cmd_knowledge_kill_count(creature_ptr);
6855 case '6': /* wanted */
6856 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6858 case '7': /* Pets */
6859 do_cmd_knowledge_pets(creature_ptr);
6861 case '8': /* Home */
6862 do_cmd_knowledge_home(creature_ptr);
6864 case '9': /* Resist list */
6865 do_cmd_knowledge_inven(creature_ptr);
6867 case '0': /* Feature list */
6869 IDX lighting_level = F_LIT_STANDARD;
6870 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6874 case 'a': /* Max stat */
6875 do_cmd_knowledge_stat(creature_ptr);
6877 case 'b': /* Mutations */
6878 do_cmd_knowledge_mutations(creature_ptr);
6880 case 'c': /* weapon-exp */
6881 do_cmd_knowledge_weapon_exp(creature_ptr);
6883 case 'd': /* spell-exp */
6884 do_cmd_knowledge_spell_exp(creature_ptr);
6886 case 'e': /* skill-exp */
6887 do_cmd_knowledge_skill_exp(creature_ptr);
6889 case 'f': /* Virtues */
6890 do_cmd_knowledge_virtues(creature_ptr);
6892 case 'g': /* Dungeon */
6893 do_cmd_knowledge_dungeon(creature_ptr);
6895 case 'h': /* Quests */
6896 do_cmd_knowledge_quests(creature_ptr);
6898 case 'i': /* Autopick */
6899 do_cmd_knowledge_autopick(creature_ptr);
6901 default: /* Unknown option */
6909 if (need_redraw) do_cmd_redraw(creature_ptr);
6914 * Check on the status of an active quest
6915 * @param creature_ptr プレーヤーへの参照ポインタ
6918 void do_cmd_checkquest(player_type *creature_ptr)
6920 /* File type is "TEXT" */
6921 FILE_TYPE(FILE_TYPE_TEXT);
6925 do_cmd_knowledge_quests(creature_ptr);
6931 * Display the time and date
6932 * @param creature_ptr プレーヤーへの参照ポインタ
6935 void do_cmd_time(player_type *creature_ptr)
6938 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6941 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6944 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6945 else strcpy(day_buf, "*****");
6947 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6948 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6952 if (!randint0(10) || creature_ptr->image)
6954 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6958 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6961 /* Open this file */
6963 fff = my_fopen(buf, "rt");
6967 /* Find this time */
6968 int full = hour * 100 + min;
6972 while (!my_fgets(fff, buf, sizeof(buf)))
6974 /* Ignore comments */
6975 if (!buf[0] || (buf[0] == '#')) continue;
6977 /* Ignore invalid lines */
6978 if (buf[1] != ':') continue;
6980 /* Process 'Start' */
6983 /* Extract the starting time */
6984 start = atoi(buf + 2);
6986 /* Assume valid for an hour */
6994 /* Extract the ending time */
6995 end = atoi(buf + 2);
6999 /* Ignore incorrect range */
7000 if ((start > full) || (full > end)) continue;
7002 /* Process 'Description' */
7007 /* Apply the randomizer */
7008 if (!randint0(num)) strcpy(desc, buf + 2);