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"
73 #include "objectkind.h"
74 #include "floor-town.h"
75 #include "view-mainwindow.h"
79 // Mark strings for auto dump
80 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
81 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
83 // Variables for auto dump
84 static FILE *auto_dump_stream;
85 static concptr auto_dump_mark;
86 static int auto_dump_line_num;
88 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
89 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
90 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
92 // Clipboard variables for copy&paste in visual mode
93 static TERM_COLOR attr_idx = 0;
94 static SYMBOL_CODE char_idx = 0;
96 /* Hack -- for feature lighting */
97 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
98 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
100 // Encode the screen colors
101 static char hack[17] = "dwsorgbuDWvyRGBU";
107 * @brief prf出力内容を消去する /
108 * Remove old lines automatically generated before.
109 * @param orig_file 消去を行うファイル名
111 static void remove_auto_dump(concptr orig_file)
113 FILE *tmp_fff, *orig_fff;
117 bool between_mark = FALSE;
118 bool changed = FALSE;
120 long header_location = 0;
121 char header_mark_str[80];
122 char footer_mark_str[80];
125 /* Prepare a header/footer mark string */
126 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
127 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
129 mark_len = strlen(footer_mark_str);
131 /* Open an old dump file in read-only mode */
132 orig_fff = my_fopen(orig_file, "r");
134 /* If original file does not exist, nothing to do */
135 if (!orig_fff) return;
137 /* Open a new (temporary) file */
138 tmp_fff = my_fopen_temp(tmp_file, 1024);
142 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
147 /* Loop for every line */
151 if (my_fgets(orig_fff, buf, sizeof(buf)))
153 /* Read error: Assume End of File */
156 * Was looking for the footer, but not found.
158 * Since automatic dump might be edited by hand,
159 * it's dangerous to kill these lines.
160 * Seek back to the next line of the (pseudo) header,
165 fseek(orig_fff, header_location, SEEK_SET);
166 between_mark = FALSE;
170 /* Success -- End the loop */
177 /* We are looking for the header mark of automatic dump */
180 /* Is this line a header? */
181 if (!strcmp(buf, header_mark_str))
183 /* Memorise seek point of this line */
184 header_location = ftell(orig_fff);
186 /* Initialize counter for number of lines */
189 /* Look for the footer from now */
192 /* There are some changes */
199 /* Copy orginally lines */
200 fprintf(tmp_fff, "%s\n", buf);
206 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
207 /* We are looking for the footer mark of automatic dump */
208 /* Is this line a footer? */
209 if (!strncmp(buf, footer_mark_str, mark_len))
214 * Compare the number of lines
216 * If there is an inconsistency between
217 * actual number of lines and the
218 * number here, the automatic dump
219 * might be edited by hand. So it's
220 * dangerous to kill these lines.
221 * Seek back to the next line of the
222 * (pseudo) header, and read again.
224 if (!sscanf(buf + mark_len, " (%d)", &tmp)
227 fseek(orig_fff, header_location, SEEK_SET);
230 /* Look for another header */
231 between_mark = FALSE;
236 /* Ignore old line, and count number of lines */
244 /* If there are some changes, overwrite the original file with new one */
247 /* Copy contents of temporary file */
248 tmp_fff = my_fopen(tmp_file, "r");
249 orig_fff = my_fopen(orig_file, "w");
251 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
252 fprintf(orig_fff, "%s\n", buf);
263 * @brief prfファイルのフォーマットに従った内容を出力する /
264 * Dump a formatted line, using "vstrnfmt()".
267 static void auto_dump_printf(concptr fmt, ...)
274 /* Begin the Varargs Stuff */
277 /* Format the args, save the length */
278 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
280 /* End the Varargs Stuff */
283 /* Count number of lines */
284 for (p = buf; *p; p++)
286 if (*p == '\n') auto_dump_line_num++;
290 fprintf(auto_dump_stream, "%s", buf);
295 * @brief prfファイルをファイルオープンする /
296 * Open file to append auto dump.
298 * @param mark 出力するヘッダマーク
299 * @return ファイルポインタを取得できたらTRUEを返す
301 static bool open_auto_dump(concptr buf, concptr mark)
303 char header_mark_str[80];
305 /* Save the mark string */
306 auto_dump_mark = mark;
308 /* Prepare a header mark string */
309 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
311 /* Remove old macro dumps */
312 remove_auto_dump(buf);
314 /* Append to the file */
315 auto_dump_stream = my_fopen(buf, "a");
318 if (!auto_dump_stream)
320 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
328 fprintf(auto_dump_stream, "%s\n", header_mark_str);
330 /* Initialize counter */
331 auto_dump_line_num = 0;
333 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
334 "# *Warning!* The lines below are an automatic dump.\n"));
335 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
336 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
341 * @brief prfファイルをファイルクローズする /
342 * Append foot part and close auto dump.
345 static void close_auto_dump(void)
347 char footer_mark_str[80];
349 /* Prepare a footer mark string */
350 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
352 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
353 "# *Warning!* The lines below are an automatic dump.\n"));
354 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
355 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
357 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
359 my_fclose(auto_dump_stream);
366 * @brief Return suffix of ordinal number
368 * @return pointer of suffix string.
370 concptr get_ordinal_number_suffix(int num)
372 num = ABS(num) % 100;
376 return (num == 11) ? "th" : "st";
378 return (num == 12) ? "th" : "nd";
380 return (num == 13) ? "th" : "rd";
389 * @brief 日記にメッセージを追加する /
390 * Take note to the diary.
391 * @param type 日記内容のID
392 * @param num 日記内容のIDに応じた数値
393 * @param note 日記内容のIDに応じた文字列参照ポインタ
396 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
400 GAME_TEXT file_name[MAX_NLEN];
402 concptr note_level = "";
403 bool do_level = TRUE;
404 char note_level_buf[40];
407 static bool disable_diary = FALSE;
409 extract_day_hour_min(creature_ptr, &day, &hour, &min);
411 if (disable_diary) return(-1);
413 if (type == DIARY_FIX_QUEST_C ||
414 type == DIARY_FIX_QUEST_F ||
415 type == DIARY_RAND_QUEST_C ||
416 type == DIARY_RAND_QUEST_F ||
417 type == DIARY_TO_QUEST)
421 old_quest = creature_ptr->current_floor_ptr->inside_quest;
422 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
424 /* Get the quest text */
425 init_flags = INIT_NAME_ONLY;
427 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
429 /* Reset the old quest number */
430 creature_ptr->current_floor_ptr->inside_quest = old_quest;
433 /* different filne name to avoid mixing */
434 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
435 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
437 /* File type is "TEXT" */
438 FILE_TYPE(FILE_TYPE_TEXT);
440 fff = my_fopen(buf, "a");
445 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
447 disable_diary = TRUE;
451 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
455 if (creature_ptr->current_floor_ptr->inside_arena)
456 note_level = _("アリーナ:", "Arane:");
457 else if (!creature_ptr->current_floor_ptr->dun_level)
458 note_level = _("地上:", "Surface:");
459 else if (q_idx && (is_fixed_quest_idx(q_idx)
460 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
461 note_level = _("クエスト:", "Quest:");
465 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
467 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
469 note_level = note_level_buf;
477 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
478 else fputs(_("*****日目\n", "Day *****\n"), fff);
482 case DIARY_DESCRIPTION:
486 fprintf(fff, "%s\n", note);
490 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
495 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
498 case DIARY_ART_SCROLL:
500 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
505 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
508 case DIARY_FIX_QUEST_C:
510 if (quest[num].flags & QUEST_FLAG_SILENT) break;
511 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
512 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
515 case DIARY_FIX_QUEST_F:
517 if (quest[num].flags & QUEST_FLAG_SILENT) break;
518 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
519 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
522 case DIARY_RAND_QUEST_C:
524 GAME_TEXT name[MAX_NLEN];
525 strcpy(name, r_name + r_info[quest[num].r_idx].name);
526 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
527 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
530 case DIARY_RAND_QUEST_F:
532 GAME_TEXT name[MAX_NLEN];
533 strcpy(name, r_name + r_info[quest[num].r_idx].name);
534 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
535 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
538 case DIARY_MAXDEAPTH:
540 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
541 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
542 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
543 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
548 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
549 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
550 _(d_name + d_info[num].name, (int)max_dlv[num]),
551 _((int)max_dlv[num], d_name + d_info[num].name));
557 if (q_idx && (is_fixed_quest_idx(q_idx)
558 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
560 to = _("地上", "the surface");
564 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
565 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
567 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
573 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
574 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
575 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
577 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
582 if (quest[num].flags & QUEST_FLAG_SILENT) break;
583 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
584 hour, min, note_level, quest[num].name);
587 case DIARY_TELEPORT_LEVEL:
589 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
590 hour, min, note_level);
595 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
600 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
608 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
609 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
612 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
613 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
615 if (num == MAX_ARENA_MONS)
617 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
618 " won all fights to become a Champion.\n"));
625 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
631 if (!creature_ptr->current_floor_ptr->dun_level)
632 to = _("地上", "the surface");
634 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
636 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
637 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
643 if (!creature_ptr->current_floor_ptr->dun_level)
644 to = _("地上", "the surface");
646 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
648 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
649 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
654 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
657 case DIARY_GAMESTART:
659 time_t ct = time((time_t*)0);
663 fprintf(fff, "%s %s", note, ctime(&ct));
666 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
669 case DIARY_NAMED_PET:
671 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
674 case RECORD_NAMED_PET_NAME:
675 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
677 case RECORD_NAMED_PET_UNNAME:
678 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
680 case RECORD_NAMED_PET_DISMISS:
681 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
683 case RECORD_NAMED_PET_DEATH:
684 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
686 case RECORD_NAMED_PET_MOVED:
687 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
689 case RECORD_NAMED_PET_LOST_SIGHT:
690 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
692 case RECORD_NAMED_PET_DESTROY:
693 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
695 case RECORD_NAMED_PET_EARTHQUAKE:
696 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
698 case RECORD_NAMED_PET_GENOCIDE:
699 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
701 case RECORD_NAMED_PET_WIZ_ZAP:
702 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
704 case RECORD_NAMED_PET_TELE_LEVEL:
705 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
707 case RECORD_NAMED_PET_BLAST:
708 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
710 case RECORD_NAMED_PET_HEAL_LEPER:
711 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
713 case RECORD_NAMED_PET_COMPACT:
714 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
716 case RECORD_NAMED_PET_LOSE_PARENT:
717 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
727 case DIARY_WIZARD_LOG:
728 fprintf(fff, "%s\n", note);
737 if (do_level) write_level = FALSE;
743 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
746 * @brief 日記のタイトル表記と内容出力 /
749 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
751 static void display_diary(player_type *creature_ptr)
753 char diary_title[256];
754 GAME_TEXT file_name[MAX_NLEN];
758 static const char subtitle[][30] = {
791 static const char subtitle[][51] = {
792 "Quest of The World's Toughest Body",
793 "Attack is the best form of defence.",
795 "An unexpected windfall",
796 "A drowning man will catch at a straw",
797 "Don't count your chickens before they are hatched.",
798 "It is no use crying over spilt milk.",
799 "Seeing is believing.",
800 "Strike the iron while it is hot.",
801 "I don't care what follows.",
802 "To dig a well to put out a house on fire.",
803 "Tomorrow is another day.",
804 "Easy come, easy go.",
805 "The more haste, the less speed.",
806 "Where there is life, there is hope.",
807 "There is no royal road to *WINNER*.",
808 "Danger past, God forgotten.",
809 "The best thing to do now is to run away.",
810 "Life is but an empty dream.",
811 "Dead men tell no tales.",
812 "A book that remains shut is but a block.",
813 "Misfortunes never come singly.",
814 "A little knowledge is a dangerous thing.",
815 "History repeats itself.",
816 "*WINNER* was not built in a day.",
817 "Ignorance is bliss.",
818 "To lose is to win?",
819 "No medicine can cure folly.",
820 "All good things come to an end.",
821 "M$ Empire strikes back.",
822 "To see is to believe",
824 "Quest of The World's Greatest Brain"
827 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
828 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
830 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
831 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
832 else if (IS_WIZARD_CLASS(creature_ptr))
833 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
834 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
837 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
839 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
842 /* Display the file contents */
843 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
848 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
851 static void add_diary_note(player_type *creature_ptr)
854 char bunshou[80] = "\0";
856 if (get_string(_("内容: ", "diary note: "), tmp, 79))
858 strcpy(bunshou, tmp);
859 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
864 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
867 static void do_cmd_last_get(player_type *creaute_ptr)
869 if (record_o_name[0] == '\0') return;
872 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
873 if (!get_check(buf)) return;
875 GAME_TURN turn_tmp = current_world_ptr->game_turn;
876 current_world_ptr->game_turn = record_turn;
877 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
878 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
879 current_world_ptr->game_turn = turn_tmp;
884 * @brief ファイル中の全日記記録を消去する /
887 static void do_cmd_erase_diary(void)
889 GAME_TEXT file_name[MAX_NLEN];
893 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
894 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
895 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
898 fff = my_fopen(buf, "w");
902 msg_format(_("記録を消去しました。", "deleted record."));
906 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
915 * @param crerature_ptr プレーヤーへの参照ポインタ
918 void do_cmd_diary(player_type *creature_ptr)
920 /* File type is "TEXT" */
921 FILE_TYPE(FILE_TYPE_TEXT);
924 /* Interact until done */
930 /* Ask for a choice */
931 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
933 /* Give some choices */
934 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
935 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
936 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
937 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
939 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
942 prt(_("コマンド:", "Command: "), 18, 0);
947 if (i == ESCAPE) break;
952 display_diary(creature_ptr);
955 add_diary_note(creature_ptr);
958 do_cmd_last_get(creature_ptr);
961 do_cmd_erase_diary();
965 prepare_movie_hooks();
967 default: /* Unknown option */
979 * @brief 画面を再描画するコマンドのメインルーチン
980 * Hack -- redraw the screen
981 * @param creature_ptr プレーヤーへの参照ポインタ
985 * This command performs various low level updates, clears all the "extra"
986 * windows, does a total redraw of the main window, and requests all of the
987 * interesting updates and redraws that I can think of.
989 * This command is also used to "instantiate" the results of the user
990 * selecting various things, such as graphics mode, so it must call
991 * the "TERM_XTRA_REACT" hook before redrawing the windows.
994 void do_cmd_redraw(player_type *creature_ptr)
996 Term_xtra(TERM_XTRA_REACT, 0);
998 /* Combine and Reorder the pack (later) */
999 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1000 creature_ptr->update |= (PU_TORCH);
1001 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1002 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1003 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1004 creature_ptr->update |= (PU_MONSTERS);
1006 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1008 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1009 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1012 handle_stuff(creature_ptr);
1014 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1016 /* Redraw every window */
1018 for (int j = 0; j < 8; j++)
1021 if (!angband_term[j]) continue;
1024 Term_activate(angband_term[j]);
1033 * @brief プレイヤーのステータス表示
1036 void do_cmd_player_status(player_type *creature_ptr)
1047 display_player(creature_ptr, mode);
1052 display_player(creature_ptr, mode);
1056 Term_putstr(2, 23, -1, TERM_WHITE,
1057 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1061 if (c == ESCAPE) break;
1066 get_name(creature_ptr);
1068 /* Process the player name */
1069 process_player_name(creature_ptr, FALSE);
1075 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1076 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1078 if (tmp[0] && (tmp[0] != ' '))
1080 file_character(creature_ptr, tmp);
1098 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1100 handle_stuff(creature_ptr);
1105 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1106 * Recall the most recent message
1109 void do_cmd_message_one(void)
1111 /* Recall one message */
1112 prt(format("> %s", message_str(0)), 0, 0);
1117 * @brief メッセージのログを表示するコマンドのメインルーチン
1118 * Recall the most recent message
1122 * Show previous messages to the user -BEN-
1124 * The screen format uses line 0 and 23 for headers and prompts,
1125 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1127 * This command shows you which commands you are viewing, and allows
1128 * you to "search" for strings in the recall.
1130 * Note that messages may be longer than 80 characters, but they are
1131 * displayed using "infinite" length, with a special sub-command to
1132 * "slide" the virtual display to the left or right.
1134 * Attempt to only hilite the matching portions of the string.
1137 void do_cmd_messages(int num_now)
1139 char shower_str[81];
1140 char finder_str[81];
1142 concptr shower = NULL;
1146 Term_get_size(&wid, &hgt);
1148 /* Number of message lines in a screen */
1149 num_lines = hgt - 4;
1152 strcpy(finder_str, "");
1155 strcpy(shower_str, "");
1157 /* Total messages */
1158 int n = message_num();
1160 /* Start on first message */
1165 /* Process requests until done */
1171 /* Dump up to 20 lines of messages */
1172 for (j = 0; (j < num_lines) && (i + j < n); j++)
1174 concptr msg = message_str(i + j);
1176 /* Dump the messages, bottom to top */
1177 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1179 if (!shower || !shower[0]) continue;
1181 /* Hilite "shower" */
1184 /* Display matches */
1185 while ((str = my_strstr(str, shower)) != NULL)
1187 int len = strlen(shower);
1189 /* Display the match */
1190 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1197 /* Erase remaining lines */
1198 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1200 /* Display header */
1202 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1203 i, i + j - 1, n), 0, 0);
1205 /* Display prompt (not very informative) */
1206 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1207 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1209 skey = inkey_special(TRUE);
1211 /* Exit on Escape */
1212 if (skey == ESCAPE) break;
1214 /* Hack -- Save the old index */
1219 /* Hack -- handle show */
1222 prt(_("強調: ", "Show: "), hgt - 1, 0);
1224 /* Get a "shower" string, or continue */
1225 strcpy(back_str, shower_str);
1226 if (askfor(shower_str, 80))
1229 shower = shower_str[0] ? shower_str : NULL;
1231 else strcpy(shower_str, back_str);
1235 /* Hack -- handle find */
1242 prt(_("検索: ", "Find: "), hgt - 1, 0);
1244 /* Get a "finder" string, or continue */
1245 strcpy(back_str, finder_str);
1246 if (!askfor(finder_str, 80))
1248 strcpy(finder_str, back_str);
1251 else if (!finder_str[0])
1253 shower = NULL; /* Stop showing */
1258 shower = finder_str;
1261 for (z = i + 1; z < n; z++)
1263 concptr msg = message_str(z);
1266 if (my_strstr(msg, finder_str))
1277 /* Recall 1 older message */
1279 /* Go to the oldest line */
1283 /* Recall 1 newer message */
1285 /* Go to the newest line */
1289 /* Recall 1 older message */
1294 /* Go older if legal */
1295 i = MIN(i + 1, n - num_lines);
1298 /* Recall 10 older messages */
1300 /* Go older if legal */
1301 i = MIN(i + 10, n - num_lines);
1304 /* Recall 20 older messages */
1309 /* Go older if legal */
1310 i = MIN(i + num_lines, n - num_lines);
1313 /* Recall 20 newer messages */
1317 /* Go newer (if able) */
1318 i = MAX(0, i - num_lines);
1321 /* Recall 10 newer messages */
1323 /* Go newer (if able) */
1327 /* Recall 1 newer messages */
1330 /* Go newer (if able) */
1335 /* Hack -- Error of some kind */
1344 * @brief prefファイルを選択して処理する /
1345 * Ask for a "user pref line" and process it
1346 * @param creature_ptr プレーヤーへの参照ポインタ
1349 * Allow absolute file names?
1351 void do_cmd_pref(player_type *creature_ptr)
1356 /* Ask for a "user pref command" */
1357 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1359 /* Process that pref command */
1360 (void)process_pref_file_command(creature_ptr, buf);
1365 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1366 * @param creature_ptr プレーヤーへの参照ポインタ
1369 void do_cmd_reload_autopick(player_type *creature_ptr)
1371 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1372 /* Load the file with messages */
1373 autopick_load_pref(creature_ptr, TRUE);
1378 * @brief マクロ情報をprefファイルに保存する /
1379 * @param fname ファイル名
1382 static errr macro_dump(concptr fname)
1384 static concptr mark = "Macro Dump";
1386 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1388 /* File type is "TEXT" */
1389 FILE_TYPE(FILE_TYPE_TEXT);
1391 /* Append to the file */
1392 if (!open_auto_dump(buf, mark)) return -1;
1395 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1398 for (int i = 0; i < macro__num; i++)
1400 /* Extract the action */
1401 ascii_to_text(buf, macro__act[i]);
1403 /* Dump the macro */
1404 auto_dump_printf("A:%s\n", buf);
1406 /* Extract the action */
1407 ascii_to_text(buf, macro__pat[i]);
1409 /* Dump normal macros */
1410 auto_dump_printf("P:%s\n", buf);
1413 auto_dump_printf("\n");
1422 * @brief マクロのトリガーキーを取得する /
1423 * Hack -- ask for a "trigger" (see below)
1424 * @param buf キー表記を保管するバッファ
1428 * Note the complex use of the "inkey()" function from "util.c".
1430 * Note that both "flush()" calls are extremely important.
1433 static void do_cmd_macro_aux(char *buf)
1437 /* Do not process macros */
1443 /* Read the pattern */
1450 /* Do not process macros */
1453 /* Do not wait for keys */
1456 /* Attempt to read a key */
1465 /* Convert the trigger */
1467 ascii_to_text(tmp, buf);
1469 /* Hack -- display the trigger */
1470 Term_addstr(-1, TERM_WHITE, tmp);
1475 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1476 * Hack -- ask for a keymap "trigger" (see below)
1477 * @param buf キー表記を取得するバッファ
1481 * Note that both "flush()" calls are extremely important. This may
1482 * no longer be true, since "util.c" is much simpler now.
1485 static void do_cmd_macro_aux_keymap(char *buf)
1495 /* Convert to ascii */
1496 ascii_to_text(tmp, buf);
1498 /* Hack -- display the trigger */
1499 Term_addstr(-1, TERM_WHITE, tmp);
1506 * @brief キーマップをprefファイルにダンプする /
1507 * Hack -- append all keymaps to the given file
1508 * @param fname ファイルネーム
1512 static errr keymap_dump(concptr fname)
1514 static concptr mark = "Keymap Dump";
1521 if (rogue_like_commands)
1523 mode = KEYMAP_MODE_ROGUE;
1529 mode = KEYMAP_MODE_ORIG;
1532 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1534 /* File type is "TEXT" */
1535 FILE_TYPE(FILE_TYPE_TEXT);
1537 /* Append to the file */
1538 if (!open_auto_dump(buf, mark)) return -1;
1541 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1544 for (int i = 0; i < 256; i++)
1548 /* Loop up the keymap */
1549 act = keymap_act[mode][i];
1551 /* Skip empty keymaps */
1554 /* Encode the key */
1557 ascii_to_text(key, buf);
1559 /* Encode the action */
1560 ascii_to_text(buf, act);
1562 /* Dump the macro */
1563 auto_dump_printf("A:%s\n", buf);
1564 auto_dump_printf("C:%d:%s\n", mode, key);
1573 * @brief マクロを設定するコマンドのメインルーチン /
1574 * Interact with "macros"
1578 * Note that the macro "action" must be defined before the trigger.
1580 * Could use some helpful instructions on this page.
1583 void do_cmd_macros(player_type *creature_ptr)
1591 if (rogue_like_commands)
1593 mode = KEYMAP_MODE_ROGUE;
1599 mode = KEYMAP_MODE_ORIG;
1602 /* File type is "TEXT" */
1603 FILE_TYPE(FILE_TYPE_TEXT);
1607 /* Process requests until done */
1611 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1613 /* Describe that action */
1614 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1616 /* Analyze the current action */
1617 ascii_to_text(buf, macro__buf);
1619 /* Display the current action */
1624 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1625 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1626 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1627 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1628 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1629 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1630 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1631 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1632 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1633 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1636 prt(_("コマンド: ", "Command: "), 16, 0);
1641 if (i == ESCAPE) break;
1643 /* Load a 'macro' file */
1649 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1652 prt(_("ファイル: ", "File: "), 18, 0);
1654 /* Default filename */
1655 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1657 /* Ask for a file */
1658 if (!askfor(tmp, 80)) continue;
1660 /* Process the given filename */
1661 err = process_pref_file(creature_ptr, tmp);
1664 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1669 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1673 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1681 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1684 prt(_("ファイル: ", "File: "), 18, 0);
1686 /* Default filename */
1687 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1689 /* Ask for a file */
1690 if (!askfor(tmp, 80)) continue;
1692 /* Dump the macros */
1693 (void)macro_dump(tmp);
1696 msg_print(_("マクロを追加しました。", "Appended macros."));
1705 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1709 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1711 /* Get a macro trigger */
1712 do_cmd_macro_aux(buf);
1714 /* Acquire action */
1715 k = macro_find_exact(buf);
1721 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1727 /* Obtain the action */
1728 strcpy(macro__buf, macro__act[k]);
1730 /* Analyze the current action */
1731 ascii_to_text(buf, macro__buf);
1733 /* Display the current action */
1737 msg_print(_("マクロを確認しました。", "Found a macro."));
1741 /* Create a macro */
1745 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1748 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1750 /* Get a macro trigger */
1751 do_cmd_macro_aux(buf);
1755 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1756 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1759 prt(_("マクロ行動: ", "Action: "), 20, 0);
1761 /* Convert to text */
1762 ascii_to_text(tmp, macro__buf);
1764 /* Get an encoded action */
1765 if (askfor(tmp, 80))
1767 /* Convert to ascii */
1768 text_to_ascii(macro__buf, tmp);
1770 /* Link the macro */
1771 macro_add(buf, macro__buf);
1774 msg_print(_("マクロを追加しました。", "Added a macro."));
1778 /* Remove a macro */
1782 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1785 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1787 /* Get a macro trigger */
1788 do_cmd_macro_aux(buf);
1790 /* Link the macro */
1791 macro_add(buf, buf);
1794 msg_print(_("マクロを削除しました。", "Removed a macro."));
1801 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1804 prt(_("ファイル: ", "File: "), 18, 0);
1806 /* Default filename */
1807 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1809 /* Ask for a file */
1810 if (!askfor(tmp, 80)) continue;
1812 /* Dump the macros */
1813 (void)keymap_dump(tmp);
1816 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1819 /* Query a keymap */
1825 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1828 prt(_("押すキー: ", "Keypress: "), 18, 0);
1830 /* Get a keymap trigger */
1831 do_cmd_macro_aux_keymap(buf);
1833 /* Look up the keymap */
1834 act = keymap_act[mode][(byte)(buf[0])];
1840 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1846 /* Obtain the action */
1847 strcpy(macro__buf, act);
1849 /* Analyze the current action */
1850 ascii_to_text(buf, macro__buf);
1852 /* Display the current action */
1856 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1860 /* Create a keymap */
1864 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1867 prt(_("押すキー: ", "Keypress: "), 18, 0);
1869 /* Get a keymap trigger */
1870 do_cmd_macro_aux_keymap(buf);
1874 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1875 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1878 prt(_("行動: ", "Action: "), 20, 0);
1880 /* Convert to text */
1881 ascii_to_text(tmp, macro__buf);
1883 /* Get an encoded action */
1884 if (askfor(tmp, 80))
1886 /* Convert to ascii */
1887 text_to_ascii(macro__buf, tmp);
1889 /* Free old keymap */
1890 string_free(keymap_act[mode][(byte)(buf[0])]);
1892 /* Make new keymap */
1893 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1896 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1900 /* Remove a keymap */
1904 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1907 prt(_("押すキー: ", "Keypress: "), 18, 0);
1909 /* Get a keymap trigger */
1910 do_cmd_macro_aux_keymap(buf);
1912 /* Free old keymap */
1913 string_free(keymap_act[mode][(byte)(buf[0])]);
1915 /* Make new keymap */
1916 keymap_act[mode][(byte)(buf[0])] = NULL;
1919 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1922 /* Enter a new action */
1926 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1930 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1931 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1934 prt(_("マクロ行動: ", "Action: "), 20, 0);
1936 /* Hack -- limit the value */
1939 /* Get an encoded action */
1940 if (!askfor(buf, 80)) continue;
1942 /* Extract an action */
1943 text_to_ascii(macro__buf, buf);
1959 * @brief キャラクタ色の明暗表現
1961 static concptr lighting_level_str[F_LIT_MAX] =
1976 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1977 * @param i 指定対象となるキャラクタコード
1978 * @param num 指定されたビジュアルIDを返す参照ポインタ
1979 * @param max ビジュアルIDの最大数
1980 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1982 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1989 sprintf(str, "%d", *num);
1991 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1994 tmp = (IDX)strtol(str, NULL, 0);
1995 if (tmp >= 0 && tmp < max)
1998 else if (isupper(i))
1999 *num = (*num + max - 1) % max;
2001 *num = (*num + 1) % max;
2007 * @brief キャラクタの変更メニュー表示
2008 * @param choice_msg 選択メッセージ
2011 static void print_visuals_menu(concptr choice_msg)
2013 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2015 /* Give some choices */
2016 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2017 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2018 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2019 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2020 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2021 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2022 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2023 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2024 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2025 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2026 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2029 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2034 * Interact with "visuals"
2036 void do_cmd_visuals(player_type *creature_ptr)
2041 bool need_redraw = FALSE;
2042 concptr empty_symbol = "<< ? >>";
2044 if (use_bigtile) empty_symbol = "<< ?? >>";
2046 /* File type is "TEXT" */
2047 FILE_TYPE(FILE_TYPE_TEXT);
2050 /* Interact until done */
2055 /* Ask for a choice */
2056 print_visuals_menu(NULL);
2061 if (i == ESCAPE) break;
2065 /* Load a 'pref' file */
2068 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2071 prt(_("ファイル: ", "File: "), 17, 0);
2073 /* Default filename */
2074 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2077 if (!askfor(tmp, 70)) continue;
2079 /* Process the given filename */
2080 (void)process_pref_file(creature_ptr, tmp);
2085 /* Dump monster attr/chars */
2088 static concptr mark = "Monster attr/chars";
2091 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2094 prt(_("ファイル: ", "File: "), 17, 0);
2096 /* Default filename */
2097 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2099 /* Get a filename */
2100 if (!askfor(tmp, 70)) continue;
2101 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2103 /* Append to the file */
2104 if (!open_auto_dump(buf, mark)) continue;
2107 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2110 for (i = 0; i < max_r_idx; i++)
2112 monster_race *r_ptr = &r_info[i];
2114 /* Skip non-entries */
2115 if (!r_ptr->name) continue;
2117 /* Dump a comment */
2118 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2120 /* Dump the monster attr/char info */
2121 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2122 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2128 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2133 /* Dump object attr/chars */
2136 static concptr mark = "Object attr/chars";
2137 KIND_OBJECT_IDX k_idx;
2140 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2143 prt(_("ファイル: ", "File: "), 17, 0);
2145 /* Default filename */
2146 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2148 /* Get a filename */
2149 if (!askfor(tmp, 70)) continue;
2150 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2152 /* Append to the file */
2153 if (!open_auto_dump(buf, mark)) continue;
2156 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2159 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2161 GAME_TEXT o_name[MAX_NLEN];
2162 object_kind *k_ptr = &k_info[k_idx];
2164 /* Skip non-entries */
2165 if (!k_ptr->name) continue;
2170 strip_name(o_name, k_idx);
2176 /* Prepare dummy object */
2177 object_prep(&forge, k_idx);
2179 /* Get un-shuffled flavor name */
2180 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2183 /* Dump a comment */
2184 auto_dump_printf("# %s\n", o_name);
2186 /* Dump the object attr/char info */
2187 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2188 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2194 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2199 /* Dump feature attr/chars */
2202 static concptr mark = "Feature attr/chars";
2205 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2208 prt(_("ファイル: ", "File: "), 17, 0);
2210 /* Default filename */
2211 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2213 /* Get a filename */
2214 if (!askfor(tmp, 70)) continue;
2215 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2217 /* Append to the file */
2218 if (!open_auto_dump(buf, mark)) continue;
2221 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2224 for (i = 0; i < max_f_idx; i++)
2226 feature_type *f_ptr = &f_info[i];
2228 /* Skip non-entries */
2229 if (!f_ptr->name) continue;
2231 /* Skip mimiccing features */
2232 if (f_ptr->mimic != i) continue;
2234 /* Dump a comment */
2235 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2237 /* Dump the feature attr/char info */
2238 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2239 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2240 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2241 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2247 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2252 /* Modify monster attr/chars (numeric operation) */
2255 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2256 static MONRACE_IDX r = 0;
2258 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2260 /* Hack -- query until done */
2263 monster_race *r_ptr = &r_info[r];
2267 TERM_COLOR da = r_ptr->d_attr;
2268 byte dc = r_ptr->d_char;
2269 TERM_COLOR ca = r_ptr->x_attr;
2270 byte cc = r_ptr->x_char;
2272 /* Label the object */
2273 Term_putstr(5, 17, -1, TERM_WHITE,
2274 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2276 /* Label the Default values */
2277 Term_putstr(10, 19, -1, TERM_WHITE,
2278 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2280 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2281 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2283 /* Label the Current values */
2284 Term_putstr(10, 20, -1, TERM_WHITE,
2285 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2287 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2288 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2291 Term_putstr(0, 22, -1, TERM_WHITE,
2292 _("コマンド (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): "));
2297 if (i == ESCAPE) break;
2299 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2300 else if (isupper(i)) c = 'a' + i - 'A';
2310 if (!cmd_visuals_aux(i, &r, max_r_idx))
2315 } while (!r_info[r].name);
2319 t = (int)r_ptr->x_attr;
2320 (void)cmd_visuals_aux(i, &t, 256);
2321 r_ptr->x_attr = (byte)t;
2325 t = (int)r_ptr->x_char;
2326 (void)cmd_visuals_aux(i, &t, 256);
2327 r_ptr->x_char = (byte)t;
2331 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2333 print_visuals_menu(choice_msg);
2341 /* Modify object attr/chars (numeric operation) */
2344 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2346 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2348 /* Hack -- query until done */
2351 object_kind *k_ptr = &k_info[k];
2355 TERM_COLOR da = k_ptr->d_attr;
2356 SYMBOL_CODE dc = k_ptr->d_char;
2357 TERM_COLOR ca = k_ptr->x_attr;
2358 SYMBOL_CODE cc = k_ptr->x_char;
2360 /* Label the object */
2361 Term_putstr(5, 17, -1, TERM_WHITE,
2362 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2363 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2365 /* Label the Default values */
2366 Term_putstr(10, 19, -1, TERM_WHITE,
2367 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2369 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2370 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2372 /* Label the Current values */
2373 Term_putstr(10, 20, -1, TERM_WHITE,
2374 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2376 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2377 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2380 Term_putstr(0, 22, -1, TERM_WHITE,
2381 _("コマンド (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): "));
2386 if (i == ESCAPE) break;
2388 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2389 else if (isupper(i)) c = 'a' + i - 'A';
2399 if (!cmd_visuals_aux(i, &k, max_k_idx))
2404 } while (!k_info[k].name);
2408 t = (int)k_ptr->x_attr;
2409 (void)cmd_visuals_aux(i, &t, 256);
2410 k_ptr->x_attr = (byte)t;
2414 t = (int)k_ptr->x_char;
2415 (void)cmd_visuals_aux(i, &t, 256);
2416 k_ptr->x_char = (byte)t;
2420 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2422 print_visuals_menu(choice_msg);
2430 /* Modify feature attr/chars (numeric operation) */
2433 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2435 static IDX lighting_level = F_LIT_STANDARD;
2436 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2438 /* Hack -- query until done */
2441 feature_type *f_ptr = &f_info[f];
2445 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2446 byte dc = f_ptr->d_char[lighting_level];
2447 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2448 byte cc = f_ptr->x_char[lighting_level];
2450 /* Label the object */
2452 Term_putstr(5, 17, -1, TERM_WHITE,
2453 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2454 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2456 /* Label the Default values */
2457 Term_putstr(10, 19, -1, TERM_WHITE,
2458 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2460 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2461 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2463 /* Label the Current values */
2465 Term_putstr(10, 20, -1, TERM_WHITE,
2466 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2468 Term_putstr(10, 20, -1, TERM_WHITE,
2469 format("Current attr/char = %3d / %3d", ca, cc));
2472 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2473 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2477 Term_putstr(0, 22, -1, TERM_WHITE,
2478 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2480 Term_putstr(0, 22, -1, TERM_WHITE,
2481 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2487 if (i == ESCAPE) break;
2489 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2490 else if (isupper(i)) c = 'a' + i - 'A';
2500 if (!cmd_visuals_aux(i, &f, max_f_idx))
2505 } while (!f_info[f].name || (f_info[f].mimic != f));
2509 t = (int)f_ptr->x_attr[lighting_level];
2510 (void)cmd_visuals_aux(i, &t, 256);
2511 f_ptr->x_attr[lighting_level] = (byte)t;
2515 t = (int)f_ptr->x_char[lighting_level];
2516 (void)cmd_visuals_aux(i, &t, 256);
2517 f_ptr->x_char[lighting_level] = (byte)t;
2521 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2524 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2528 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2530 print_visuals_menu(choice_msg);
2538 /* Modify monster attr/chars (visual mode) */
2540 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2543 /* Modify object attr/chars (visual mode) */
2545 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2548 /* Modify feature attr/chars (visual mode) */
2551 IDX lighting_level = F_LIT_STANDARD;
2552 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2560 reset_visuals(creature_ptr);
2562 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2566 /* Unknown option */
2577 if (need_redraw) do_cmd_redraw(creature_ptr);
2582 * Interact with "colors"
2584 void do_cmd_colors(player_type *creature_ptr)
2590 /* File type is "TEXT" */
2591 FILE_TYPE(FILE_TYPE_TEXT);
2595 /* Interact until done */
2600 /* Ask for a choice */
2601 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2603 /* Give some choices */
2604 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2605 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2606 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2609 prt(_("コマンド: ", "Command: "), 8, 0);
2613 if (i == ESCAPE) break;
2615 /* Load a 'pref' file */
2619 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2622 prt(_("ファイル: ", "File: "), 10, 0);
2625 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2628 if (!askfor(tmp, 70)) continue;
2630 /* Process the given filename */
2631 (void)process_pref_file(creature_ptr, tmp);
2633 /* Mega-Hack -- react to changes */
2634 Term_xtra(TERM_XTRA_REACT, 0);
2636 /* Mega-Hack -- redraw */
2643 static concptr mark = "Colors";
2646 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2649 prt(_("ファイル: ", "File: "), 10, 0);
2651 /* Default filename */
2652 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2654 /* Get a filename */
2655 if (!askfor(tmp, 70)) continue;
2656 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2658 /* Append to the file */
2659 if (!open_auto_dump(buf, mark)) continue;
2662 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2665 for (i = 0; i < 256; i++)
2667 int kv = angband_color_table[i][0];
2668 int rv = angband_color_table[i][1];
2669 int gv = angband_color_table[i][2];
2670 int bv = angband_color_table[i][3];
2672 concptr name = _("未知", "unknown");
2674 /* Skip non-entries */
2675 if (!kv && !rv && !gv && !bv) continue;
2677 /* Extract the color name */
2678 if (i < 16) name = color_names[i];
2680 /* Dump a comment */
2681 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2683 /* Dump the monster attr/char info */
2684 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2691 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2700 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2702 /* Hack -- query until done */
2709 /* Exhibit the normal colors */
2710 for (j = 0; j < 16; j++)
2712 /* Exhibit this color */
2713 Term_putstr(j * 4, 20, -1, a, "###");
2715 /* Exhibit all colors */
2716 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2719 /* Describe the color */
2720 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2722 /* Describe the color */
2723 Term_putstr(5, 10, -1, TERM_WHITE,
2724 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2726 /* Label the Current values */
2727 Term_putstr(5, 12, -1, TERM_WHITE,
2728 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2729 angband_color_table[a][0],
2730 angband_color_table[a][1],
2731 angband_color_table[a][2],
2732 angband_color_table[a][3]));
2735 Term_putstr(0, 14, -1, TERM_WHITE,
2736 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2741 if (i == ESCAPE) break;
2744 if (i == 'n') a = (byte)(a + 1);
2745 if (i == 'N') a = (byte)(a - 1);
2746 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2747 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2748 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2749 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2750 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2751 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2752 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2753 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2755 /* Hack -- react to changes */
2756 Term_xtra(TERM_XTRA_REACT, 0);
2758 /* Hack -- redraw */
2763 /* Unknown option */
2777 * Note something in the message recall
2779 void do_cmd_note(void)
2787 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2789 /* Ignore empty notes */
2790 if (!buf[0] || (buf[0] == ' ')) return;
2792 /* Add the note to the message recall */
2793 msg_format(_("メモ: %s", "Note: %s"), buf);
2798 * Mention the current version
2800 void do_cmd_version(void)
2802 #if FAKE_VER_EXTRA > 0
2803 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2804 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2806 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2807 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2813 * Array of feeling strings
2815 static concptr do_cmd_feeling_text[11] =
2817 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2818 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2819 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2820 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2821 _("とても悪い予感がする...", "You have a very bad feeling..."),
2822 _("悪い予感がする...", "You have a bad feeling..."),
2823 _("何か緊張する。", "You feel nervous."),
2824 _("少し不運な気がする...", "You feel your luck is turning..."),
2825 _("この場所は好きになれない。", "You don't like the look of this place."),
2826 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2827 _("なんて退屈なところだ...", "What a boring place...")
2830 static concptr do_cmd_feeling_text_combat[11] =
2832 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2833 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2834 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2835 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2836 _("とても悪い予感がする...", "You have a very bad feeling..."),
2837 _("悪い予感がする...", "You have a bad feeling..."),
2838 _("何か緊張する。", "You feel nervous."),
2839 _("少し不運な気がする...", "You feel your luck is turning..."),
2840 _("この場所は好きになれない。", "You don't like the look of this place."),
2841 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2842 _("なんて退屈なところだ...", "What a boring place...")
2845 static concptr do_cmd_feeling_text_lucky[11] =
2847 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2848 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2849 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2850 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2851 _("とても良い感じがする...", "You have a very good feeling..."),
2852 _("良い感じがする...", "You have a good feeling..."),
2853 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2854 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2855 _("見た感じ悪くはない...", "You like the look of this place..."),
2856 _("全然駄目ということはないが...", "This level can't be all bad..."),
2857 _("なんて退屈なところだ...", "What a boring place...")
2862 * Note that "feeling" is set to zero unless some time has passed.
2863 * Note that this is done when the level is GENERATED, not entered.
2865 void do_cmd_feeling(player_type *creature_ptr)
2867 if (creature_ptr->wild_mode) return;
2869 /* No useful feeling in quests */
2870 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2872 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2876 /* No useful feeling in town */
2877 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2879 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2881 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2885 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2889 /* No useful feeling in the wilderness */
2890 if (!creature_ptr->current_floor_ptr->dun_level)
2892 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2896 /* Display the feeling */
2897 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2898 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2899 else if (IS_ECHIZEN(creature_ptr))
2900 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2902 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2907 * Description of each monster group.
2909 static concptr monster_group_text[] =
2912 "ユニーク", /* "Uniques" */
2913 "乗馬可能なモンスター", /* "Riding" */
2914 "賞金首", /* "Wanted */
2915 "アンバーの王族", /* "Amberite" */
2944 /* "古代ドラゴン/ワイアーム", */
3005 /* "Ancient Dragon/Wyrm", */
3014 "Multi-Headed Reptile",
3019 "Reptile/Amphibian",
3020 "Spider/Scorpion/Tick",
3022 /* "Major Demon", */
3039 * Symbols of monsters in each group. Note the "Uniques" group
3040 * is handled differently.
3042 static concptr monster_group_char[] =
3099 "!$&()+./=>?[\\]`{|~",
3109 * todo 引数と戻り値について追記求む
3110 * Build a list of monster indexes in the given group.
3112 * mode & 0x01 : check for non-empty group
3113 * mode & 0x02 : visual operation only
3115 * @param creature_ptr プレーヤーへの参照ポインタ
3116 * @param grp_cur ???
3117 * @param mon_idx[] ???
3119 * @return The number of monsters in the group
3121 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3123 /* Get a list of x_char in this group */
3124 concptr group_char = monster_group_char[grp_cur];
3126 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3127 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3128 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3129 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3131 /* Check every race */
3133 for (IDX i = 0; i < max_r_idx; i++)
3135 /* Access the race */
3136 monster_race *r_ptr = &r_info[i];
3138 /* Skip empty race */
3139 if (!r_ptr->name) continue;
3141 /* Require known monsters */
3142 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3146 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3149 else if (grp_riding)
3151 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3154 else if (grp_wanted)
3156 bool wanted = FALSE;
3158 for (j = 0; j < MAX_BOUNTY; j++)
3160 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3161 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3167 if (!wanted) continue;
3170 else if (grp_amberite)
3172 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3177 /* Check for race in the group */
3178 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3182 mon_idx[mon_cnt++] = i;
3184 /* XXX Hack -- Just checking for non-empty group */
3185 if (mode & 0x01) break;
3188 /* Terminate the list */
3189 mon_idx[mon_cnt] = -1;
3192 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3194 /* Return the number of races */
3200 * Description of each monster group.
3202 static concptr object_group_text[] =
3205 "キノコ", /* "Mushrooms" */
3206 "薬", /* "Potions" */
3207 "油つぼ", /* "Flasks" */
3208 "巻物", /* "Scrolls" */
3210 "アミュレット", /* "Amulets" */
3211 "笛", /* "Whistle" */
3212 "光源", /* "Lanterns" */
3213 "魔法棒", /* "Wands" */
3216 "カード", /* "Cards" */
3227 "刀剣類", /* "Swords" */
3228 "鈍器", /* "Blunt Weapons" */
3229 "長柄武器", /* "Polearms" */
3230 "採掘道具", /* "Diggers" */
3231 "飛び道具", /* "Bows" */
3235 "軽装鎧", /* "Soft Armor" */
3236 "重装鎧", /* "Hard Armor" */
3237 "ドラゴン鎧", /* "Dragon Armor" */
3238 "盾", /* "Shields" */
3239 "クローク", /* "Cloaks" */
3240 "籠手", /* "Gloves" */
3241 "ヘルメット", /* "Helms" */
3243 "ブーツ", /* "Boots" */
3296 * TVALs of items in each group
3298 static byte object_group_tval[] =
3339 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3347 * Build a list of object indexes in the given group. Return the number
3348 * of objects in the group.
3350 * mode & 0x01 : check for non-empty group
3351 * mode & 0x02 : visual operation only
3353 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3355 KIND_OBJECT_IDX i, object_cnt = 0;
3358 /* Get a list of x_char in this group */
3359 byte group_tval = object_group_tval[grp_cur];
3361 /* Check every object */
3362 for (i = 0; i < max_k_idx; i++)
3364 /* Access the object */
3365 object_kind *k_ptr = &k_info[i];
3367 /* Skip empty objects */
3368 if (!k_ptr->name) continue;
3372 if (!current_world_ptr->wizard)
3374 /* Skip non-flavoured objects */
3375 if (!k_ptr->flavor) continue;
3377 /* Require objects ever seen */
3378 if (!k_ptr->aware) continue;
3381 /* Skip items with no distribution (special artifacts) */
3382 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3386 /* Check for objects in the group */
3387 if (TV_LIFE_BOOK == group_tval)
3389 /* Hack -- All spell books */
3390 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3392 /* Add the object */
3393 object_idx[object_cnt++] = i;
3397 else if (k_ptr->tval == group_tval)
3399 /* Add the object */
3400 object_idx[object_cnt++] = i;
3404 /* XXX Hack -- Just checking for non-empty group */
3405 if (mode & 0x01) break;
3408 /* Terminate the list */
3409 object_idx[object_cnt] = -1;
3411 /* Return the number of objects */
3417 * Description of each feature group.
3419 static concptr feature_group_text[] =
3427 * Build a list of feature indexes in the given group. Return the number
3428 * of features in the group.
3430 * mode & 0x01 : check for non-empty group
3432 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3434 /* Check every feature */
3435 FEAT_IDX feat_cnt = 0;
3436 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3438 feature_type *f_ptr = &f_info[i];
3440 /* Skip empty index */
3441 if (!f_ptr->name) continue;
3443 /* Skip mimiccing features */
3444 if (f_ptr->mimic != i) continue;
3447 feat_idx[feat_cnt++] = i;
3449 /* XXX Hack -- Just checking for non-empty group */
3450 if (mode & 0x01) break;
3453 /* Terminate the list */
3454 feat_idx[feat_cnt] = -1;
3456 /* Return the number of races */
3462 * Hack -- load a screen dump from a file
3464 void do_cmd_load_screen(void)
3468 SYMBOL_CODE c = ' ';
3474 Term_get_size(&wid, &hgt);
3475 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3477 /* Append to the file */
3478 fff = my_fopen(buf, "r");
3482 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3490 /* Load the screen */
3491 for (y = 0; okay; y++)
3493 /* Get a line of data including control code */
3494 if (!fgets(buf, 1024, fff)) okay = FALSE;
3496 /* Get the blank line */
3497 if (buf[0] == '\n' || buf[0] == '\0') break;
3499 /* Ignore too large screen image */
3500 if (y >= hgt) continue;
3503 for (x = 0; x < wid - 1; x++)
3506 if (buf[x] == '\n' || buf[x] == '\0') break;
3508 /* Put the attr/char */
3509 Term_draw(x, y, TERM_WHITE, buf[x]);
3513 /* Dump the screen */
3514 for (y = 0; okay; y++)
3516 /* Get a line of data including control code */
3517 if (!fgets(buf, 1024, fff)) okay = FALSE;
3519 /* Get the blank line */
3520 if (buf[0] == '\n' || buf[0] == '\0') break;
3522 /* Ignore too large screen image */
3523 if (y >= hgt) continue;
3526 for (x = 0; x < wid - 1; x++)
3529 if (buf[x] == '\n' || buf[x] == '\0') break;
3531 /* Get the attr/char */
3532 (void)(Term_what(x, y, &a, &c));
3534 /* Look up the attr */
3535 for (int i = 0; i < 16; i++)
3537 /* Use attr matches */
3538 if (hack[i] == buf[x]) a = (byte)i;
3541 /* Put the attr/char */
3542 Term_draw(x, y, a, c);
3548 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3556 // todo なぜこんな中途半端なところに? defineも…
3557 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3558 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3560 #define IM_FLAG_STR _("*", "* ")
3561 #define HAS_FLAG_STR _("+", "+ ")
3562 #define NO_FLAG_STR _("・", ". ")
3564 #define print_im_or_res_flag(IM, RES) \
3566 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3567 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3570 #define print_flag(TR) \
3572 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3576 /* XTRA HACK RESLIST */
3577 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)
3579 GAME_TEXT o_name[MAX_NLEN];
3580 BIT_FLAGS flgs[TR_FLAG_SIZE];
3582 if (!o_ptr->k_idx) return;
3583 if (o_ptr->tval != tval) return;
3585 /* Identified items only */
3586 if (!object_is_known(o_ptr)) return;
3589 * HACK:Ring of Lordly protection and Dragon equipment
3590 * have random resistances.
3592 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3593 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3594 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3595 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3596 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3597 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3598 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3599 || object_is_artifact(o_ptr);
3600 if (!is_special_item_type)
3606 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3608 while (o_name[i] && (i < 26))
3611 if (iskanji(o_name[i])) i++;
3620 o_name[i] = ' '; i++;
3626 fprintf(fff, "%s %s", where, o_name);
3628 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
3630 fputs(_("-------不明--------------- -------不明---------\n",
3631 "-------unknown------------ -------unknown------\n"), fff);
3635 object_flags_known(o_ptr, flgs);
3637 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3638 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3639 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3640 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3641 print_flag(TR_RES_POIS);
3642 print_flag(TR_RES_LITE);
3643 print_flag(TR_RES_DARK);
3644 print_flag(TR_RES_SHARDS);
3645 print_flag(TR_RES_SOUND);
3646 print_flag(TR_RES_NETHER);
3647 print_flag(TR_RES_NEXUS);
3648 print_flag(TR_RES_CHAOS);
3649 print_flag(TR_RES_DISEN);
3653 print_flag(TR_RES_BLIND);
3654 print_flag(TR_RES_FEAR);
3655 print_flag(TR_RES_CONF);
3656 print_flag(TR_FREE_ACT);
3657 print_flag(TR_SEE_INVIS);
3658 print_flag(TR_HOLD_EXP);
3659 print_flag(TR_TELEPATHY);
3660 print_flag(TR_SLOW_DIGEST);
3661 print_flag(TR_REGEN);
3662 print_flag(TR_LEVITATION);
3671 fprintf(fff, "%s\n", inven_res_label);
3676 * Display *ID* ed weapons/armors's resistances
3678 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3681 GAME_TEXT file_name[1024];
3683 OBJECT_TYPE_VALUE tval;
3689 /* Open a new file */
3690 fff = my_fopen_temp(file_name, 1024);
3693 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3698 fprintf(fff, "%s\n", inven_res_label);
3700 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3704 for (; j < 9; j++) fputc('\n', fff);
3706 fprintf(fff, "%s\n", inven_res_label);
3709 strcpy(where, _("装", "E "));
3710 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3712 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3715 strcpy(where, _("持", "I "));
3716 for (i = 0; i < INVEN_PACK; i++)
3718 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3721 st_ptr = &town_info[1].store[STORE_HOME];
3722 strcpy(where, _("家", "H "));
3723 for (i = 0; i < st_ptr->stock_num; i++)
3725 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3731 /* Display the file contents */
3732 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3737 void do_cmd_save_screen_html_aux(char *filename, int message)
3745 concptr html_head[] = {
3746 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3750 concptr html_foot[] = {
3752 "</body>\n</html>\n",
3757 Term_get_size(&wid, &hgt);
3759 /* File type is "TEXT" */
3760 FILE_TYPE(FILE_TYPE_TEXT);
3762 /* Append to the file */
3764 fff = my_fopen(filename, "w");
3770 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3777 if (message) screen_save();
3779 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3781 tmpfff = my_fopen(buf, "r");
3784 for (int i = 0; html_head[i]; i++)
3785 fputs(html_head[i], fff);
3789 bool is_first_line = TRUE;
3790 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3794 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3795 is_first_line = FALSE;
3799 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3801 fprintf(fff, "%s\n", buf);
3806 /* Dump the screen */
3807 for (TERM_LEN y = 0; y < hgt; y++)
3810 if (y != 0) fprintf(fff, "\n");
3813 TERM_COLOR a = 0, old_a = 0;
3815 for (TERM_LEN x = 0; x < wid - 1; x++)
3818 /* Get the attr/char */
3819 (void)(Term_what(x, y, &a, &c));
3823 case '&': cc = "&"; break;
3824 case '<': cc = "<"; break;
3825 case '>': cc = ">"; break;
3827 case 0x1f: c = '.'; break;
3828 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3833 if ((y == 0 && x == 0) || a != old_a)
3835 int rv = angband_color_table[a][1];
3836 int gv = angband_color_table[a][2];
3837 int bv = angband_color_table[a][3];
3838 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3839 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3844 fprintf(fff, "%s", cc);
3846 fprintf(fff, "%c", c);
3850 fprintf(fff, "</font>");
3854 for (int i = 0; html_foot[i]; i++)
3855 fputs(html_foot[i], fff);
3860 bool is_first_line = TRUE;
3861 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3865 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3866 is_first_line = FALSE;
3870 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3872 fprintf(fff, "%s\n", buf);
3885 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3894 * Hack -- save a screen dump to a file
3896 static void do_cmd_save_screen_html(void)
3898 char buf[1024], tmp[256] = "screen.html";
3900 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3902 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3906 do_cmd_save_screen_html_aux(buf, 1);
3911 * Redefinable "save_screen" action
3913 void(*screendump_aux)(void) = NULL;
3917 * Save a screen dump to a file
3918 * @param creature_ptr プレーヤーへの参照ポインタ
3921 void do_cmd_save_screen(player_type *creature_ptr)
3923 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3924 bool html_dump = FALSE;
3928 if (c == 'Y' || c == 'y')
3930 else if (c == 'H' || c == 'h')
3943 Term_get_size(&wid, &hgt);
3945 bool old_use_graphics = use_graphics;
3946 if (old_use_graphics)
3948 use_graphics = FALSE;
3949 reset_visuals(creature_ptr);
3950 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3951 handle_stuff(creature_ptr);
3956 do_cmd_save_screen_html();
3957 do_cmd_redraw(creature_ptr);
3960 /* Do we use a special screendump function ? */
3961 else if (screendump_aux)
3963 /* Dump the screen to a graphics file */
3964 (*screendump_aux)();
3966 else /* Dump the screen as text */
3970 SYMBOL_CODE c = ' ';
3973 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3975 /* File type is "TEXT" */
3976 FILE_TYPE(FILE_TYPE_TEXT);
3978 /* Append to the file */
3979 fff = my_fopen(buf, "w");
3983 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3990 /* Dump the screen */
3991 for (y = 0; y < hgt; y++)
3994 for (x = 0; x < wid - 1; x++)
3996 /* Get the attr/char */
3997 (void)(Term_what(x, y, &a, &c));
4007 fprintf(fff, "%s\n", buf);
4014 /* Dump the screen */
4015 for (y = 0; y < hgt; y++)
4018 for (x = 0; x < wid - 1; x++)
4020 /* Get the attr/char */
4021 (void)(Term_what(x, y, &a, &c));
4024 buf[x] = hack[a & 0x0F];
4031 fprintf(fff, "%s\n", buf);
4038 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4043 if (!old_use_graphics) return;
4045 use_graphics = TRUE;
4046 reset_visuals(creature_ptr);
4047 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4048 handle_stuff(creature_ptr);
4053 * todo okay = 既知のアーティファクト? と思われるが確証がない
4054 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4055 * Check the status of "artifacts"
4056 * @param player_ptr プレーヤーへの参照ポインタ
4059 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4061 /* Open a new file */
4063 GAME_TEXT file_name[1024];
4064 fff = my_fopen_temp(file_name, 1024);
4067 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4072 /* Allocate the "who" array */
4074 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4076 /* Allocate the "okay" array */
4078 C_MAKE(okay, max_a_idx, bool);
4080 /* Scan the artifacts */
4081 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4083 artifact_type *a_ptr = &a_info[k];
4088 /* Skip "empty" artifacts */
4089 if (!a_ptr->name) continue;
4091 /* Skip "uncreated" artifacts */
4092 if (!a_ptr->cur_num) continue;
4098 /* Check the dungeon */
4099 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4101 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4103 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4105 OBJECT_IDX this_o_idx, next_o_idx = 0;
4107 /* Scan all objects in the grid */
4108 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4111 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4112 next_o_idx = o_ptr->next_o_idx;
4114 /* Ignore non-artifacts */
4115 if (!object_is_fixed_artifact(o_ptr)) continue;
4117 /* Ignore known items */
4118 if (object_is_known(o_ptr)) continue;
4120 /* Note the artifact */
4121 okay[o_ptr->name1] = FALSE;
4126 /* Check the player_ptr->inventory_list and equipment */
4127 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4129 object_type *o_ptr = &player_ptr->inventory_list[i];
4131 /* Ignore non-objects */
4132 if (!o_ptr->k_idx) continue;
4134 /* Ignore non-artifacts */
4135 if (!object_is_fixed_artifact(o_ptr)) continue;
4137 /* Ignore known items */
4138 if (object_is_known(o_ptr)) continue;
4140 /* Note the artifact */
4141 okay[o_ptr->name1] = FALSE;
4145 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4147 if (okay[k]) who[n++] = k;
4151 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4153 /* Scan the artifacts */
4154 for (ARTIFACT_IDX k = 0; k < n; k++)
4156 artifact_type *a_ptr = &a_info[who[k]];
4157 GAME_TEXT base_name[MAX_NLEN];
4158 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4160 /* Obtain the base object type */
4161 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4170 /* Create fake object */
4171 object_prep(q_ptr, z);
4173 /* Make it an artifact */
4174 q_ptr->name1 = (byte)who[k];
4176 /* Display as if known */
4177 q_ptr->ident |= IDENT_STORE;
4179 /* Describe the artifact */
4180 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4183 /* Hack -- Build the artifact name */
4184 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4187 /* Free the "who" array */
4188 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4190 /* Free the "okay" array */
4191 C_KILL(okay, max_a_idx, bool);
4194 /* Display the file contents */
4195 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4201 * Display known uniques
4202 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4204 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4211 GAME_TEXT file_name[1024];
4214 int n_alive_surface = 0;
4215 int n_alive_over100 = 0;
4216 int n_alive_total = 0;
4219 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4221 /* Open a new file */
4222 fff = my_fopen_temp(file_name, 1024);
4226 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4231 /* Allocate the "who" array */
4232 C_MAKE(who, max_r_idx, MONRACE_IDX);
4234 /* Scan the monsters */
4236 for (IDX i = 1; i < max_r_idx; i++)
4238 monster_race *r_ptr = &r_info[i];
4241 if (!r_ptr->name) continue;
4243 /* Require unique monsters */
4244 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4246 /* Only display "known" uniques */
4247 if (!cheat_know && !r_ptr->r_sights) continue;
4249 /* Only print rarity <= 100 uniques */
4250 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4252 /* Only "alive" uniques */
4253 if (r_ptr->max_num == 0) continue;
4257 lev = (r_ptr->level - 1) / 10;
4261 if (max_lev < lev) max_lev = lev;
4263 else n_alive_over100++;
4265 else n_alive_surface++;
4267 /* Collect "appropriate" monsters */
4271 /* Sort the array by dungeon depth of monsters */
4272 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4274 if (n_alive_surface)
4276 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4277 n_alive_total += n_alive_surface;
4280 for (IDX i = 0; i <= max_lev; i++)
4282 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4283 n_alive_total += n_alive[i];
4286 if (n_alive_over100)
4288 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4289 n_alive_total += n_alive_over100;
4294 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4295 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4299 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4302 /* Scan the monster races */
4303 for (int k = 0; k < n; k++)
4305 monster_race *r_ptr = &r_info[who[k]];
4306 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4309 /* Free the "who" array */
4310 C_KILL(who, max_r_idx, s16b);
4313 /* Display the file contents */
4314 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4320 * Display weapon-exp
4322 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4324 /* Open a new file */
4326 GAME_TEXT file_name[1024];
4327 fff = my_fopen_temp(file_name, 1024);
4330 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4335 for (int i = 0; i < 5; i++)
4337 for (int num = 0; num < 64; num++)
4341 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4343 object_kind *k_ptr = &k_info[j];
4345 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4346 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4348 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4350 fprintf(fff, "%-25s ", tmp);
4351 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4352 else fprintf(fff, " ");
4353 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4354 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4363 /* Display the file contents */
4364 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4370 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4374 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4376 /* Open a new file */
4378 GAME_TEXT file_name[1024];
4379 fff = my_fopen_temp(file_name, 1024);
4382 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4387 if (creature_ptr->realm1 != REALM_NONE)
4389 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4390 for (SPELL_IDX i = 0; i < 32; i++)
4392 const magic_type *s_ptr;
4393 if (!is_magic(creature_ptr->realm1))
4395 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4399 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4402 if (s_ptr->slevel >= 99) continue;
4403 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4404 int exp_level = spell_exp_level(spell_exp);
4405 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4406 if (creature_ptr->realm1 == REALM_HISSATSU)
4407 fprintf(fff, "[--]");
4410 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4411 else fprintf(fff, " ");
4412 fprintf(fff, "%s", exp_level_str[exp_level]);
4415 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4420 if (creature_ptr->realm2 != REALM_NONE)
4422 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4423 for (SPELL_IDX i = 0; i < 32; i++)
4425 const magic_type *s_ptr;
4426 if (!is_magic(creature_ptr->realm1))
4428 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4432 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4435 if (s_ptr->slevel >= 99) continue;
4437 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4438 int exp_level = spell_exp_level(spell_exp);
4439 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4440 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4441 else fprintf(fff, " ");
4442 fprintf(fff, "%s", exp_level_str[exp_level]);
4443 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4450 /* Display the file contents */
4451 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4457 * @brief スキル情報を表示するコマンドのメインルーチン /
4461 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4463 char skill_name[GINOU_TEMPMAX][20] =
4465 _("マーシャルアーツ", "Martial Arts "),
4466 _("二刀流 ", "Dual Wielding "),
4467 _("乗馬 ", "Riding "),
4471 /* Open a new file */
4473 char file_name[1024];
4474 fff = my_fopen_temp(file_name, 1024);
4477 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4482 for (int i = 0; i < GINOU_TEMPMAX; i++)
4484 int skill_exp = creature_ptr->skill_exp[i];
4485 fprintf(fff, "%-20s ", skill_name[i]);
4486 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4487 else fprintf(fff, " ");
4488 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4489 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4495 /* Display the file contents */
4496 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4502 * @brief 現在のペットを表示するコマンドのメインルーチン /
4503 * Display current pets
4504 * @param creature_ptr プレーヤーへの参照ポインタ
4507 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4509 /* Open a new file */
4510 GAME_TEXT file_name[1024];
4512 fff = my_fopen_temp(file_name, 1024);
4515 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4520 /* Process the monsters (backwards) */
4521 monster_type *m_ptr;
4522 GAME_TEXT pet_name[MAX_NLEN];
4524 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4526 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4528 /* Ignore "dead" monsters */
4529 if (!monster_is_valid(m_ptr)) continue;
4531 /* Calculate "upkeep" for pets */
4532 if (!is_pet(m_ptr)) continue;
4535 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4536 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4539 int show_upkeep = calculate_upkeep(creature_ptr);
4541 fprintf(fff, "----------------------------------------------\n");
4543 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4545 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4547 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4551 /* Display the file contents */
4552 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4558 * @brief 現在のペットを表示するコマンドのメインルーチン /
4559 * @param creature_ptr プレーヤーへの参照ポインタ
4562 * @note the player ghosts are ignored.
4564 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4566 /* Open a new file */
4568 GAME_TEXT file_name[1024];
4569 fff = my_fopen_temp(file_name, 1024);
4572 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4577 /* Allocate the "who" array */
4579 C_MAKE(who, max_r_idx, MONRACE_IDX);
4583 /* Monsters slain */
4584 for (int kk = 1; kk < max_r_idx; kk++)
4586 monster_race *r_ptr = &r_info[kk];
4588 if (r_ptr->flags1 & (RF1_UNIQUE))
4590 bool dead = (r_ptr->max_num == 0);
4599 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4601 if (this_monster > 0)
4603 total += this_monster;
4609 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4612 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4614 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4620 /* Scan the monsters */
4622 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4624 monster_race *r_ptr = &r_info[i];
4626 /* Use that monster */
4627 if (r_ptr->name) who[n++] = i;
4630 /* Sort the array by dungeon depth of monsters */
4632 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4634 /* Scan the monster races */
4635 for (int k = 0; k < n; k++)
4637 monster_race *r_ptr = &r_info[who[k]];
4639 if (r_ptr->flags1 & (RF1_UNIQUE))
4641 bool dead = (r_ptr->max_num == 0);
4645 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4652 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4654 if (this_monster <= 0) continue;
4657 /* p,tは人と数える by ita */
4658 if (my_strchr("pt", r_ptr->d_char))
4659 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4661 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4663 if (this_monster < 2)
4665 if (my_strstr(r_name + r_ptr->name, "coins"))
4667 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4671 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4677 strcpy(ToPlural, (r_name + r_ptr->name));
4678 plural_aux(ToPlural);
4679 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4682 total += this_monster;
4685 fprintf(fff, "----------------------------------------------\n");
4687 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4689 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4692 /* Free the "who" array */
4693 C_KILL(who, max_r_idx, s16b);
4696 /* Display the file contents */
4697 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4703 * @brief モンスター情報リスト中のグループを表示する /
4704 * Display the object groups.
4708 * @param per_page リストの表示行
4709 * @param grp_idx グループのID配列
4710 * @param group_text グループ名の文字列配列
4711 * @param grp_cur 現在の選択ID
4712 * @param grp_top 現在の選択リスト最上部ID
4715 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)
4717 /* Display lines until done */
4718 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4720 /* Get the group index */
4721 int grp = grp_idx[grp_top + i];
4723 /* Choose a color */
4724 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4726 /* Erase the entire line */
4727 Term_erase(col, row + i, wid);
4729 /* Display the group label */
4730 c_put_str(attr, group_text[grp], row + i, col);
4736 * Move the cursor in a browser window
4738 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4739 IDX *list_cur, int list_cnt)
4744 IDX list = *list_cur;
4746 /* Extract direction */
4749 /* Hack -- scroll up full screen */
4754 /* Hack -- scroll down full screen */
4759 d = get_keymap_dir(ch);
4764 /* Diagonals - hack */
4765 if ((ddx[d] > 0) && ddy[d])
4770 Term_get_size(&wid, &hgt);
4772 browser_rows = hgt - 8;
4774 /* Browse group list */
4779 /* Move up or down */
4780 grp += ddy[d] * (browser_rows - 1);
4783 if (grp >= grp_cnt) grp = grp_cnt - 1;
4784 if (grp < 0) grp = 0;
4785 if (grp != old_grp) list = 0;
4788 /* Browse sub-list list */
4791 /* Move up or down */
4792 list += ddy[d] * browser_rows;
4795 if (list >= list_cnt) list = list_cnt - 1;
4796 if (list < 0) list = 0;
4808 if (col < 0) col = 0;
4809 if (col > 1) col = 1;
4816 /* Browse group list */
4821 /* Move up or down */
4825 if (grp >= grp_cnt) grp = grp_cnt - 1;
4826 if (grp < 0) grp = 0;
4827 if (grp != old_grp) list = 0;
4830 /* Browse sub-list list */
4833 /* Move up or down */
4834 list += (IDX)ddy[d];
4837 if (list >= list_cnt) list = list_cnt - 1;
4838 if (list < 0) list = 0;
4849 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4851 /* Clear the display lines */
4852 for (int i = 0; i < height; i++)
4854 Term_erase(col, row + i, width);
4857 /* Bigtile mode uses double width */
4858 if (use_bigtile) width /= 2;
4860 /* Display lines until done */
4861 for (int i = 0; i < height; i++)
4863 /* Display columns until done */
4864 for (int j = 0; j < width; j++)
4866 TERM_LEN x = col + j;
4867 TERM_LEN y = row + i;
4869 /* Bigtile mode uses double width */
4870 if (use_bigtile) x += j;
4872 TERM_COLOR ia = attr_top + i;
4873 SYMBOL_CODE ic = char_left + j;
4875 /* Ignore illegal characters */
4876 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4877 (!use_graphics && ic > 0x7f))
4883 /* Force correct code for both ASCII character and tile */
4884 if (c & 0x80) a |= 0x80;
4886 /* Display symbol */
4887 Term_queue_bigchar(x, y, a, c, 0, 0);
4894 * Place the cursor at the collect position for visual mode
4896 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4898 int i = (a & 0x7f) - attr_top;
4899 int j = c - char_left;
4901 TERM_LEN x = col + j;
4902 TERM_LEN y = row + i;
4904 /* Bigtile mode uses double width */
4905 if (use_bigtile) x += j;
4907 /* Place the cursor */
4913 * Do visual mode command -- Change symbols
4915 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4916 int height, int width,
4917 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4918 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4920 static TERM_COLOR attr_old = 0;
4921 static SYMBOL_CODE char_old = 0;
4926 if (*visual_list_ptr)
4929 *cur_attr_ptr = attr_old;
4930 *cur_char_ptr = char_old;
4931 *visual_list_ptr = FALSE;
4939 if (*visual_list_ptr)
4942 *visual_list_ptr = FALSE;
4943 *need_redraw = TRUE;
4951 if (!*visual_list_ptr)
4953 *visual_list_ptr = TRUE;
4955 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4956 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4958 attr_old = *cur_attr_ptr;
4959 char_old = *cur_char_ptr;
4970 /* Set the visual */
4971 attr_idx = *cur_attr_ptr;
4972 char_idx = *cur_char_ptr;
4974 /* Hack -- for feature lighting */
4975 for (i = 0; i < F_LIT_MAX; i++)
4977 attr_idx_feat[i] = 0;
4978 char_idx_feat[i] = 0;
4985 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4988 *cur_attr_ptr = attr_idx;
4989 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4990 if (!*visual_list_ptr) *need_redraw = TRUE;
4996 *cur_char_ptr = char_idx;
4997 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4998 if (!*visual_list_ptr) *need_redraw = TRUE;
5004 if (*visual_list_ptr)
5007 int d = get_keymap_dir(ch);
5008 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5009 SYMBOL_CODE c = *cur_char_ptr;
5011 if (use_bigtile) eff_width = width / 2;
5012 else eff_width = width;
5014 /* Restrict direction */
5015 if ((a == 0) && (ddy[d] < 0)) d = 0;
5016 if ((c == 0) && (ddx[d] < 0)) d = 0;
5017 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5018 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5020 a += (TERM_COLOR)ddy[d];
5021 c += (SYMBOL_CODE)ddx[d];
5023 /* Force correct code for both ASCII character and tile */
5024 if (c & 0x80) a |= 0x80;
5026 /* Set the visual */
5031 /* Move the frame */
5032 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5033 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5034 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5035 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5041 /* Visual mode command is not used */
5047 * Display the monsters in a group.
5049 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5050 int mon_cur, int mon_top, bool visual_only)
5052 /* Display lines until done */
5054 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5058 /* Get the race index */
5059 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5061 /* Access the race */
5062 monster_race *r_ptr = &r_info[r_idx];
5064 /* Choose a color */
5065 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5067 /* Display the name */
5068 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5070 /* Hack -- visual_list mode */
5073 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5076 if (current_world_ptr->wizard || visual_only)
5078 c_prt(attr, format("%d", r_idx), row + i, 62);
5081 /* Erase chars before overwritten by the race letter */
5082 Term_erase(69, row + i, 255);
5084 /* Display symbol */
5085 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5090 if (!(r_ptr->flags1 & RF1_UNIQUE))
5091 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5093 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5094 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5098 /* Clear remaining lines */
5099 for (; i < per_page; i++)
5101 Term_erase(col, row + i, 255);
5107 * todo 引数の詳細について加筆求む
5108 * Display known monsters.
5109 * @param creature_ptr プレーヤーへの参照ポインタ
5110 * @param need_redraw 画面の再描画が必要な時TRUE
5111 * @param visual_only ???
5112 * @param direct_r_idx モンスターID
5115 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5118 Term_get_size(&wid, &hgt);
5120 /* Allocate the "mon_idx" array */
5122 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5128 bool visual_list = FALSE;
5129 TERM_COLOR attr_top = 0;
5132 int browser_rows = hgt - 8;
5133 if (direct_r_idx < 0)
5135 mode = visual_only ? 0x03 : 0x01;
5137 /* Check every group */
5139 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5141 /* Measure the label */
5142 len = strlen(monster_group_text[i]);
5144 /* Save the maximum length */
5145 if (len > max) max = len;
5147 /* See if any monsters are known */
5148 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5150 /* Build a list of groups with known monsters */
5151 grp_idx[grp_cnt++] = i;
5159 mon_idx[0] = direct_r_idx;
5162 /* Terminate the list */
5165 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5166 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5169 /* Terminate the list */
5170 grp_idx[grp_cnt] = -1;
5172 mode = visual_only ? 0x02 : 0x00;
5173 IDX old_grp_cur = -1;
5186 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5187 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5188 prt(_("名前", "Name"), 4, max + 3);
5189 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5190 prt(_("文字", "Sym"), 4, 67);
5191 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5193 for (IDX i = 0; i < 78; i++)
5195 Term_putch(i, 5, TERM_WHITE, '=');
5198 if (direct_r_idx < 0)
5200 for (IDX i = 0; i < browser_rows; i++)
5202 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5209 if (direct_r_idx < 0)
5211 /* Scroll group list */
5212 if (grp_cur < grp_top) grp_top = grp_cur;
5213 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5215 /* Display a list of monster groups */
5216 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5218 if (old_grp_cur != grp_cur)
5220 old_grp_cur = grp_cur;
5222 /* Get a list of monsters in the current group */
5223 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5226 /* Scroll monster list */
5227 while (mon_cur < mon_top)
5228 mon_top = MAX(0, mon_top - browser_rows / 2);
5229 while (mon_cur >= mon_top + browser_rows)
5230 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5235 /* Display a list of monsters in the current group */
5236 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5242 /* Display a monster name */
5243 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5245 /* Display visual list below first monster */
5246 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5250 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5251 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5252 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5253 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5256 /* Get the current monster */
5257 monster_race *r_ptr;
5258 r_ptr = &r_info[mon_idx[mon_cur]];
5262 /* Mega Hack -- track this monster race */
5263 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5264 handle_stuff(creature_ptr);
5269 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5273 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5277 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5282 /* Do visual mode command if needed */
5283 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))
5285 if (direct_r_idx >= 0)
5311 /* Recall on screen */
5312 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5314 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5326 /* Move the cursor */
5327 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5334 /* Free the "mon_idx" array */
5335 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5340 * Display the objects in a group.
5342 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5343 int object_cur, int object_top, bool visual_only)
5345 /* Display lines until done */
5347 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5349 GAME_TEXT o_name[MAX_NLEN];
5352 object_kind *flavor_k_ptr;
5354 /* Get the object index */
5355 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5357 /* Access the object */
5358 object_kind *k_ptr = &k_info[k_idx];
5360 /* Choose a color */
5361 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5362 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5364 if (!visual_only && k_ptr->flavor)
5366 /* Appearance of this object is shuffled */
5367 flavor_k_ptr = &k_info[k_ptr->flavor];
5371 /* Appearance of this object is very normal */
5372 flavor_k_ptr = k_ptr;
5375 attr = ((i + object_top == object_cur) ? cursor : attr);
5377 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5380 strip_name(o_name, k_idx);
5385 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5388 /* Display the name */
5389 c_prt(attr, o_name, row + i, col);
5391 /* Hack -- visual_list mode */
5394 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);
5397 if (current_world_ptr->wizard || visual_only)
5399 c_prt(attr, format("%d", k_idx), row + i, 70);
5402 a = flavor_k_ptr->x_attr;
5403 c = flavor_k_ptr->x_char;
5405 /* Display symbol */
5406 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5409 /* Clear remaining lines */
5410 for (; i < per_page; i++)
5412 Term_erase(col, row + i, 255);
5418 * Describe fake object
5420 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5423 object_type object_type_body;
5424 o_ptr = &object_type_body;
5426 object_prep(o_ptr, k_idx);
5428 /* It's fully know */
5429 o_ptr->ident |= IDENT_KNOWN;
5430 handle_stuff(creature_ptr);
5432 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5434 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5440 * Display known objects
5442 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5444 IDX object_old, object_top;
5447 OBJECT_IDX *object_idx;
5449 bool visual_list = FALSE;
5450 TERM_COLOR attr_top = 0;
5455 Term_get_size(&wid, &hgt);
5457 int browser_rows = hgt - 8;
5459 /* Allocate the "object_idx" array */
5460 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5465 if (direct_k_idx < 0)
5467 mode = visual_only ? 0x03 : 0x01;
5469 /* Check every group */
5470 for (IDX i = 0; object_group_text[i] != NULL; i++)
5472 /* Measure the label */
5473 len = strlen(object_group_text[i]);
5475 /* Save the maximum length */
5476 if (len > max) max = len;
5478 /* See if any monsters are known */
5479 if (collect_objects(i, object_idx, mode))
5481 /* Build a list of groups with known monsters */
5482 grp_idx[grp_cnt++] = i;
5491 object_kind *k_ptr = &k_info[direct_k_idx];
5492 object_kind *flavor_k_ptr;
5494 if (!visual_only && k_ptr->flavor)
5496 /* Appearance of this object is shuffled */
5497 flavor_k_ptr = &k_info[k_ptr->flavor];
5501 /* Appearance of this object is very normal */
5502 flavor_k_ptr = k_ptr;
5505 object_idx[0] = direct_k_idx;
5506 object_old = direct_k_idx;
5509 /* Terminate the list */
5512 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5513 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5516 /* Terminate the list */
5517 grp_idx[grp_cnt] = -1;
5519 mode = visual_only ? 0x02 : 0x00;
5520 IDX old_grp_cur = -1;
5523 IDX object_cur = object_top = 0;
5529 object_kind *k_ptr, *flavor_k_ptr;
5536 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5537 if (direct_k_idx < 0) prt("グループ", 4, 0);
5538 prt("名前", 4, max + 3);
5539 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5542 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5543 if (direct_k_idx < 0) prt("Group", 4, 0);
5544 prt("Name", 4, max + 3);
5545 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5549 for (IDX i = 0; i < 78; i++)
5551 Term_putch(i, 5, TERM_WHITE, '=');
5554 if (direct_k_idx < 0)
5556 for (IDX i = 0; i < browser_rows; i++)
5558 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5565 if (direct_k_idx < 0)
5567 /* Scroll group list */
5568 if (grp_cur < grp_top) grp_top = grp_cur;
5569 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5571 /* Display a list of object groups */
5572 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5574 if (old_grp_cur != grp_cur)
5576 old_grp_cur = grp_cur;
5578 /* Get a list of objects in the current group */
5579 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5582 /* Scroll object list */
5583 while (object_cur < object_top)
5584 object_top = MAX(0, object_top - browser_rows / 2);
5585 while (object_cur >= object_top + browser_rows)
5586 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5591 /* Display a list of objects in the current group */
5592 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5596 object_top = object_cur;
5598 /* Display a list of objects in the current group */
5599 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5601 /* Display visual list below first object */
5602 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5605 /* Get the current object */
5606 k_ptr = &k_info[object_idx[object_cur]];
5608 if (!visual_only && k_ptr->flavor)
5610 /* Appearance of this object is shuffled */
5611 flavor_k_ptr = &k_info[k_ptr->flavor];
5615 /* Appearance of this object is very normal */
5616 flavor_k_ptr = k_ptr;
5621 prt(format("<方向>%s%s%s, ESC",
5622 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5623 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5624 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5627 prt(format("<dir>%s%s%s, ESC",
5628 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5629 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5630 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5636 /* Mega Hack -- track this object */
5637 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5639 /* The "current" object changed */
5640 if (object_old != object_idx[object_cur])
5642 handle_stuff(creature_ptr);
5644 /* Remember the "current" object */
5645 object_old = object_idx[object_cur];
5651 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5655 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5659 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5664 /* Do visual mode command if needed */
5665 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))
5667 if (direct_k_idx >= 0)
5692 /* Recall on screen */
5693 if (!visual_list && !visual_only && (grp_cnt > 0))
5695 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5703 /* Move the cursor */
5704 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5710 /* Free the "object_idx" array */
5711 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5716 * Display the features in a group.
5718 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5719 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5721 int lit_col[F_LIT_MAX], i;
5722 int f_idx_col = use_bigtile ? 62 : 64;
5724 /* Correct columns 1 and 4 */
5725 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5726 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5727 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5729 /* Display lines until done */
5730 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5733 FEAT_IDX f_idx = feat_idx[feat_top + i];
5734 feature_type *f_ptr = &f_info[f_idx];
5735 int row_i = row + i;
5737 /* Choose a color */
5738 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5740 /* Display the name */
5741 c_prt(attr, f_name + f_ptr->name, row_i, col);
5743 /* Hack -- visual_list mode */
5746 /* Display lighting level */
5747 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5749 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));
5751 if (current_world_ptr->wizard || visual_only)
5753 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5756 /* Display symbol */
5757 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);
5759 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5760 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5762 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5764 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5766 /* Mega-hack -- Use non-standard colour */
5767 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5769 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5773 /* Clear remaining lines */
5774 for (; i < per_page; i++)
5776 Term_erase(col, row + i, 255);
5782 * Interact with feature visuals.
5784 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5786 TERM_COLOR attr_old[F_LIT_MAX];
5787 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5788 SYMBOL_CODE char_old[F_LIT_MAX];
5789 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5792 Term_get_size(&wid, &hgt);
5794 /* Allocate the "feat_idx" array */
5796 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5802 FEAT_IDX grp_idx[100];
5803 TERM_COLOR attr_top = 0;
5804 bool visual_list = FALSE;
5806 TERM_LEN browser_rows = hgt - 8;
5807 if (direct_f_idx < 0)
5809 /* Check every group */
5810 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5812 /* Measure the label */
5813 len = strlen(feature_group_text[i]);
5815 /* Save the maximum length */
5816 if (len > max) max = len;
5818 /* See if any features are known */
5819 if (collect_features(feat_idx, 0x01))
5821 /* Build a list of groups with known features */
5822 grp_idx[grp_cnt++] = i;
5830 feature_type *f_ptr = &f_info[direct_f_idx];
5832 feat_idx[0] = direct_f_idx;
5835 /* Terminate the list */
5838 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5839 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5841 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5843 attr_old[i] = f_ptr->x_attr[i];
5844 char_old[i] = f_ptr->x_char[i];
5848 /* Terminate the list */
5849 grp_idx[grp_cnt] = -1;
5851 FEAT_IDX old_grp_cur = -1;
5852 FEAT_IDX grp_cur = 0;
5853 FEAT_IDX grp_top = 0;
5854 FEAT_IDX feat_cur = 0;
5855 FEAT_IDX feat_top = 0;
5856 TERM_LEN column = 0;
5859 TERM_COLOR *cur_attr_ptr;
5860 SYMBOL_CODE *cur_char_ptr;
5864 feature_type *f_ptr;
5870 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5871 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5872 prt(_("名前", "Name"), 4, max + 3);
5875 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5876 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5880 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5881 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5884 for (FEAT_IDX i = 0; i < 78; i++)
5886 Term_putch(i, 5, TERM_WHITE, '=');
5889 if (direct_f_idx < 0)
5891 for (FEAT_IDX i = 0; i < browser_rows; i++)
5893 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5900 if (direct_f_idx < 0)
5902 /* Scroll group list */
5903 if (grp_cur < grp_top) grp_top = grp_cur;
5904 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5906 /* Display a list of feature groups */
5907 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5909 if (old_grp_cur != grp_cur)
5911 old_grp_cur = grp_cur;
5913 /* Get a list of features in the current group */
5914 feat_cnt = collect_features(feat_idx, 0x00);
5917 /* Scroll feature list */
5918 while (feat_cur < feat_top)
5919 feat_top = MAX(0, feat_top - browser_rows / 2);
5920 while (feat_cur >= feat_top + browser_rows)
5921 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5926 /* Display a list of features in the current group */
5927 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5931 feat_top = feat_cur;
5933 /* Display a list of features in the current group */
5934 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5936 /* Display visual list below first object */
5937 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5941 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5942 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5943 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5946 /* Get the current feature */
5947 f_ptr = &f_info[feat_idx[feat_cur]];
5948 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5949 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5953 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5957 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5961 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5966 if (visual_list && ((ch == 'A') || (ch == 'a')))
5968 int prev_lighting_level = *lighting_level;
5972 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5973 else (*lighting_level)--;
5977 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5978 else (*lighting_level)++;
5981 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5982 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5984 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5985 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5990 else if ((ch == 'D') || (ch == 'd'))
5992 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5993 byte prev_x_char = f_ptr->x_char[*lighting_level];
5995 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
5999 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6000 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6002 if (prev_x_char != f_ptr->x_char[*lighting_level])
6003 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6005 else *need_redraw = TRUE;
6010 /* Do visual mode command if needed */
6011 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))
6015 /* Restore previous visual settings */
6017 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6019 f_ptr->x_attr[i] = attr_old[i];
6020 f_ptr->x_char[i] = char_old[i];
6027 if (direct_f_idx >= 0) flag = TRUE;
6028 else *lighting_level = F_LIT_STANDARD;
6031 /* Preserve current visual settings */
6034 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6036 attr_old[i] = f_ptr->x_attr[i];
6037 char_old[i] = f_ptr->x_char[i];
6039 *lighting_level = F_LIT_STANDARD;
6046 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6048 attr_idx_feat[i] = f_ptr->x_attr[i];
6049 char_idx_feat[i] = f_ptr->x_char[i];
6058 /* Allow TERM_DARK text */
6059 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6061 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6062 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6080 /* Move the cursor */
6081 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6087 /* Free the "feat_idx" array */
6088 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6093 * List wanted monsters
6094 * @param creature_ptr プレーヤーへの参照ポインタ
6097 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6099 /* Open a new file */
6101 GAME_TEXT file_name[1024];
6102 fff = my_fopen_temp(file_name, 1024);
6105 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6110 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
6111 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6113 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6114 fprintf(fff, "----------------------------------------------\n");
6116 bool listed = FALSE;
6117 for (int i = 0; i < MAX_BOUNTY; i++)
6119 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6121 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6128 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
6133 /* Display the file contents */
6134 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6139 * List virtues & status
6141 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6143 /* Open a new file */
6145 GAME_TEXT file_name[1024];
6146 fff = my_fopen_temp(file_name, 1024);
6149 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6154 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6155 dump_virtues(creature_ptr, fff);
6158 /* Display the file contents */
6159 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6166 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6168 /* Open a new file */
6170 GAME_TEXT file_name[1024];
6171 fff = my_fopen_temp(file_name, 1024);
6174 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6179 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6183 if (!d_info[i].maxdepth) continue;
6184 if (!max_dlv[i]) continue;
6185 if (d_info[i].final_guardian)
6187 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6189 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6191 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6196 /* Display the file contents */
6197 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6203 * List virtues & status
6206 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6208 /* Open a new file */
6210 GAME_TEXT file_name[1024];
6211 fff = my_fopen_temp(file_name, 1024);
6214 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6219 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6220 (2 * creature_ptr->hitdie +
6221 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6223 if (creature_ptr->knowledge & KNOW_HPRATE)
6224 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6225 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6227 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6228 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6230 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);
6231 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6234 dump_yourself(creature_ptr, fff);
6237 /* Display the file contents */
6238 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6244 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6245 * Print all active quests
6246 * @param creature_ptr プレーヤーへの参照ポインタ
6249 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6252 char rand_tmp_str[120] = "\0";
6253 GAME_TEXT name[MAX_NLEN];
6254 monster_race *r_ptr;
6255 int rand_level = 100;
6258 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6260 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6262 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6263 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6264 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6268 /* Set the quest number temporary */
6269 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6271 /* Clear the text */
6272 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6273 quest_text_line = 0;
6275 creature_ptr->current_floor_ptr->inside_quest = i;
6277 /* Get the quest text */
6278 init_flags = INIT_SHOW_TEXT;
6280 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6282 /* Reset the old quest number */
6283 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6285 /* No info from "silent" quests */
6286 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6290 if (quest[i].type != QUEST_TYPE_RANDOM)
6292 char note[80] = "\0";
6294 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6296 switch (quest[i].type)
6298 case QUEST_TYPE_KILL_LEVEL:
6299 case QUEST_TYPE_KILL_ANY_LEVEL:
6300 r_ptr = &r_info[quest[i].r_idx];
6301 strcpy(name, r_name + r_ptr->name);
6302 if (quest[i].max_num > 1)
6305 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6306 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6309 sprintf(note, " - kill %d %s, have killed %d.",
6310 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6314 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6317 case QUEST_TYPE_FIND_ARTIFACT:
6320 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6322 object_type *q_ptr = &forge;
6323 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6324 object_prep(q_ptr, k_idx);
6325 q_ptr->name1 = quest[i].k_idx;
6326 q_ptr->ident = IDENT_STORE;
6327 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6329 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
6331 case QUEST_TYPE_FIND_EXIT:
6332 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
6335 case QUEST_TYPE_KILL_NUMBER:
6337 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6338 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6340 sprintf(note, " - Kill %d monsters, have killed %d.",
6341 (int)quest[i].max_num, (int)quest[i].cur_num);
6345 case QUEST_TYPE_KILL_ALL:
6346 case QUEST_TYPE_TOWER:
6347 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6352 /* Print the quest info */
6353 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6354 quest[i].name, (int)quest[i].level, note);
6356 fputs(tmp_str, fff);
6358 if (quest[i].status == QUEST_STATUS_COMPLETED)
6360 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6361 fputs(tmp_str, fff);
6366 while (quest_text[k][0] && k < 10)
6368 fprintf(fff, " %s\n", quest_text[k]);
6375 /* QUEST_TYPE_RANDOM */
6376 if (quest[i].level >= rand_level)
6380 rand_level = quest[i].level;
6382 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6384 /* Print the quest info */
6385 r_ptr = &r_info[quest[i].r_idx];
6386 strcpy(name, r_name + r_ptr->name);
6388 if (quest[i].max_num <= 1)
6390 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6391 quest[i].name, (int)quest[i].level, name);
6396 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6397 quest[i].name, (int)quest[i].level,
6398 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6402 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6403 quest[i].name, (int)quest[i].level,
6404 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6408 /* Print the current random quest */
6409 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6411 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6415 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6418 char playtime_str[16];
6419 quest_type* const q_ptr = &quest[q_idx];
6421 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6422 if (is_fixed_quest_idx(q_idx))
6424 /* Set the quest number temporary */
6425 IDX old_quest = floor_ptr->inside_quest;
6427 floor_ptr->inside_quest = q_idx;
6430 init_flags = INIT_NAME_ONLY;
6432 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6434 /* Reset the old quest number */
6435 floor_ptr->inside_quest = old_quest;
6437 /* No info from "silent" quests */
6438 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6441 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6442 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6444 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
6446 /* Print the quest info */
6448 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6449 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6450 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6451 fputs(tmp_str, fff);
6455 /* Print the quest info */
6456 if (q_ptr->complev == 0)
6459 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6460 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6461 r_name + r_info[q_ptr->r_idx].name,
6462 (int)q_ptr->level, playtime_str);
6463 fputs(tmp_str, fff);
6468 _(" %-35s (%3d階) - レベル%2d - %s\n",
6469 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6470 r_name + r_info[q_ptr->r_idx].name,
6474 fputs(tmp_str, fff);
6480 * Print all finished quests
6481 * @param creature_ptr プレーヤーへの参照ポインタ
6482 * @param fff セーブファイル (展開済?)
6483 * @param quest_num[] 受注したことのあるクエスト群
6486 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6488 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6489 QUEST_IDX total = 0;
6490 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6492 QUEST_IDX q_idx = quest_num[i];
6493 quest_type* const q_ptr = &quest[q_idx];
6495 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6501 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6506 * Print all failed quests
6507 * @param creature_ptr プレーヤーへの参照ポインタ
6508 * @param fff セーブファイル (展開済?)
6509 * @param quest_num[] 受注したことのあるクエスト群
6512 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6514 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6515 QUEST_IDX total = 0;
6516 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6518 QUEST_IDX q_idx = quest_num[i];
6519 quest_type* const q_ptr = &quest[q_idx];
6521 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6522 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6528 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6533 * Print all random quests
6535 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6537 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6538 GAME_TEXT tmp_str[120];
6539 QUEST_IDX total = 0;
6540 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6542 /* No info from "silent" quests */
6543 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6545 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6549 /* Print the quest info */
6550 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6551 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6552 fputs(tmp_str, fff);
6556 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6560 * Print quest status of all active quests
6561 * @param creature_ptr プレーヤーへの参照ポインタ
6564 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6566 /* Open a new file */
6568 GAME_TEXT file_name[1024];
6569 fff = my_fopen_temp(file_name, 1024);
6572 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6577 /* Allocate Memory */
6579 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6581 /* Sort by compete level */
6582 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6584 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6586 /* Dump Quest Information */
6587 do_cmd_knowledge_quests_current(creature_ptr, fff);
6589 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6591 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6592 if (current_world_ptr->wizard)
6595 do_cmd_knowledge_quests_wiz_random(fff);
6600 /* Display the file contents */
6601 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6605 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6611 * @param player_ptr プレーヤーへの参照ポインタ
6614 static void do_cmd_knowledge_home(player_type *player_ptr)
6616 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6618 /* Open a new file */
6620 GAME_TEXT file_name[1024];
6621 fff = my_fopen_temp(file_name, 1024);
6624 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6629 /* Print all homes in the different towns */
6631 st_ptr = &town_info[1].store[STORE_HOME];
6633 /* Home -- if anything there */
6634 if (st_ptr->stock_num)
6639 /* Header with name of the town */
6640 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6642 /* Dump all available items */
6643 concptr paren = ")";
6644 GAME_TEXT o_name[MAX_NLEN];
6645 for (int i = 0; i < st_ptr->stock_num; i++)
6648 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6649 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6650 if (strlen(o_name) <= 80 - 3)
6652 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6658 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6659 if (iskanji(*t)) { t++; n++; }
6660 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6662 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6663 fprintf(fff, " %.77s\n", o_name + n);
6666 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6667 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6671 /* Add an empty line */
6672 fprintf(fff, "\n\n");
6677 /* Display the file contents */
6678 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6684 * Check the status of "autopick"
6686 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6688 /* Open a new file */
6690 GAME_TEXT file_name[1024];
6691 fff = my_fopen_temp(file_name, 1024);
6694 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6701 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6705 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6706 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6709 for (int k = 0; k < max_autopick; k++)
6712 byte act = autopick_list[k].action;
6713 if (act & DONT_AUTOPICK)
6715 tmp = _("放置", "Leave");
6717 else if (act & DO_AUTODESTROY)
6719 tmp = _("破壊", "Destroy");
6721 else if (act & DO_AUTOPICK)
6723 tmp = _("拾う", "Pickup");
6727 tmp = _("確認", "Query");
6730 if (act & DO_DISPLAY)
6731 fprintf(fff, "%11s", format("[%s]", tmp));
6733 fprintf(fff, "%11s", format("(%s)", tmp));
6735 tmp = autopick_line_from_entry(&autopick_list[k]);
6736 fprintf(fff, " %s", tmp);
6743 /* Display the file contents */
6744 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6750 * Interact with "knowledge"
6752 void do_cmd_knowledge(player_type *creature_ptr)
6755 bool need_redraw = FALSE;
6757 /* File type is "TEXT" */
6758 FILE_TYPE(FILE_TYPE_TEXT);
6761 /* Interact until done */
6766 /* Ask for a choice */
6767 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6768 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6770 /* Give some choices */
6774 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6775 prt("(2) 既知のアイテム の一覧", 7, 5);
6776 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6777 prt("(4) 既知のモンスター の一覧", 9, 5);
6778 prt("(5) 倒した敵の数 の一覧", 10, 5);
6779 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6780 prt("(7) 現在のペット の一覧", 12, 5);
6781 prt("(8) 我が家のアイテム の一覧", 13, 5);
6782 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6783 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6787 prt("(a) 自分に関する情報 の一覧", 6, 5);
6788 prt("(b) 突然変異 の一覧", 7, 5);
6789 prt("(c) 武器の経験値 の一覧", 8, 5);
6790 prt("(d) 魔法の経験値 の一覧", 9, 5);
6791 prt("(e) 技能の経験値 の一覧", 10, 5);
6792 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6793 prt("(g) 入ったダンジョン の一覧", 12, 5);
6794 prt("(h) 実行中のクエスト の一覧", 13, 5);
6795 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6800 prt("(1) Display known artifacts", 6, 5);
6801 prt("(2) Display known objects", 7, 5);
6802 prt("(3) Display remaining uniques", 8, 5);
6803 prt("(4) Display known monster", 9, 5);
6804 prt("(5) Display kill count", 10, 5);
6805 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6806 prt("(7) Display current pets", 12, 5);
6807 prt("(8) Display home inventory", 13, 5);
6808 prt("(9) Display *identified* equip.", 14, 5);
6809 prt("(0) Display terrain symbols.", 15, 5);
6813 prt("(a) Display about yourself", 6, 5);
6814 prt("(b) Display mutations", 7, 5);
6815 prt("(c) Display weapon proficiency", 8, 5);
6816 prt("(d) Display spell proficiency", 9, 5);
6817 prt("(e) Display misc. proficiency", 10, 5);
6818 prt("(f) Display virtues", 11, 5);
6819 prt("(g) Display dungeons", 12, 5);
6820 prt("(h) Display current quests", 13, 5);
6821 prt("(i) Display auto pick/destroy", 14, 5);
6825 prt(_("-続く-", "-more-"), 17, 8);
6826 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6827 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6828 /*prt("-) 前ページ", 21, 60);*/
6829 prt(_("コマンド:", "Command: "), 20, 0);
6832 if (i == ESCAPE) break;
6835 case ' ': /* Page change */
6839 case '1': /* Artifacts */
6840 do_cmd_knowledge_artifacts(creature_ptr);
6842 case '2': /* Objects */
6843 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6845 case '3': /* Uniques */
6846 do_cmd_knowledge_uniques(creature_ptr);
6848 case '4': /* Monsters */
6849 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6851 case '5': /* Kill count */
6852 do_cmd_knowledge_kill_count(creature_ptr);
6854 case '6': /* wanted */
6855 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6857 case '7': /* Pets */
6858 do_cmd_knowledge_pets(creature_ptr);
6860 case '8': /* Home */
6861 do_cmd_knowledge_home(creature_ptr);
6863 case '9': /* Resist list */
6864 do_cmd_knowledge_inven(creature_ptr);
6866 case '0': /* Feature list */
6868 IDX lighting_level = F_LIT_STANDARD;
6869 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6873 case 'a': /* Max stat */
6874 do_cmd_knowledge_stat(creature_ptr);
6876 case 'b': /* Mutations */
6877 do_cmd_knowledge_mutations(creature_ptr);
6879 case 'c': /* weapon-exp */
6880 do_cmd_knowledge_weapon_exp(creature_ptr);
6882 case 'd': /* spell-exp */
6883 do_cmd_knowledge_spell_exp(creature_ptr);
6885 case 'e': /* skill-exp */
6886 do_cmd_knowledge_skill_exp(creature_ptr);
6888 case 'f': /* Virtues */
6889 do_cmd_knowledge_virtues(creature_ptr);
6891 case 'g': /* Dungeon */
6892 do_cmd_knowledge_dungeon(creature_ptr);
6894 case 'h': /* Quests */
6895 do_cmd_knowledge_quests(creature_ptr);
6897 case 'i': /* Autopick */
6898 do_cmd_knowledge_autopick(creature_ptr);
6900 default: /* Unknown option */
6908 if (need_redraw) do_cmd_redraw(creature_ptr);
6913 * Check on the status of an active quest
6914 * @param creature_ptr プレーヤーへの参照ポインタ
6917 void do_cmd_checkquest(player_type *creature_ptr)
6919 /* File type is "TEXT" */
6920 FILE_TYPE(FILE_TYPE_TEXT);
6924 do_cmd_knowledge_quests(creature_ptr);
6930 * Display the time and date
6931 * @param creature_ptr プレーヤーへの参照ポインタ
6934 void do_cmd_time(player_type *creature_ptr)
6937 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6940 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6943 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6944 else strcpy(day_buf, "*****");
6946 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6947 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6951 if (!randint0(10) || creature_ptr->image)
6953 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6957 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6960 /* Open this file */
6962 fff = my_fopen(buf, "rt");
6966 /* Find this time */
6967 int full = hour * 100 + min;
6971 while (!my_fgets(fff, buf, sizeof(buf)))
6973 /* Ignore comments */
6974 if (!buf[0] || (buf[0] == '#')) continue;
6976 /* Ignore invalid lines */
6977 if (buf[1] != ':') continue;
6979 /* Process 'Start' */
6982 /* Extract the starting time */
6983 start = atoi(buf + 2);
6985 /* Assume valid for an hour */
6993 /* Extract the ending time */
6994 end = atoi(buf + 2);
6998 /* Ignore incorrect range */
6999 if ((start > full) || (full > end)) continue;
7001 /* Process 'Description' */
7006 /* Apply the randomizer */
7007 if (!randint0(num)) strcpy(desc, buf + 2);