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-uniques.h"
54 #include "view/display-player.h" // 暫定。後で消す.
55 #include "player/process-name.h"
56 #include "player-effects.h"
57 #include "player-skill.h"
58 #include "player-personality.h"
62 #include "market/store.h"
65 #include "object-flavor.h"
66 #include "object-hook.h"
67 #include "monster-status.h"
68 #include "dungeon-file.h"
69 #include "objectkind.h"
70 #include "floor-town.h"
71 #include "cmd/feeling-table.h"
72 #include "cmd/monster-group-table.h"
73 #include "cmd/object-group-table.h"
74 #include "market/store-util.h"
75 #include "view-mainwindow.h" // 暫定。後で消す
78 #include "diary-subtitle-table.h"
79 #include "io/write-diary.h"
83 * @brief prefファイルを選択して処理する /
84 * Ask for a "user pref line" and process it
85 * @brief prf出力内容を消去する /
86 * Remove old lines automatically generated before.
87 * @param orig_file 消去を行うファイル名
89 static void remove_auto_dump(concptr orig_file, concptr auto_dump_mark)
92 bool between_mark = FALSE;
95 long header_location = 0;
96 char header_mark_str[80];
97 char footer_mark_str[80];
99 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
100 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
101 size_t mark_len = strlen(footer_mark_str);
104 orig_fff = my_fopen(orig_file, "r");
105 if (!orig_fff) return;
107 FILE *tmp_fff = NULL;
108 char tmp_file[FILE_NAME_SIZE];
109 if (!open_temporary_file(&tmp_fff, tmp_file)) return;
113 if (my_fgets(orig_fff, buf, sizeof(buf)))
117 fseek(orig_fff, header_location, SEEK_SET);
118 between_mark = FALSE;
129 if (!strcmp(buf, header_mark_str))
131 header_location = ftell(orig_fff);
138 fprintf(tmp_fff, "%s\n", buf);
144 if (!strncmp(buf, footer_mark_str, mark_len))
147 if (!sscanf(buf + mark_len, " (%d)", &tmp)
150 fseek(orig_fff, header_location, SEEK_SET);
153 between_mark = FALSE;
165 tmp_fff = my_fopen(tmp_file, "r");
166 orig_fff = my_fopen(orig_file, "w");
167 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
168 fprintf(orig_fff, "%s\n", buf);
181 * @brief Return suffix of ordinal number
183 * @return pointer of suffix string.
185 concptr get_ordinal_number_suffix(int num)
187 num = ABS(num) % 100;
191 return (num == 11) ? "th" : "st";
193 return (num == 12) ? "th" : "nd";
195 return (num == 13) ? "th" : "rd";
203 * @brief 画面を再描画するコマンドのメインルーチン
204 * Hack -- redraw the screen
205 * @param creature_ptr プレーヤーへの参照ポインタ
208 * Allow absolute file names?
210 void do_cmd_pref(player_type *creature_ptr)
214 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
216 (void)interpret_pref_file(creature_ptr, buf);
221 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
222 * @param creature_ptr プレーヤーへの参照ポインタ
225 void do_cmd_reload_autopick(player_type *creature_ptr)
227 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? ")))
230 autopick_load_pref(creature_ptr, TRUE);
235 * Interact with "colors"
237 void do_cmd_colors(player_type *creature_ptr)
242 FILE *auto_dump_stream;
243 FILE_TYPE(FILE_TYPE_TEXT);
248 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
249 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
250 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
251 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
252 prt(_("コマンド: ", "Command: "), 8, 0);
254 if (i == ESCAPE) break;
258 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
259 prt(_("ファイル: ", "File: "), 10, 0);
260 sprintf(tmp, "%s.prf", creature_ptr->base_name);
261 if (!askfor(tmp, 70)) continue;
263 (void)process_pref_file(creature_ptr, tmp);
264 Term_xtra(TERM_XTRA_REACT, 0);
269 static concptr mark = "Colors";
270 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
271 prt(_("ファイル: ", "File: "), 10, 0);
272 sprintf(tmp, "%s.prf", creature_ptr->base_name);
273 if (!askfor(tmp, 70)) continue;
275 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
276 if (!open_auto_dump(&auto_dump_stream, buf, mark)) continue;
278 auto_dump_printf(auto_dump_stream, _("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
279 for (i = 0; i < 256; i++)
281 int kv = angband_color_table[i][0];
282 int rv = angband_color_table[i][1];
283 int gv = angband_color_table[i][2];
284 int bv = angband_color_table[i][3];
286 concptr name = _("未知", "unknown");
287 if (!kv && !rv && !gv && !bv) continue;
289 if (i < 16) name = color_names[i];
291 auto_dump_printf(auto_dump_stream, _("# カラー '%s'\n", "# Color '%s'\n"), name);
292 auto_dump_printf(auto_dump_stream, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
296 close_auto_dump(&auto_dump_stream, mark);
297 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
302 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
307 for (byte j = 0; j < 16; j++)
309 Term_putstr(j * 4, 20, -1, a, "###");
310 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
313 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
314 Term_putstr(5, 10, -1, TERM_WHITE,
315 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
316 Term_putstr(5, 12, -1, TERM_WHITE,
317 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
318 angband_color_table[a][0],
319 angband_color_table[a][1],
320 angband_color_table[a][2],
321 angband_color_table[a][3]));
322 Term_putstr(0, 14, -1, TERM_WHITE,
323 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
325 if (i == ESCAPE) break;
327 if (i == 'n') a = (byte)(a + 1);
328 if (i == 'N') a = (byte)(a - 1);
329 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
330 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
331 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
332 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
333 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
334 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
335 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
336 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
338 Term_xtra(TERM_XTRA_REACT, 0);
355 * Note something in the message recall
357 void do_cmd_note(void)
361 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
362 if (!buf[0] || (buf[0] == ' ')) return;
364 msg_format(_("メモ: %s", "Note: %s"), buf);
369 * Mention the current version
371 void do_cmd_version(void)
373 #if FAKE_VER_EXTRA > 0
374 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
375 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
377 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
378 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
384 * Note that "feeling" is set to zero unless some time has passed.
385 * Note that this is done when the level is GENERATED, not entered.
387 void do_cmd_feeling(player_type *creature_ptr)
389 if (creature_ptr->wild_mode) return;
391 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
393 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
397 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
399 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
401 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
405 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
409 if (!creature_ptr->current_floor_ptr->dun_level)
411 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
415 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
416 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
417 else if (IS_ECHIZEN(creature_ptr))
418 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
420 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
425 * todo 引数と戻り値について追記求む
426 * Build a list of monster indexes in the given group.
428 * mode & 0x01 : check for non-empty group
429 * mode & 0x02 : visual operation only
431 * @param creature_ptr プレーヤーへの参照ポインタ
433 * @param mon_idx[] ???
435 * @return The number of monsters in the group
437 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
439 concptr group_char = monster_group_char[grp_cur];
440 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
441 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
442 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
443 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
446 for (IDX i = 0; i < max_r_idx; i++)
448 monster_race *r_ptr = &r_info[i];
449 if (!r_ptr->name) continue;
450 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
454 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
458 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
463 for (int j = 0; j < MAX_BOUNTY; j++)
465 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
466 (creature_ptr->today_mon && creature_ptr->today_mon == i))
473 if (!wanted) continue;
475 else if (grp_amberite)
477 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
481 if (!my_strchr(group_char, r_ptr->d_char)) continue;
484 mon_idx[mon_cnt++] = i;
485 if (mode & 0x01) break;
488 mon_idx[mon_cnt] = -1;
490 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
496 * Build a list of object indexes in the given group. Return the number
497 * of objects in the group.
499 * mode & 0x01 : check for non-empty group
500 * mode & 0x02 : visual operation only
502 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
504 KIND_OBJECT_IDX object_cnt = 0;
505 byte group_tval = object_group_tval[grp_cur];
506 for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++)
508 object_kind *k_ptr = &k_info[i];
509 if (!k_ptr->name) continue;
513 if (!current_world_ptr->wizard)
515 if (!k_ptr->flavor) continue;
516 if (!k_ptr->aware) continue;
520 for (int j = 0; j < 4; j++)
521 k += k_ptr->chance[j];
525 if (TV_LIFE_BOOK == group_tval)
527 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
529 object_idx[object_cnt++] = i;
534 else if (k_ptr->tval == group_tval)
536 object_idx[object_cnt++] = i;
541 if (mode & 0x01) break;
544 object_idx[object_cnt] = -1;
550 * Build a list of feature indexes in the given group. Return the number
551 * of features in the group.
553 * mode & 0x01 : check for non-empty group
555 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
557 FEAT_IDX feat_cnt = 0;
558 for (FEAT_IDX i = 0; i < max_f_idx; i++)
560 feature_type *f_ptr = &f_info[i];
561 if (!f_ptr->name) continue;
562 if (f_ptr->mimic != i) continue;
564 feat_idx[feat_cnt++] = i;
565 if (mode & 0x01) break;
568 feat_idx[feat_cnt] = -1;
574 * @brief 現在のペットを表示するコマンドのメインルーチン /
575 * Display current pets
576 * @param creature_ptr プレーヤーへの参照ポインタ
579 static void do_cmd_knowledge_pets(player_type *creature_ptr)
582 GAME_TEXT file_name[FILE_NAME_SIZE];
583 if (!open_temporary_file(&fff, file_name)) return;
586 GAME_TEXT pet_name[MAX_NLEN];
588 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
590 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
591 if (!monster_is_valid(m_ptr)) continue;
592 if (!is_pet(m_ptr)) continue;
595 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
596 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
599 int show_upkeep = calculate_upkeep(creature_ptr);
601 fprintf(fff, "----------------------------------------------\n");
603 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
605 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
607 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
610 (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
616 * @brief 現在のペットを表示するコマンドのメインルーチン /
617 * @param creature_ptr プレーヤーへの参照ポインタ
620 * @note the player ghosts are ignored.
622 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
625 GAME_TEXT file_name[FILE_NAME_SIZE];
626 if (!open_temporary_file(&fff, file_name)) return;
629 C_MAKE(who, max_r_idx, MONRACE_IDX);
631 for (int kk = 1; kk < max_r_idx; kk++)
633 monster_race *r_ptr = &r_info[kk];
635 if (r_ptr->flags1 & (RF1_UNIQUE))
637 bool dead = (r_ptr->max_num == 0);
646 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
648 if (this_monster > 0)
650 total += this_monster;
656 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
659 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
661 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
666 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
668 monster_race *r_ptr = &r_info[i];
669 if (r_ptr->name) who[n++] = i;
673 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
674 for (int k = 0; k < n; k++)
676 monster_race *r_ptr = &r_info[who[k]];
677 if (r_ptr->flags1 & (RF1_UNIQUE))
679 bool dead = (r_ptr->max_num == 0);
682 fprintf(fff, " %s\n", (r_name + r_ptr->name));
689 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
690 if (this_monster <= 0) continue;
693 if (my_strchr("pt", r_ptr->d_char))
694 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
696 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
698 if (this_monster < 2)
700 if (my_strstr(r_name + r_ptr->name, "coins"))
702 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
706 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
712 strcpy(ToPlural, (r_name + r_ptr->name));
713 plural_aux(ToPlural);
714 fprintf(fff, " %d %s\n", this_monster, ToPlural);
717 total += this_monster;
720 fprintf(fff, "----------------------------------------------\n");
722 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
724 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
727 C_KILL(who, max_r_idx, s16b);
729 (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
735 * @brief モンスター情報リスト中のグループを表示する /
736 * Display the object groups.
740 * @param per_page リストの表示行
741 * @param grp_idx グループのID配列
742 * @param group_text グループ名の文字列配列
743 * @param grp_cur 現在の選択ID
744 * @param grp_top 現在の選択リスト最上部ID
747 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)
749 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
751 int grp = grp_idx[grp_top + i];
752 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
753 Term_erase(col, row + i, wid);
754 c_put_str(attr, group_text[grp], row + i, col);
760 * Move the cursor in a browser window
762 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt, IDX *list_cur, int list_cnt)
767 IDX list = *list_cur;
773 d = get_keymap_dir(ch);
777 if ((ddx[d] > 0) && ddy[d])
781 Term_get_size(&wid, &hgt);
782 browser_rows = hgt - 8;
786 grp += ddy[d] * (browser_rows - 1);
787 if (grp >= grp_cnt) grp = grp_cnt - 1;
788 if (grp < 0) grp = 0;
789 if (grp != old_grp) list = 0;
793 list += ddy[d] * browser_rows;
794 if (list >= list_cnt) list = list_cnt - 1;
795 if (list < 0) list = 0;
806 if (col < 0) col = 0;
807 if (col > 1) col = 1;
817 if (grp >= grp_cnt) grp = grp_cnt - 1;
818 if (grp < 0) grp = 0;
819 if (grp != old_grp) list = 0;
824 if (list >= list_cnt) list = list_cnt - 1;
825 if (list < 0) list = 0;
836 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
838 for (int i = 0; i < height; i++)
840 Term_erase(col, row + i, width);
843 if (use_bigtile) width /= 2;
845 for (int i = 0; i < height; i++)
847 for (int j = 0; j < width; j++)
849 TERM_LEN x = col + j;
850 TERM_LEN y = row + i;
851 if (use_bigtile) x += j;
853 int ia = attr_top + i;
854 int ic = char_left + j;
855 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
856 (!use_graphics && ic > 0x7f))
859 TERM_COLOR a = (TERM_COLOR)ia;
860 SYMBOL_CODE c = (SYMBOL_CODE)ic;
861 if (c & 0x80) a |= 0x80;
863 Term_queue_bigchar(x, y, a, c, 0, 0);
870 * Place the cursor at the collect position for visual mode
872 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
874 int i = (a & 0x7f) - attr_top;
875 int j = c - char_left;
877 TERM_LEN x = col + j;
878 TERM_LEN y = row + i;
879 if (use_bigtile) x += j;
886 * Display the monsters in a group.
888 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[], int mon_cur, int mon_top, bool visual_only)
891 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
894 MONRACE_IDX r_idx = mon_idx[mon_top + i];
895 monster_race *r_ptr = &r_info[r_idx];
896 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
897 c_prt(attr, (r_name + r_ptr->name), row + i, col);
900 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
903 if (current_world_ptr->wizard || visual_only)
905 c_prt(attr, format("%d", r_idx), row + i, 62);
908 Term_erase(69, row + i, 255);
909 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
912 if (!(r_ptr->flags1 & RF1_UNIQUE))
913 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
915 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
916 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
920 for (; i < per_page; i++)
922 Term_erase(col, row + i, 255);
929 * Display known monsters.
930 * @param creature_ptr プレーヤーへの参照ポインタ
931 * @param need_redraw 画面の再描画が必要な時TRUE
932 * @param visual_only ???
933 * @param direct_r_idx モンスターID
936 void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
939 Term_get_size(&wid, &hgt);
941 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
947 bool visual_list = FALSE;
948 TERM_COLOR attr_top = 0;
951 int browser_rows = hgt - 8;
952 if (direct_r_idx < 0)
954 mode = visual_only ? 0x03 : 0x01;
956 for (IDX i = 0; monster_group_text[i] != NULL; i++)
958 len = strlen(monster_group_text[i]);
959 if (len > max) max = len;
961 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
963 grp_idx[grp_cnt++] = i;
971 mon_idx[0] = direct_r_idx;
975 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
976 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
979 grp_idx[grp_cnt] = -1;
980 mode = visual_only ? 0x02 : 0x00;
981 IDX old_grp_cur = -1;
994 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
995 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
996 prt(_("名前", "Name"), 4, max + 3);
997 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
998 prt(_("文字", "Sym"), 4, 67);
999 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
1001 for (IDX i = 0; i < 78; i++)
1003 Term_putch(i, 5, TERM_WHITE, '=');
1006 if (direct_r_idx < 0)
1008 for (IDX i = 0; i < browser_rows; i++)
1010 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1017 if (direct_r_idx < 0)
1019 if (grp_cur < grp_top) grp_top = grp_cur;
1020 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1022 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
1023 if (old_grp_cur != grp_cur)
1025 old_grp_cur = grp_cur;
1026 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
1029 while (mon_cur < mon_top)
1030 mon_top = MAX(0, mon_top - browser_rows / 2);
1031 while (mon_cur >= mon_top + browser_rows)
1032 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
1037 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
1042 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
1043 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1046 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
1047 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
1048 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
1049 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
1052 monster_race *r_ptr;
1053 r_ptr = &r_info[mon_idx[mon_cur]];
1057 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
1058 handle_stuff(creature_ptr);
1063 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
1067 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1071 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
1075 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))
1077 if (direct_r_idx >= 0)
1103 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
1105 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
1117 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
1124 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
1129 * Display the objects in a group.
1131 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
1132 int object_cur, int object_top, bool visual_only)
1135 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
1137 GAME_TEXT o_name[MAX_NLEN];
1140 object_kind *flavor_k_ptr;
1141 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
1142 object_kind *k_ptr = &k_info[k_idx];
1143 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
1144 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
1145 if (!visual_only && k_ptr->flavor)
1147 flavor_k_ptr = &k_info[k_ptr->flavor];
1151 flavor_k_ptr = k_ptr;
1154 attr = ((i + object_top == object_cur) ? cursor : attr);
1155 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
1157 strip_name(o_name, k_idx);
1161 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
1164 c_prt(attr, o_name, row + i, col);
1167 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);
1170 if (current_world_ptr->wizard || visual_only)
1172 c_prt(attr, format("%d", k_idx), row + i, 70);
1175 a = flavor_k_ptr->x_attr;
1176 c = flavor_k_ptr->x_char;
1178 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
1181 for (; i < per_page; i++)
1183 Term_erase(col, row + i, 255);
1189 * Describe fake object
1191 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
1194 object_type object_type_body;
1195 o_ptr = &object_type_body;
1197 object_prep(o_ptr, k_idx);
1199 o_ptr->ident |= IDENT_KNOWN;
1200 handle_stuff(creature_ptr);
1202 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
1204 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1210 * Display known objects
1212 void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
1214 IDX object_old, object_top;
1217 OBJECT_IDX *object_idx;
1219 bool visual_list = FALSE;
1220 TERM_COLOR attr_top = 0;
1225 Term_get_size(&wid, &hgt);
1227 int browser_rows = hgt - 8;
1228 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
1233 if (direct_k_idx < 0)
1235 mode = visual_only ? 0x03 : 0x01;
1236 for (IDX i = 0; object_group_text[i] != NULL; i++)
1238 len = strlen(object_group_text[i]);
1239 if (len > max) max = len;
1241 if (collect_objects(i, object_idx, mode))
1243 grp_idx[grp_cnt++] = i;
1252 object_kind *k_ptr = &k_info[direct_k_idx];
1253 object_kind *flavor_k_ptr;
1255 if (!visual_only && k_ptr->flavor)
1257 flavor_k_ptr = &k_info[k_ptr->flavor];
1261 flavor_k_ptr = k_ptr;
1264 object_idx[0] = direct_k_idx;
1265 object_old = direct_k_idx;
1268 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
1269 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
1272 grp_idx[grp_cnt] = -1;
1273 mode = visual_only ? 0x02 : 0x00;
1274 IDX old_grp_cur = -1;
1277 IDX object_cur = object_top = 0;
1283 object_kind *k_ptr, *flavor_k_ptr;
1290 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
1291 if (direct_k_idx < 0) prt("グループ", 4, 0);
1292 prt("名前", 4, max + 3);
1293 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
1296 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
1297 if (direct_k_idx < 0) prt("Group", 4, 0);
1298 prt("Name", 4, max + 3);
1299 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
1303 for (IDX i = 0; i < 78; i++)
1305 Term_putch(i, 5, TERM_WHITE, '=');
1308 if (direct_k_idx < 0)
1310 for (IDX i = 0; i < browser_rows; i++)
1312 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1319 if (direct_k_idx < 0)
1321 if (grp_cur < grp_top) grp_top = grp_cur;
1322 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1324 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
1325 if (old_grp_cur != grp_cur)
1327 old_grp_cur = grp_cur;
1328 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
1331 while (object_cur < object_top)
1332 object_top = MAX(0, object_top - browser_rows / 2);
1333 while (object_cur >= object_top + browser_rows)
1334 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
1339 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
1343 object_top = object_cur;
1344 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
1345 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1348 k_ptr = &k_info[object_idx[object_cur]];
1350 if (!visual_only && k_ptr->flavor)
1352 flavor_k_ptr = &k_info[k_ptr->flavor];
1356 flavor_k_ptr = k_ptr;
1360 prt(format("<方向>%s%s%s, ESC",
1361 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
1362 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
1363 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
1366 prt(format("<dir>%s%s%s, ESC",
1367 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
1368 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
1369 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
1375 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
1377 if (object_old != object_idx[object_cur])
1379 handle_stuff(creature_ptr);
1380 object_old = object_idx[object_cur];
1386 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
1390 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1394 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
1398 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))
1400 if (direct_k_idx >= 0)
1425 if (!visual_list && !visual_only && (grp_cnt > 0))
1427 desc_obj_fake(creature_ptr, object_idx[object_cur]);
1436 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
1442 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
1447 * Display the features in a group.
1449 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
1450 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
1452 int lit_col[F_LIT_MAX], i;
1453 int f_idx_col = use_bigtile ? 62 : 64;
1455 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
1456 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
1457 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
1459 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
1462 FEAT_IDX f_idx = feat_idx[feat_top + i];
1463 feature_type *f_ptr = &f_info[f_idx];
1464 int row_i = row + i;
1465 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
1466 c_prt(attr, f_name + f_ptr->name, row_i, col);
1469 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
1470 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));
1472 if (current_world_ptr->wizard || visual_only)
1474 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
1477 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);
1478 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
1479 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
1481 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
1484 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
1485 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
1487 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
1491 for (; i < per_page; i++)
1493 Term_erase(col, row + i, 255);
1499 * Interact with feature visuals.
1501 void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
1503 TERM_COLOR attr_old[F_LIT_MAX];
1504 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
1505 SYMBOL_CODE char_old[F_LIT_MAX];
1506 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
1509 Term_get_size(&wid, &hgt);
1512 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
1514 concptr feature_group_text[] = { "terrains", NULL };
1519 FEAT_IDX grp_idx[100];
1520 TERM_COLOR attr_top = 0;
1521 bool visual_list = FALSE;
1523 TERM_LEN browser_rows = hgt - 8;
1524 if (direct_f_idx < 0)
1526 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
1528 len = strlen(feature_group_text[i]);
1529 if (len > max) max = len;
1531 if (collect_features(feat_idx, 0x01))
1533 grp_idx[grp_cnt++] = i;
1541 feature_type *f_ptr = &f_info[direct_f_idx];
1543 feat_idx[0] = direct_f_idx;
1547 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
1548 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
1550 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1552 attr_old[i] = f_ptr->x_attr[i];
1553 char_old[i] = f_ptr->x_char[i];
1557 grp_idx[grp_cnt] = -1;
1559 FEAT_IDX old_grp_cur = -1;
1560 FEAT_IDX grp_cur = 0;
1561 FEAT_IDX grp_top = 0;
1562 FEAT_IDX feat_cur = 0;
1563 FEAT_IDX feat_top = 0;
1564 TERM_LEN column = 0;
1567 TERM_COLOR *cur_attr_ptr;
1568 SYMBOL_CODE *cur_char_ptr;
1572 feature_type *f_ptr;
1578 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
1579 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
1580 prt(_("名前", "Name"), 4, max + 3);
1583 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
1584 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
1588 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
1589 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
1592 for (FEAT_IDX i = 0; i < 78; i++)
1594 Term_putch(i, 5, TERM_WHITE, '=');
1597 if (direct_f_idx < 0)
1599 for (FEAT_IDX i = 0; i < browser_rows; i++)
1601 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
1608 if (direct_f_idx < 0)
1610 if (grp_cur < grp_top) grp_top = grp_cur;
1611 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
1613 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
1614 if (old_grp_cur != grp_cur)
1616 old_grp_cur = grp_cur;
1617 feat_cnt = collect_features(feat_idx, 0x00);
1620 while (feat_cur < feat_top)
1621 feat_top = MAX(0, feat_top - browser_rows / 2);
1622 while (feat_cur >= feat_top + browser_rows)
1623 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
1628 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
1632 feat_top = feat_cur;
1633 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
1634 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
1637 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
1638 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
1639 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
1642 f_ptr = &f_info[feat_idx[feat_cur]];
1643 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
1644 cur_char_ptr = &f_ptr->x_char[*lighting_level];
1648 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
1652 Term_gotoxy(0, 6 + (grp_cur - grp_top));
1656 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
1660 if (visual_list && ((ch == 'A') || (ch == 'a')))
1662 int prev_lighting_level = *lighting_level;
1666 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
1667 else (*lighting_level)--;
1671 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
1672 else (*lighting_level)++;
1675 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
1676 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
1678 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
1679 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
1683 else if ((ch == 'D') || (ch == 'd'))
1685 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
1686 byte prev_x_char = f_ptr->x_char[*lighting_level];
1688 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
1692 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
1693 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
1695 if (prev_x_char != f_ptr->x_char[*lighting_level])
1696 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
1698 else *need_redraw = TRUE;
1702 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))
1707 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1709 f_ptr->x_attr[i] = attr_old[i];
1710 f_ptr->x_char[i] = char_old[i];
1716 if (direct_f_idx >= 0) flag = TRUE;
1717 else *lighting_level = F_LIT_STANDARD;
1721 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1723 attr_old[i] = f_ptr->x_attr[i];
1724 char_old[i] = f_ptr->x_char[i];
1726 *lighting_level = F_LIT_STANDARD;
1733 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
1735 attr_idx_feat[i] = f_ptr->x_attr[i];
1736 char_idx_feat[i] = f_ptr->x_char[i];
1745 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
1747 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
1748 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
1766 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
1772 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
1777 * List wanted monsters
1778 * @param creature_ptr プレーヤーへの参照ポインタ
1781 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
1784 GAME_TEXT file_name[FILE_NAME_SIZE];
1785 if (!open_temporary_file(&fff, file_name)) return;
1787 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
1788 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
1790 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
1791 fprintf(fff, "----------------------------------------------\n");
1793 bool listed = FALSE;
1794 for (int i = 0; i < MAX_BOUNTY; i++)
1796 if (current_world_ptr->bounty_r_idx[i] <= 10000)
1798 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
1805 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
1809 (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
1814 * List virtues & status
1816 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
1819 GAME_TEXT file_name[FILE_NAME_SIZE];
1820 if (!open_temporary_file(&fff, file_name)) return;
1822 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
1823 dump_virtues(creature_ptr, fff);
1825 (void)show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
1832 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
1835 GAME_TEXT file_name[FILE_NAME_SIZE];
1836 if (!open_temporary_file(&fff, file_name)) return;
1838 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
1842 if (!d_info[i].maxdepth) continue;
1843 if (!max_dlv[i]) continue;
1844 if (d_info[i].final_guardian)
1846 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
1848 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
1850 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
1854 (void)show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
1860 * List virtues & status
1863 static void do_cmd_knowledge_stat(player_type *creature_ptr)
1866 GAME_TEXT file_name[FILE_NAME_SIZE];
1867 if (!open_temporary_file(&fff, file_name)) return;
1869 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
1870 (2 * creature_ptr->hitdie +
1871 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
1873 if (creature_ptr->knowledge & KNOW_HPRATE)
1874 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
1875 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
1877 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
1878 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
1880 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);
1881 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
1884 dump_yourself(creature_ptr, fff);
1886 (void)show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
1892 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
1893 * Print all active quests
1894 * @param creature_ptr プレーヤーへの参照ポインタ
1897 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
1900 char rand_tmp_str[120] = "\0";
1901 GAME_TEXT name[MAX_NLEN];
1902 monster_race *r_ptr;
1903 int rand_level = 100;
1906 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
1908 for (QUEST_IDX i = 1; i < max_q_idx; i++)
1910 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
1911 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
1912 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
1916 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
1917 for (int j = 0; j < 10; j++)
1918 quest_text[j][0] = '\0';
1920 quest_text_line = 0;
1921 creature_ptr->current_floor_ptr->inside_quest = i;
1922 init_flags = INIT_SHOW_TEXT;
1923 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
1924 creature_ptr->current_floor_ptr->inside_quest = old_quest;
1925 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
1928 if (quest[i].type != QUEST_TYPE_RANDOM)
1930 char note[80] = "\0";
1932 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
1934 switch (quest[i].type)
1936 case QUEST_TYPE_KILL_LEVEL:
1937 case QUEST_TYPE_KILL_ANY_LEVEL:
1938 r_ptr = &r_info[quest[i].r_idx];
1939 strcpy(name, r_name + r_ptr->name);
1940 if (quest[i].max_num > 1)
1943 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
1944 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
1947 sprintf(note, " - kill %d %s, have killed %d.",
1948 (int)quest[i].max_num, name, (int)quest[i].cur_num);
1952 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
1955 case QUEST_TYPE_FIND_ARTIFACT:
1958 artifact_type *a_ptr = &a_info[quest[i].k_idx];
1960 object_type *q_ptr = &forge;
1961 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
1962 object_prep(q_ptr, k_idx);
1963 q_ptr->name1 = quest[i].k_idx;
1964 q_ptr->ident = IDENT_STORE;
1965 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
1967 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
1969 case QUEST_TYPE_FIND_EXIT:
1970 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
1973 case QUEST_TYPE_KILL_NUMBER:
1975 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
1976 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
1978 sprintf(note, " - Kill %d monsters, have killed %d.",
1979 (int)quest[i].max_num, (int)quest[i].cur_num);
1983 case QUEST_TYPE_KILL_ALL:
1984 case QUEST_TYPE_TOWER:
1985 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
1990 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
1991 quest[i].name, (int)quest[i].level, note);
1992 fputs(tmp_str, fff);
1993 if (quest[i].status == QUEST_STATUS_COMPLETED)
1995 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
1996 fputs(tmp_str, fff);
2001 while (quest_text[k][0] && k < 10)
2003 fprintf(fff, " %s\n", quest_text[k]);
2010 if (quest[i].level >= rand_level)
2013 rand_level = quest[i].level;
2014 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
2016 r_ptr = &r_info[quest[i].r_idx];
2017 strcpy(name, r_name + r_ptr->name);
2018 if (quest[i].max_num <= 1)
2020 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
2021 quest[i].name, (int)quest[i].level, name);
2026 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
2027 quest[i].name, (int)quest[i].level,
2028 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
2032 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
2033 quest[i].name, (int)quest[i].level,
2034 (int)quest[i].max_num, name, (int)quest[i].cur_num);
2038 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
2040 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
2044 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
2047 char playtime_str[16];
2048 quest_type* const q_ptr = &quest[q_idx];
2050 floor_type *floor_ptr = player_ptr->current_floor_ptr;
2051 if (is_fixed_quest_idx(q_idx))
2053 IDX old_quest = floor_ptr->inside_quest;
2054 floor_ptr->inside_quest = q_idx;
2055 init_flags = INIT_NAME_ONLY;
2056 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
2057 floor_ptr->inside_quest = old_quest;
2058 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
2061 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
2062 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
2064 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
2067 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
2068 " %-35s (Danger level: %3d) - level %2d - %s\n"),
2069 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
2070 fputs(tmp_str, fff);
2074 if (q_ptr->complev == 0)
2077 _(" %-35s (%3d階) - 不戦勝 - %s\n",
2078 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
2079 r_name + r_info[q_ptr->r_idx].name,
2080 (int)q_ptr->level, playtime_str);
2081 fputs(tmp_str, fff);
2086 _(" %-35s (%3d階) - レベル%2d - %s\n",
2087 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
2088 r_name + r_info[q_ptr->r_idx].name,
2092 fputs(tmp_str, fff);
2098 * Print all finished quests
2099 * @param creature_ptr プレーヤーへの参照ポインタ
2100 * @param fff セーブファイル (展開済?)
2101 * @param quest_num[] 受注したことのあるクエスト群
2104 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
2106 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
2107 QUEST_IDX total = 0;
2108 for (QUEST_IDX i = 1; i < max_q_idx; i++)
2110 QUEST_IDX q_idx = quest_num[i];
2111 quest_type* const q_ptr = &quest[q_idx];
2113 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
2119 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
2124 * Print all failed quests
2125 * @param creature_ptr プレーヤーへの参照ポインタ
2126 * @param fff セーブファイル (展開済?)
2127 * @param quest_num[] 受注したことのあるクエスト群
2130 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
2132 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
2133 QUEST_IDX total = 0;
2134 for (QUEST_IDX i = 1; i < max_q_idx; i++)
2136 QUEST_IDX q_idx = quest_num[i];
2137 quest_type* const q_ptr = &quest[q_idx];
2139 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
2140 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
2146 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
2151 * Print all random quests
2153 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
2155 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
2156 GAME_TEXT tmp_str[120];
2157 QUEST_IDX total = 0;
2158 for (QUEST_IDX i = 1; i < max_q_idx; i++)
2160 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
2162 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
2165 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
2166 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
2167 fputs(tmp_str, fff);
2171 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
2175 * Print quest status of all active quests
2176 * @param creature_ptr プレーヤーへの参照ポインタ
2179 static void do_cmd_knowledge_quests(player_type *creature_ptr)
2182 GAME_TEXT file_name[FILE_NAME_SIZE];
2183 if (!open_temporary_file(&fff, file_name)) return;
2186 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
2188 for (IDX i = 1; i < max_q_idx; i++)
2192 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
2194 do_cmd_knowledge_quests_current(creature_ptr, fff);
2196 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
2198 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
2199 if (current_world_ptr->wizard)
2202 do_cmd_knowledge_quests_wiz_random(fff);
2206 (void)show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
2208 C_KILL(quest_num, max_q_idx, QUEST_IDX);
2214 * @param player_ptr プレーヤーへの参照ポインタ
2217 static void do_cmd_knowledge_home(player_type *player_ptr)
2219 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
2222 GAME_TEXT file_name[FILE_NAME_SIZE];
2223 if (!open_temporary_file(&fff, file_name)) return;
2225 store_type *store_ptr;
2226 store_ptr = &town_info[1].store[STORE_HOME];
2228 if (store_ptr->stock_num)
2233 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
2234 concptr paren = ")";
2235 GAME_TEXT o_name[MAX_NLEN];
2236 for (int i = 0; i < store_ptr->stock_num; i++)
2239 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
2240 object_desc(player_ptr, o_name, &store_ptr->stock[i], 0);
2241 if (strlen(o_name) <= 80 - 3)
2243 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
2249 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
2250 if (iskanji(*t)) { t++; n++; }
2251 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
2253 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
2254 fprintf(fff, " %.77s\n", o_name + n);
2257 object_desc(player_ptr, o_name, &store_ptr->stock[i], 0);
2258 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
2262 fprintf(fff, "\n\n");
2266 (void)show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
2272 * Check the status of "autopick"
2274 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
2277 GAME_TEXT file_name[FILE_NAME_SIZE];
2278 if (!open_temporary_file(&fff, file_name)) return;
2282 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
2286 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
2287 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
2290 for (int k = 0; k < max_autopick; k++)
2293 byte act = autopick_list[k].action;
2294 if (act & DONT_AUTOPICK)
2296 tmp = _("放置", "Leave");
2298 else if (act & DO_AUTODESTROY)
2300 tmp = _("破壊", "Destroy");
2302 else if (act & DO_AUTOPICK)
2304 tmp = _("拾う", "Pickup");
2308 tmp = _("確認", "Query");
2311 if (act & DO_DISPLAY)
2312 fprintf(fff, "%11s", format("[%s]", tmp));
2314 fprintf(fff, "%11s", format("(%s)", tmp));
2316 tmp = autopick_line_from_entry(&autopick_list[k]);
2317 fprintf(fff, " %s", tmp);
2324 (void)show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
2330 * Interact with "knowledge"
2332 void do_cmd_knowledge(player_type *creature_ptr)
2335 bool need_redraw = FALSE;
2336 FILE_TYPE(FILE_TYPE_TEXT);
2341 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
2342 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
2345 prt(_("(1) 既知の伝説のアイテム の一覧", "(1) Display known artifacts"), 6, 5);
2346 prt(_("(2) 既知のアイテム の一覧", "(2) Display known objects"), 7, 5);
2347 prt(_("(3) 既知の生きているユニーク・モンスター の一覧", "(3) Display remaining uniques"), 8, 5);
2348 prt(_("(4) 既知のモンスター の一覧", "(4) Display known monster"), 9, 5);
2349 prt(_("(5) 倒した敵の数 の一覧", "(5) Display kill count"), 10, 5);
2350 if (!vanilla_town) prt(_("(6) 賞金首 の一覧", "(6) Display wanted monsters"), 11, 5);
2351 prt(_("(7) 現在のペット の一覧", "(7) Display current pets"), 12, 5);
2352 prt(_("(8) 我が家のアイテム の一覧", "(8) Display home inventory"), 13, 5);
2353 prt(_("(9) *鑑定*済み装備の耐性 の一覧", "(9) Display *identified* equip."), 14, 5);
2354 prt(_("(0) 地形の表示文字/タイル の一覧", "(0) Display terrain symbols."), 15, 5);
2358 prt(_("(a) 自分に関する情報 の一覧", "(a) Display about yourself"), 6, 5);
2359 prt(_("(b) 突然変異 の一覧", "(b) Display mutations"), 7, 5);
2360 prt(_("(c) 武器の経験値 の一覧", "(c) Display weapon proficiency"), 8, 5);
2361 prt(_("(d) 魔法の経験値 の一覧", "(d) Display spell proficiency"), 9, 5);
2362 prt(_("(e) 技能の経験値 の一覧", "(e) Display misc. proficiency"), 10, 5);
2363 prt(_("(f) プレイヤーの徳 の一覧", "(f) Display virtues"), 11, 5);
2364 prt(_("(g) 入ったダンジョン の一覧", "(g) Display dungeons"), 12, 5);
2365 prt(_("(h) 実行中のクエスト の一覧", "(h) Display current quests"), 13, 5);
2366 prt(_("(i) 現在の自動拾い/破壊設定 の一覧", "(i) Display auto pick/destroy"), 14, 5);
2369 prt(_("-続く-", "-more-"), 17, 8);
2370 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
2371 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
2372 prt(_("コマンド:", "Command: "), 20, 0);
2375 if (i == ESCAPE) break;
2378 case ' ': /* Page change */
2382 case '1': /* Artifacts */
2383 do_cmd_knowledge_artifacts(creature_ptr);
2385 case '2': /* Objects */
2386 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
2388 case '3': /* Uniques */
2389 do_cmd_knowledge_uniques(creature_ptr);
2391 case '4': /* Monsters */
2392 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
2394 case '5': /* Kill count */
2395 do_cmd_knowledge_kill_count(creature_ptr);
2397 case '6': /* wanted */
2398 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
2400 case '7': /* Pets */
2401 do_cmd_knowledge_pets(creature_ptr);
2403 case '8': /* Home */
2404 do_cmd_knowledge_home(creature_ptr);
2406 case '9': /* Resist list */
2407 do_cmd_knowledge_inventory(creature_ptr);
2409 case '0': /* Feature list */
2411 IDX lighting_level = F_LIT_STANDARD;
2412 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
2416 case 'a': /* Max stat */
2417 do_cmd_knowledge_stat(creature_ptr);
2419 case 'b': /* Mutations */
2420 do_cmd_knowledge_mutations(creature_ptr);
2422 case 'c': /* weapon-exp */
2423 do_cmd_knowledge_weapon_exp(creature_ptr);
2425 case 'd': /* spell-exp */
2426 do_cmd_knowledge_spell_exp(creature_ptr);
2428 case 'e': /* skill-exp */
2429 do_cmd_knowledge_skill_exp(creature_ptr);
2431 case 'f': /* Virtues */
2432 do_cmd_knowledge_virtues(creature_ptr);
2434 case 'g': /* Dungeon */
2435 do_cmd_knowledge_dungeon(creature_ptr);
2437 case 'h': /* Quests */
2438 do_cmd_knowledge_quests(creature_ptr);
2440 case 'i': /* Autopick */
2441 do_cmd_knowledge_autopick(creature_ptr);
2443 default: /* Unknown option */
2451 if (need_redraw) do_cmd_redraw(creature_ptr);
2456 * Check on the status of an active quest
2457 * @param creature_ptr プレーヤーへの参照ポインタ
2460 void do_cmd_checkquest(player_type *creature_ptr)
2462 FILE_TYPE(FILE_TYPE_TEXT);
2464 do_cmd_knowledge_quests(creature_ptr);
2470 * Display the time and date
2471 * @param creature_ptr プレーヤーへの参照ポインタ
2474 void do_cmd_time(player_type *creature_ptr)
2477 extract_day_hour_min(creature_ptr, &day, &hour, &min);
2480 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
2483 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
2484 else strcpy(day_buf, "*****");
2486 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
2487 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
2490 if (!randint0(10) || creature_ptr->image)
2492 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
2496 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
2500 fff = my_fopen(buf, "rt");
2504 int full = hour * 100 + min;
2508 while (!my_fgets(fff, buf, sizeof(buf)))
2510 if (!buf[0] || (buf[0] == '#')) continue;
2511 if (buf[1] != ':') continue;
2515 start = atoi(buf + 2);
2522 end = atoi(buf + 2);
2526 if ((start > full) || (full > end)) continue;
2531 if (!randint0(num)) strcpy(desc, buf + 2);