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.
46 #include "core/show-file.h"
47 #include "io/read-pref-file.h"
48 #include "io/write-diary.h"
57 #include "view/display-player.h"
58 #include "player/process-name.h"
59 #include "player-effects.h"
60 #include "player-status.h"
61 #include "player-skill.h"
62 #include "player-personality.h"
69 #include "object-flavor.h"
70 #include "object-hook.h"
72 #include "monster-status.h"
73 #include "view-mainwindow.h"
74 #include "dungeon-file.h"
75 #include "io/interpret-pref-file.h"
78 #include "objectkind.h"
79 #include "floor-town.h"
80 #include "view-mainwindow.h" // 暫定。後で消す
84 // Mark strings for auto dump
85 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
86 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
88 // Variables for auto dump
89 static FILE *auto_dump_stream;
90 static concptr auto_dump_mark;
91 static int auto_dump_line_num;
93 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
94 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
95 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
97 // Clipboard variables for copy&paste in visual mode
98 static TERM_COLOR attr_idx = 0;
99 static SYMBOL_CODE char_idx = 0;
101 /* Hack -- for feature lighting */
102 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
103 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
105 // Encode the screen colors
106 static char hack[17] = "dwsorgbuDWvyRGBU";
109 * @brief prf出力内容を消去する /
110 * Remove old lines automatically generated before.
111 * @param orig_file 消去を行うファイル名
113 static void remove_auto_dump(concptr orig_file)
115 FILE *tmp_fff, *orig_fff;
119 bool between_mark = FALSE;
120 bool changed = FALSE;
122 long header_location = 0;
123 char header_mark_str[80];
124 char footer_mark_str[80];
127 /* Prepare a header/footer mark string */
128 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
129 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
131 mark_len = strlen(footer_mark_str);
133 /* Open an old dump file in read-only mode */
134 orig_fff = my_fopen(orig_file, "r");
136 /* If original file does not exist, nothing to do */
137 if (!orig_fff) return;
139 /* Open a new (temporary) file */
140 tmp_fff = my_fopen_temp(tmp_file, 1024);
144 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
149 /* Loop for every line */
153 if (my_fgets(orig_fff, buf, sizeof(buf)))
155 /* Read error: Assume End of File */
158 * Was looking for the footer, but not found.
160 * Since automatic dump might be edited by hand,
161 * it's dangerous to kill these lines.
162 * Seek back to the next line of the (pseudo) header,
167 fseek(orig_fff, header_location, SEEK_SET);
168 between_mark = FALSE;
172 /* Success -- End the loop */
179 /* We are looking for the header mark of automatic dump */
182 /* Is this line a header? */
183 if (!strcmp(buf, header_mark_str))
185 /* Memorise seek point of this line */
186 header_location = ftell(orig_fff);
188 /* Initialize counter for number of lines */
191 /* Look for the footer from now */
194 /* There are some changes */
201 /* Copy orginally lines */
202 fprintf(tmp_fff, "%s\n", buf);
208 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
209 /* We are looking for the footer mark of automatic dump */
210 /* Is this line a footer? */
211 if (!strncmp(buf, footer_mark_str, mark_len))
216 * Compare the number of lines
218 * If there is an inconsistency between
219 * actual number of lines and the
220 * number here, the automatic dump
221 * might be edited by hand. So it's
222 * dangerous to kill these lines.
223 * Seek back to the next line of the
224 * (pseudo) header, and read again.
226 if (!sscanf(buf + mark_len, " (%d)", &tmp)
229 fseek(orig_fff, header_location, SEEK_SET);
232 /* Look for another header */
233 between_mark = FALSE;
238 /* Ignore old line, and count number of lines */
246 /* If there are some changes, overwrite the original file with new one */
249 /* Copy contents of temporary file */
250 tmp_fff = my_fopen(tmp_file, "r");
251 orig_fff = my_fopen(orig_file, "w");
253 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
254 fprintf(orig_fff, "%s\n", buf);
265 * @brief prfファイルのフォーマットに従った内容を出力する /
266 * Dump a formatted line, using "vstrnfmt()".
269 static void auto_dump_printf(concptr fmt, ...)
276 /* Begin the Varargs Stuff */
279 /* Format the args, save the length */
280 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
282 /* End the Varargs Stuff */
285 /* Count number of lines */
286 for (p = buf; *p; p++)
288 if (*p == '\n') auto_dump_line_num++;
292 fprintf(auto_dump_stream, "%s", buf);
297 * @brief prfファイルをファイルオープンする /
298 * Open file to append auto dump.
300 * @param mark 出力するヘッダマーク
301 * @return ファイルポインタを取得できたらTRUEを返す
303 static bool open_auto_dump(concptr buf, concptr mark)
305 char header_mark_str[80];
307 /* Save the mark string */
308 auto_dump_mark = mark;
310 /* Prepare a header mark string */
311 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
313 /* Remove old macro dumps */
314 remove_auto_dump(buf);
316 /* Append to the file */
317 auto_dump_stream = my_fopen(buf, "a");
320 if (!auto_dump_stream)
322 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
330 fprintf(auto_dump_stream, "%s\n", header_mark_str);
332 /* Initialize counter */
333 auto_dump_line_num = 0;
335 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
336 "# *Warning!* The lines below are an automatic dump.\n"));
337 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
338 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
343 * @brief prfファイルをファイルクローズする /
344 * Append foot part and close auto dump.
347 static void close_auto_dump(void)
349 char footer_mark_str[80];
351 /* Prepare a footer mark string */
352 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
354 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
355 "# *Warning!* The lines below are an automatic dump.\n"));
356 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
357 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
359 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
361 my_fclose(auto_dump_stream);
368 * @brief Return suffix of ordinal number
370 * @return pointer of suffix string.
372 concptr get_ordinal_number_suffix(int num)
374 num = ABS(num) % 100;
378 return (num == 11) ? "th" : "st";
380 return (num == 12) ? "th" : "nd";
382 return (num == 13) ? "th" : "rd";
389 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
392 * @brief 日記のタイトル表記と内容出力 /
395 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
397 static void display_diary(player_type *creature_ptr)
399 char diary_title[256];
400 GAME_TEXT file_name[MAX_NLEN];
404 static const char subtitle[][30] = {
437 static const char subtitle[][51] = {
438 "Quest of The World's Toughest Body",
439 "Attack is the best form of defence.",
441 "An unexpected windfall",
442 "A drowning man will catch at a straw",
443 "Don't count your chickens before they are hatched.",
444 "It is no use crying over spilt milk.",
445 "Seeing is believing.",
446 "Strike the iron while it is hot.",
447 "I don't care what follows.",
448 "To dig a well to put out a house on fire.",
449 "Tomorrow is another day.",
450 "Easy come, easy go.",
451 "The more haste, the less speed.",
452 "Where there is life, there is hope.",
453 "There is no royal road to *WINNER*.",
454 "Danger past, God forgotten.",
455 "The best thing to do now is to run away.",
456 "Life is but an empty dream.",
457 "Dead men tell no tales.",
458 "A book that remains shut is but a block.",
459 "Misfortunes never come singly.",
460 "A little knowledge is a dangerous thing.",
461 "History repeats itself.",
462 "*WINNER* was not built in a day.",
463 "Ignorance is bliss.",
464 "To lose is to win?",
465 "No medicine can cure folly.",
466 "All good things come to an end.",
467 "M$ Empire strikes back.",
468 "To see is to believe",
470 "Quest of The World's Greatest Brain"
473 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
474 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
476 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
477 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
478 else if (IS_WIZARD_CLASS(creature_ptr))
479 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
480 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
483 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
485 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
488 /* Display the file contents */
489 (void)show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
494 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
497 static void add_diary_note(player_type *creature_ptr)
500 char bunshou[80] = "\0";
502 if (get_string(_("内容: ", "diary note: "), tmp, 79))
504 strcpy(bunshou, tmp);
505 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
510 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
513 static void do_cmd_last_get(player_type *creaute_ptr)
515 if (record_o_name[0] == '\0') return;
518 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
519 if (!get_check(buf)) return;
521 GAME_TURN turn_tmp = current_world_ptr->game_turn;
522 current_world_ptr->game_turn = record_turn;
523 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
524 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
525 current_world_ptr->game_turn = turn_tmp;
530 * @brief ファイル中の全日記記録を消去する /
533 static void do_cmd_erase_diary(void)
535 GAME_TEXT file_name[MAX_NLEN];
539 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
540 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
541 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
544 fff = my_fopen(buf, "w");
548 msg_format(_("記録を消去しました。", "deleted record."));
552 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
561 * @param crerature_ptr プレーヤーへの参照ポインタ
564 void do_cmd_diary(player_type *creature_ptr)
566 /* File type is "TEXT" */
567 FILE_TYPE(FILE_TYPE_TEXT);
570 /* Interact until done */
576 /* Ask for a choice */
577 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
579 /* Give some choices */
580 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
581 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
582 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
583 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
585 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
588 prt(_("コマンド:", "Command: "), 18, 0);
593 if (i == ESCAPE) break;
598 display_diary(creature_ptr);
601 add_diary_note(creature_ptr);
604 do_cmd_last_get(creature_ptr);
607 do_cmd_erase_diary();
611 prepare_movie_hooks();
613 default: /* Unknown option */
625 * @brief 画面を再描画するコマンドのメインルーチン
626 * Hack -- redraw the screen
627 * @param creature_ptr プレーヤーへの参照ポインタ
631 * This command performs various low level updates, clears all the "extra"
632 * windows, does a total redraw of the main window, and requests all of the
633 * interesting updates and redraws that I can think of.
635 * This command is also used to "instantiate" the results of the user
636 * selecting various things, such as graphics mode, so it must call
637 * the "TERM_XTRA_REACT" hook before redrawing the windows.
640 void do_cmd_redraw(player_type *creature_ptr)
642 Term_xtra(TERM_XTRA_REACT, 0);
644 /* Combine and Reorder the pack (later) */
645 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
646 creature_ptr->update |= (PU_TORCH);
647 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
648 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
649 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
650 creature_ptr->update |= (PU_MONSTERS);
652 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
654 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
655 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
658 handle_stuff(creature_ptr);
660 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
662 /* Redraw every window */
664 for (int j = 0; j < 8; j++)
667 if (!angband_term[j]) continue;
670 Term_activate(angband_term[j]);
679 * @brief プレイヤーのステータス表示
682 void do_cmd_player_status(player_type *creature_ptr)
693 display_player(creature_ptr, mode, map_name);
698 display_player(creature_ptr, mode, map_name);
702 Term_putstr(2, 23, -1, TERM_WHITE,
703 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
707 if (c == ESCAPE) break;
712 get_name(creature_ptr);
714 /* Process the player name */
715 process_player_name(creature_ptr, FALSE);
721 sprintf(tmp, "%s.txt", creature_ptr->base_name);
722 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
724 if (tmp[0] && (tmp[0] != ' '))
726 file_character(creature_ptr, tmp, update_playtime, display_player, map_name);
744 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
746 handle_stuff(creature_ptr);
751 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
752 * Recall the most recent message
755 void do_cmd_message_one(void)
757 /* Recall one message */
758 prt(format("> %s", message_str(0)), 0, 0);
763 * @brief メッセージのログを表示するコマンドのメインルーチン
764 * Recall the most recent message
768 * Show previous messages to the user -BEN-
770 * The screen format uses line 0 and 23 for headers and prompts,
771 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
773 * This command shows you which commands you are viewing, and allows
774 * you to "search" for strings in the recall.
776 * Note that messages may be longer than 80 characters, but they are
777 * displayed using "infinite" length, with a special sub-command to
778 * "slide" the virtual display to the left or right.
780 * Attempt to only hilite the matching portions of the string.
783 void do_cmd_messages(int num_now)
788 concptr shower = NULL;
792 Term_get_size(&wid, &hgt);
794 /* Number of message lines in a screen */
798 strcpy(finder_str, "");
801 strcpy(shower_str, "");
804 int n = message_num();
806 /* Start on first message */
811 /* Process requests until done */
817 /* Dump up to 20 lines of messages */
818 for (j = 0; (j < num_lines) && (i + j < n); j++)
820 concptr msg = message_str(i + j);
822 /* Dump the messages, bottom to top */
823 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
825 if (!shower || !shower[0]) continue;
827 /* Hilite "shower" */
830 /* Display matches */
831 while ((str = my_strstr(str, shower)) != NULL)
833 int len = strlen(shower);
835 /* Display the match */
836 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
843 /* Erase remaining lines */
844 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
848 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
849 i, i + j - 1, n), 0, 0);
851 /* Display prompt (not very informative) */
852 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
853 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
855 skey = inkey_special(TRUE);
858 if (skey == ESCAPE) break;
860 /* Hack -- Save the old index */
865 /* Hack -- handle show */
868 prt(_("強調: ", "Show: "), hgt - 1, 0);
870 /* Get a "shower" string, or continue */
871 strcpy(back_str, shower_str);
872 if (askfor(shower_str, 80))
875 shower = shower_str[0] ? shower_str : NULL;
877 else strcpy(shower_str, back_str);
881 /* Hack -- handle find */
888 prt(_("検索: ", "Find: "), hgt - 1, 0);
890 /* Get a "finder" string, or continue */
891 strcpy(back_str, finder_str);
892 if (!askfor(finder_str, 80))
894 strcpy(finder_str, back_str);
897 else if (!finder_str[0])
899 shower = NULL; /* Stop showing */
907 for (z = i + 1; z < n; z++)
909 concptr msg = message_str(z);
912 if (my_strstr(msg, finder_str))
923 /* Recall 1 older message */
925 /* Go to the oldest line */
929 /* Recall 1 newer message */
931 /* Go to the newest line */
935 /* Recall 1 older message */
940 /* Go older if legal */
941 i = MIN(i + 1, n - num_lines);
944 /* Recall 10 older messages */
946 /* Go older if legal */
947 i = MIN(i + 10, n - num_lines);
950 /* Recall 20 older messages */
955 /* Go older if legal */
956 i = MIN(i + num_lines, n - num_lines);
959 /* Recall 20 newer messages */
963 /* Go newer (if able) */
964 i = MAX(0, i - num_lines);
967 /* Recall 10 newer messages */
969 /* Go newer (if able) */
973 /* Recall 1 newer messages */
976 /* Go newer (if able) */
981 /* Hack -- Error of some kind */
990 * @brief prefファイルを選択して処理する /
991 * Ask for a "user pref line" and process it
992 * @param creature_ptr プレーヤーへの参照ポインタ
995 * Allow absolute file names?
997 void do_cmd_pref(player_type *creature_ptr)
1002 /* Ask for a "user pref command" */
1003 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1005 /* Process that pref command */
1006 (void)interpret_pref_file(creature_ptr, buf);
1011 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1012 * @param creature_ptr プレーヤーへの参照ポインタ
1015 void do_cmd_reload_autopick(player_type *creature_ptr)
1017 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1018 /* Load the file with messages */
1019 autopick_load_pref(creature_ptr, TRUE);
1024 * @brief マクロ情報をprefファイルに保存する /
1025 * @param fname ファイル名
1028 static errr macro_dump(concptr fname)
1030 static concptr mark = "Macro Dump";
1032 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1034 /* File type is "TEXT" */
1035 FILE_TYPE(FILE_TYPE_TEXT);
1037 /* Append to the file */
1038 if (!open_auto_dump(buf, mark)) return -1;
1041 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1044 for (int i = 0; i < macro__num; i++)
1046 /* Extract the action */
1047 ascii_to_text(buf, macro__act[i]);
1049 /* Dump the macro */
1050 auto_dump_printf("A:%s\n", buf);
1052 /* Extract the action */
1053 ascii_to_text(buf, macro__pat[i]);
1055 /* Dump normal macros */
1056 auto_dump_printf("P:%s\n", buf);
1059 auto_dump_printf("\n");
1068 * @brief マクロのトリガーキーを取得する /
1069 * Hack -- ask for a "trigger" (see below)
1070 * @param buf キー表記を保管するバッファ
1074 * Note the complex use of the "inkey()" function from "util.c".
1076 * Note that both "flush()" calls are extremely important.
1079 static void do_cmd_macro_aux(char *buf)
1083 /* Do not process macros */
1089 /* Read the pattern */
1096 /* Do not process macros */
1099 /* Do not wait for keys */
1102 /* Attempt to read a key */
1111 /* Convert the trigger */
1113 ascii_to_text(tmp, buf);
1115 /* Hack -- display the trigger */
1116 Term_addstr(-1, TERM_WHITE, tmp);
1121 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1122 * Hack -- ask for a keymap "trigger" (see below)
1123 * @param buf キー表記を取得するバッファ
1127 * Note that both "flush()" calls are extremely important. This may
1128 * no longer be true, since "util.c" is much simpler now.
1131 static void do_cmd_macro_aux_keymap(char *buf)
1141 /* Convert to ascii */
1142 ascii_to_text(tmp, buf);
1144 /* Hack -- display the trigger */
1145 Term_addstr(-1, TERM_WHITE, tmp);
1152 * @brief キーマップをprefファイルにダンプする /
1153 * Hack -- append all keymaps to the given file
1154 * @param fname ファイルネーム
1158 static errr keymap_dump(concptr fname)
1160 static concptr mark = "Keymap Dump";
1167 if (rogue_like_commands)
1169 mode = KEYMAP_MODE_ROGUE;
1175 mode = KEYMAP_MODE_ORIG;
1178 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1180 /* File type is "TEXT" */
1181 FILE_TYPE(FILE_TYPE_TEXT);
1183 /* Append to the file */
1184 if (!open_auto_dump(buf, mark)) return -1;
1187 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1190 for (int i = 0; i < 256; i++)
1194 /* Loop up the keymap */
1195 act = keymap_act[mode][i];
1197 /* Skip empty keymaps */
1200 /* Encode the key */
1203 ascii_to_text(key, buf);
1205 /* Encode the action */
1206 ascii_to_text(buf, act);
1208 /* Dump the macro */
1209 auto_dump_printf("A:%s\n", buf);
1210 auto_dump_printf("C:%d:%s\n", mode, key);
1219 * @brief マクロを設定するコマンドのメインルーチン /
1220 * Interact with "macros"
1224 * Note that the macro "action" must be defined before the trigger.
1226 * Could use some helpful instructions on this page.
1229 void do_cmd_macros(player_type *creature_ptr)
1237 if (rogue_like_commands)
1239 mode = KEYMAP_MODE_ROGUE;
1245 mode = KEYMAP_MODE_ORIG;
1248 /* File type is "TEXT" */
1249 FILE_TYPE(FILE_TYPE_TEXT);
1253 /* Process requests until done */
1257 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1259 /* Describe that action */
1260 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1262 /* Analyze the current action */
1263 ascii_to_text(buf, macro__buf);
1265 /* Display the current action */
1270 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1271 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1272 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1273 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1274 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1275 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1276 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1277 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1278 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1279 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1282 prt(_("コマンド: ", "Command: "), 16, 0);
1287 if (i == ESCAPE) break;
1289 /* Load a 'macro' file */
1295 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1298 prt(_("ファイル: ", "File: "), 18, 0);
1300 /* Default filename */
1301 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1303 /* Ask for a file */
1304 if (!askfor(tmp, 80)) continue;
1306 /* Process the given filename */
1307 err = process_pref_file(creature_ptr, tmp);
1310 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1315 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1319 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1327 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1330 prt(_("ファイル: ", "File: "), 18, 0);
1332 /* Default filename */
1333 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1335 /* Ask for a file */
1336 if (!askfor(tmp, 80)) continue;
1338 /* Dump the macros */
1339 (void)macro_dump(tmp);
1342 msg_print(_("マクロを追加しました。", "Appended macros."));
1351 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1355 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1357 /* Get a macro trigger */
1358 do_cmd_macro_aux(buf);
1360 /* Acquire action */
1361 k = macro_find_exact(buf);
1367 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1373 /* Obtain the action */
1374 strcpy(macro__buf, macro__act[k]);
1376 /* Analyze the current action */
1377 ascii_to_text(buf, macro__buf);
1379 /* Display the current action */
1383 msg_print(_("マクロを確認しました。", "Found a macro."));
1387 /* Create a macro */
1391 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1394 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1396 /* Get a macro trigger */
1397 do_cmd_macro_aux(buf);
1401 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1402 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1405 prt(_("マクロ行動: ", "Action: "), 20, 0);
1407 /* Convert to text */
1408 ascii_to_text(tmp, macro__buf);
1410 /* Get an encoded action */
1411 if (askfor(tmp, 80))
1413 /* Convert to ascii */
1414 text_to_ascii(macro__buf, tmp);
1416 /* Link the macro */
1417 macro_add(buf, macro__buf);
1420 msg_print(_("マクロを追加しました。", "Added a macro."));
1424 /* Remove a macro */
1428 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1431 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1433 /* Get a macro trigger */
1434 do_cmd_macro_aux(buf);
1436 /* Link the macro */
1437 macro_add(buf, buf);
1440 msg_print(_("マクロを削除しました。", "Removed a macro."));
1447 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1450 prt(_("ファイル: ", "File: "), 18, 0);
1452 /* Default filename */
1453 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1455 /* Ask for a file */
1456 if (!askfor(tmp, 80)) continue;
1458 /* Dump the macros */
1459 (void)keymap_dump(tmp);
1462 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1465 /* Query a keymap */
1471 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1474 prt(_("押すキー: ", "Keypress: "), 18, 0);
1476 /* Get a keymap trigger */
1477 do_cmd_macro_aux_keymap(buf);
1479 /* Look up the keymap */
1480 act = keymap_act[mode][(byte)(buf[0])];
1486 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1492 /* Obtain the action */
1493 strcpy(macro__buf, act);
1495 /* Analyze the current action */
1496 ascii_to_text(buf, macro__buf);
1498 /* Display the current action */
1502 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1506 /* Create a keymap */
1510 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1513 prt(_("押すキー: ", "Keypress: "), 18, 0);
1515 /* Get a keymap trigger */
1516 do_cmd_macro_aux_keymap(buf);
1520 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1521 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1524 prt(_("行動: ", "Action: "), 20, 0);
1526 /* Convert to text */
1527 ascii_to_text(tmp, macro__buf);
1529 /* Get an encoded action */
1530 if (askfor(tmp, 80))
1532 /* Convert to ascii */
1533 text_to_ascii(macro__buf, tmp);
1535 /* Free old keymap */
1536 string_free(keymap_act[mode][(byte)(buf[0])]);
1538 /* Make new keymap */
1539 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1542 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1546 /* Remove a keymap */
1550 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1553 prt(_("押すキー: ", "Keypress: "), 18, 0);
1555 /* Get a keymap trigger */
1556 do_cmd_macro_aux_keymap(buf);
1558 /* Free old keymap */
1559 string_free(keymap_act[mode][(byte)(buf[0])]);
1561 /* Make new keymap */
1562 keymap_act[mode][(byte)(buf[0])] = NULL;
1565 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1568 /* Enter a new action */
1572 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1576 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1577 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1580 prt(_("マクロ行動: ", "Action: "), 20, 0);
1582 /* Hack -- limit the value */
1585 /* Get an encoded action */
1586 if (!askfor(buf, 80)) continue;
1588 /* Extract an action */
1589 text_to_ascii(macro__buf, buf);
1605 * @brief キャラクタ色の明暗表現
1607 static concptr lighting_level_str[F_LIT_MAX] =
1622 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1623 * @param i 指定対象となるキャラクタコード
1624 * @param num 指定されたビジュアルIDを返す参照ポインタ
1625 * @param max ビジュアルIDの最大数
1626 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1628 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1635 sprintf(str, "%d", *num);
1637 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1640 tmp = (IDX)strtol(str, NULL, 0);
1641 if (tmp >= 0 && tmp < max)
1644 else if (isupper(i))
1645 *num = (*num + max - 1) % max;
1647 *num = (*num + 1) % max;
1653 * @brief キャラクタの変更メニュー表示
1654 * @param choice_msg 選択メッセージ
1657 static void print_visuals_menu(concptr choice_msg)
1659 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
1661 /* Give some choices */
1662 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
1663 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
1664 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
1665 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
1666 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
1667 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
1668 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
1669 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
1670 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
1671 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
1672 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
1675 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
1680 * Interact with "visuals"
1682 void do_cmd_visuals(player_type *creature_ptr)
1687 bool need_redraw = FALSE;
1688 concptr empty_symbol = "<< ? >>";
1690 if (use_bigtile) empty_symbol = "<< ?? >>";
1692 /* File type is "TEXT" */
1693 FILE_TYPE(FILE_TYPE_TEXT);
1696 /* Interact until done */
1701 /* Ask for a choice */
1702 print_visuals_menu(NULL);
1707 if (i == ESCAPE) break;
1711 /* Load a 'pref' file */
1714 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
1717 prt(_("ファイル: ", "File: "), 17, 0);
1719 /* Default filename */
1720 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1723 if (!askfor(tmp, 70)) continue;
1725 /* Process the given filename */
1726 (void)process_pref_file(creature_ptr, tmp);
1731 /* Dump monster attr/chars */
1734 static concptr mark = "Monster attr/chars";
1737 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
1740 prt(_("ファイル: ", "File: "), 17, 0);
1742 /* Default filename */
1743 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1745 /* Get a filename */
1746 if (!askfor(tmp, 70)) continue;
1747 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
1749 /* Append to the file */
1750 if (!open_auto_dump(buf, mark)) continue;
1753 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
1756 for (i = 0; i < max_r_idx; i++)
1758 monster_race *r_ptr = &r_info[i];
1760 /* Skip non-entries */
1761 if (!r_ptr->name) continue;
1763 /* Dump a comment */
1764 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
1766 /* Dump the monster attr/char info */
1767 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
1768 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
1774 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
1779 /* Dump object attr/chars */
1782 static concptr mark = "Object attr/chars";
1783 KIND_OBJECT_IDX k_idx;
1786 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
1789 prt(_("ファイル: ", "File: "), 17, 0);
1791 /* Default filename */
1792 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1794 /* Get a filename */
1795 if (!askfor(tmp, 70)) continue;
1796 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
1798 /* Append to the file */
1799 if (!open_auto_dump(buf, mark)) continue;
1802 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
1805 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
1807 GAME_TEXT o_name[MAX_NLEN];
1808 object_kind *k_ptr = &k_info[k_idx];
1810 /* Skip non-entries */
1811 if (!k_ptr->name) continue;
1816 strip_name(o_name, k_idx);
1822 /* Prepare dummy object */
1823 object_prep(&forge, k_idx);
1825 /* Get un-shuffled flavor name */
1826 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
1829 /* Dump a comment */
1830 auto_dump_printf("# %s\n", o_name);
1832 /* Dump the object attr/char info */
1833 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
1834 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
1840 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
1845 /* Dump feature attr/chars */
1848 static concptr mark = "Feature attr/chars";
1851 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
1854 prt(_("ファイル: ", "File: "), 17, 0);
1856 /* Default filename */
1857 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1859 /* Get a filename */
1860 if (!askfor(tmp, 70)) continue;
1861 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
1863 /* Append to the file */
1864 if (!open_auto_dump(buf, mark)) continue;
1867 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
1870 for (i = 0; i < max_f_idx; i++)
1872 feature_type *f_ptr = &f_info[i];
1874 /* Skip non-entries */
1875 if (!f_ptr->name) continue;
1877 /* Skip mimiccing features */
1878 if (f_ptr->mimic != i) continue;
1880 /* Dump a comment */
1881 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
1883 /* Dump the feature attr/char info */
1884 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
1885 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
1886 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
1887 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
1893 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
1898 /* Modify monster attr/chars (numeric operation) */
1901 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
1902 static MONRACE_IDX r = 0;
1904 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
1906 /* Hack -- query until done */
1909 monster_race *r_ptr = &r_info[r];
1913 TERM_COLOR da = r_ptr->d_attr;
1914 byte dc = r_ptr->d_char;
1915 TERM_COLOR ca = r_ptr->x_attr;
1916 byte cc = r_ptr->x_char;
1918 /* Label the object */
1919 Term_putstr(5, 17, -1, TERM_WHITE,
1920 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
1922 /* Label the Default values */
1923 Term_putstr(10, 19, -1, TERM_WHITE,
1924 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
1926 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
1927 Term_queue_bigchar(43, 19, da, dc, 0, 0);
1929 /* Label the Current values */
1930 Term_putstr(10, 20, -1, TERM_WHITE,
1931 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
1933 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
1934 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
1937 Term_putstr(0, 22, -1, TERM_WHITE,
1938 _("コマンド (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): "));
1943 if (i == ESCAPE) break;
1945 if (iscntrl(i)) c = 'a' + i - KTRL('A');
1946 else if (isupper(i)) c = 'a' + i - 'A';
1956 if (!cmd_visuals_aux(i, &r, max_r_idx))
1961 } while (!r_info[r].name);
1965 t = (int)r_ptr->x_attr;
1966 (void)cmd_visuals_aux(i, &t, 256);
1967 r_ptr->x_attr = (byte)t;
1971 t = (int)r_ptr->x_char;
1972 (void)cmd_visuals_aux(i, &t, 256);
1973 r_ptr->x_char = (byte)t;
1977 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
1979 print_visuals_menu(choice_msg);
1987 /* Modify object attr/chars (numeric operation) */
1990 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
1992 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
1994 /* Hack -- query until done */
1997 object_kind *k_ptr = &k_info[k];
2001 TERM_COLOR da = k_ptr->d_attr;
2002 SYMBOL_CODE dc = k_ptr->d_char;
2003 TERM_COLOR ca = k_ptr->x_attr;
2004 SYMBOL_CODE cc = k_ptr->x_char;
2006 /* Label the object */
2007 Term_putstr(5, 17, -1, TERM_WHITE,
2008 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2009 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2011 /* Label the Default values */
2012 Term_putstr(10, 19, -1, TERM_WHITE,
2013 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2015 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2016 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2018 /* Label the Current values */
2019 Term_putstr(10, 20, -1, TERM_WHITE,
2020 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2022 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2023 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2026 Term_putstr(0, 22, -1, TERM_WHITE,
2027 _("コマンド (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): "));
2032 if (i == ESCAPE) break;
2034 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2035 else if (isupper(i)) c = 'a' + i - 'A';
2045 if (!cmd_visuals_aux(i, &k, max_k_idx))
2050 } while (!k_info[k].name);
2054 t = (int)k_ptr->x_attr;
2055 (void)cmd_visuals_aux(i, &t, 256);
2056 k_ptr->x_attr = (byte)t;
2060 t = (int)k_ptr->x_char;
2061 (void)cmd_visuals_aux(i, &t, 256);
2062 k_ptr->x_char = (byte)t;
2066 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2068 print_visuals_menu(choice_msg);
2076 /* Modify feature attr/chars (numeric operation) */
2079 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2081 static IDX lighting_level = F_LIT_STANDARD;
2082 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2084 /* Hack -- query until done */
2087 feature_type *f_ptr = &f_info[f];
2091 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2092 byte dc = f_ptr->d_char[lighting_level];
2093 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2094 byte cc = f_ptr->x_char[lighting_level];
2096 /* Label the object */
2098 Term_putstr(5, 17, -1, TERM_WHITE,
2099 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2100 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2102 /* Label the Default values */
2103 Term_putstr(10, 19, -1, TERM_WHITE,
2104 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2106 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2107 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2109 /* Label the Current values */
2111 Term_putstr(10, 20, -1, TERM_WHITE,
2112 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2114 Term_putstr(10, 20, -1, TERM_WHITE,
2115 format("Current attr/char = %3d / %3d", ca, cc));
2118 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2119 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2123 Term_putstr(0, 22, -1, TERM_WHITE,
2124 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2126 Term_putstr(0, 22, -1, TERM_WHITE,
2127 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2133 if (i == ESCAPE) break;
2135 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2136 else if (isupper(i)) c = 'a' + i - 'A';
2146 if (!cmd_visuals_aux(i, &f, max_f_idx))
2151 } while (!f_info[f].name || (f_info[f].mimic != f));
2155 t = (int)f_ptr->x_attr[lighting_level];
2156 (void)cmd_visuals_aux(i, &t, 256);
2157 f_ptr->x_attr[lighting_level] = (byte)t;
2161 t = (int)f_ptr->x_char[lighting_level];
2162 (void)cmd_visuals_aux(i, &t, 256);
2163 f_ptr->x_char[lighting_level] = (byte)t;
2167 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2170 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2174 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2176 print_visuals_menu(choice_msg);
2184 /* Modify monster attr/chars (visual mode) */
2186 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2189 /* Modify object attr/chars (visual mode) */
2191 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2194 /* Modify feature attr/chars (visual mode) */
2197 IDX lighting_level = F_LIT_STANDARD;
2198 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2206 reset_visuals(creature_ptr);
2208 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2212 /* Unknown option */
2223 if (need_redraw) do_cmd_redraw(creature_ptr);
2228 * Interact with "colors"
2230 void do_cmd_colors(player_type *creature_ptr)
2236 /* File type is "TEXT" */
2237 FILE_TYPE(FILE_TYPE_TEXT);
2241 /* Interact until done */
2246 /* Ask for a choice */
2247 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2249 /* Give some choices */
2250 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2251 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2252 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2255 prt(_("コマンド: ", "Command: "), 8, 0);
2259 if (i == ESCAPE) break;
2261 /* Load a 'pref' file */
2265 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2268 prt(_("ファイル: ", "File: "), 10, 0);
2271 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2274 if (!askfor(tmp, 70)) continue;
2276 /* Process the given filename */
2277 (void)process_pref_file(creature_ptr, tmp);
2279 /* Mega-Hack -- react to changes */
2280 Term_xtra(TERM_XTRA_REACT, 0);
2282 /* Mega-Hack -- redraw */
2289 static concptr mark = "Colors";
2292 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2295 prt(_("ファイル: ", "File: "), 10, 0);
2297 /* Default filename */
2298 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2300 /* Get a filename */
2301 if (!askfor(tmp, 70)) continue;
2302 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2304 /* Append to the file */
2305 if (!open_auto_dump(buf, mark)) continue;
2308 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2311 for (i = 0; i < 256; i++)
2313 int kv = angband_color_table[i][0];
2314 int rv = angband_color_table[i][1];
2315 int gv = angband_color_table[i][2];
2316 int bv = angband_color_table[i][3];
2318 concptr name = _("未知", "unknown");
2320 /* Skip non-entries */
2321 if (!kv && !rv && !gv && !bv) continue;
2323 /* Extract the color name */
2324 if (i < 16) name = color_names[i];
2326 /* Dump a comment */
2327 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2329 /* Dump the monster attr/char info */
2330 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2337 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2346 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2348 /* Hack -- query until done */
2355 /* Exhibit the normal colors */
2356 for (j = 0; j < 16; j++)
2358 /* Exhibit this color */
2359 Term_putstr(j * 4, 20, -1, a, "###");
2361 /* Exhibit all colors */
2362 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2365 /* Describe the color */
2366 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2368 /* Describe the color */
2369 Term_putstr(5, 10, -1, TERM_WHITE,
2370 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2372 /* Label the Current values */
2373 Term_putstr(5, 12, -1, TERM_WHITE,
2374 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2375 angband_color_table[a][0],
2376 angband_color_table[a][1],
2377 angband_color_table[a][2],
2378 angband_color_table[a][3]));
2381 Term_putstr(0, 14, -1, TERM_WHITE,
2382 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2387 if (i == ESCAPE) break;
2390 if (i == 'n') a = (byte)(a + 1);
2391 if (i == 'N') a = (byte)(a - 1);
2392 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2393 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2394 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2395 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2396 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2397 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2398 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2399 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2401 /* Hack -- react to changes */
2402 Term_xtra(TERM_XTRA_REACT, 0);
2404 /* Hack -- redraw */
2409 /* Unknown option */
2423 * Note something in the message recall
2425 void do_cmd_note(void)
2433 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2435 /* Ignore empty notes */
2436 if (!buf[0] || (buf[0] == ' ')) return;
2438 /* Add the note to the message recall */
2439 msg_format(_("メモ: %s", "Note: %s"), buf);
2444 * Mention the current version
2446 void do_cmd_version(void)
2448 #if FAKE_VER_EXTRA > 0
2449 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2450 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2452 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2453 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2459 * Array of feeling strings
2461 static concptr do_cmd_feeling_text[11] =
2463 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2464 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2465 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2466 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2467 _("とても悪い予感がする...", "You have a very bad feeling..."),
2468 _("悪い予感がする...", "You have a bad feeling..."),
2469 _("何か緊張する。", "You feel nervous."),
2470 _("少し不運な気がする...", "You feel your luck is turning..."),
2471 _("この場所は好きになれない。", "You don't like the look of this place."),
2472 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2473 _("なんて退屈なところだ...", "What a boring place...")
2476 static concptr do_cmd_feeling_text_combat[11] =
2478 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2479 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2480 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2481 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2482 _("とても悪い予感がする...", "You have a very bad feeling..."),
2483 _("悪い予感がする...", "You have a bad feeling..."),
2484 _("何か緊張する。", "You feel nervous."),
2485 _("少し不運な気がする...", "You feel your luck is turning..."),
2486 _("この場所は好きになれない。", "You don't like the look of this place."),
2487 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2488 _("なんて退屈なところだ...", "What a boring place...")
2491 static concptr do_cmd_feeling_text_lucky[11] =
2493 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2494 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2495 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2496 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2497 _("とても良い感じがする...", "You have a very good feeling..."),
2498 _("良い感じがする...", "You have a good feeling..."),
2499 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2500 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2501 _("見た感じ悪くはない...", "You like the look of this place..."),
2502 _("全然駄目ということはないが...", "This level can't be all bad..."),
2503 _("なんて退屈なところだ...", "What a boring place...")
2508 * Note that "feeling" is set to zero unless some time has passed.
2509 * Note that this is done when the level is GENERATED, not entered.
2511 void do_cmd_feeling(player_type *creature_ptr)
2513 if (creature_ptr->wild_mode) return;
2515 /* No useful feeling in quests */
2516 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2518 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2522 /* No useful feeling in town */
2523 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2525 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2527 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2531 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2535 /* No useful feeling in the wilderness */
2536 if (!creature_ptr->current_floor_ptr->dun_level)
2538 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2542 /* Display the feeling */
2543 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2544 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2545 else if (IS_ECHIZEN(creature_ptr))
2546 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2548 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2553 * Description of each monster group.
2555 static concptr monster_group_text[] =
2558 "ユニーク", /* "Uniques" */
2559 "乗馬可能なモンスター", /* "Riding" */
2560 "賞金首", /* "Wanted */
2561 "アンバーの王族", /* "Amberite" */
2590 /* "古代ドラゴン/ワイアーム", */
2651 /* "Ancient Dragon/Wyrm", */
2660 "Multi-Headed Reptile",
2665 "Reptile/Amphibian",
2666 "Spider/Scorpion/Tick",
2668 /* "Major Demon", */
2685 * Symbols of monsters in each group. Note the "Uniques" group
2686 * is handled differently.
2688 static concptr monster_group_char[] =
2745 "!$&()+./=>?[\\]`{|~",
2755 * todo 引数と戻り値について追記求む
2756 * Build a list of monster indexes in the given group.
2758 * mode & 0x01 : check for non-empty group
2759 * mode & 0x02 : visual operation only
2761 * @param creature_ptr プレーヤーへの参照ポインタ
2762 * @param grp_cur ???
2763 * @param mon_idx[] ???
2765 * @return The number of monsters in the group
2767 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
2769 /* Get a list of x_char in this group */
2770 concptr group_char = monster_group_char[grp_cur];
2772 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
2773 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
2774 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
2775 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
2777 /* Check every race */
2779 for (IDX i = 0; i < max_r_idx; i++)
2781 /* Access the race */
2782 monster_race *r_ptr = &r_info[i];
2784 /* Skip empty race */
2785 if (!r_ptr->name) continue;
2787 /* Require known monsters */
2788 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
2792 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
2795 else if (grp_riding)
2797 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
2800 else if (grp_wanted)
2802 bool wanted = FALSE;
2804 for (j = 0; j < MAX_BOUNTY; j++)
2806 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
2807 (creature_ptr->today_mon && creature_ptr->today_mon == i))
2813 if (!wanted) continue;
2816 else if (grp_amberite)
2818 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
2823 /* Check for race in the group */
2824 if (!my_strchr(group_char, r_ptr->d_char)) continue;
2828 mon_idx[mon_cnt++] = i;
2830 /* XXX Hack -- Just checking for non-empty group */
2831 if (mode & 0x01) break;
2834 /* Terminate the list */
2835 mon_idx[mon_cnt] = -1;
2838 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
2840 /* Return the number of races */
2846 * Description of each monster group.
2848 static concptr object_group_text[] =
2851 "キノコ", /* "Mushrooms" */
2852 "薬", /* "Potions" */
2853 "油つぼ", /* "Flasks" */
2854 "巻物", /* "Scrolls" */
2856 "アミュレット", /* "Amulets" */
2857 "笛", /* "Whistle" */
2858 "光源", /* "Lanterns" */
2859 "魔法棒", /* "Wands" */
2862 "カード", /* "Cards" */
2873 "刀剣類", /* "Swords" */
2874 "鈍器", /* "Blunt Weapons" */
2875 "長柄武器", /* "Polearms" */
2876 "採掘道具", /* "Diggers" */
2877 "飛び道具", /* "Bows" */
2881 "軽装鎧", /* "Soft Armor" */
2882 "重装鎧", /* "Hard Armor" */
2883 "ドラゴン鎧", /* "Dragon Armor" */
2884 "盾", /* "Shields" */
2885 "クローク", /* "Cloaks" */
2886 "籠手", /* "Gloves" */
2887 "ヘルメット", /* "Helms" */
2889 "ブーツ", /* "Boots" */
2942 * TVALs of items in each group
2944 static byte object_group_tval[] =
2985 TV_LIFE_BOOK, /* Hack -- all spellbooks */
2993 * Build a list of object indexes in the given group. Return the number
2994 * of objects in the group.
2996 * mode & 0x01 : check for non-empty group
2997 * mode & 0x02 : visual operation only
2999 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3001 KIND_OBJECT_IDX i, object_cnt = 0;
3004 /* Get a list of x_char in this group */
3005 byte group_tval = object_group_tval[grp_cur];
3007 /* Check every object */
3008 for (i = 0; i < max_k_idx; i++)
3010 /* Access the object */
3011 object_kind *k_ptr = &k_info[i];
3013 /* Skip empty objects */
3014 if (!k_ptr->name) continue;
3018 if (!current_world_ptr->wizard)
3020 /* Skip non-flavoured objects */
3021 if (!k_ptr->flavor) continue;
3023 /* Require objects ever seen */
3024 if (!k_ptr->aware) continue;
3027 /* Skip items with no distribution (special artifacts) */
3028 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3032 /* Check for objects in the group */
3033 if (TV_LIFE_BOOK == group_tval)
3035 /* Hack -- All spell books */
3036 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3038 /* Add the object */
3039 object_idx[object_cnt++] = i;
3043 else if (k_ptr->tval == group_tval)
3045 /* Add the object */
3046 object_idx[object_cnt++] = i;
3050 /* XXX Hack -- Just checking for non-empty group */
3051 if (mode & 0x01) break;
3054 /* Terminate the list */
3055 object_idx[object_cnt] = -1;
3057 /* Return the number of objects */
3063 * Description of each feature group.
3065 static concptr feature_group_text[] =
3073 * Build a list of feature indexes in the given group. Return the number
3074 * of features in the group.
3076 * mode & 0x01 : check for non-empty group
3078 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3080 /* Check every feature */
3081 FEAT_IDX feat_cnt = 0;
3082 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3084 feature_type *f_ptr = &f_info[i];
3086 /* Skip empty index */
3087 if (!f_ptr->name) continue;
3089 /* Skip mimiccing features */
3090 if (f_ptr->mimic != i) continue;
3093 feat_idx[feat_cnt++] = i;
3095 /* XXX Hack -- Just checking for non-empty group */
3096 if (mode & 0x01) break;
3099 /* Terminate the list */
3100 feat_idx[feat_cnt] = -1;
3102 /* Return the number of races */
3108 * Hack -- load a screen dump from a file
3110 void do_cmd_load_screen(void)
3114 SYMBOL_CODE c = ' ';
3120 Term_get_size(&wid, &hgt);
3121 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3123 /* Append to the file */
3124 fff = my_fopen(buf, "r");
3128 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3136 /* Load the screen */
3137 for (y = 0; okay; y++)
3139 /* Get a line of data including control code */
3140 if (!fgets(buf, 1024, fff)) okay = FALSE;
3142 /* Get the blank line */
3143 if (buf[0] == '\n' || buf[0] == '\0') break;
3145 /* Ignore too large screen image */
3146 if (y >= hgt) continue;
3149 for (x = 0; x < wid - 1; x++)
3152 if (buf[x] == '\n' || buf[x] == '\0') break;
3154 /* Put the attr/char */
3155 Term_draw(x, y, TERM_WHITE, buf[x]);
3159 /* Dump the screen */
3160 for (y = 0; okay; y++)
3162 /* Get a line of data including control code */
3163 if (!fgets(buf, 1024, fff)) okay = FALSE;
3165 /* Get the blank line */
3166 if (buf[0] == '\n' || buf[0] == '\0') break;
3168 /* Ignore too large screen image */
3169 if (y >= hgt) continue;
3172 for (x = 0; x < wid - 1; x++)
3175 if (buf[x] == '\n' || buf[x] == '\0') break;
3177 /* Get the attr/char */
3178 (void)(Term_what(x, y, &a, &c));
3180 /* Look up the attr */
3181 for (int i = 0; i < 16; i++)
3183 /* Use attr matches */
3184 if (hack[i] == buf[x]) a = (byte)i;
3187 /* Put the attr/char */
3188 Term_draw(x, y, a, c);
3194 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3202 // todo なぜこんな中途半端なところに? defineも…
3203 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3204 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3206 #define IM_FLAG_STR _("*", "* ")
3207 #define HAS_FLAG_STR _("+", "+ ")
3208 #define NO_FLAG_STR _("・", ". ")
3210 #define print_im_or_res_flag(IM, RES) \
3212 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3213 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3216 #define print_flag(TR) \
3218 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3222 /* XTRA HACK RESLIST */
3223 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)
3225 GAME_TEXT o_name[MAX_NLEN];
3226 BIT_FLAGS flgs[TR_FLAG_SIZE];
3228 if (!o_ptr->k_idx) return;
3229 if (o_ptr->tval != tval) return;
3231 /* Identified items only */
3232 if (!object_is_known(o_ptr)) return;
3235 * HACK:Ring of Lordly protection and Dragon equipment
3236 * have random resistances.
3238 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3239 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3240 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3241 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3242 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3243 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3244 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3245 || object_is_artifact(o_ptr);
3246 if (!is_special_item_type)
3252 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3254 while (o_name[i] && (i < 26))
3257 if (iskanji(o_name[i])) i++;
3266 o_name[i] = ' '; i++;
3272 fprintf(fff, "%s %s", where, o_name);
3274 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
3276 fputs(_("-------不明--------------- -------不明---------\n",
3277 "-------unknown------------ -------unknown------\n"), fff);
3281 object_flags_known(o_ptr, flgs);
3283 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3284 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3285 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3286 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3287 print_flag(TR_RES_POIS);
3288 print_flag(TR_RES_LITE);
3289 print_flag(TR_RES_DARK);
3290 print_flag(TR_RES_SHARDS);
3291 print_flag(TR_RES_SOUND);
3292 print_flag(TR_RES_NETHER);
3293 print_flag(TR_RES_NEXUS);
3294 print_flag(TR_RES_CHAOS);
3295 print_flag(TR_RES_DISEN);
3299 print_flag(TR_RES_BLIND);
3300 print_flag(TR_RES_FEAR);
3301 print_flag(TR_RES_CONF);
3302 print_flag(TR_FREE_ACT);
3303 print_flag(TR_SEE_INVIS);
3304 print_flag(TR_HOLD_EXP);
3305 print_flag(TR_TELEPATHY);
3306 print_flag(TR_SLOW_DIGEST);
3307 print_flag(TR_REGEN);
3308 print_flag(TR_LEVITATION);
3317 fprintf(fff, "%s\n", inven_res_label);
3322 * Display *ID* ed weapons/armors's resistances
3324 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3327 GAME_TEXT file_name[1024];
3329 OBJECT_TYPE_VALUE tval;
3335 /* Open a new file */
3336 fff = my_fopen_temp(file_name, 1024);
3339 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3344 fprintf(fff, "%s\n", inven_res_label);
3346 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3350 for (; j < 9; j++) fputc('\n', fff);
3352 fprintf(fff, "%s\n", inven_res_label);
3355 strcpy(where, _("装", "E "));
3356 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3358 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3361 strcpy(where, _("持", "I "));
3362 for (i = 0; i < INVEN_PACK; i++)
3364 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3367 st_ptr = &town_info[1].store[STORE_HOME];
3368 strcpy(where, _("家", "H "));
3369 for (i = 0; i < st_ptr->stock_num; i++)
3371 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3377 /* Display the file contents */
3378 (void)show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3383 void do_cmd_save_screen_html_aux(char *filename, int message)
3391 concptr html_head[] = {
3392 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3396 concptr html_foot[] = {
3398 "</body>\n</html>\n",
3403 Term_get_size(&wid, &hgt);
3405 /* File type is "TEXT" */
3406 FILE_TYPE(FILE_TYPE_TEXT);
3408 /* Append to the file */
3410 fff = my_fopen(filename, "w");
3416 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3423 if (message) screen_save();
3425 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3427 tmpfff = my_fopen(buf, "r");
3430 for (int i = 0; html_head[i]; i++)
3431 fputs(html_head[i], fff);
3435 bool is_first_line = TRUE;
3436 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3440 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3441 is_first_line = FALSE;
3445 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3447 fprintf(fff, "%s\n", buf);
3452 /* Dump the screen */
3453 for (TERM_LEN y = 0; y < hgt; y++)
3456 if (y != 0) fprintf(fff, "\n");
3459 TERM_COLOR a = 0, old_a = 0;
3461 for (TERM_LEN x = 0; x < wid - 1; x++)
3464 /* Get the attr/char */
3465 (void)(Term_what(x, y, &a, &c));
3469 case '&': cc = "&"; break;
3470 case '<': cc = "<"; break;
3471 case '>': cc = ">"; break;
3473 case 0x1f: c = '.'; break;
3474 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3479 if ((y == 0 && x == 0) || a != old_a)
3481 int rv = angband_color_table[a][1];
3482 int gv = angband_color_table[a][2];
3483 int bv = angband_color_table[a][3];
3484 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3485 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3490 fprintf(fff, "%s", cc);
3492 fprintf(fff, "%c", c);
3496 fprintf(fff, "</font>");
3500 for (int i = 0; html_foot[i]; i++)
3501 fputs(html_foot[i], fff);
3506 bool is_first_line = TRUE;
3507 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3511 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3512 is_first_line = FALSE;
3516 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3518 fprintf(fff, "%s\n", buf);
3531 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3540 * Hack -- save a screen dump to a file
3542 static void do_cmd_save_screen_html(void)
3544 char buf[1024], tmp[256] = "screen.html";
3546 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3548 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3552 do_cmd_save_screen_html_aux(buf, 1);
3557 * Redefinable "save_screen" action
3559 void(*screendump_aux)(void) = NULL;
3563 * Save a screen dump to a file
3564 * @param creature_ptr プレーヤーへの参照ポインタ
3567 void do_cmd_save_screen(player_type *creature_ptr)
3569 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3570 bool html_dump = FALSE;
3574 if (c == 'Y' || c == 'y')
3576 else if (c == 'H' || c == 'h')
3589 Term_get_size(&wid, &hgt);
3591 bool old_use_graphics = use_graphics;
3592 if (old_use_graphics)
3594 use_graphics = FALSE;
3595 reset_visuals(creature_ptr);
3596 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3597 handle_stuff(creature_ptr);
3602 do_cmd_save_screen_html();
3603 do_cmd_redraw(creature_ptr);
3606 /* Do we use a special screendump function ? */
3607 else if (screendump_aux)
3609 /* Dump the screen to a graphics file */
3610 (*screendump_aux)();
3612 else /* Dump the screen as text */
3616 SYMBOL_CODE c = ' ';
3619 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3621 /* File type is "TEXT" */
3622 FILE_TYPE(FILE_TYPE_TEXT);
3624 /* Append to the file */
3625 fff = my_fopen(buf, "w");
3629 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3636 /* Dump the screen */
3637 for (y = 0; y < hgt; y++)
3640 for (x = 0; x < wid - 1; x++)
3642 /* Get the attr/char */
3643 (void)(Term_what(x, y, &a, &c));
3653 fprintf(fff, "%s\n", buf);
3660 /* Dump the screen */
3661 for (y = 0; y < hgt; y++)
3664 for (x = 0; x < wid - 1; x++)
3666 /* Get the attr/char */
3667 (void)(Term_what(x, y, &a, &c));
3670 buf[x] = hack[a & 0x0F];
3677 fprintf(fff, "%s\n", buf);
3684 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3689 if (!old_use_graphics) return;
3691 use_graphics = TRUE;
3692 reset_visuals(creature_ptr);
3693 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3694 handle_stuff(creature_ptr);
3699 * todo okay = 既知のアーティファクト? と思われるが確証がない
3700 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
3701 * Check the status of "artifacts"
3702 * @param player_ptr プレーヤーへの参照ポインタ
3705 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
3707 /* Open a new file */
3709 GAME_TEXT file_name[1024];
3710 fff = my_fopen_temp(file_name, 1024);
3713 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3718 /* Allocate the "who" array */
3720 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
3722 /* Allocate the "okay" array */
3724 C_MAKE(okay, max_a_idx, bool);
3726 /* Scan the artifacts */
3727 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
3729 artifact_type *a_ptr = &a_info[k];
3734 /* Skip "empty" artifacts */
3735 if (!a_ptr->name) continue;
3737 /* Skip "uncreated" artifacts */
3738 if (!a_ptr->cur_num) continue;
3744 /* Check the dungeon */
3745 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
3747 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
3749 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
3751 OBJECT_IDX this_o_idx, next_o_idx = 0;
3753 /* Scan all objects in the grid */
3754 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
3757 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
3758 next_o_idx = o_ptr->next_o_idx;
3760 /* Ignore non-artifacts */
3761 if (!object_is_fixed_artifact(o_ptr)) continue;
3763 /* Ignore known items */
3764 if (object_is_known(o_ptr)) continue;
3766 /* Note the artifact */
3767 okay[o_ptr->name1] = FALSE;
3772 /* Check the player_ptr->inventory_list and equipment */
3773 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
3775 object_type *o_ptr = &player_ptr->inventory_list[i];
3777 /* Ignore non-objects */
3778 if (!o_ptr->k_idx) continue;
3780 /* Ignore non-artifacts */
3781 if (!object_is_fixed_artifact(o_ptr)) continue;
3783 /* Ignore known items */
3784 if (object_is_known(o_ptr)) continue;
3786 /* Note the artifact */
3787 okay[o_ptr->name1] = FALSE;
3791 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
3793 if (okay[k]) who[n++] = k;
3797 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
3799 /* Scan the artifacts */
3800 for (ARTIFACT_IDX k = 0; k < n; k++)
3802 artifact_type *a_ptr = &a_info[who[k]];
3803 GAME_TEXT base_name[MAX_NLEN];
3804 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
3806 /* Obtain the base object type */
3807 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
3816 /* Create fake object */
3817 object_prep(q_ptr, z);
3819 /* Make it an artifact */
3820 q_ptr->name1 = (byte)who[k];
3822 /* Display as if known */
3823 q_ptr->ident |= IDENT_STORE;
3825 /* Describe the artifact */
3826 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
3829 /* Hack -- Build the artifact name */
3830 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
3833 /* Free the "who" array */
3834 C_KILL(who, max_a_idx, ARTIFACT_IDX);
3836 /* Free the "okay" array */
3837 C_KILL(okay, max_a_idx, bool);
3840 /* Display the file contents */
3841 (void)show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
3847 * Display known uniques
3848 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
3850 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
3857 GAME_TEXT file_name[1024];
3860 int n_alive_surface = 0;
3861 int n_alive_over100 = 0;
3862 int n_alive_total = 0;
3865 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
3867 /* Open a new file */
3868 fff = my_fopen_temp(file_name, 1024);
3872 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3877 /* Allocate the "who" array */
3878 C_MAKE(who, max_r_idx, MONRACE_IDX);
3880 /* Scan the monsters */
3882 for (IDX i = 1; i < max_r_idx; i++)
3884 monster_race *r_ptr = &r_info[i];
3887 if (!r_ptr->name) continue;
3889 /* Require unique monsters */
3890 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3892 /* Only display "known" uniques */
3893 if (!cheat_know && !r_ptr->r_sights) continue;
3895 /* Only print rarity <= 100 uniques */
3896 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
3898 /* Only "alive" uniques */
3899 if (r_ptr->max_num == 0) continue;
3903 lev = (r_ptr->level - 1) / 10;
3907 if (max_lev < lev) max_lev = lev;
3909 else n_alive_over100++;
3911 else n_alive_surface++;
3913 /* Collect "appropriate" monsters */
3917 /* Sort the array by dungeon depth of monsters */
3918 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
3920 if (n_alive_surface)
3922 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
3923 n_alive_total += n_alive_surface;
3926 for (IDX i = 0; i <= max_lev; i++)
3928 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
3929 n_alive_total += n_alive[i];
3932 if (n_alive_over100)
3934 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
3935 n_alive_total += n_alive_over100;
3940 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
3941 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
3945 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
3948 /* Scan the monster races */
3949 for (int k = 0; k < n; k++)
3951 monster_race *r_ptr = &r_info[who[k]];
3952 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
3955 /* Free the "who" array */
3956 C_KILL(who, max_r_idx, s16b);
3959 /* Display the file contents */
3960 (void)show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
3966 * Display weapon-exp
3968 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
3970 /* Open a new file */
3972 GAME_TEXT file_name[1024];
3973 fff = my_fopen_temp(file_name, 1024);
3976 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3981 for (int i = 0; i < 5; i++)
3983 for (int num = 0; num < 64; num++)
3987 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
3989 object_kind *k_ptr = &k_info[j];
3991 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
3992 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
3994 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
3996 fprintf(fff, "%-25s ", tmp);
3997 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
3998 else fprintf(fff, " ");
3999 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4000 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4009 /* Display the file contents */
4010 (void)show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4016 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4020 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4022 /* Open a new file */
4024 GAME_TEXT file_name[1024];
4025 fff = my_fopen_temp(file_name, 1024);
4028 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4033 if (creature_ptr->realm1 != REALM_NONE)
4035 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4036 for (SPELL_IDX i = 0; i < 32; i++)
4038 const magic_type *s_ptr;
4039 if (!is_magic(creature_ptr->realm1))
4041 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4045 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4048 if (s_ptr->slevel >= 99) continue;
4049 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4050 int exp_level = spell_exp_level(spell_exp);
4051 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4052 if (creature_ptr->realm1 == REALM_HISSATSU)
4053 fprintf(fff, "[--]");
4056 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4057 else fprintf(fff, " ");
4058 fprintf(fff, "%s", exp_level_str[exp_level]);
4061 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4066 if (creature_ptr->realm2 != REALM_NONE)
4068 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4069 for (SPELL_IDX i = 0; i < 32; i++)
4071 const magic_type *s_ptr;
4072 if (!is_magic(creature_ptr->realm1))
4074 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4078 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4081 if (s_ptr->slevel >= 99) continue;
4083 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4084 int exp_level = spell_exp_level(spell_exp);
4085 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4086 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4087 else fprintf(fff, " ");
4088 fprintf(fff, "%s", exp_level_str[exp_level]);
4089 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4096 /* Display the file contents */
4097 (void)show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4103 * @brief スキル情報を表示するコマンドのメインルーチン /
4107 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4109 char skill_name[GINOU_TEMPMAX][20] =
4111 _("マーシャルアーツ", "Martial Arts "),
4112 _("二刀流 ", "Dual Wielding "),
4113 _("乗馬 ", "Riding "),
4117 /* Open a new file */
4119 char file_name[1024];
4120 fff = my_fopen_temp(file_name, 1024);
4123 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4128 for (int i = 0; i < GINOU_TEMPMAX; i++)
4130 int skill_exp = creature_ptr->skill_exp[i];
4131 fprintf(fff, "%-20s ", skill_name[i]);
4132 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4133 else fprintf(fff, " ");
4134 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4135 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4141 /* Display the file contents */
4142 (void)show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4148 * @brief 現在のペットを表示するコマンドのメインルーチン /
4149 * Display current pets
4150 * @param creature_ptr プレーヤーへの参照ポインタ
4153 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4155 /* Open a new file */
4156 GAME_TEXT file_name[1024];
4158 fff = my_fopen_temp(file_name, 1024);
4161 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4166 /* Process the monsters (backwards) */
4167 monster_type *m_ptr;
4168 GAME_TEXT pet_name[MAX_NLEN];
4170 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4172 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4174 /* Ignore "dead" monsters */
4175 if (!monster_is_valid(m_ptr)) continue;
4177 /* Calculate "upkeep" for pets */
4178 if (!is_pet(m_ptr)) continue;
4181 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4182 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4185 int show_upkeep = calculate_upkeep(creature_ptr);
4187 fprintf(fff, "----------------------------------------------\n");
4189 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4191 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4193 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4197 /* Display the file contents */
4198 (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4204 * @brief 現在のペットを表示するコマンドのメインルーチン /
4205 * @param creature_ptr プレーヤーへの参照ポインタ
4208 * @note the player ghosts are ignored.
4210 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4212 /* Open a new file */
4214 GAME_TEXT file_name[1024];
4215 fff = my_fopen_temp(file_name, 1024);
4218 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4223 /* Allocate the "who" array */
4225 C_MAKE(who, max_r_idx, MONRACE_IDX);
4229 /* Monsters slain */
4230 for (int kk = 1; kk < max_r_idx; kk++)
4232 monster_race *r_ptr = &r_info[kk];
4234 if (r_ptr->flags1 & (RF1_UNIQUE))
4236 bool dead = (r_ptr->max_num == 0);
4245 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4247 if (this_monster > 0)
4249 total += this_monster;
4255 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4258 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4260 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4266 /* Scan the monsters */
4268 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4270 monster_race *r_ptr = &r_info[i];
4272 /* Use that monster */
4273 if (r_ptr->name) who[n++] = i;
4276 /* Sort the array by dungeon depth of monsters */
4278 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4280 /* Scan the monster races */
4281 for (int k = 0; k < n; k++)
4283 monster_race *r_ptr = &r_info[who[k]];
4285 if (r_ptr->flags1 & (RF1_UNIQUE))
4287 bool dead = (r_ptr->max_num == 0);
4291 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4298 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4300 if (this_monster <= 0) continue;
4303 /* p,tは人と数える by ita */
4304 if (my_strchr("pt", r_ptr->d_char))
4305 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4307 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4309 if (this_monster < 2)
4311 if (my_strstr(r_name + r_ptr->name, "coins"))
4313 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4317 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4323 strcpy(ToPlural, (r_name + r_ptr->name));
4324 plural_aux(ToPlural);
4325 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4328 total += this_monster;
4331 fprintf(fff, "----------------------------------------------\n");
4333 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4335 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4338 /* Free the "who" array */
4339 C_KILL(who, max_r_idx, s16b);
4342 /* Display the file contents */
4343 (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4349 * @brief モンスター情報リスト中のグループを表示する /
4350 * Display the object groups.
4354 * @param per_page リストの表示行
4355 * @param grp_idx グループのID配列
4356 * @param group_text グループ名の文字列配列
4357 * @param grp_cur 現在の選択ID
4358 * @param grp_top 現在の選択リスト最上部ID
4361 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)
4363 /* Display lines until done */
4364 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4366 /* Get the group index */
4367 int grp = grp_idx[grp_top + i];
4369 /* Choose a color */
4370 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4372 /* Erase the entire line */
4373 Term_erase(col, row + i, wid);
4375 /* Display the group label */
4376 c_put_str(attr, group_text[grp], row + i, col);
4382 * Move the cursor in a browser window
4384 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4385 IDX *list_cur, int list_cnt)
4390 IDX list = *list_cur;
4392 /* Extract direction */
4395 /* Hack -- scroll up full screen */
4400 /* Hack -- scroll down full screen */
4405 d = get_keymap_dir(ch);
4410 /* Diagonals - hack */
4411 if ((ddx[d] > 0) && ddy[d])
4416 Term_get_size(&wid, &hgt);
4418 browser_rows = hgt - 8;
4420 /* Browse group list */
4425 /* Move up or down */
4426 grp += ddy[d] * (browser_rows - 1);
4429 if (grp >= grp_cnt) grp = grp_cnt - 1;
4430 if (grp < 0) grp = 0;
4431 if (grp != old_grp) list = 0;
4434 /* Browse sub-list list */
4437 /* Move up or down */
4438 list += ddy[d] * browser_rows;
4441 if (list >= list_cnt) list = list_cnt - 1;
4442 if (list < 0) list = 0;
4454 if (col < 0) col = 0;
4455 if (col > 1) col = 1;
4462 /* Browse group list */
4467 /* Move up or down */
4471 if (grp >= grp_cnt) grp = grp_cnt - 1;
4472 if (grp < 0) grp = 0;
4473 if (grp != old_grp) list = 0;
4476 /* Browse sub-list list */
4479 /* Move up or down */
4480 list += (IDX)ddy[d];
4483 if (list >= list_cnt) list = list_cnt - 1;
4484 if (list < 0) list = 0;
4495 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4497 /* Clear the display lines */
4498 for (int i = 0; i < height; i++)
4500 Term_erase(col, row + i, width);
4503 /* Bigtile mode uses double width */
4504 if (use_bigtile) width /= 2;
4506 /* Display lines until done */
4507 for (int i = 0; i < height; i++)
4509 /* Display columns until done */
4510 for (int j = 0; j < width; j++)
4512 TERM_LEN x = col + j;
4513 TERM_LEN y = row + i;
4515 /* Bigtile mode uses double width */
4516 if (use_bigtile) x += j;
4518 TERM_COLOR ia = attr_top + i;
4519 SYMBOL_CODE ic = char_left + j;
4521 /* Ignore illegal characters */
4522 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4523 (!use_graphics && ic > 0x7f))
4529 /* Force correct code for both ASCII character and tile */
4530 if (c & 0x80) a |= 0x80;
4532 /* Display symbol */
4533 Term_queue_bigchar(x, y, a, c, 0, 0);
4540 * Place the cursor at the collect position for visual mode
4542 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4544 int i = (a & 0x7f) - attr_top;
4545 int j = c - char_left;
4547 TERM_LEN x = col + j;
4548 TERM_LEN y = row + i;
4550 /* Bigtile mode uses double width */
4551 if (use_bigtile) x += j;
4553 /* Place the cursor */
4559 * Do visual mode command -- Change symbols
4561 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4562 int height, int width,
4563 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4564 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4566 static TERM_COLOR attr_old = 0;
4567 static SYMBOL_CODE char_old = 0;
4572 if (*visual_list_ptr)
4575 *cur_attr_ptr = attr_old;
4576 *cur_char_ptr = char_old;
4577 *visual_list_ptr = FALSE;
4585 if (*visual_list_ptr)
4588 *visual_list_ptr = FALSE;
4589 *need_redraw = TRUE;
4597 if (!*visual_list_ptr)
4599 *visual_list_ptr = TRUE;
4601 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4602 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4604 attr_old = *cur_attr_ptr;
4605 char_old = *cur_char_ptr;
4616 /* Set the visual */
4617 attr_idx = *cur_attr_ptr;
4618 char_idx = *cur_char_ptr;
4620 /* Hack -- for feature lighting */
4621 for (i = 0; i < F_LIT_MAX; i++)
4623 attr_idx_feat[i] = 0;
4624 char_idx_feat[i] = 0;
4631 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4634 *cur_attr_ptr = attr_idx;
4635 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4636 if (!*visual_list_ptr) *need_redraw = TRUE;
4642 *cur_char_ptr = char_idx;
4643 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4644 if (!*visual_list_ptr) *need_redraw = TRUE;
4650 if (*visual_list_ptr)
4653 int d = get_keymap_dir(ch);
4654 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
4655 SYMBOL_CODE c = *cur_char_ptr;
4657 if (use_bigtile) eff_width = width / 2;
4658 else eff_width = width;
4660 /* Restrict direction */
4661 if ((a == 0) && (ddy[d] < 0)) d = 0;
4662 if ((c == 0) && (ddx[d] < 0)) d = 0;
4663 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
4664 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
4666 a += (TERM_COLOR)ddy[d];
4667 c += (SYMBOL_CODE)ddx[d];
4669 /* Force correct code for both ASCII character and tile */
4670 if (c & 0x80) a |= 0x80;
4672 /* Set the visual */
4677 /* Move the frame */
4678 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
4679 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
4680 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
4681 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
4687 /* Visual mode command is not used */
4693 * Display the monsters in a group.
4695 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
4696 int mon_cur, int mon_top, bool visual_only)
4698 /* Display lines until done */
4700 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
4704 /* Get the race index */
4705 MONRACE_IDX r_idx = mon_idx[mon_top + i];
4707 /* Access the race */
4708 monster_race *r_ptr = &r_info[r_idx];
4710 /* Choose a color */
4711 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
4713 /* Display the name */
4714 c_prt(attr, (r_name + r_ptr->name), row + i, col);
4716 /* Hack -- visual_list mode */
4719 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
4722 if (current_world_ptr->wizard || visual_only)
4724 c_prt(attr, format("%d", r_idx), row + i, 62);
4727 /* Erase chars before overwritten by the race letter */
4728 Term_erase(69, row + i, 255);
4730 /* Display symbol */
4731 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
4736 if (!(r_ptr->flags1 & RF1_UNIQUE))
4737 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
4739 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
4740 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
4744 /* Clear remaining lines */
4745 for (; i < per_page; i++)
4747 Term_erase(col, row + i, 255);
4753 * todo 引数の詳細について加筆求む
4754 * Display known monsters.
4755 * @param creature_ptr プレーヤーへの参照ポインタ
4756 * @param need_redraw 画面の再描画が必要な時TRUE
4757 * @param visual_only ???
4758 * @param direct_r_idx モンスターID
4761 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
4764 Term_get_size(&wid, &hgt);
4766 /* Allocate the "mon_idx" array */
4768 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
4774 bool visual_list = FALSE;
4775 TERM_COLOR attr_top = 0;
4778 int browser_rows = hgt - 8;
4779 if (direct_r_idx < 0)
4781 mode = visual_only ? 0x03 : 0x01;
4783 /* Check every group */
4785 for (IDX i = 0; monster_group_text[i] != NULL; i++)
4787 /* Measure the label */
4788 len = strlen(monster_group_text[i]);
4790 /* Save the maximum length */
4791 if (len > max) max = len;
4793 /* See if any monsters are known */
4794 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
4796 /* Build a list of groups with known monsters */
4797 grp_idx[grp_cnt++] = i;
4805 mon_idx[0] = direct_r_idx;
4808 /* Terminate the list */
4811 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
4812 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
4815 /* Terminate the list */
4816 grp_idx[grp_cnt] = -1;
4818 mode = visual_only ? 0x02 : 0x00;
4819 IDX old_grp_cur = -1;
4832 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
4833 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
4834 prt(_("名前", "Name"), 4, max + 3);
4835 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
4836 prt(_("文字", "Sym"), 4, 67);
4837 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
4839 for (IDX i = 0; i < 78; i++)
4841 Term_putch(i, 5, TERM_WHITE, '=');
4844 if (direct_r_idx < 0)
4846 for (IDX i = 0; i < browser_rows; i++)
4848 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
4855 if (direct_r_idx < 0)
4857 /* Scroll group list */
4858 if (grp_cur < grp_top) grp_top = grp_cur;
4859 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
4861 /* Display a list of monster groups */
4862 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
4864 if (old_grp_cur != grp_cur)
4866 old_grp_cur = grp_cur;
4868 /* Get a list of monsters in the current group */
4869 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
4872 /* Scroll monster list */
4873 while (mon_cur < mon_top)
4874 mon_top = MAX(0, mon_top - browser_rows / 2);
4875 while (mon_cur >= mon_top + browser_rows)
4876 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
4881 /* Display a list of monsters in the current group */
4882 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
4888 /* Display a monster name */
4889 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
4891 /* Display visual list below first monster */
4892 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
4896 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
4897 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
4898 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
4899 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
4902 /* Get the current monster */
4903 monster_race *r_ptr;
4904 r_ptr = &r_info[mon_idx[mon_cur]];
4908 /* Mega Hack -- track this monster race */
4909 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
4910 handle_stuff(creature_ptr);
4915 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
4919 Term_gotoxy(0, 6 + (grp_cur - grp_top));
4923 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
4928 /* Do visual mode command if needed */
4929 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))
4931 if (direct_r_idx >= 0)
4957 /* Recall on screen */
4958 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
4960 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
4972 /* Move the cursor */
4973 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
4980 /* Free the "mon_idx" array */
4981 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
4986 * Display the objects in a group.
4988 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
4989 int object_cur, int object_top, bool visual_only)
4991 /* Display lines until done */
4993 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
4995 GAME_TEXT o_name[MAX_NLEN];
4998 object_kind *flavor_k_ptr;
5000 /* Get the object index */
5001 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5003 /* Access the object */
5004 object_kind *k_ptr = &k_info[k_idx];
5006 /* Choose a color */
5007 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5008 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5010 if (!visual_only && k_ptr->flavor)
5012 /* Appearance of this object is shuffled */
5013 flavor_k_ptr = &k_info[k_ptr->flavor];
5017 /* Appearance of this object is very normal */
5018 flavor_k_ptr = k_ptr;
5021 attr = ((i + object_top == object_cur) ? cursor : attr);
5023 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5026 strip_name(o_name, k_idx);
5031 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5034 /* Display the name */
5035 c_prt(attr, o_name, row + i, col);
5037 /* Hack -- visual_list mode */
5040 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);
5043 if (current_world_ptr->wizard || visual_only)
5045 c_prt(attr, format("%d", k_idx), row + i, 70);
5048 a = flavor_k_ptr->x_attr;
5049 c = flavor_k_ptr->x_char;
5051 /* Display symbol */
5052 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5055 /* Clear remaining lines */
5056 for (; i < per_page; i++)
5058 Term_erase(col, row + i, 255);
5064 * Describe fake object
5066 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5069 object_type object_type_body;
5070 o_ptr = &object_type_body;
5072 object_prep(o_ptr, k_idx);
5074 /* It's fully know */
5075 o_ptr->ident |= IDENT_KNOWN;
5076 handle_stuff(creature_ptr);
5078 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5080 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5086 * Display known objects
5088 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5090 IDX object_old, object_top;
5093 OBJECT_IDX *object_idx;
5095 bool visual_list = FALSE;
5096 TERM_COLOR attr_top = 0;
5101 Term_get_size(&wid, &hgt);
5103 int browser_rows = hgt - 8;
5105 /* Allocate the "object_idx" array */
5106 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5111 if (direct_k_idx < 0)
5113 mode = visual_only ? 0x03 : 0x01;
5115 /* Check every group */
5116 for (IDX i = 0; object_group_text[i] != NULL; i++)
5118 /* Measure the label */
5119 len = strlen(object_group_text[i]);
5121 /* Save the maximum length */
5122 if (len > max) max = len;
5124 /* See if any monsters are known */
5125 if (collect_objects(i, object_idx, mode))
5127 /* Build a list of groups with known monsters */
5128 grp_idx[grp_cnt++] = i;
5137 object_kind *k_ptr = &k_info[direct_k_idx];
5138 object_kind *flavor_k_ptr;
5140 if (!visual_only && k_ptr->flavor)
5142 /* Appearance of this object is shuffled */
5143 flavor_k_ptr = &k_info[k_ptr->flavor];
5147 /* Appearance of this object is very normal */
5148 flavor_k_ptr = k_ptr;
5151 object_idx[0] = direct_k_idx;
5152 object_old = direct_k_idx;
5155 /* Terminate the list */
5158 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5159 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5162 /* Terminate the list */
5163 grp_idx[grp_cnt] = -1;
5165 mode = visual_only ? 0x02 : 0x00;
5166 IDX old_grp_cur = -1;
5169 IDX object_cur = object_top = 0;
5175 object_kind *k_ptr, *flavor_k_ptr;
5182 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5183 if (direct_k_idx < 0) prt("グループ", 4, 0);
5184 prt("名前", 4, max + 3);
5185 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5188 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5189 if (direct_k_idx < 0) prt("Group", 4, 0);
5190 prt("Name", 4, max + 3);
5191 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5195 for (IDX i = 0; i < 78; i++)
5197 Term_putch(i, 5, TERM_WHITE, '=');
5200 if (direct_k_idx < 0)
5202 for (IDX i = 0; i < browser_rows; i++)
5204 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5211 if (direct_k_idx < 0)
5213 /* Scroll group list */
5214 if (grp_cur < grp_top) grp_top = grp_cur;
5215 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5217 /* Display a list of object groups */
5218 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5220 if (old_grp_cur != grp_cur)
5222 old_grp_cur = grp_cur;
5224 /* Get a list of objects in the current group */
5225 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5228 /* Scroll object list */
5229 while (object_cur < object_top)
5230 object_top = MAX(0, object_top - browser_rows / 2);
5231 while (object_cur >= object_top + browser_rows)
5232 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5237 /* Display a list of objects in the current group */
5238 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5242 object_top = object_cur;
5244 /* Display a list of objects in the current group */
5245 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5247 /* Display visual list below first object */
5248 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5251 /* Get the current object */
5252 k_ptr = &k_info[object_idx[object_cur]];
5254 if (!visual_only && k_ptr->flavor)
5256 /* Appearance of this object is shuffled */
5257 flavor_k_ptr = &k_info[k_ptr->flavor];
5261 /* Appearance of this object is very normal */
5262 flavor_k_ptr = k_ptr;
5267 prt(format("<方向>%s%s%s, ESC",
5268 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5269 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5270 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5273 prt(format("<dir>%s%s%s, ESC",
5274 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5275 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5276 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5282 /* Mega Hack -- track this object */
5283 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5285 /* The "current" object changed */
5286 if (object_old != object_idx[object_cur])
5288 handle_stuff(creature_ptr);
5290 /* Remember the "current" object */
5291 object_old = object_idx[object_cur];
5297 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5301 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5305 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5310 /* Do visual mode command if needed */
5311 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))
5313 if (direct_k_idx >= 0)
5338 /* Recall on screen */
5339 if (!visual_list && !visual_only && (grp_cnt > 0))
5341 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5349 /* Move the cursor */
5350 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5356 /* Free the "object_idx" array */
5357 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5362 * Display the features in a group.
5364 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5365 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5367 int lit_col[F_LIT_MAX], i;
5368 int f_idx_col = use_bigtile ? 62 : 64;
5370 /* Correct columns 1 and 4 */
5371 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5372 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5373 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5375 /* Display lines until done */
5376 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5379 FEAT_IDX f_idx = feat_idx[feat_top + i];
5380 feature_type *f_ptr = &f_info[f_idx];
5381 int row_i = row + i;
5383 /* Choose a color */
5384 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5386 /* Display the name */
5387 c_prt(attr, f_name + f_ptr->name, row_i, col);
5389 /* Hack -- visual_list mode */
5392 /* Display lighting level */
5393 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5395 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));
5397 if (current_world_ptr->wizard || visual_only)
5399 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5402 /* Display symbol */
5403 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);
5405 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5406 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5408 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5410 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5412 /* Mega-hack -- Use non-standard colour */
5413 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5415 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5419 /* Clear remaining lines */
5420 for (; i < per_page; i++)
5422 Term_erase(col, row + i, 255);
5428 * Interact with feature visuals.
5430 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5432 TERM_COLOR attr_old[F_LIT_MAX];
5433 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5434 SYMBOL_CODE char_old[F_LIT_MAX];
5435 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5438 Term_get_size(&wid, &hgt);
5440 /* Allocate the "feat_idx" array */
5442 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5448 FEAT_IDX grp_idx[100];
5449 TERM_COLOR attr_top = 0;
5450 bool visual_list = FALSE;
5452 TERM_LEN browser_rows = hgt - 8;
5453 if (direct_f_idx < 0)
5455 /* Check every group */
5456 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5458 /* Measure the label */
5459 len = strlen(feature_group_text[i]);
5461 /* Save the maximum length */
5462 if (len > max) max = len;
5464 /* See if any features are known */
5465 if (collect_features(feat_idx, 0x01))
5467 /* Build a list of groups with known features */
5468 grp_idx[grp_cnt++] = i;
5476 feature_type *f_ptr = &f_info[direct_f_idx];
5478 feat_idx[0] = direct_f_idx;
5481 /* Terminate the list */
5484 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5485 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5487 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5489 attr_old[i] = f_ptr->x_attr[i];
5490 char_old[i] = f_ptr->x_char[i];
5494 /* Terminate the list */
5495 grp_idx[grp_cnt] = -1;
5497 FEAT_IDX old_grp_cur = -1;
5498 FEAT_IDX grp_cur = 0;
5499 FEAT_IDX grp_top = 0;
5500 FEAT_IDX feat_cur = 0;
5501 FEAT_IDX feat_top = 0;
5502 TERM_LEN column = 0;
5505 TERM_COLOR *cur_attr_ptr;
5506 SYMBOL_CODE *cur_char_ptr;
5510 feature_type *f_ptr;
5516 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5517 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5518 prt(_("名前", "Name"), 4, max + 3);
5521 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5522 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5526 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5527 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5530 for (FEAT_IDX i = 0; i < 78; i++)
5532 Term_putch(i, 5, TERM_WHITE, '=');
5535 if (direct_f_idx < 0)
5537 for (FEAT_IDX i = 0; i < browser_rows; i++)
5539 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5546 if (direct_f_idx < 0)
5548 /* Scroll group list */
5549 if (grp_cur < grp_top) grp_top = grp_cur;
5550 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5552 /* Display a list of feature groups */
5553 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5555 if (old_grp_cur != grp_cur)
5557 old_grp_cur = grp_cur;
5559 /* Get a list of features in the current group */
5560 feat_cnt = collect_features(feat_idx, 0x00);
5563 /* Scroll feature list */
5564 while (feat_cur < feat_top)
5565 feat_top = MAX(0, feat_top - browser_rows / 2);
5566 while (feat_cur >= feat_top + browser_rows)
5567 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5572 /* Display a list of features in the current group */
5573 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5577 feat_top = feat_cur;
5579 /* Display a list of features in the current group */
5580 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5582 /* Display visual list below first object */
5583 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5587 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5588 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5589 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5592 /* Get the current feature */
5593 f_ptr = &f_info[feat_idx[feat_cur]];
5594 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5595 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5599 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5603 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5607 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5612 if (visual_list && ((ch == 'A') || (ch == 'a')))
5614 int prev_lighting_level = *lighting_level;
5618 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5619 else (*lighting_level)--;
5623 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5624 else (*lighting_level)++;
5627 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5628 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5630 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5631 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5636 else if ((ch == 'D') || (ch == 'd'))
5638 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5639 byte prev_x_char = f_ptr->x_char[*lighting_level];
5641 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
5645 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
5646 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5648 if (prev_x_char != f_ptr->x_char[*lighting_level])
5649 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5651 else *need_redraw = TRUE;
5656 /* Do visual mode command if needed */
5657 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))
5661 /* Restore previous visual settings */
5663 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5665 f_ptr->x_attr[i] = attr_old[i];
5666 f_ptr->x_char[i] = char_old[i];
5673 if (direct_f_idx >= 0) flag = TRUE;
5674 else *lighting_level = F_LIT_STANDARD;
5677 /* Preserve current visual settings */
5680 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5682 attr_old[i] = f_ptr->x_attr[i];
5683 char_old[i] = f_ptr->x_char[i];
5685 *lighting_level = F_LIT_STANDARD;
5692 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5694 attr_idx_feat[i] = f_ptr->x_attr[i];
5695 char_idx_feat[i] = f_ptr->x_char[i];
5704 /* Allow TERM_DARK text */
5705 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5707 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
5708 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
5726 /* Move the cursor */
5727 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
5733 /* Free the "feat_idx" array */
5734 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
5739 * List wanted monsters
5740 * @param creature_ptr プレーヤーへの参照ポインタ
5743 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
5745 /* Open a new file */
5747 GAME_TEXT file_name[1024];
5748 fff = my_fopen_temp(file_name, 1024);
5751 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5756 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
5757 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
5759 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
5760 fprintf(fff, "----------------------------------------------\n");
5762 bool listed = FALSE;
5763 for (int i = 0; i < MAX_BOUNTY; i++)
5765 if (current_world_ptr->bounty_r_idx[i] <= 10000)
5767 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
5774 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
5779 /* Display the file contents */
5780 (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
5785 * List virtues & status
5787 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
5789 /* Open a new file */
5791 GAME_TEXT file_name[1024];
5792 fff = my_fopen_temp(file_name, 1024);
5795 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5800 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
5801 dump_virtues(creature_ptr, fff);
5804 /* Display the file contents */
5805 (void)show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
5812 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
5814 /* Open a new file */
5816 GAME_TEXT file_name[1024];
5817 fff = my_fopen_temp(file_name, 1024);
5820 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5825 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
5829 if (!d_info[i].maxdepth) continue;
5830 if (!max_dlv[i]) continue;
5831 if (d_info[i].final_guardian)
5833 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
5835 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
5837 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
5842 /* Display the file contents */
5843 (void)show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
5849 * List virtues & status
5852 static void do_cmd_knowledge_stat(player_type *creature_ptr)
5854 /* Open a new file */
5856 GAME_TEXT file_name[1024];
5857 fff = my_fopen_temp(file_name, 1024);
5860 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5865 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
5866 (2 * creature_ptr->hitdie +
5867 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
5869 if (creature_ptr->knowledge & KNOW_HPRATE)
5870 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
5871 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
5873 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
5874 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
5876 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);
5877 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
5880 dump_yourself(creature_ptr, fff);
5883 /* Display the file contents */
5884 (void)show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
5890 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
5891 * Print all active quests
5892 * @param creature_ptr プレーヤーへの参照ポインタ
5895 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
5898 char rand_tmp_str[120] = "\0";
5899 GAME_TEXT name[MAX_NLEN];
5900 monster_race *r_ptr;
5901 int rand_level = 100;
5904 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
5906 for (QUEST_IDX i = 1; i < max_q_idx; i++)
5908 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
5909 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
5910 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
5914 /* Set the quest number temporary */
5915 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
5917 /* Clear the text */
5918 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
5919 quest_text_line = 0;
5921 creature_ptr->current_floor_ptr->inside_quest = i;
5923 /* Get the quest text */
5924 init_flags = INIT_SHOW_TEXT;
5926 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
5928 /* Reset the old quest number */
5929 creature_ptr->current_floor_ptr->inside_quest = old_quest;
5931 /* No info from "silent" quests */
5932 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
5936 if (quest[i].type != QUEST_TYPE_RANDOM)
5938 char note[80] = "\0";
5940 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
5942 switch (quest[i].type)
5944 case QUEST_TYPE_KILL_LEVEL:
5945 case QUEST_TYPE_KILL_ANY_LEVEL:
5946 r_ptr = &r_info[quest[i].r_idx];
5947 strcpy(name, r_name + r_ptr->name);
5948 if (quest[i].max_num > 1)
5951 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
5952 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
5955 sprintf(note, " - kill %d %s, have killed %d.",
5956 (int)quest[i].max_num, name, (int)quest[i].cur_num);
5960 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
5963 case QUEST_TYPE_FIND_ARTIFACT:
5966 artifact_type *a_ptr = &a_info[quest[i].k_idx];
5968 object_type *q_ptr = &forge;
5969 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
5970 object_prep(q_ptr, k_idx);
5971 q_ptr->name1 = quest[i].k_idx;
5972 q_ptr->ident = IDENT_STORE;
5973 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
5975 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
5977 case QUEST_TYPE_FIND_EXIT:
5978 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
5981 case QUEST_TYPE_KILL_NUMBER:
5983 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
5984 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
5986 sprintf(note, " - Kill %d monsters, have killed %d.",
5987 (int)quest[i].max_num, (int)quest[i].cur_num);
5991 case QUEST_TYPE_KILL_ALL:
5992 case QUEST_TYPE_TOWER:
5993 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
5998 /* Print the quest info */
5999 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6000 quest[i].name, (int)quest[i].level, note);
6002 fputs(tmp_str, fff);
6004 if (quest[i].status == QUEST_STATUS_COMPLETED)
6006 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6007 fputs(tmp_str, fff);
6012 while (quest_text[k][0] && k < 10)
6014 fprintf(fff, " %s\n", quest_text[k]);
6021 /* QUEST_TYPE_RANDOM */
6022 if (quest[i].level >= rand_level)
6026 rand_level = quest[i].level;
6028 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6030 /* Print the quest info */
6031 r_ptr = &r_info[quest[i].r_idx];
6032 strcpy(name, r_name + r_ptr->name);
6034 if (quest[i].max_num <= 1)
6036 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6037 quest[i].name, (int)quest[i].level, name);
6042 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6043 quest[i].name, (int)quest[i].level,
6044 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6048 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6049 quest[i].name, (int)quest[i].level,
6050 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6054 /* Print the current random quest */
6055 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6057 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6061 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6064 char playtime_str[16];
6065 quest_type* const q_ptr = &quest[q_idx];
6067 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6068 if (is_fixed_quest_idx(q_idx))
6070 /* Set the quest number temporary */
6071 IDX old_quest = floor_ptr->inside_quest;
6073 floor_ptr->inside_quest = q_idx;
6076 init_flags = INIT_NAME_ONLY;
6078 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6080 /* Reset the old quest number */
6081 floor_ptr->inside_quest = old_quest;
6083 /* No info from "silent" quests */
6084 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6087 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6088 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6090 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
6092 /* Print the quest info */
6094 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6095 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6096 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6097 fputs(tmp_str, fff);
6101 /* Print the quest info */
6102 if (q_ptr->complev == 0)
6105 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6106 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6107 r_name + r_info[q_ptr->r_idx].name,
6108 (int)q_ptr->level, playtime_str);
6109 fputs(tmp_str, fff);
6114 _(" %-35s (%3d階) - レベル%2d - %s\n",
6115 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6116 r_name + r_info[q_ptr->r_idx].name,
6120 fputs(tmp_str, fff);
6126 * Print all finished quests
6127 * @param creature_ptr プレーヤーへの参照ポインタ
6128 * @param fff セーブファイル (展開済?)
6129 * @param quest_num[] 受注したことのあるクエスト群
6132 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6134 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6135 QUEST_IDX total = 0;
6136 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6138 QUEST_IDX q_idx = quest_num[i];
6139 quest_type* const q_ptr = &quest[q_idx];
6141 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6147 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6152 * Print all failed quests
6153 * @param creature_ptr プレーヤーへの参照ポインタ
6154 * @param fff セーブファイル (展開済?)
6155 * @param quest_num[] 受注したことのあるクエスト群
6158 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6160 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6161 QUEST_IDX total = 0;
6162 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6164 QUEST_IDX q_idx = quest_num[i];
6165 quest_type* const q_ptr = &quest[q_idx];
6167 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6168 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6174 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6179 * Print all random quests
6181 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6183 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6184 GAME_TEXT tmp_str[120];
6185 QUEST_IDX total = 0;
6186 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6188 /* No info from "silent" quests */
6189 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6191 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6195 /* Print the quest info */
6196 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6197 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6198 fputs(tmp_str, fff);
6202 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6206 * Print quest status of all active quests
6207 * @param creature_ptr プレーヤーへの参照ポインタ
6210 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6212 /* Open a new file */
6214 GAME_TEXT file_name[1024];
6215 fff = my_fopen_temp(file_name, 1024);
6218 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6223 /* Allocate Memory */
6225 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6227 /* Sort by compete level */
6228 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6230 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6232 /* Dump Quest Information */
6233 do_cmd_knowledge_quests_current(creature_ptr, fff);
6235 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6237 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6238 if (current_world_ptr->wizard)
6241 do_cmd_knowledge_quests_wiz_random(fff);
6246 /* Display the file contents */
6247 (void)show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6251 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6257 * @param player_ptr プレーヤーへの参照ポインタ
6260 static void do_cmd_knowledge_home(player_type *player_ptr)
6262 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6264 /* Open a new file */
6266 GAME_TEXT file_name[1024];
6267 fff = my_fopen_temp(file_name, 1024);
6270 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6275 /* Print all homes in the different towns */
6277 st_ptr = &town_info[1].store[STORE_HOME];
6279 /* Home -- if anything there */
6280 if (st_ptr->stock_num)
6285 /* Header with name of the town */
6286 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6288 /* Dump all available items */
6289 concptr paren = ")";
6290 GAME_TEXT o_name[MAX_NLEN];
6291 for (int i = 0; i < st_ptr->stock_num; i++)
6294 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6295 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6296 if (strlen(o_name) <= 80 - 3)
6298 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6304 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6305 if (iskanji(*t)) { t++; n++; }
6306 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6308 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6309 fprintf(fff, " %.77s\n", o_name + n);
6312 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6313 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6317 /* Add an empty line */
6318 fprintf(fff, "\n\n");
6323 /* Display the file contents */
6324 (void)show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6330 * Check the status of "autopick"
6332 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6334 /* Open a new file */
6336 GAME_TEXT file_name[1024];
6337 fff = my_fopen_temp(file_name, 1024);
6340 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6347 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6351 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6352 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6355 for (int k = 0; k < max_autopick; k++)
6358 byte act = autopick_list[k].action;
6359 if (act & DONT_AUTOPICK)
6361 tmp = _("放置", "Leave");
6363 else if (act & DO_AUTODESTROY)
6365 tmp = _("破壊", "Destroy");
6367 else if (act & DO_AUTOPICK)
6369 tmp = _("拾う", "Pickup");
6373 tmp = _("確認", "Query");
6376 if (act & DO_DISPLAY)
6377 fprintf(fff, "%11s", format("[%s]", tmp));
6379 fprintf(fff, "%11s", format("(%s)", tmp));
6381 tmp = autopick_line_from_entry(&autopick_list[k]);
6382 fprintf(fff, " %s", tmp);
6389 /* Display the file contents */
6390 (void)show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6396 * Interact with "knowledge"
6398 void do_cmd_knowledge(player_type *creature_ptr)
6401 bool need_redraw = FALSE;
6403 /* File type is "TEXT" */
6404 FILE_TYPE(FILE_TYPE_TEXT);
6407 /* Interact until done */
6412 /* Ask for a choice */
6413 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6414 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6416 /* Give some choices */
6420 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6421 prt("(2) 既知のアイテム の一覧", 7, 5);
6422 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6423 prt("(4) 既知のモンスター の一覧", 9, 5);
6424 prt("(5) 倒した敵の数 の一覧", 10, 5);
6425 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6426 prt("(7) 現在のペット の一覧", 12, 5);
6427 prt("(8) 我が家のアイテム の一覧", 13, 5);
6428 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6429 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6433 prt("(a) 自分に関する情報 の一覧", 6, 5);
6434 prt("(b) 突然変異 の一覧", 7, 5);
6435 prt("(c) 武器の経験値 の一覧", 8, 5);
6436 prt("(d) 魔法の経験値 の一覧", 9, 5);
6437 prt("(e) 技能の経験値 の一覧", 10, 5);
6438 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6439 prt("(g) 入ったダンジョン の一覧", 12, 5);
6440 prt("(h) 実行中のクエスト の一覧", 13, 5);
6441 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6446 prt("(1) Display known artifacts", 6, 5);
6447 prt("(2) Display known objects", 7, 5);
6448 prt("(3) Display remaining uniques", 8, 5);
6449 prt("(4) Display known monster", 9, 5);
6450 prt("(5) Display kill count", 10, 5);
6451 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6452 prt("(7) Display current pets", 12, 5);
6453 prt("(8) Display home inventory", 13, 5);
6454 prt("(9) Display *identified* equip.", 14, 5);
6455 prt("(0) Display terrain symbols.", 15, 5);
6459 prt("(a) Display about yourself", 6, 5);
6460 prt("(b) Display mutations", 7, 5);
6461 prt("(c) Display weapon proficiency", 8, 5);
6462 prt("(d) Display spell proficiency", 9, 5);
6463 prt("(e) Display misc. proficiency", 10, 5);
6464 prt("(f) Display virtues", 11, 5);
6465 prt("(g) Display dungeons", 12, 5);
6466 prt("(h) Display current quests", 13, 5);
6467 prt("(i) Display auto pick/destroy", 14, 5);
6471 prt(_("-続く-", "-more-"), 17, 8);
6472 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6473 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6474 /*prt("-) 前ページ", 21, 60);*/
6475 prt(_("コマンド:", "Command: "), 20, 0);
6478 if (i == ESCAPE) break;
6481 case ' ': /* Page change */
6485 case '1': /* Artifacts */
6486 do_cmd_knowledge_artifacts(creature_ptr);
6488 case '2': /* Objects */
6489 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6491 case '3': /* Uniques */
6492 do_cmd_knowledge_uniques(creature_ptr);
6494 case '4': /* Monsters */
6495 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6497 case '5': /* Kill count */
6498 do_cmd_knowledge_kill_count(creature_ptr);
6500 case '6': /* wanted */
6501 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6503 case '7': /* Pets */
6504 do_cmd_knowledge_pets(creature_ptr);
6506 case '8': /* Home */
6507 do_cmd_knowledge_home(creature_ptr);
6509 case '9': /* Resist list */
6510 do_cmd_knowledge_inven(creature_ptr);
6512 case '0': /* Feature list */
6514 IDX lighting_level = F_LIT_STANDARD;
6515 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6519 case 'a': /* Max stat */
6520 do_cmd_knowledge_stat(creature_ptr);
6522 case 'b': /* Mutations */
6523 do_cmd_knowledge_mutations(creature_ptr);
6525 case 'c': /* weapon-exp */
6526 do_cmd_knowledge_weapon_exp(creature_ptr);
6528 case 'd': /* spell-exp */
6529 do_cmd_knowledge_spell_exp(creature_ptr);
6531 case 'e': /* skill-exp */
6532 do_cmd_knowledge_skill_exp(creature_ptr);
6534 case 'f': /* Virtues */
6535 do_cmd_knowledge_virtues(creature_ptr);
6537 case 'g': /* Dungeon */
6538 do_cmd_knowledge_dungeon(creature_ptr);
6540 case 'h': /* Quests */
6541 do_cmd_knowledge_quests(creature_ptr);
6543 case 'i': /* Autopick */
6544 do_cmd_knowledge_autopick(creature_ptr);
6546 default: /* Unknown option */
6554 if (need_redraw) do_cmd_redraw(creature_ptr);
6559 * Check on the status of an active quest
6560 * @param creature_ptr プレーヤーへの参照ポインタ
6563 void do_cmd_checkquest(player_type *creature_ptr)
6565 /* File type is "TEXT" */
6566 FILE_TYPE(FILE_TYPE_TEXT);
6570 do_cmd_knowledge_quests(creature_ptr);
6576 * Display the time and date
6577 * @param creature_ptr プレーヤーへの参照ポインタ
6580 void do_cmd_time(player_type *creature_ptr)
6583 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6586 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6589 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6590 else strcpy(day_buf, "*****");
6592 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6593 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6597 if (!randint0(10) || creature_ptr->image)
6599 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6603 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6606 /* Open this file */
6608 fff = my_fopen(buf, "rt");
6612 /* Find this time */
6613 int full = hour * 100 + min;
6617 while (!my_fgets(fff, buf, sizeof(buf)))
6619 /* Ignore comments */
6620 if (!buf[0] || (buf[0] == '#')) continue;
6622 /* Ignore invalid lines */
6623 if (buf[1] != ':') continue;
6625 /* Process 'Start' */
6628 /* Extract the starting time */
6629 start = atoi(buf + 2);
6631 /* Assume valid for an hour */
6639 /* Extract the ending time */
6640 end = atoi(buf + 2);
6644 /* Ignore incorrect range */
6645 if ((start > full) || (full > end)) continue;
6647 /* Process 'Description' */
6652 /* Apply the randomizer */
6653 if (!randint0(num)) strcpy(desc, buf + 2);