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-items.h"
47 #include "knowledge/knowledge-experiences.h"
48 #include "knowledge/knowledge-features.h"
49 #include "knowledge/knowledge-monsters.h"
50 #include "knowledge/knowledge-quests.h"
51 #include "knowledge/knowledge-self.h"
52 #include "knowledge/knowledge-uniques.h"
57 #include "view/display-player.h" // 暫定。後で消す.
58 #include "player-personality.h"
62 #include "market/store.h"
64 #include "object-flavor.h"
65 #include "object/object-kind.h"
66 #include "floor-town.h"
67 #include "cmd/feeling-table.h"
68 #include "cmd/object-group-table.h"
69 #include "market/store-util.h"
70 #include "view-mainwindow.h" // 暫定。後で消す
73 #include "diary-subtitle-table.h"
74 #include "io/write-diary.h"
78 * @brief prefファイルを選択して処理する /
79 * Ask for a "user pref line" and process it
80 * @brief prf出力内容を消去する /
81 * Remove old lines automatically generated before.
82 * @param orig_file 消去を行うファイル名
84 static void remove_auto_dump(concptr orig_file, concptr auto_dump_mark)
87 bool between_mark = FALSE;
90 long header_location = 0;
91 char header_mark_str[80];
92 char footer_mark_str[80];
94 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
95 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
96 size_t mark_len = strlen(footer_mark_str);
99 orig_fff = my_fopen(orig_file, "r");
100 if (!orig_fff) return;
102 FILE *tmp_fff = NULL;
103 char tmp_file[FILE_NAME_SIZE];
104 if (!open_temporary_file(&tmp_fff, tmp_file)) return;
108 if (my_fgets(orig_fff, buf, sizeof(buf)))
112 fseek(orig_fff, header_location, SEEK_SET);
113 between_mark = FALSE;
124 if (!strcmp(buf, header_mark_str))
126 header_location = ftell(orig_fff);
133 fprintf(tmp_fff, "%s\n", buf);
139 if (!strncmp(buf, footer_mark_str, mark_len))
142 if (!sscanf(buf + mark_len, " (%d)", &tmp)
145 fseek(orig_fff, header_location, SEEK_SET);
148 between_mark = FALSE;
160 tmp_fff = my_fopen(tmp_file, "r");
161 orig_fff = my_fopen(orig_file, "w");
162 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
163 fprintf(orig_fff, "%s\n", buf);
176 * @brief Return suffix of ordinal number
178 * @return pointer of suffix string.
180 concptr get_ordinal_number_suffix(int num)
182 num = ABS(num) % 100;
186 return (num == 11) ? "th" : "st";
188 return (num == 12) ? "th" : "nd";
190 return (num == 13) ? "th" : "rd";
198 * @brief 画面を再描画するコマンドのメインルーチン
199 * Hack -- redraw the screen
200 * @param creature_ptr プレーヤーへの参照ポインタ
203 * Allow absolute file names?
205 void do_cmd_pref(player_type *creature_ptr)
209 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
211 (void)interpret_pref_file(creature_ptr, buf);
216 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
217 * @param creature_ptr プレーヤーへの参照ポインタ
220 void do_cmd_reload_autopick(player_type *creature_ptr)
222 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? ")))
225 autopick_load_pref(creature_ptr, TRUE);
230 * Interact with "colors"
232 void do_cmd_colors(player_type *creature_ptr)
237 FILE *auto_dump_stream;
238 FILE_TYPE(FILE_TYPE_TEXT);
243 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
244 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
245 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
246 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
247 prt(_("コマンド: ", "Command: "), 8, 0);
249 if (i == ESCAPE) break;
253 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
254 prt(_("ファイル: ", "File: "), 10, 0);
255 sprintf(tmp, "%s.prf", creature_ptr->base_name);
256 if (!askfor(tmp, 70)) continue;
258 (void)process_pref_file(creature_ptr, tmp);
259 Term_xtra(TERM_XTRA_REACT, 0);
264 static concptr mark = "Colors";
265 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
266 prt(_("ファイル: ", "File: "), 10, 0);
267 sprintf(tmp, "%s.prf", creature_ptr->base_name);
268 if (!askfor(tmp, 70)) continue;
270 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
271 if (!open_auto_dump(&auto_dump_stream, buf, mark)) continue;
273 auto_dump_printf(auto_dump_stream, _("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
274 for (i = 0; i < 256; i++)
276 int kv = angband_color_table[i][0];
277 int rv = angband_color_table[i][1];
278 int gv = angband_color_table[i][2];
279 int bv = angband_color_table[i][3];
281 concptr name = _("未知", "unknown");
282 if (!kv && !rv && !gv && !bv) continue;
284 if (i < 16) name = color_names[i];
286 auto_dump_printf(auto_dump_stream, _("# カラー '%s'\n", "# Color '%s'\n"), name);
287 auto_dump_printf(auto_dump_stream, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
291 close_auto_dump(&auto_dump_stream, mark);
292 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
297 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
302 for (byte j = 0; j < 16; j++)
304 Term_putstr(j * 4, 20, -1, a, "###");
305 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
308 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
309 Term_putstr(5, 10, -1, TERM_WHITE,
310 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
311 Term_putstr(5, 12, -1, TERM_WHITE,
312 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
313 angband_color_table[a][0],
314 angband_color_table[a][1],
315 angband_color_table[a][2],
316 angband_color_table[a][3]));
317 Term_putstr(0, 14, -1, TERM_WHITE,
318 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
320 if (i == ESCAPE) break;
322 if (i == 'n') a = (byte)(a + 1);
323 if (i == 'N') a = (byte)(a - 1);
324 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
325 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
326 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
327 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
328 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
329 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
330 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
331 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
333 Term_xtra(TERM_XTRA_REACT, 0);
350 * Note something in the message recall
352 void do_cmd_note(void)
356 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
357 if (!buf[0] || (buf[0] == ' ')) return;
359 msg_format(_("メモ: %s", "Note: %s"), buf);
364 * Mention the current version
366 void do_cmd_version(void)
368 #if FAKE_VER_EXTRA > 0
369 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
370 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
372 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
373 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
379 * Note that "feeling" is set to zero unless some time has passed.
380 * Note that this is done when the level is GENERATED, not entered.
382 void do_cmd_feeling(player_type *creature_ptr)
384 if (creature_ptr->wild_mode) return;
386 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
388 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
392 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
394 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
396 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
400 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
404 if (!creature_ptr->current_floor_ptr->dun_level)
406 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
410 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
411 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
412 else if (IS_ECHIZEN(creature_ptr))
413 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
415 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
420 * Check the status of "autopick"
422 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
425 GAME_TEXT file_name[FILE_NAME_SIZE];
426 if (!open_temporary_file(&fff, file_name)) return;
430 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
434 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
435 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
438 for (int k = 0; k < max_autopick; k++)
441 byte act = autopick_list[k].action;
442 if (act & DONT_AUTOPICK)
444 tmp = _("放置", "Leave");
446 else if (act & DO_AUTODESTROY)
448 tmp = _("破壊", "Destroy");
450 else if (act & DO_AUTOPICK)
452 tmp = _("拾う", "Pickup");
456 tmp = _("確認", "Query");
459 if (act & DO_DISPLAY)
460 fprintf(fff, "%11s", format("[%s]", tmp));
462 fprintf(fff, "%11s", format("(%s)", tmp));
464 tmp = autopick_line_from_entry(&autopick_list[k]);
465 fprintf(fff, " %s", tmp);
472 (void)show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
478 * Interact with "knowledge"
480 void do_cmd_knowledge(player_type *creature_ptr)
483 bool need_redraw = FALSE;
484 FILE_TYPE(FILE_TYPE_TEXT);
489 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
490 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
493 prt(_("(1) 既知の伝説のアイテム の一覧", "(1) Display known artifacts"), 6, 5);
494 prt(_("(2) 既知のアイテム の一覧", "(2) Display known objects"), 7, 5);
495 prt(_("(3) 既知の生きているユニーク・モンスター の一覧", "(3) Display remaining uniques"), 8, 5);
496 prt(_("(4) 既知のモンスター の一覧", "(4) Display known monster"), 9, 5);
497 prt(_("(5) 倒した敵の数 の一覧", "(5) Display kill count"), 10, 5);
498 if (!vanilla_town) prt(_("(6) 賞金首 の一覧", "(6) Display wanted monsters"), 11, 5);
499 prt(_("(7) 現在のペット の一覧", "(7) Display current pets"), 12, 5);
500 prt(_("(8) 我が家のアイテム の一覧", "(8) Display home inventory"), 13, 5);
501 prt(_("(9) *鑑定*済み装備の耐性 の一覧", "(9) Display *identified* equip."), 14, 5);
502 prt(_("(0) 地形の表示文字/タイル の一覧", "(0) Display terrain symbols."), 15, 5);
506 prt(_("(a) 自分に関する情報 の一覧", "(a) Display about yourself"), 6, 5);
507 prt(_("(b) 突然変異 の一覧", "(b) Display mutations"), 7, 5);
508 prt(_("(c) 武器の経験値 の一覧", "(c) Display weapon proficiency"), 8, 5);
509 prt(_("(d) 魔法の経験値 の一覧", "(d) Display spell proficiency"), 9, 5);
510 prt(_("(e) 技能の経験値 の一覧", "(e) Display misc. proficiency"), 10, 5);
511 prt(_("(f) プレイヤーの徳 の一覧", "(f) Display virtues"), 11, 5);
512 prt(_("(g) 入ったダンジョン の一覧", "(g) Display dungeons"), 12, 5);
513 prt(_("(h) 実行中のクエスト の一覧", "(h) Display current quests"), 13, 5);
514 prt(_("(i) 現在の自動拾い/破壊設定 の一覧", "(i) Display auto pick/destroy"), 14, 5);
517 prt(_("-続く-", "-more-"), 17, 8);
518 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
519 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
520 prt(_("コマンド:", "Command: "), 20, 0);
523 if (i == ESCAPE) break;
526 case ' ': /* Page change */
530 case '1': /* Artifacts */
531 do_cmd_knowledge_artifacts(creature_ptr);
533 case '2': /* Objects */
534 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
536 case '3': /* Uniques */
537 do_cmd_knowledge_uniques(creature_ptr);
539 case '4': /* Monsters */
540 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
542 case '5': /* Kill count */
543 do_cmd_knowledge_kill_count(creature_ptr);
545 case '6': /* wanted */
546 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
549 do_cmd_knowledge_pets(creature_ptr);
552 do_cmd_knowledge_home(creature_ptr);
554 case '9': /* Resist list */
555 do_cmd_knowledge_inventory(creature_ptr);
557 case '0': /* Feature list */
559 IDX lighting_level = F_LIT_STANDARD;
560 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
564 case 'a': /* Max stat */
565 do_cmd_knowledge_stat(creature_ptr);
567 case 'b': /* Mutations */
568 do_cmd_knowledge_mutations(creature_ptr);
570 case 'c': /* weapon-exp */
571 do_cmd_knowledge_weapon_exp(creature_ptr);
573 case 'd': /* spell-exp */
574 do_cmd_knowledge_spell_exp(creature_ptr);
576 case 'e': /* skill-exp */
577 do_cmd_knowledge_skill_exp(creature_ptr);
579 case 'f': /* Virtues */
580 do_cmd_knowledge_virtues(creature_ptr);
582 case 'g': /* Dungeon */
583 do_cmd_knowledge_dungeon(creature_ptr);
585 case 'h': /* Quests */
586 do_cmd_knowledge_quests(creature_ptr);
588 case 'i': /* Autopick */
589 do_cmd_knowledge_autopick(creature_ptr);
591 default: /* Unknown option */
599 if (need_redraw) do_cmd_redraw(creature_ptr);
604 * Check on the status of an active quest
605 * @param creature_ptr プレーヤーへの参照ポインタ
608 void do_cmd_checkquest(player_type *creature_ptr)
610 FILE_TYPE(FILE_TYPE_TEXT);
612 do_cmd_knowledge_quests(creature_ptr);
618 * Display the time and date
619 * @param creature_ptr プレーヤーへの参照ポインタ
622 void do_cmd_time(player_type *creature_ptr)
625 extract_day_hour_min(creature_ptr, &day, &hour, &min);
628 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
631 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
632 else strcpy(day_buf, "*****");
634 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
635 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
638 if (!randint0(10) || creature_ptr->image)
640 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
644 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
648 fff = my_fopen(buf, "rt");
652 int full = hour * 100 + min;
656 while (!my_fgets(fff, buf, sizeof(buf)))
658 if (!buf[0] || (buf[0] == '#')) continue;
659 if (buf[1] != ':') continue;
663 start = atoi(buf + 2);
674 if ((start > full) || (full > end)) continue;
679 if (!randint0(num)) strcpy(desc, buf + 2);