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.
15 * The dump commands of original Angband simply add new lines to
16 * existing files; these files will become bigger and bigger unless
17 * an user deletes some or all of these files by hand at some
19 * These three functions automatically delete old dumped lines
20 * before adding new ones. Since there are various kinds of automatic
21 * dumps in a single file, we add a header and a footer with a type
22 * name for every automatic dump, and kill old lines only when the
23 * lines have the correct type of header and footer.
24 * We need to be quite paranoid about correctness; the user might
25 * (mistakenly) edit the file by hand, and see all their work come
26 * to nothing on the next auto dump otherwise. The current code only
27 * detects changes by noting inconsistencies between the actual number
28 * of lines and the number written in the footer. Note that this will
29 * not catch single-line edits.
34 #include "cmd/cmd-draw.h"
35 #include "cmd/cmd-dump.h"
36 #include "cmd/cmd-inventory.h"
37 #include "cmd/lighting-level-table.h"
38 #include "cmd/cmd-visuals.h"
39 #include "cmd/dump-util.h"
41 #include "core.h" // 暫定。後で消す.
42 #include "core/show-file.h"
43 #include "io/read-pref-file.h"
44 #include "io/interpret-pref-file.h"
46 #include "knowledge/knowledge-artifacts.h"
47 #include "knowledge/knowledge-experiences.h"
48 #include "knowledge/knowledge-quests.h"
49 #include "knowledge/knowledge-uniques.h"
55 #include "view/display-player.h" // 暫定。後で消す.
56 #include "player-personality.h"
60 #include "market/store.h"
63 #include "object-flavor.h"
64 #include "monster-status.h"
65 #include "dungeon-file.h"
66 #include "object/object-kind.h"
67 #include "floor-town.h"
68 #include "cmd/feeling-table.h"
69 #include "cmd/monster-group-table.h"
70 #include "cmd/object-group-table.h"
71 #include "market/store-util.h"
72 #include "view-mainwindow.h" // 暫定。後で消す
75 #include "diary-subtitle-table.h"
76 #include "io/write-diary.h"
80 * @brief prefファイルを選択して処理する /
81 * Ask for a "user pref line" and process it
82 * @brief prf出力内容を消去する /
83 * Remove old lines automatically generated before.
84 * @param orig_file 消去を行うファイル名
86 static void remove_auto_dump(concptr orig_file, concptr auto_dump_mark)
89 bool between_mark = FALSE;
92 long header_location = 0;
93 char header_mark_str[80];
94 char footer_mark_str[80];
96 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
97 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
98 size_t mark_len = strlen(footer_mark_str);
101 orig_fff = my_fopen(orig_file, "r");
102 if (!orig_fff) return;
104 FILE *tmp_fff = NULL;
105 char tmp_file[FILE_NAME_SIZE];
106 if (!open_temporary_file(&tmp_fff, tmp_file)) return;
110 if (my_fgets(orig_fff, buf, sizeof(buf)))
114 fseek(orig_fff, header_location, SEEK_SET);
115 between_mark = FALSE;
126 if (!strcmp(buf, header_mark_str))
128 header_location = ftell(orig_fff);
135 fprintf(tmp_fff, "%s\n", buf);
141 if (!strncmp(buf, footer_mark_str, mark_len))
144 if (!sscanf(buf + mark_len, " (%d)", &tmp)
147 fseek(orig_fff, header_location, SEEK_SET);
150 between_mark = FALSE;
162 tmp_fff = my_fopen(tmp_file, "r");
163 orig_fff = my_fopen(orig_file, "w");
164 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
165 fprintf(orig_fff, "%s\n", buf);
178 * @brief Return suffix of ordinal number
180 * @return pointer of suffix string.
182 concptr get_ordinal_number_suffix(int num)
184 num = ABS(num) % 100;
188 return (num == 11) ? "th" : "st";
190 return (num == 12) ? "th" : "nd";
192 return (num == 13) ? "th" : "rd";
200 * @brief 画面を再描画するコマンドのメインルーチン
201 * Hack -- redraw the screen
202 * @param creature_ptr プレーヤーへの参照ポインタ
205 * Allow absolute file names?
207 void do_cmd_pref(player_type *creature_ptr)
211 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
213 (void)interpret_pref_file(creature_ptr, buf);
218 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
219 * @param creature_ptr プレーヤーへの参照ポインタ
222 void do_cmd_reload_autopick(player_type *creature_ptr)
224 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? ")))
227 autopick_load_pref(creature_ptr, TRUE);
232 * Interact with "colors"
234 void do_cmd_colors(player_type *creature_ptr)
239 FILE *auto_dump_stream;
240 FILE_TYPE(FILE_TYPE_TEXT);
245 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
246 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
247 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
248 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
249 prt(_("コマンド: ", "Command: "), 8, 0);
251 if (i == ESCAPE) break;
255 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
256 prt(_("ファイル: ", "File: "), 10, 0);
257 sprintf(tmp, "%s.prf", creature_ptr->base_name);
258 if (!askfor(tmp, 70)) continue;
260 (void)process_pref_file(creature_ptr, tmp);
261 Term_xtra(TERM_XTRA_REACT, 0);
266 static concptr mark = "Colors";
267 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
268 prt(_("ファイル: ", "File: "), 10, 0);
269 sprintf(tmp, "%s.prf", creature_ptr->base_name);
270 if (!askfor(tmp, 70)) continue;
272 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
273 if (!open_auto_dump(&auto_dump_stream, buf, mark)) continue;
275 auto_dump_printf(auto_dump_stream, _("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
276 for (i = 0; i < 256; i++)
278 int kv = angband_color_table[i][0];
279 int rv = angband_color_table[i][1];
280 int gv = angband_color_table[i][2];
281 int bv = angband_color_table[i][3];
283 concptr name = _("未知", "unknown");
284 if (!kv && !rv && !gv && !bv) continue;
286 if (i < 16) name = color_names[i];
288 auto_dump_printf(auto_dump_stream, _("# カラー '%s'\n", "# Color '%s'\n"), name);
289 auto_dump_printf(auto_dump_stream, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
293 close_auto_dump(&auto_dump_stream, mark);
294 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
299 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
304 for (byte j = 0; j < 16; j++)
306 Term_putstr(j * 4, 20, -1, a, "###");
307 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
310 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
311 Term_putstr(5, 10, -1, TERM_WHITE,
312 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
313 Term_putstr(5, 12, -1, TERM_WHITE,
314 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
315 angband_color_table[a][0],
316 angband_color_table[a][1],
317 angband_color_table[a][2],
318 angband_color_table[a][3]));
319 Term_putstr(0, 14, -1, TERM_WHITE,
320 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
322 if (i == ESCAPE) break;
324 if (i == 'n') a = (byte)(a + 1);
325 if (i == 'N') a = (byte)(a - 1);
326 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
327 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
328 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
329 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
330 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
331 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
332 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
333 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
335 Term_xtra(TERM_XTRA_REACT, 0);
352 * Note something in the message recall
354 void do_cmd_note(void)
358 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
359 if (!buf[0] || (buf[0] == ' ')) return;
361 msg_format(_("メモ: %s", "Note: %s"), buf);
366 * Mention the current version
368 void do_cmd_version(void)
370 #if FAKE_VER_EXTRA > 0
371 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
372 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
374 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
375 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
381 * Note that "feeling" is set to zero unless some time has passed.
382 * Note that this is done when the level is GENERATED, not entered.
384 void do_cmd_feeling(player_type *creature_ptr)
386 if (creature_ptr->wild_mode) return;
388 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
390 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
394 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
396 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
398 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
402 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
406 if (!creature_ptr->current_floor_ptr->dun_level)
408 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
412 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
413 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
414 else if (IS_ECHIZEN(creature_ptr))
415 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
417 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
422 * todo 引数と戻り値について追記求む
423 * Build a list of monster indexes in the given group.
425 * mode & 0x01 : check for non-empty group
426 * mode & 0x02 : visual operation only
428 * @param creature_ptr プレーヤーへの参照ポインタ
430 * @param mon_idx[] ???
432 * @return The number of monsters in the group
434 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
436 concptr group_char = monster_group_char[grp_cur];
437 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
438 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
439 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
440 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
443 for (IDX i = 0; i < max_r_idx; i++)
445 monster_race *r_ptr = &r_info[i];
446 if (!r_ptr->name) continue;
447 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
451 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
455 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
460 for (int j = 0; j < MAX_BOUNTY; j++)
462 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
463 (creature_ptr->today_mon && creature_ptr->today_mon == i))
470 if (!wanted) continue;
472 else if (grp_amberite)
474 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
478 if (!my_strchr(group_char, r_ptr->d_char)) continue;
481 mon_idx[mon_cnt++] = i;
482 if (mode & 0x01) break;
485 mon_idx[mon_cnt] = -1;
487 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
493 * Build a list of object indexes in the given group. Return the number
494 * of objects in the group.
496 * mode & 0x01 : check for non-empty group
497 * mode & 0x02 : visual operation only
499 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
501 KIND_OBJECT_IDX object_cnt = 0;
502 byte group_tval = object_group_tval[grp_cur];
503 for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++)
505 object_kind *k_ptr = &k_info[i];
506 if (!k_ptr->name) continue;
510 if (!current_world_ptr->wizard)
512 if (!k_ptr->flavor) continue;
513 if (!k_ptr->aware) continue;
517 for (int j = 0; j < 4; j++)
518 k += k_ptr->chance[j];
522 if (TV_LIFE_BOOK == group_tval)
524 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
526 object_idx[object_cnt++] = i;
531 else if (k_ptr->tval == group_tval)
533 object_idx[object_cnt++] = i;
538 if (mode & 0x01) break;
541 object_idx[object_cnt] = -1;
547 * Build a list of feature indexes in the given group. Return the number
548 * of features in the group.
550 * mode & 0x01 : check for non-empty group
552 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
554 FEAT_IDX feat_cnt = 0;
555 for (FEAT_IDX i = 0; i < max_f_idx; i++)
557 feature_type *f_ptr = &f_info[i];
558 if (!f_ptr->name) continue;
559 if (f_ptr->mimic != i) continue;
561 feat_idx[feat_cnt++] = i;
562 if (mode & 0x01) break;
565 feat_idx[feat_cnt] = -1;
571 * @brief 現在のペットを表示するコマンドのメインルーチン /
572 * Display current pets
573 * @param creature_ptr プレーヤーへの参照ポインタ
576 static void do_cmd_knowledge_pets(player_type *creature_ptr)
579 GAME_TEXT file_name[FILE_NAME_SIZE];
580 if (!open_temporary_file(&fff, file_name)) return;
583 GAME_TEXT pet_name[MAX_NLEN];
585 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
587 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
588 if (!monster_is_valid(m_ptr)) continue;
589 if (!is_pet(m_ptr)) continue;
592 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
593 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
596 int show_upkeep = calculate_upkeep(creature_ptr);
598 fprintf(fff, "----------------------------------------------\n");
600 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
602 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
604 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
607 (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
613 * @brief 現在のペットを表示するコマンドのメインルーチン /
614 * @param creature_ptr プレーヤーへの参照ポインタ
617 * @note the player ghosts are ignored.
619 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
622 GAME_TEXT file_name[FILE_NAME_SIZE];
623 if (!open_temporary_file(&fff, file_name)) return;
626 C_MAKE(who, max_r_idx, MONRACE_IDX);
628 for (int kk = 1; kk < max_r_idx; kk++)
630 monster_race *r_ptr = &r_info[kk];
632 if (r_ptr->flags1 & (RF1_UNIQUE))
634 bool dead = (r_ptr->max_num == 0);
643 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
645 if (this_monster > 0)
647 total += this_monster;
653 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
656 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
658 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
663 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
665 monster_race *r_ptr = &r_info[i];
666 if (r_ptr->name) who[n++] = i;
670 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
671 for (int k = 0; k < n; k++)
673 monster_race *r_ptr = &r_info[who[k]];
674 if (r_ptr->flags1 & (RF1_UNIQUE))
676 bool dead = (r_ptr->max_num == 0);
679 fprintf(fff, " %s\n", (r_name + r_ptr->name));
686 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
687 if (this_monster <= 0) continue;
690 if (my_strchr("pt", r_ptr->d_char))
691 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
693 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
695 if (this_monster < 2)
697 if (my_strstr(r_name + r_ptr->name, "coins"))
699 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
703 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
709 strcpy(ToPlural, (r_name + r_ptr->name));
710 plural_aux(ToPlural);
711 fprintf(fff, " %d %s\n", this_monster, ToPlural);
714 total += this_monster;
717 fprintf(fff, "----------------------------------------------\n");
719 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
721 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
724 C_KILL(who, max_r_idx, s16b);
726 (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
732 * @brief モンスター情報リスト中のグループを表示する /
733 * Display the object groups.
737 * @param per_page リストの表示行
738 * @param grp_idx グループのID配列
739 * @param group_text グループ名の文字列配列
740 * @param grp_cur 現在の選択ID
741 * @param grp_top 現在の選択リスト最上部ID
744 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)
746 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
748 int grp = grp_idx[grp_top + i];
749 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
750 Term_erase(col, row + i, wid);
751 c_put_str(attr, group_text[grp], row + i, col);
757 * Move the cursor in a browser window
759 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt, IDX *list_cur, int list_cnt)
764 IDX list = *list_cur;
770 d = get_keymap_dir(ch);
774 if ((ddx[d] > 0) && ddy[d])
778 Term_get_size(&wid, &hgt);
779 browser_rows = hgt - 8;
783 grp += ddy[d] * (browser_rows - 1);
784 if (grp >= grp_cnt) grp = grp_cnt - 1;
785 if (grp < 0) grp = 0;
786 if (grp != old_grp) list = 0;
790 list += ddy[d] * browser_rows;
791 if (list >= list_cnt) list = list_cnt - 1;
792 if (list < 0) list = 0;
803 if (col < 0) col = 0;
804 if (col > 1) col = 1;
814 if (grp >= grp_cnt) grp = grp_cnt - 1;
815 if (grp < 0) grp = 0;
816 if (grp != old_grp) list = 0;
821 if (list >= list_cnt) list = list_cnt - 1;
822 if (list < 0) list = 0;
833 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
835 for (int i = 0; i < height; i++)
837 Term_erase(col, row + i, width);
840 if (use_bigtile) width /= 2;
842 for (int i = 0; i < height; i++)
844 for (int j = 0; j < width; j++)
846 TERM_LEN x = col + j;
847 TERM_LEN y = row + i;
848 if (use_bigtile) x += j;
850 int ia = attr_top + i;
851 int ic = char_left + j;
852 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
853 (!use_graphics && ic > 0x7f))
856 TERM_COLOR a = (TERM_COLOR)ia;
857 SYMBOL_CODE c = (SYMBOL_CODE)ic;
858 if (c & 0x80) a |= 0x80;
860 Term_queue_bigchar(x, y, a, c, 0, 0);
867 * Place the cursor at the collect position for visual mode
869 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
871 int i = (a & 0x7f) - attr_top;
872 int j = c - char_left;
874 TERM_LEN x = col + j;
875 TERM_LEN y = row + i;
876 if (use_bigtile) x += j;
883 * Display the monsters in a group.
885 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[], int mon_cur, int mon_top, bool visual_only)
888 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
891 MONRACE_IDX r_idx = mon_idx[mon_top + i];
892 monster_race *r_ptr = &r_info[r_idx];
893 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
894 c_prt(attr, (r_name + r_ptr->name), row + i, col);
897 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
900 if (current_world_ptr->wizard || visual_only)
902 c_prt(attr, format("%d", r_idx), row + i, 62);
905 Term_erase(69, row + i, 255);
906 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
909 if (!(r_ptr->flags1 & RF1_UNIQUE))
910 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
912 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
913 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
917 for (; i < per_page; i++)
919 Term_erase(col, row + i, 255);
926 * Display known monsters.
927 * @param creature_ptr プレーヤーへの参照ポインタ
928 * @param need_redraw 画面の再描画が必要な時TRUE
929 * @param visual_only ???
930 * @param direct_r_idx モンスターID
933 void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
936 Term_get_size(&wid, &hgt);
938 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
944 bool visual_list = FALSE;
945 TERM_COLOR attr_top = 0;
948 int browser_rows = hgt - 8;
949 if (direct_r_idx < 0)
951 mode = visual_only ? 0x03 : 0x01;
953 for (IDX i = 0; monster_group_text[i] != NULL; i++)
955 len = strlen(monster_group_text[i]);
956 if (len > max) max = len;
958 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
960 grp_idx[grp_cnt++] = i;
968 mon_idx[0] = direct_r_idx;
972 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
973 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
976 grp_idx[grp_cnt] = -1;
977 mode = visual_only ? 0x02 : 0x00;
978 IDX old_grp_cur = -1;
991 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
992 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
993 prt(_("名前", "Name"), 4, max + 3);
994 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
995 prt(_("文字", "Sym"), 4, 67);
996 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
998 for (IDX i = 0; i < 78; i++)
1000 Term_putch(i, 5, TERM_WHITE, '=');
1003 if (direct_r_idx < 0)
1005 for (IDX i = 0; i < browser_rows; i++)
1007 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1014 if (direct_r_idx < 0)
1016 if (grp_cur < grp_top) grp_top = grp_cur;
1017 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1019 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
1020 if (old_grp_cur != grp_cur)
1022 old_grp_cur = grp_cur;
1023 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
1026 while (mon_cur < mon_top)
1027 mon_top = MAX(0, mon_top - browser_rows / 2);
1028 while (mon_cur >= mon_top + browser_rows)
1029 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
1034 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
1039 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
1040 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1043 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
1044 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
1045 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
1046 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
1049 monster_race *r_ptr;
1050 r_ptr = &r_info[mon_idx[mon_cur]];
1054 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
1055 handle_stuff(creature_ptr);
1060 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
1064 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1068 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
1072 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))
1074 if (direct_r_idx >= 0)
1100 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
1102 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
1114 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
1121 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
1126 * Display the objects in a group.
1128 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
1129 int object_cur, int object_top, bool visual_only)
1132 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
1134 GAME_TEXT o_name[MAX_NLEN];
1137 object_kind *flavor_k_ptr;
1138 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
1139 object_kind *k_ptr = &k_info[k_idx];
1140 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
1141 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
1142 if (!visual_only && k_ptr->flavor)
1144 flavor_k_ptr = &k_info[k_ptr->flavor];
1148 flavor_k_ptr = k_ptr;
1151 attr = ((i + object_top == object_cur) ? cursor : attr);
1152 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
1154 strip_name(o_name, k_idx);
1158 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
1161 c_prt(attr, o_name, row + i, col);
1164 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);
1167 if (current_world_ptr->wizard || visual_only)
1169 c_prt(attr, format("%d", k_idx), row + i, 70);
1172 a = flavor_k_ptr->x_attr;
1173 c = flavor_k_ptr->x_char;
1175 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
1178 for (; i < per_page; i++)
1180 Term_erase(col, row + i, 255);
1186 * Describe fake object
1188 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
1191 object_type object_type_body;
1192 o_ptr = &object_type_body;
1194 object_prep(o_ptr, k_idx);
1196 o_ptr->ident |= IDENT_KNOWN;
1197 handle_stuff(creature_ptr);
1199 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
1201 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1207 * Display known objects
1209 void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
1211 IDX object_old, object_top;
1214 OBJECT_IDX *object_idx;
1216 bool visual_list = FALSE;
1217 TERM_COLOR attr_top = 0;
1222 Term_get_size(&wid, &hgt);
1224 int browser_rows = hgt - 8;
1225 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
1230 if (direct_k_idx < 0)
1232 mode = visual_only ? 0x03 : 0x01;
1233 for (IDX i = 0; object_group_text[i] != NULL; i++)
1235 len = strlen(object_group_text[i]);
1236 if (len > max) max = len;
1238 if (collect_objects(i, object_idx, mode))
1240 grp_idx[grp_cnt++] = i;
1249 object_kind *k_ptr = &k_info[direct_k_idx];
1250 object_kind *flavor_k_ptr;
1252 if (!visual_only && k_ptr->flavor)
1254 flavor_k_ptr = &k_info[k_ptr->flavor];
1258 flavor_k_ptr = k_ptr;
1261 object_idx[0] = direct_k_idx;
1262 object_old = direct_k_idx;
1265 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
1266 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
1269 grp_idx[grp_cnt] = -1;
1270 mode = visual_only ? 0x02 : 0x00;
1271 IDX old_grp_cur = -1;
1274 IDX object_cur = object_top = 0;
1280 object_kind *k_ptr, *flavor_k_ptr;
1287 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
1288 if (direct_k_idx < 0) prt("グループ", 4, 0);
1289 prt("名前", 4, max + 3);
1290 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
1293 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
1294 if (direct_k_idx < 0) prt("Group", 4, 0);
1295 prt("Name", 4, max + 3);
1296 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
1300 for (IDX i = 0; i < 78; i++)
1302 Term_putch(i, 5, TERM_WHITE, '=');
1305 if (direct_k_idx < 0)
1307 for (IDX i = 0; i < browser_rows; i++)
1309 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1316 if (direct_k_idx < 0)
1318 if (grp_cur < grp_top) grp_top = grp_cur;
1319 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1321 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
1322 if (old_grp_cur != grp_cur)
1324 old_grp_cur = grp_cur;
1325 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
1328 while (object_cur < object_top)
1329 object_top = MAX(0, object_top - browser_rows / 2);
1330 while (object_cur >= object_top + browser_rows)
1331 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
1336 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
1340 object_top = object_cur;
1341 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
1342 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1345 k_ptr = &k_info[object_idx[object_cur]];
1347 if (!visual_only && k_ptr->flavor)
1349 flavor_k_ptr = &k_info[k_ptr->flavor];
1353 flavor_k_ptr = k_ptr;
1357 prt(format("<方向>%s%s%s, ESC",
1358 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
1359 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
1360 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
1363 prt(format("<dir>%s%s%s, ESC",
1364 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
1365 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
1366 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
1372 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
1374 if (object_old != object_idx[object_cur])
1376 handle_stuff(creature_ptr);
1377 object_old = object_idx[object_cur];
1383 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
1387 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1391 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
1395 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))
1397 if (direct_k_idx >= 0)
1422 if (!visual_list && !visual_only && (grp_cnt > 0))
1424 desc_obj_fake(creature_ptr, object_idx[object_cur]);
1433 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
1439 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
1444 * Display the features in a group.
1446 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
1447 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
1449 int lit_col[F_LIT_MAX], i;
1450 int f_idx_col = use_bigtile ? 62 : 64;
1452 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
1453 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
1454 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
1456 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
1459 FEAT_IDX f_idx = feat_idx[feat_top + i];
1460 feature_type *f_ptr = &f_info[f_idx];
1461 int row_i = row + i;
1462 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
1463 c_prt(attr, f_name + f_ptr->name, row_i, col);
1466 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
1467 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));
1469 if (current_world_ptr->wizard || visual_only)
1471 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
1474 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);
1475 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
1476 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
1478 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
1481 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
1482 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
1484 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
1488 for (; i < per_page; i++)
1490 Term_erase(col, row + i, 255);
1496 * Interact with feature visuals.
1498 void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
1500 TERM_COLOR attr_old[F_LIT_MAX];
1501 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
1502 SYMBOL_CODE char_old[F_LIT_MAX];
1503 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
1506 Term_get_size(&wid, &hgt);
1509 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
1511 concptr feature_group_text[] = { "terrains", NULL };
1516 FEAT_IDX grp_idx[100];
1517 TERM_COLOR attr_top = 0;
1518 bool visual_list = FALSE;
1520 TERM_LEN browser_rows = hgt - 8;
1521 if (direct_f_idx < 0)
1523 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
1525 len = strlen(feature_group_text[i]);
1526 if (len > max) max = len;
1528 if (collect_features(feat_idx, 0x01))
1530 grp_idx[grp_cnt++] = i;
1538 feature_type *f_ptr = &f_info[direct_f_idx];
1540 feat_idx[0] = direct_f_idx;
1544 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
1545 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
1547 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1549 attr_old[i] = f_ptr->x_attr[i];
1550 char_old[i] = f_ptr->x_char[i];
1554 grp_idx[grp_cnt] = -1;
1556 FEAT_IDX old_grp_cur = -1;
1557 FEAT_IDX grp_cur = 0;
1558 FEAT_IDX grp_top = 0;
1559 FEAT_IDX feat_cur = 0;
1560 FEAT_IDX feat_top = 0;
1561 TERM_LEN column = 0;
1564 TERM_COLOR *cur_attr_ptr;
1565 SYMBOL_CODE *cur_char_ptr;
1569 feature_type *f_ptr;
1575 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
1576 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
1577 prt(_("名前", "Name"), 4, max + 3);
1580 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
1581 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
1585 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
1586 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
1589 for (FEAT_IDX i = 0; i < 78; i++)
1591 Term_putch(i, 5, TERM_WHITE, '=');
1594 if (direct_f_idx < 0)
1596 for (FEAT_IDX i = 0; i < browser_rows; i++)
1598 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1605 if (direct_f_idx < 0)
1607 if (grp_cur < grp_top) grp_top = grp_cur;
1608 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1610 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
1611 if (old_grp_cur != grp_cur)
1613 old_grp_cur = grp_cur;
1614 feat_cnt = collect_features(feat_idx, 0x00);
1617 while (feat_cur < feat_top)
1618 feat_top = MAX(0, feat_top - browser_rows / 2);
1619 while (feat_cur >= feat_top + browser_rows)
1620 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
1625 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
1629 feat_top = feat_cur;
1630 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
1631 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1634 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
1635 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
1636 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
1639 f_ptr = &f_info[feat_idx[feat_cur]];
1640 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
1641 cur_char_ptr = &f_ptr->x_char[*lighting_level];
1645 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
1649 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1653 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
1657 if (visual_list && ((ch == 'A') || (ch == 'a')))
1659 int prev_lighting_level = *lighting_level;
1663 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
1664 else (*lighting_level)--;
1668 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
1669 else (*lighting_level)++;
1672 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
1673 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
1675 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
1676 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
1680 else if ((ch == 'D') || (ch == 'd'))
1682 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
1683 byte prev_x_char = f_ptr->x_char[*lighting_level];
1685 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
1689 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
1690 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
1692 if (prev_x_char != f_ptr->x_char[*lighting_level])
1693 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
1695 else *need_redraw = TRUE;
1699 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))
1704 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1706 f_ptr->x_attr[i] = attr_old[i];
1707 f_ptr->x_char[i] = char_old[i];
1713 if (direct_f_idx >= 0) flag = TRUE;
1714 else *lighting_level = F_LIT_STANDARD;
1718 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1720 attr_old[i] = f_ptr->x_attr[i];
1721 char_old[i] = f_ptr->x_char[i];
1723 *lighting_level = F_LIT_STANDARD;
1730 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1732 attr_idx_feat[i] = f_ptr->x_attr[i];
1733 char_idx_feat[i] = f_ptr->x_char[i];
1742 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
1744 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
1745 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
1763 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
1769 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
1774 * List wanted monsters
1775 * @param creature_ptr プレーヤーへの参照ポインタ
1778 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
1781 GAME_TEXT file_name[FILE_NAME_SIZE];
1782 if (!open_temporary_file(&fff, file_name)) return;
1784 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
1785 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
1787 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
1788 fprintf(fff, "----------------------------------------------\n");
1790 bool listed = FALSE;
1791 for (int i = 0; i < MAX_BOUNTY; i++)
1793 if (current_world_ptr->bounty_r_idx[i] <= 10000)
1795 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
1802 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
1806 (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
1811 * List virtues & status
1813 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
1816 GAME_TEXT file_name[FILE_NAME_SIZE];
1817 if (!open_temporary_file(&fff, file_name)) return;
1819 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
1820 dump_virtues(creature_ptr, fff);
1822 (void)show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
1829 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
1832 GAME_TEXT file_name[FILE_NAME_SIZE];
1833 if (!open_temporary_file(&fff, file_name)) return;
1835 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
1839 if (!d_info[i].maxdepth) continue;
1840 if (!max_dlv[i]) continue;
1841 if (d_info[i].final_guardian)
1843 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
1845 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
1847 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
1851 (void)show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
1857 * List virtues & status
1860 static void do_cmd_knowledge_stat(player_type *creature_ptr)
1863 GAME_TEXT file_name[FILE_NAME_SIZE];
1864 if (!open_temporary_file(&fff, file_name)) return;
1866 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
1867 (2 * creature_ptr->hitdie +
1868 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
1870 if (creature_ptr->knowledge & KNOW_HPRATE)
1871 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
1872 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
1874 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
1875 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
1877 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);
1878 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
1881 dump_yourself(creature_ptr, fff);
1883 (void)show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
1890 * @param player_ptr プレーヤーへの参照ポインタ
1893 static void do_cmd_knowledge_home(player_type *player_ptr)
1895 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
1898 GAME_TEXT file_name[FILE_NAME_SIZE];
1899 if (!open_temporary_file(&fff, file_name)) return;
1901 store_type *store_ptr;
1902 store_ptr = &town_info[1].store[STORE_HOME];
1904 if (store_ptr->stock_num)
1909 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
1910 concptr paren = ")";
1911 GAME_TEXT o_name[MAX_NLEN];
1912 for (int i = 0; i < store_ptr->stock_num; i++)
1915 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
1916 object_desc(player_ptr, o_name, &store_ptr->stock[i], 0);
1917 if (strlen(o_name) <= 80 - 3)
1919 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
1925 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
1926 if (iskanji(*t)) { t++; n++; }
1927 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
1929 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
1930 fprintf(fff, " %.77s\n", o_name + n);
1933 object_desc(player_ptr, o_name, &store_ptr->stock[i], 0);
1934 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
1938 fprintf(fff, "\n\n");
1942 (void)show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
1948 * Check the status of "autopick"
1950 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
1953 GAME_TEXT file_name[FILE_NAME_SIZE];
1954 if (!open_temporary_file(&fff, file_name)) return;
1958 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
1962 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
1963 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
1966 for (int k = 0; k < max_autopick; k++)
1969 byte act = autopick_list[k].action;
1970 if (act & DONT_AUTOPICK)
1972 tmp = _("放置", "Leave");
1974 else if (act & DO_AUTODESTROY)
1976 tmp = _("破壊", "Destroy");
1978 else if (act & DO_AUTOPICK)
1980 tmp = _("拾う", "Pickup");
1984 tmp = _("確認", "Query");
1987 if (act & DO_DISPLAY)
1988 fprintf(fff, "%11s", format("[%s]", tmp));
1990 fprintf(fff, "%11s", format("(%s)", tmp));
1992 tmp = autopick_line_from_entry(&autopick_list[k]);
1993 fprintf(fff, " %s", tmp);
2000 (void)show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
2006 * Interact with "knowledge"
2008 void do_cmd_knowledge(player_type *creature_ptr)
2011 bool need_redraw = FALSE;
2012 FILE_TYPE(FILE_TYPE_TEXT);
2017 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
2018 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
2021 prt(_("(1) 既知の伝説のアイテム の一覧", "(1) Display known artifacts"), 6, 5);
2022 prt(_("(2) 既知のアイテム の一覧", "(2) Display known objects"), 7, 5);
2023 prt(_("(3) 既知の生きているユニーク・モンスター の一覧", "(3) Display remaining uniques"), 8, 5);
2024 prt(_("(4) 既知のモンスター の一覧", "(4) Display known monster"), 9, 5);
2025 prt(_("(5) 倒した敵の数 の一覧", "(5) Display kill count"), 10, 5);
2026 if (!vanilla_town) prt(_("(6) 賞金首 の一覧", "(6) Display wanted monsters"), 11, 5);
2027 prt(_("(7) 現在のペット の一覧", "(7) Display current pets"), 12, 5);
2028 prt(_("(8) 我が家のアイテム の一覧", "(8) Display home inventory"), 13, 5);
2029 prt(_("(9) *鑑定*済み装備の耐性 の一覧", "(9) Display *identified* equip."), 14, 5);
2030 prt(_("(0) 地形の表示文字/タイル の一覧", "(0) Display terrain symbols."), 15, 5);
2034 prt(_("(a) 自分に関する情報 の一覧", "(a) Display about yourself"), 6, 5);
2035 prt(_("(b) 突然変異 の一覧", "(b) Display mutations"), 7, 5);
2036 prt(_("(c) 武器の経験値 の一覧", "(c) Display weapon proficiency"), 8, 5);
2037 prt(_("(d) 魔法の経験値 の一覧", "(d) Display spell proficiency"), 9, 5);
2038 prt(_("(e) 技能の経験値 の一覧", "(e) Display misc. proficiency"), 10, 5);
2039 prt(_("(f) プレイヤーの徳 の一覧", "(f) Display virtues"), 11, 5);
2040 prt(_("(g) 入ったダンジョン の一覧", "(g) Display dungeons"), 12, 5);
2041 prt(_("(h) 実行中のクエスト の一覧", "(h) Display current quests"), 13, 5);
2042 prt(_("(i) 現在の自動拾い/破壊設定 の一覧", "(i) Display auto pick/destroy"), 14, 5);
2045 prt(_("-続く-", "-more-"), 17, 8);
2046 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
2047 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
2048 prt(_("コマンド:", "Command: "), 20, 0);
2051 if (i == ESCAPE) break;
2054 case ' ': /* Page change */
2058 case '1': /* Artifacts */
2059 do_cmd_knowledge_artifacts(creature_ptr);
2061 case '2': /* Objects */
2062 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
2064 case '3': /* Uniques */
2065 do_cmd_knowledge_uniques(creature_ptr);
2067 case '4': /* Monsters */
2068 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
2070 case '5': /* Kill count */
2071 do_cmd_knowledge_kill_count(creature_ptr);
2073 case '6': /* wanted */
2074 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
2076 case '7': /* Pets */
2077 do_cmd_knowledge_pets(creature_ptr);
2079 case '8': /* Home */
2080 do_cmd_knowledge_home(creature_ptr);
2082 case '9': /* Resist list */
2083 do_cmd_knowledge_inventory(creature_ptr);
2085 case '0': /* Feature list */
2087 IDX lighting_level = F_LIT_STANDARD;
2088 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
2092 case 'a': /* Max stat */
2093 do_cmd_knowledge_stat(creature_ptr);
2095 case 'b': /* Mutations */
2096 do_cmd_knowledge_mutations(creature_ptr);
2098 case 'c': /* weapon-exp */
2099 do_cmd_knowledge_weapon_exp(creature_ptr);
2101 case 'd': /* spell-exp */
2102 do_cmd_knowledge_spell_exp(creature_ptr);
2104 case 'e': /* skill-exp */
2105 do_cmd_knowledge_skill_exp(creature_ptr);
2107 case 'f': /* Virtues */
2108 do_cmd_knowledge_virtues(creature_ptr);
2110 case 'g': /* Dungeon */
2111 do_cmd_knowledge_dungeon(creature_ptr);
2113 case 'h': /* Quests */
2114 do_cmd_knowledge_quests(creature_ptr);
2116 case 'i': /* Autopick */
2117 do_cmd_knowledge_autopick(creature_ptr);
2119 default: /* Unknown option */
2127 if (need_redraw) do_cmd_redraw(creature_ptr);
2132 * Check on the status of an active quest
2133 * @param creature_ptr プレーヤーへの参照ポインタ
2136 void do_cmd_checkquest(player_type *creature_ptr)
2138 FILE_TYPE(FILE_TYPE_TEXT);
2140 do_cmd_knowledge_quests(creature_ptr);
2146 * Display the time and date
2147 * @param creature_ptr プレーヤーへの参照ポインタ
2150 void do_cmd_time(player_type *creature_ptr)
2153 extract_day_hour_min(creature_ptr, &day, &hour, &min);
2156 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
2159 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
2160 else strcpy(day_buf, "*****");
2162 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
2163 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
2166 if (!randint0(10) || creature_ptr->image)
2168 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
2172 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
2176 fff = my_fopen(buf, "rt");
2180 int full = hour * 100 + min;
2184 while (!my_fgets(fff, buf, sizeof(buf)))
2186 if (!buf[0] || (buf[0] == '#')) continue;
2187 if (buf[1] != ':') continue;
2191 start = atoi(buf + 2);
2198 end = atoi(buf + 2);
2202 if ((start > full) || (full > end)) continue;
2207 if (!randint0(num)) strcpy(desc, buf + 2);