3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
46 #include "core/show-file.h"
47 #include "io/read-pref-file.h"
56 #include "view/display-player.h"
57 #include "player/process-name.h"
58 #include "player-effects.h"
59 #include "player-status.h"
60 #include "player-skill.h"
61 #include "player-personality.h"
68 #include "object-flavor.h"
69 #include "object-hook.h"
71 #include "monster-status.h"
72 #include "view-mainwindow.h"
73 #include "dungeon-file.h"
74 #include "io/interpret-pref-file.h"
77 #include "objectkind.h"
78 #include "floor-town.h"
79 #include "view-mainwindow.h" // 暫定。後で消す
83 // Mark strings for auto dump
84 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
85 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
87 // Variables for auto dump
88 static FILE *auto_dump_stream;
89 static concptr auto_dump_mark;
90 static int auto_dump_line_num;
92 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
93 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
94 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
96 // Clipboard variables for copy&paste in visual mode
97 static TERM_COLOR attr_idx = 0;
98 static SYMBOL_CODE char_idx = 0;
100 /* Hack -- for feature lighting */
101 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
102 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
104 // Encode the screen colors
105 static char hack[17] = "dwsorgbuDWvyRGBU";
111 * @brief prf出力内容を消去する /
112 * Remove old lines automatically generated before.
113 * @param orig_file 消去を行うファイル名
115 static void remove_auto_dump(concptr orig_file)
117 FILE *tmp_fff, *orig_fff;
121 bool between_mark = FALSE;
122 bool changed = FALSE;
124 long header_location = 0;
125 char header_mark_str[80];
126 char footer_mark_str[80];
129 /* Prepare a header/footer mark string */
130 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
131 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
133 mark_len = strlen(footer_mark_str);
135 /* Open an old dump file in read-only mode */
136 orig_fff = my_fopen(orig_file, "r");
138 /* If original file does not exist, nothing to do */
139 if (!orig_fff) return;
141 /* Open a new (temporary) file */
142 tmp_fff = my_fopen_temp(tmp_file, 1024);
146 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
151 /* Loop for every line */
155 if (my_fgets(orig_fff, buf, sizeof(buf)))
157 /* Read error: Assume End of File */
160 * Was looking for the footer, but not found.
162 * Since automatic dump might be edited by hand,
163 * it's dangerous to kill these lines.
164 * Seek back to the next line of the (pseudo) header,
169 fseek(orig_fff, header_location, SEEK_SET);
170 between_mark = FALSE;
174 /* Success -- End the loop */
181 /* We are looking for the header mark of automatic dump */
184 /* Is this line a header? */
185 if (!strcmp(buf, header_mark_str))
187 /* Memorise seek point of this line */
188 header_location = ftell(orig_fff);
190 /* Initialize counter for number of lines */
193 /* Look for the footer from now */
196 /* There are some changes */
203 /* Copy orginally lines */
204 fprintf(tmp_fff, "%s\n", buf);
210 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
211 /* We are looking for the footer mark of automatic dump */
212 /* Is this line a footer? */
213 if (!strncmp(buf, footer_mark_str, mark_len))
218 * Compare the number of lines
220 * If there is an inconsistency between
221 * actual number of lines and the
222 * number here, the automatic dump
223 * might be edited by hand. So it's
224 * dangerous to kill these lines.
225 * Seek back to the next line of the
226 * (pseudo) header, and read again.
228 if (!sscanf(buf + mark_len, " (%d)", &tmp)
231 fseek(orig_fff, header_location, SEEK_SET);
234 /* Look for another header */
235 between_mark = FALSE;
240 /* Ignore old line, and count number of lines */
248 /* If there are some changes, overwrite the original file with new one */
251 /* Copy contents of temporary file */
252 tmp_fff = my_fopen(tmp_file, "r");
253 orig_fff = my_fopen(orig_file, "w");
255 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
256 fprintf(orig_fff, "%s\n", buf);
267 * @brief prfファイルのフォーマットに従った内容を出力する /
268 * Dump a formatted line, using "vstrnfmt()".
271 static void auto_dump_printf(concptr fmt, ...)
278 /* Begin the Varargs Stuff */
281 /* Format the args, save the length */
282 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
284 /* End the Varargs Stuff */
287 /* Count number of lines */
288 for (p = buf; *p; p++)
290 if (*p == '\n') auto_dump_line_num++;
294 fprintf(auto_dump_stream, "%s", buf);
299 * @brief prfファイルをファイルオープンする /
300 * Open file to append auto dump.
302 * @param mark 出力するヘッダマーク
303 * @return ファイルポインタを取得できたらTRUEを返す
305 static bool open_auto_dump(concptr buf, concptr mark)
307 char header_mark_str[80];
309 /* Save the mark string */
310 auto_dump_mark = mark;
312 /* Prepare a header mark string */
313 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
315 /* Remove old macro dumps */
316 remove_auto_dump(buf);
318 /* Append to the file */
319 auto_dump_stream = my_fopen(buf, "a");
322 if (!auto_dump_stream)
324 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
332 fprintf(auto_dump_stream, "%s\n", header_mark_str);
334 /* Initialize counter */
335 auto_dump_line_num = 0;
337 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
338 "# *Warning!* The lines below are an automatic dump.\n"));
339 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
340 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
345 * @brief prfファイルをファイルクローズする /
346 * Append foot part and close auto dump.
349 static void close_auto_dump(void)
351 char footer_mark_str[80];
353 /* Prepare a footer mark string */
354 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
356 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
357 "# *Warning!* The lines below are an automatic dump.\n"));
358 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
359 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
361 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
363 my_fclose(auto_dump_stream);
370 * @brief Return suffix of ordinal number
372 * @return pointer of suffix string.
374 concptr get_ordinal_number_suffix(int num)
376 num = ABS(num) % 100;
380 return (num == 11) ? "th" : "st";
382 return (num == 12) ? "th" : "nd";
384 return (num == 13) ? "th" : "rd";
393 * @brief 日記にメッセージを追加する /
394 * Take note to the diary.
395 * @param type 日記内容のID
396 * @param num 日記内容のIDに応じた数値
397 * @param note 日記内容のIDに応じた文字列参照ポインタ
400 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
404 GAME_TEXT file_name[MAX_NLEN];
406 concptr note_level = "";
407 bool do_level = TRUE;
408 char note_level_buf[40];
411 static bool disable_diary = FALSE;
413 extract_day_hour_min(creature_ptr, &day, &hour, &min);
415 if (disable_diary) return(-1);
417 if (type == DIARY_FIX_QUEST_C ||
418 type == DIARY_FIX_QUEST_F ||
419 type == DIARY_RAND_QUEST_C ||
420 type == DIARY_RAND_QUEST_F ||
421 type == DIARY_TO_QUEST)
425 old_quest = creature_ptr->current_floor_ptr->inside_quest;
426 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
428 /* Get the quest text */
429 init_flags = INIT_NAME_ONLY;
431 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
433 /* Reset the old quest number */
434 creature_ptr->current_floor_ptr->inside_quest = old_quest;
437 /* different filne name to avoid mixing */
438 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
439 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
441 /* File type is "TEXT" */
442 FILE_TYPE(FILE_TYPE_TEXT);
444 fff = my_fopen(buf, "a");
449 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
451 disable_diary = TRUE;
455 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
459 if (creature_ptr->current_floor_ptr->inside_arena)
460 note_level = _("アリーナ:", "Arane:");
461 else if (!creature_ptr->current_floor_ptr->dun_level)
462 note_level = _("地上:", "Surface:");
463 else if (q_idx && (is_fixed_quest_idx(q_idx)
464 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
465 note_level = _("クエスト:", "Quest:");
469 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
471 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
473 note_level = note_level_buf;
481 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
482 else fputs(_("*****日目\n", "Day *****\n"), fff);
486 case DIARY_DESCRIPTION:
490 fprintf(fff, "%s\n", note);
494 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
499 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
502 case DIARY_ART_SCROLL:
504 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
509 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
512 case DIARY_FIX_QUEST_C:
514 if (quest[num].flags & QUEST_FLAG_SILENT) break;
515 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
516 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
519 case DIARY_FIX_QUEST_F:
521 if (quest[num].flags & QUEST_FLAG_SILENT) break;
522 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
523 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
526 case DIARY_RAND_QUEST_C:
528 GAME_TEXT name[MAX_NLEN];
529 strcpy(name, r_name + r_info[quest[num].r_idx].name);
530 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
531 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
534 case DIARY_RAND_QUEST_F:
536 GAME_TEXT name[MAX_NLEN];
537 strcpy(name, r_name + r_info[quest[num].r_idx].name);
538 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
539 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
542 case DIARY_MAXDEAPTH:
544 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
545 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
546 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
547 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
552 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
553 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
554 _(d_name + d_info[num].name, (int)max_dlv[num]),
555 _((int)max_dlv[num], d_name + d_info[num].name));
561 if (q_idx && (is_fixed_quest_idx(q_idx)
562 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
564 to = _("地上", "the surface");
568 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
569 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
571 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
577 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
578 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
579 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
581 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
586 if (quest[num].flags & QUEST_FLAG_SILENT) break;
587 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
588 hour, min, note_level, quest[num].name);
591 case DIARY_TELEPORT_LEVEL:
593 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
594 hour, min, note_level);
599 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
604 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
612 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
613 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
616 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
617 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
619 if (num == MAX_ARENA_MONS)
621 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
622 " won all fights to become a Champion.\n"));
629 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
635 if (!creature_ptr->current_floor_ptr->dun_level)
636 to = _("地上", "the surface");
638 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
640 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
641 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
647 if (!creature_ptr->current_floor_ptr->dun_level)
648 to = _("地上", "the surface");
650 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
652 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
653 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
658 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
661 case DIARY_GAMESTART:
663 time_t ct = time((time_t*)0);
667 fprintf(fff, "%s %s", note, ctime(&ct));
670 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
673 case DIARY_NAMED_PET:
675 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
678 case RECORD_NAMED_PET_NAME:
679 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
681 case RECORD_NAMED_PET_UNNAME:
682 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
684 case RECORD_NAMED_PET_DISMISS:
685 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
687 case RECORD_NAMED_PET_DEATH:
688 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
690 case RECORD_NAMED_PET_MOVED:
691 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
693 case RECORD_NAMED_PET_LOST_SIGHT:
694 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
696 case RECORD_NAMED_PET_DESTROY:
697 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
699 case RECORD_NAMED_PET_EARTHQUAKE:
700 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
702 case RECORD_NAMED_PET_GENOCIDE:
703 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
705 case RECORD_NAMED_PET_WIZ_ZAP:
706 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
708 case RECORD_NAMED_PET_TELE_LEVEL:
709 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
711 case RECORD_NAMED_PET_BLAST:
712 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
714 case RECORD_NAMED_PET_HEAL_LEPER:
715 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
717 case RECORD_NAMED_PET_COMPACT:
718 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
720 case RECORD_NAMED_PET_LOSE_PARENT:
721 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
731 case DIARY_WIZARD_LOG:
732 fprintf(fff, "%s\n", note);
741 if (do_level) write_level = FALSE;
747 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
750 * @brief 日記のタイトル表記と内容出力 /
753 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
755 static void display_diary(player_type *creature_ptr)
757 char diary_title[256];
758 GAME_TEXT file_name[MAX_NLEN];
762 static const char subtitle[][30] = {
795 static const char subtitle[][51] = {
796 "Quest of The World's Toughest Body",
797 "Attack is the best form of defence.",
799 "An unexpected windfall",
800 "A drowning man will catch at a straw",
801 "Don't count your chickens before they are hatched.",
802 "It is no use crying over spilt milk.",
803 "Seeing is believing.",
804 "Strike the iron while it is hot.",
805 "I don't care what follows.",
806 "To dig a well to put out a house on fire.",
807 "Tomorrow is another day.",
808 "Easy come, easy go.",
809 "The more haste, the less speed.",
810 "Where there is life, there is hope.",
811 "There is no royal road to *WINNER*.",
812 "Danger past, God forgotten.",
813 "The best thing to do now is to run away.",
814 "Life is but an empty dream.",
815 "Dead men tell no tales.",
816 "A book that remains shut is but a block.",
817 "Misfortunes never come singly.",
818 "A little knowledge is a dangerous thing.",
819 "History repeats itself.",
820 "*WINNER* was not built in a day.",
821 "Ignorance is bliss.",
822 "To lose is to win?",
823 "No medicine can cure folly.",
824 "All good things come to an end.",
825 "M$ Empire strikes back.",
826 "To see is to believe",
828 "Quest of The World's Greatest Brain"
831 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
832 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
834 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
835 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
836 else if (IS_WIZARD_CLASS(creature_ptr))
837 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
838 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
841 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
843 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
846 /* Display the file contents */
847 (void)show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
852 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
855 static void add_diary_note(player_type *creature_ptr)
858 char bunshou[80] = "\0";
860 if (get_string(_("内容: ", "diary note: "), tmp, 79))
862 strcpy(bunshou, tmp);
863 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
868 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
871 static void do_cmd_last_get(player_type *creaute_ptr)
873 if (record_o_name[0] == '\0') return;
876 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
877 if (!get_check(buf)) return;
879 GAME_TURN turn_tmp = current_world_ptr->game_turn;
880 current_world_ptr->game_turn = record_turn;
881 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
882 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
883 current_world_ptr->game_turn = turn_tmp;
888 * @brief ファイル中の全日記記録を消去する /
891 static void do_cmd_erase_diary(void)
893 GAME_TEXT file_name[MAX_NLEN];
897 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
898 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
899 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
902 fff = my_fopen(buf, "w");
906 msg_format(_("記録を消去しました。", "deleted record."));
910 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
919 * @param crerature_ptr プレーヤーへの参照ポインタ
922 void do_cmd_diary(player_type *creature_ptr)
924 /* File type is "TEXT" */
925 FILE_TYPE(FILE_TYPE_TEXT);
928 /* Interact until done */
934 /* Ask for a choice */
935 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
937 /* Give some choices */
938 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
939 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
940 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
941 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
943 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
946 prt(_("コマンド:", "Command: "), 18, 0);
951 if (i == ESCAPE) break;
956 display_diary(creature_ptr);
959 add_diary_note(creature_ptr);
962 do_cmd_last_get(creature_ptr);
965 do_cmd_erase_diary();
969 prepare_movie_hooks();
971 default: /* Unknown option */
983 * @brief 画面を再描画するコマンドのメインルーチン
984 * Hack -- redraw the screen
985 * @param creature_ptr プレーヤーへの参照ポインタ
989 * This command performs various low level updates, clears all the "extra"
990 * windows, does a total redraw of the main window, and requests all of the
991 * interesting updates and redraws that I can think of.
993 * This command is also used to "instantiate" the results of the user
994 * selecting various things, such as graphics mode, so it must call
995 * the "TERM_XTRA_REACT" hook before redrawing the windows.
998 void do_cmd_redraw(player_type *creature_ptr)
1000 Term_xtra(TERM_XTRA_REACT, 0);
1002 /* Combine and Reorder the pack (later) */
1003 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1004 creature_ptr->update |= (PU_TORCH);
1005 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1006 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1007 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1008 creature_ptr->update |= (PU_MONSTERS);
1010 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1012 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1013 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1016 handle_stuff(creature_ptr);
1018 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1020 /* Redraw every window */
1022 for (int j = 0; j < 8; j++)
1025 if (!angband_term[j]) continue;
1028 Term_activate(angband_term[j]);
1037 * @brief プレイヤーのステータス表示
1040 void do_cmd_player_status(player_type *creature_ptr)
1051 display_player(creature_ptr, mode, map_name);
1056 display_player(creature_ptr, mode, map_name);
1060 Term_putstr(2, 23, -1, TERM_WHITE,
1061 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1065 if (c == ESCAPE) break;
1070 get_name(creature_ptr);
1072 /* Process the player name */
1073 process_player_name(creature_ptr, FALSE);
1079 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1080 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1082 if (tmp[0] && (tmp[0] != ' '))
1084 file_character(creature_ptr, tmp, update_playtime, display_player, map_name);
1102 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1104 handle_stuff(creature_ptr);
1109 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1110 * Recall the most recent message
1113 void do_cmd_message_one(void)
1115 /* Recall one message */
1116 prt(format("> %s", message_str(0)), 0, 0);
1121 * @brief メッセージのログを表示するコマンドのメインルーチン
1122 * Recall the most recent message
1126 * Show previous messages to the user -BEN-
1128 * The screen format uses line 0 and 23 for headers and prompts,
1129 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1131 * This command shows you which commands you are viewing, and allows
1132 * you to "search" for strings in the recall.
1134 * Note that messages may be longer than 80 characters, but they are
1135 * displayed using "infinite" length, with a special sub-command to
1136 * "slide" the virtual display to the left or right.
1138 * Attempt to only hilite the matching portions of the string.
1141 void do_cmd_messages(int num_now)
1143 char shower_str[81];
1144 char finder_str[81];
1146 concptr shower = NULL;
1150 Term_get_size(&wid, &hgt);
1152 /* Number of message lines in a screen */
1153 num_lines = hgt - 4;
1156 strcpy(finder_str, "");
1159 strcpy(shower_str, "");
1161 /* Total messages */
1162 int n = message_num();
1164 /* Start on first message */
1169 /* Process requests until done */
1175 /* Dump up to 20 lines of messages */
1176 for (j = 0; (j < num_lines) && (i + j < n); j++)
1178 concptr msg = message_str(i + j);
1180 /* Dump the messages, bottom to top */
1181 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1183 if (!shower || !shower[0]) continue;
1185 /* Hilite "shower" */
1188 /* Display matches */
1189 while ((str = my_strstr(str, shower)) != NULL)
1191 int len = strlen(shower);
1193 /* Display the match */
1194 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1201 /* Erase remaining lines */
1202 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1204 /* Display header */
1206 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1207 i, i + j - 1, n), 0, 0);
1209 /* Display prompt (not very informative) */
1210 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1211 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1213 skey = inkey_special(TRUE);
1215 /* Exit on Escape */
1216 if (skey == ESCAPE) break;
1218 /* Hack -- Save the old index */
1223 /* Hack -- handle show */
1226 prt(_("強調: ", "Show: "), hgt - 1, 0);
1228 /* Get a "shower" string, or continue */
1229 strcpy(back_str, shower_str);
1230 if (askfor(shower_str, 80))
1233 shower = shower_str[0] ? shower_str : NULL;
1235 else strcpy(shower_str, back_str);
1239 /* Hack -- handle find */
1246 prt(_("検索: ", "Find: "), hgt - 1, 0);
1248 /* Get a "finder" string, or continue */
1249 strcpy(back_str, finder_str);
1250 if (!askfor(finder_str, 80))
1252 strcpy(finder_str, back_str);
1255 else if (!finder_str[0])
1257 shower = NULL; /* Stop showing */
1262 shower = finder_str;
1265 for (z = i + 1; z < n; z++)
1267 concptr msg = message_str(z);
1270 if (my_strstr(msg, finder_str))
1281 /* Recall 1 older message */
1283 /* Go to the oldest line */
1287 /* Recall 1 newer message */
1289 /* Go to the newest line */
1293 /* Recall 1 older message */
1298 /* Go older if legal */
1299 i = MIN(i + 1, n - num_lines);
1302 /* Recall 10 older messages */
1304 /* Go older if legal */
1305 i = MIN(i + 10, n - num_lines);
1308 /* Recall 20 older messages */
1313 /* Go older if legal */
1314 i = MIN(i + num_lines, n - num_lines);
1317 /* Recall 20 newer messages */
1321 /* Go newer (if able) */
1322 i = MAX(0, i - num_lines);
1325 /* Recall 10 newer messages */
1327 /* Go newer (if able) */
1331 /* Recall 1 newer messages */
1334 /* Go newer (if able) */
1339 /* Hack -- Error of some kind */
1348 * @brief prefファイルを選択して処理する /
1349 * Ask for a "user pref line" and process it
1350 * @param creature_ptr プレーヤーへの参照ポインタ
1353 * Allow absolute file names?
1355 void do_cmd_pref(player_type *creature_ptr)
1360 /* Ask for a "user pref command" */
1361 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1363 /* Process that pref command */
1364 (void)interpret_pref_file(creature_ptr, buf);
1369 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1370 * @param creature_ptr プレーヤーへの参照ポインタ
1373 void do_cmd_reload_autopick(player_type *creature_ptr)
1375 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1376 /* Load the file with messages */
1377 autopick_load_pref(creature_ptr, TRUE);
1382 * @brief マクロ情報をprefファイルに保存する /
1383 * @param fname ファイル名
1386 static errr macro_dump(concptr fname)
1388 static concptr mark = "Macro Dump";
1390 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1392 /* File type is "TEXT" */
1393 FILE_TYPE(FILE_TYPE_TEXT);
1395 /* Append to the file */
1396 if (!open_auto_dump(buf, mark)) return -1;
1399 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1402 for (int i = 0; i < macro__num; i++)
1404 /* Extract the action */
1405 ascii_to_text(buf, macro__act[i]);
1407 /* Dump the macro */
1408 auto_dump_printf("A:%s\n", buf);
1410 /* Extract the action */
1411 ascii_to_text(buf, macro__pat[i]);
1413 /* Dump normal macros */
1414 auto_dump_printf("P:%s\n", buf);
1417 auto_dump_printf("\n");
1426 * @brief マクロのトリガーキーを取得する /
1427 * Hack -- ask for a "trigger" (see below)
1428 * @param buf キー表記を保管するバッファ
1432 * Note the complex use of the "inkey()" function from "util.c".
1434 * Note that both "flush()" calls are extremely important.
1437 static void do_cmd_macro_aux(char *buf)
1441 /* Do not process macros */
1447 /* Read the pattern */
1454 /* Do not process macros */
1457 /* Do not wait for keys */
1460 /* Attempt to read a key */
1469 /* Convert the trigger */
1471 ascii_to_text(tmp, buf);
1473 /* Hack -- display the trigger */
1474 Term_addstr(-1, TERM_WHITE, tmp);
1479 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1480 * Hack -- ask for a keymap "trigger" (see below)
1481 * @param buf キー表記を取得するバッファ
1485 * Note that both "flush()" calls are extremely important. This may
1486 * no longer be true, since "util.c" is much simpler now.
1489 static void do_cmd_macro_aux_keymap(char *buf)
1499 /* Convert to ascii */
1500 ascii_to_text(tmp, buf);
1502 /* Hack -- display the trigger */
1503 Term_addstr(-1, TERM_WHITE, tmp);
1510 * @brief キーマップをprefファイルにダンプする /
1511 * Hack -- append all keymaps to the given file
1512 * @param fname ファイルネーム
1516 static errr keymap_dump(concptr fname)
1518 static concptr mark = "Keymap Dump";
1525 if (rogue_like_commands)
1527 mode = KEYMAP_MODE_ROGUE;
1533 mode = KEYMAP_MODE_ORIG;
1536 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1538 /* File type is "TEXT" */
1539 FILE_TYPE(FILE_TYPE_TEXT);
1541 /* Append to the file */
1542 if (!open_auto_dump(buf, mark)) return -1;
1545 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1548 for (int i = 0; i < 256; i++)
1552 /* Loop up the keymap */
1553 act = keymap_act[mode][i];
1555 /* Skip empty keymaps */
1558 /* Encode the key */
1561 ascii_to_text(key, buf);
1563 /* Encode the action */
1564 ascii_to_text(buf, act);
1566 /* Dump the macro */
1567 auto_dump_printf("A:%s\n", buf);
1568 auto_dump_printf("C:%d:%s\n", mode, key);
1577 * @brief マクロを設定するコマンドのメインルーチン /
1578 * Interact with "macros"
1582 * Note that the macro "action" must be defined before the trigger.
1584 * Could use some helpful instructions on this page.
1587 void do_cmd_macros(player_type *creature_ptr)
1595 if (rogue_like_commands)
1597 mode = KEYMAP_MODE_ROGUE;
1603 mode = KEYMAP_MODE_ORIG;
1606 /* File type is "TEXT" */
1607 FILE_TYPE(FILE_TYPE_TEXT);
1611 /* Process requests until done */
1615 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1617 /* Describe that action */
1618 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1620 /* Analyze the current action */
1621 ascii_to_text(buf, macro__buf);
1623 /* Display the current action */
1628 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1629 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1630 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1631 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1632 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1633 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1634 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1635 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1636 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1637 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1640 prt(_("コマンド: ", "Command: "), 16, 0);
1645 if (i == ESCAPE) break;
1647 /* Load a 'macro' file */
1653 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1656 prt(_("ファイル: ", "File: "), 18, 0);
1658 /* Default filename */
1659 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1661 /* Ask for a file */
1662 if (!askfor(tmp, 80)) continue;
1664 /* Process the given filename */
1665 err = process_pref_file(creature_ptr, tmp);
1668 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1673 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1677 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1685 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1688 prt(_("ファイル: ", "File: "), 18, 0);
1690 /* Default filename */
1691 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1693 /* Ask for a file */
1694 if (!askfor(tmp, 80)) continue;
1696 /* Dump the macros */
1697 (void)macro_dump(tmp);
1700 msg_print(_("マクロを追加しました。", "Appended macros."));
1709 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1713 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1715 /* Get a macro trigger */
1716 do_cmd_macro_aux(buf);
1718 /* Acquire action */
1719 k = macro_find_exact(buf);
1725 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1731 /* Obtain the action */
1732 strcpy(macro__buf, macro__act[k]);
1734 /* Analyze the current action */
1735 ascii_to_text(buf, macro__buf);
1737 /* Display the current action */
1741 msg_print(_("マクロを確認しました。", "Found a macro."));
1745 /* Create a macro */
1749 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1752 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1754 /* Get a macro trigger */
1755 do_cmd_macro_aux(buf);
1759 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1760 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1763 prt(_("マクロ行動: ", "Action: "), 20, 0);
1765 /* Convert to text */
1766 ascii_to_text(tmp, macro__buf);
1768 /* Get an encoded action */
1769 if (askfor(tmp, 80))
1771 /* Convert to ascii */
1772 text_to_ascii(macro__buf, tmp);
1774 /* Link the macro */
1775 macro_add(buf, macro__buf);
1778 msg_print(_("マクロを追加しました。", "Added a macro."));
1782 /* Remove a macro */
1786 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1789 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1791 /* Get a macro trigger */
1792 do_cmd_macro_aux(buf);
1794 /* Link the macro */
1795 macro_add(buf, buf);
1798 msg_print(_("マクロを削除しました。", "Removed a macro."));
1805 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1808 prt(_("ファイル: ", "File: "), 18, 0);
1810 /* Default filename */
1811 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1813 /* Ask for a file */
1814 if (!askfor(tmp, 80)) continue;
1816 /* Dump the macros */
1817 (void)keymap_dump(tmp);
1820 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1823 /* Query a keymap */
1829 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1832 prt(_("押すキー: ", "Keypress: "), 18, 0);
1834 /* Get a keymap trigger */
1835 do_cmd_macro_aux_keymap(buf);
1837 /* Look up the keymap */
1838 act = keymap_act[mode][(byte)(buf[0])];
1844 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1850 /* Obtain the action */
1851 strcpy(macro__buf, act);
1853 /* Analyze the current action */
1854 ascii_to_text(buf, macro__buf);
1856 /* Display the current action */
1860 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1864 /* Create a keymap */
1868 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1871 prt(_("押すキー: ", "Keypress: "), 18, 0);
1873 /* Get a keymap trigger */
1874 do_cmd_macro_aux_keymap(buf);
1878 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1879 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1882 prt(_("行動: ", "Action: "), 20, 0);
1884 /* Convert to text */
1885 ascii_to_text(tmp, macro__buf);
1887 /* Get an encoded action */
1888 if (askfor(tmp, 80))
1890 /* Convert to ascii */
1891 text_to_ascii(macro__buf, tmp);
1893 /* Free old keymap */
1894 string_free(keymap_act[mode][(byte)(buf[0])]);
1896 /* Make new keymap */
1897 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1900 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1904 /* Remove a keymap */
1908 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1911 prt(_("押すキー: ", "Keypress: "), 18, 0);
1913 /* Get a keymap trigger */
1914 do_cmd_macro_aux_keymap(buf);
1916 /* Free old keymap */
1917 string_free(keymap_act[mode][(byte)(buf[0])]);
1919 /* Make new keymap */
1920 keymap_act[mode][(byte)(buf[0])] = NULL;
1923 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1926 /* Enter a new action */
1930 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1934 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1935 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1938 prt(_("マクロ行動: ", "Action: "), 20, 0);
1940 /* Hack -- limit the value */
1943 /* Get an encoded action */
1944 if (!askfor(buf, 80)) continue;
1946 /* Extract an action */
1947 text_to_ascii(macro__buf, buf);
1963 * @brief キャラクタ色の明暗表現
1965 static concptr lighting_level_str[F_LIT_MAX] =
1980 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1981 * @param i 指定対象となるキャラクタコード
1982 * @param num 指定されたビジュアルIDを返す参照ポインタ
1983 * @param max ビジュアルIDの最大数
1984 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1986 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1993 sprintf(str, "%d", *num);
1995 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1998 tmp = (IDX)strtol(str, NULL, 0);
1999 if (tmp >= 0 && tmp < max)
2002 else if (isupper(i))
2003 *num = (*num + max - 1) % max;
2005 *num = (*num + 1) % max;
2011 * @brief キャラクタの変更メニュー表示
2012 * @param choice_msg 選択メッセージ
2015 static void print_visuals_menu(concptr choice_msg)
2017 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2019 /* Give some choices */
2020 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2021 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2022 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2023 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2024 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2025 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2026 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2027 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2028 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2029 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2030 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2033 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2038 * Interact with "visuals"
2040 void do_cmd_visuals(player_type *creature_ptr)
2045 bool need_redraw = FALSE;
2046 concptr empty_symbol = "<< ? >>";
2048 if (use_bigtile) empty_symbol = "<< ?? >>";
2050 /* File type is "TEXT" */
2051 FILE_TYPE(FILE_TYPE_TEXT);
2054 /* Interact until done */
2059 /* Ask for a choice */
2060 print_visuals_menu(NULL);
2065 if (i == ESCAPE) break;
2069 /* Load a 'pref' file */
2072 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2075 prt(_("ファイル: ", "File: "), 17, 0);
2077 /* Default filename */
2078 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2081 if (!askfor(tmp, 70)) continue;
2083 /* Process the given filename */
2084 (void)process_pref_file(creature_ptr, tmp);
2089 /* Dump monster attr/chars */
2092 static concptr mark = "Monster attr/chars";
2095 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2098 prt(_("ファイル: ", "File: "), 17, 0);
2100 /* Default filename */
2101 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2103 /* Get a filename */
2104 if (!askfor(tmp, 70)) continue;
2105 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2107 /* Append to the file */
2108 if (!open_auto_dump(buf, mark)) continue;
2111 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2114 for (i = 0; i < max_r_idx; i++)
2116 monster_race *r_ptr = &r_info[i];
2118 /* Skip non-entries */
2119 if (!r_ptr->name) continue;
2121 /* Dump a comment */
2122 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2124 /* Dump the monster attr/char info */
2125 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2126 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2132 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2137 /* Dump object attr/chars */
2140 static concptr mark = "Object attr/chars";
2141 KIND_OBJECT_IDX k_idx;
2144 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2147 prt(_("ファイル: ", "File: "), 17, 0);
2149 /* Default filename */
2150 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2152 /* Get a filename */
2153 if (!askfor(tmp, 70)) continue;
2154 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2156 /* Append to the file */
2157 if (!open_auto_dump(buf, mark)) continue;
2160 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2163 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2165 GAME_TEXT o_name[MAX_NLEN];
2166 object_kind *k_ptr = &k_info[k_idx];
2168 /* Skip non-entries */
2169 if (!k_ptr->name) continue;
2174 strip_name(o_name, k_idx);
2180 /* Prepare dummy object */
2181 object_prep(&forge, k_idx);
2183 /* Get un-shuffled flavor name */
2184 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2187 /* Dump a comment */
2188 auto_dump_printf("# %s\n", o_name);
2190 /* Dump the object attr/char info */
2191 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2192 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2198 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2203 /* Dump feature attr/chars */
2206 static concptr mark = "Feature attr/chars";
2209 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2212 prt(_("ファイル: ", "File: "), 17, 0);
2214 /* Default filename */
2215 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2217 /* Get a filename */
2218 if (!askfor(tmp, 70)) continue;
2219 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2221 /* Append to the file */
2222 if (!open_auto_dump(buf, mark)) continue;
2225 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2228 for (i = 0; i < max_f_idx; i++)
2230 feature_type *f_ptr = &f_info[i];
2232 /* Skip non-entries */
2233 if (!f_ptr->name) continue;
2235 /* Skip mimiccing features */
2236 if (f_ptr->mimic != i) continue;
2238 /* Dump a comment */
2239 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2241 /* Dump the feature attr/char info */
2242 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2243 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2244 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2245 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2251 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2256 /* Modify monster attr/chars (numeric operation) */
2259 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2260 static MONRACE_IDX r = 0;
2262 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2264 /* Hack -- query until done */
2267 monster_race *r_ptr = &r_info[r];
2271 TERM_COLOR da = r_ptr->d_attr;
2272 byte dc = r_ptr->d_char;
2273 TERM_COLOR ca = r_ptr->x_attr;
2274 byte cc = r_ptr->x_char;
2276 /* Label the object */
2277 Term_putstr(5, 17, -1, TERM_WHITE,
2278 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2280 /* Label the Default values */
2281 Term_putstr(10, 19, -1, TERM_WHITE,
2282 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2284 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2285 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2287 /* Label the Current values */
2288 Term_putstr(10, 20, -1, TERM_WHITE,
2289 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2291 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2292 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2295 Term_putstr(0, 22, -1, TERM_WHITE,
2296 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
2301 if (i == ESCAPE) break;
2303 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2304 else if (isupper(i)) c = 'a' + i - 'A';
2314 if (!cmd_visuals_aux(i, &r, max_r_idx))
2319 } while (!r_info[r].name);
2323 t = (int)r_ptr->x_attr;
2324 (void)cmd_visuals_aux(i, &t, 256);
2325 r_ptr->x_attr = (byte)t;
2329 t = (int)r_ptr->x_char;
2330 (void)cmd_visuals_aux(i, &t, 256);
2331 r_ptr->x_char = (byte)t;
2335 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2337 print_visuals_menu(choice_msg);
2345 /* Modify object attr/chars (numeric operation) */
2348 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2350 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2352 /* Hack -- query until done */
2355 object_kind *k_ptr = &k_info[k];
2359 TERM_COLOR da = k_ptr->d_attr;
2360 SYMBOL_CODE dc = k_ptr->d_char;
2361 TERM_COLOR ca = k_ptr->x_attr;
2362 SYMBOL_CODE cc = k_ptr->x_char;
2364 /* Label the object */
2365 Term_putstr(5, 17, -1, TERM_WHITE,
2366 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2367 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2369 /* Label the Default values */
2370 Term_putstr(10, 19, -1, TERM_WHITE,
2371 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2373 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2374 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2376 /* Label the Current values */
2377 Term_putstr(10, 20, -1, TERM_WHITE,
2378 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2380 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2381 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2384 Term_putstr(0, 22, -1, TERM_WHITE,
2385 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
2390 if (i == ESCAPE) break;
2392 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2393 else if (isupper(i)) c = 'a' + i - 'A';
2403 if (!cmd_visuals_aux(i, &k, max_k_idx))
2408 } while (!k_info[k].name);
2412 t = (int)k_ptr->x_attr;
2413 (void)cmd_visuals_aux(i, &t, 256);
2414 k_ptr->x_attr = (byte)t;
2418 t = (int)k_ptr->x_char;
2419 (void)cmd_visuals_aux(i, &t, 256);
2420 k_ptr->x_char = (byte)t;
2424 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2426 print_visuals_menu(choice_msg);
2434 /* Modify feature attr/chars (numeric operation) */
2437 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2439 static IDX lighting_level = F_LIT_STANDARD;
2440 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2442 /* Hack -- query until done */
2445 feature_type *f_ptr = &f_info[f];
2449 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2450 byte dc = f_ptr->d_char[lighting_level];
2451 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2452 byte cc = f_ptr->x_char[lighting_level];
2454 /* Label the object */
2456 Term_putstr(5, 17, -1, TERM_WHITE,
2457 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2458 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2460 /* Label the Default values */
2461 Term_putstr(10, 19, -1, TERM_WHITE,
2462 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2464 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2465 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2467 /* Label the Current values */
2469 Term_putstr(10, 20, -1, TERM_WHITE,
2470 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2472 Term_putstr(10, 20, -1, TERM_WHITE,
2473 format("Current attr/char = %3d / %3d", ca, cc));
2476 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2477 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2481 Term_putstr(0, 22, -1, TERM_WHITE,
2482 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2484 Term_putstr(0, 22, -1, TERM_WHITE,
2485 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2491 if (i == ESCAPE) break;
2493 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2494 else if (isupper(i)) c = 'a' + i - 'A';
2504 if (!cmd_visuals_aux(i, &f, max_f_idx))
2509 } while (!f_info[f].name || (f_info[f].mimic != f));
2513 t = (int)f_ptr->x_attr[lighting_level];
2514 (void)cmd_visuals_aux(i, &t, 256);
2515 f_ptr->x_attr[lighting_level] = (byte)t;
2519 t = (int)f_ptr->x_char[lighting_level];
2520 (void)cmd_visuals_aux(i, &t, 256);
2521 f_ptr->x_char[lighting_level] = (byte)t;
2525 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2528 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2532 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2534 print_visuals_menu(choice_msg);
2542 /* Modify monster attr/chars (visual mode) */
2544 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2547 /* Modify object attr/chars (visual mode) */
2549 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2552 /* Modify feature attr/chars (visual mode) */
2555 IDX lighting_level = F_LIT_STANDARD;
2556 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2564 reset_visuals(creature_ptr);
2566 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2570 /* Unknown option */
2581 if (need_redraw) do_cmd_redraw(creature_ptr);
2586 * Interact with "colors"
2588 void do_cmd_colors(player_type *creature_ptr)
2594 /* File type is "TEXT" */
2595 FILE_TYPE(FILE_TYPE_TEXT);
2599 /* Interact until done */
2604 /* Ask for a choice */
2605 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2607 /* Give some choices */
2608 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2609 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2610 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2613 prt(_("コマンド: ", "Command: "), 8, 0);
2617 if (i == ESCAPE) break;
2619 /* Load a 'pref' file */
2623 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2626 prt(_("ファイル: ", "File: "), 10, 0);
2629 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2632 if (!askfor(tmp, 70)) continue;
2634 /* Process the given filename */
2635 (void)process_pref_file(creature_ptr, tmp);
2637 /* Mega-Hack -- react to changes */
2638 Term_xtra(TERM_XTRA_REACT, 0);
2640 /* Mega-Hack -- redraw */
2647 static concptr mark = "Colors";
2650 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2653 prt(_("ファイル: ", "File: "), 10, 0);
2655 /* Default filename */
2656 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2658 /* Get a filename */
2659 if (!askfor(tmp, 70)) continue;
2660 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2662 /* Append to the file */
2663 if (!open_auto_dump(buf, mark)) continue;
2666 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2669 for (i = 0; i < 256; i++)
2671 int kv = angband_color_table[i][0];
2672 int rv = angband_color_table[i][1];
2673 int gv = angband_color_table[i][2];
2674 int bv = angband_color_table[i][3];
2676 concptr name = _("未知", "unknown");
2678 /* Skip non-entries */
2679 if (!kv && !rv && !gv && !bv) continue;
2681 /* Extract the color name */
2682 if (i < 16) name = color_names[i];
2684 /* Dump a comment */
2685 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2687 /* Dump the monster attr/char info */
2688 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2695 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2704 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2706 /* Hack -- query until done */
2713 /* Exhibit the normal colors */
2714 for (j = 0; j < 16; j++)
2716 /* Exhibit this color */
2717 Term_putstr(j * 4, 20, -1, a, "###");
2719 /* Exhibit all colors */
2720 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2723 /* Describe the color */
2724 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2726 /* Describe the color */
2727 Term_putstr(5, 10, -1, TERM_WHITE,
2728 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2730 /* Label the Current values */
2731 Term_putstr(5, 12, -1, TERM_WHITE,
2732 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2733 angband_color_table[a][0],
2734 angband_color_table[a][1],
2735 angband_color_table[a][2],
2736 angband_color_table[a][3]));
2739 Term_putstr(0, 14, -1, TERM_WHITE,
2740 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2745 if (i == ESCAPE) break;
2748 if (i == 'n') a = (byte)(a + 1);
2749 if (i == 'N') a = (byte)(a - 1);
2750 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2751 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2752 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2753 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2754 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2755 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2756 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2757 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2759 /* Hack -- react to changes */
2760 Term_xtra(TERM_XTRA_REACT, 0);
2762 /* Hack -- redraw */
2767 /* Unknown option */
2781 * Note something in the message recall
2783 void do_cmd_note(void)
2791 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2793 /* Ignore empty notes */
2794 if (!buf[0] || (buf[0] == ' ')) return;
2796 /* Add the note to the message recall */
2797 msg_format(_("メモ: %s", "Note: %s"), buf);
2802 * Mention the current version
2804 void do_cmd_version(void)
2806 #if FAKE_VER_EXTRA > 0
2807 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2808 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2810 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2811 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2817 * Array of feeling strings
2819 static concptr do_cmd_feeling_text[11] =
2821 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2822 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2823 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2824 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2825 _("とても悪い予感がする...", "You have a very bad feeling..."),
2826 _("悪い予感がする...", "You have a bad feeling..."),
2827 _("何か緊張する。", "You feel nervous."),
2828 _("少し不運な気がする...", "You feel your luck is turning..."),
2829 _("この場所は好きになれない。", "You don't like the look of this place."),
2830 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2831 _("なんて退屈なところだ...", "What a boring place...")
2834 static concptr do_cmd_feeling_text_combat[11] =
2836 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2837 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2838 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2839 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2840 _("とても悪い予感がする...", "You have a very bad feeling..."),
2841 _("悪い予感がする...", "You have a bad feeling..."),
2842 _("何か緊張する。", "You feel nervous."),
2843 _("少し不運な気がする...", "You feel your luck is turning..."),
2844 _("この場所は好きになれない。", "You don't like the look of this place."),
2845 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2846 _("なんて退屈なところだ...", "What a boring place...")
2849 static concptr do_cmd_feeling_text_lucky[11] =
2851 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2852 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2853 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2854 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2855 _("とても良い感じがする...", "You have a very good feeling..."),
2856 _("良い感じがする...", "You have a good feeling..."),
2857 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2858 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2859 _("見た感じ悪くはない...", "You like the look of this place..."),
2860 _("全然駄目ということはないが...", "This level can't be all bad..."),
2861 _("なんて退屈なところだ...", "What a boring place...")
2866 * Note that "feeling" is set to zero unless some time has passed.
2867 * Note that this is done when the level is GENERATED, not entered.
2869 void do_cmd_feeling(player_type *creature_ptr)
2871 if (creature_ptr->wild_mode) return;
2873 /* No useful feeling in quests */
2874 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2876 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2880 /* No useful feeling in town */
2881 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2883 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2885 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2889 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2893 /* No useful feeling in the wilderness */
2894 if (!creature_ptr->current_floor_ptr->dun_level)
2896 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2900 /* Display the feeling */
2901 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2902 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2903 else if (IS_ECHIZEN(creature_ptr))
2904 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2906 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2911 * Description of each monster group.
2913 static concptr monster_group_text[] =
2916 "ユニーク", /* "Uniques" */
2917 "乗馬可能なモンスター", /* "Riding" */
2918 "賞金首", /* "Wanted */
2919 "アンバーの王族", /* "Amberite" */
2948 /* "古代ドラゴン/ワイアーム", */
3009 /* "Ancient Dragon/Wyrm", */
3018 "Multi-Headed Reptile",
3023 "Reptile/Amphibian",
3024 "Spider/Scorpion/Tick",
3026 /* "Major Demon", */
3043 * Symbols of monsters in each group. Note the "Uniques" group
3044 * is handled differently.
3046 static concptr monster_group_char[] =
3103 "!$&()+./=>?[\\]`{|~",
3113 * todo 引数と戻り値について追記求む
3114 * Build a list of monster indexes in the given group.
3116 * mode & 0x01 : check for non-empty group
3117 * mode & 0x02 : visual operation only
3119 * @param creature_ptr プレーヤーへの参照ポインタ
3120 * @param grp_cur ???
3121 * @param mon_idx[] ???
3123 * @return The number of monsters in the group
3125 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3127 /* Get a list of x_char in this group */
3128 concptr group_char = monster_group_char[grp_cur];
3130 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3131 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3132 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3133 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3135 /* Check every race */
3137 for (IDX i = 0; i < max_r_idx; i++)
3139 /* Access the race */
3140 monster_race *r_ptr = &r_info[i];
3142 /* Skip empty race */
3143 if (!r_ptr->name) continue;
3145 /* Require known monsters */
3146 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3150 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3153 else if (grp_riding)
3155 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3158 else if (grp_wanted)
3160 bool wanted = FALSE;
3162 for (j = 0; j < MAX_BOUNTY; j++)
3164 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3165 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3171 if (!wanted) continue;
3174 else if (grp_amberite)
3176 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3181 /* Check for race in the group */
3182 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3186 mon_idx[mon_cnt++] = i;
3188 /* XXX Hack -- Just checking for non-empty group */
3189 if (mode & 0x01) break;
3192 /* Terminate the list */
3193 mon_idx[mon_cnt] = -1;
3196 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3198 /* Return the number of races */
3204 * Description of each monster group.
3206 static concptr object_group_text[] =
3209 "キノコ", /* "Mushrooms" */
3210 "薬", /* "Potions" */
3211 "油つぼ", /* "Flasks" */
3212 "巻物", /* "Scrolls" */
3214 "アミュレット", /* "Amulets" */
3215 "笛", /* "Whistle" */
3216 "光源", /* "Lanterns" */
3217 "魔法棒", /* "Wands" */
3220 "カード", /* "Cards" */
3231 "刀剣類", /* "Swords" */
3232 "鈍器", /* "Blunt Weapons" */
3233 "長柄武器", /* "Polearms" */
3234 "採掘道具", /* "Diggers" */
3235 "飛び道具", /* "Bows" */
3239 "軽装鎧", /* "Soft Armor" */
3240 "重装鎧", /* "Hard Armor" */
3241 "ドラゴン鎧", /* "Dragon Armor" */
3242 "盾", /* "Shields" */
3243 "クローク", /* "Cloaks" */
3244 "籠手", /* "Gloves" */
3245 "ヘルメット", /* "Helms" */
3247 "ブーツ", /* "Boots" */
3300 * TVALs of items in each group
3302 static byte object_group_tval[] =
3343 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3351 * Build a list of object indexes in the given group. Return the number
3352 * of objects in the group.
3354 * mode & 0x01 : check for non-empty group
3355 * mode & 0x02 : visual operation only
3357 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3359 KIND_OBJECT_IDX i, object_cnt = 0;
3362 /* Get a list of x_char in this group */
3363 byte group_tval = object_group_tval[grp_cur];
3365 /* Check every object */
3366 for (i = 0; i < max_k_idx; i++)
3368 /* Access the object */
3369 object_kind *k_ptr = &k_info[i];
3371 /* Skip empty objects */
3372 if (!k_ptr->name) continue;
3376 if (!current_world_ptr->wizard)
3378 /* Skip non-flavoured objects */
3379 if (!k_ptr->flavor) continue;
3381 /* Require objects ever seen */
3382 if (!k_ptr->aware) continue;
3385 /* Skip items with no distribution (special artifacts) */
3386 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3390 /* Check for objects in the group */
3391 if (TV_LIFE_BOOK == group_tval)
3393 /* Hack -- All spell books */
3394 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3396 /* Add the object */
3397 object_idx[object_cnt++] = i;
3401 else if (k_ptr->tval == group_tval)
3403 /* Add the object */
3404 object_idx[object_cnt++] = i;
3408 /* XXX Hack -- Just checking for non-empty group */
3409 if (mode & 0x01) break;
3412 /* Terminate the list */
3413 object_idx[object_cnt] = -1;
3415 /* Return the number of objects */
3421 * Description of each feature group.
3423 static concptr feature_group_text[] =
3431 * Build a list of feature indexes in the given group. Return the number
3432 * of features in the group.
3434 * mode & 0x01 : check for non-empty group
3436 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3438 /* Check every feature */
3439 FEAT_IDX feat_cnt = 0;
3440 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3442 feature_type *f_ptr = &f_info[i];
3444 /* Skip empty index */
3445 if (!f_ptr->name) continue;
3447 /* Skip mimiccing features */
3448 if (f_ptr->mimic != i) continue;
3451 feat_idx[feat_cnt++] = i;
3453 /* XXX Hack -- Just checking for non-empty group */
3454 if (mode & 0x01) break;
3457 /* Terminate the list */
3458 feat_idx[feat_cnt] = -1;
3460 /* Return the number of races */
3466 * Hack -- load a screen dump from a file
3468 void do_cmd_load_screen(void)
3472 SYMBOL_CODE c = ' ';
3478 Term_get_size(&wid, &hgt);
3479 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3481 /* Append to the file */
3482 fff = my_fopen(buf, "r");
3486 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3494 /* Load the screen */
3495 for (y = 0; okay; y++)
3497 /* Get a line of data including control code */
3498 if (!fgets(buf, 1024, fff)) okay = FALSE;
3500 /* Get the blank line */
3501 if (buf[0] == '\n' || buf[0] == '\0') break;
3503 /* Ignore too large screen image */
3504 if (y >= hgt) continue;
3507 for (x = 0; x < wid - 1; x++)
3510 if (buf[x] == '\n' || buf[x] == '\0') break;
3512 /* Put the attr/char */
3513 Term_draw(x, y, TERM_WHITE, buf[x]);
3517 /* Dump the screen */
3518 for (y = 0; okay; y++)
3520 /* Get a line of data including control code */
3521 if (!fgets(buf, 1024, fff)) okay = FALSE;
3523 /* Get the blank line */
3524 if (buf[0] == '\n' || buf[0] == '\0') break;
3526 /* Ignore too large screen image */
3527 if (y >= hgt) continue;
3530 for (x = 0; x < wid - 1; x++)
3533 if (buf[x] == '\n' || buf[x] == '\0') break;
3535 /* Get the attr/char */
3536 (void)(Term_what(x, y, &a, &c));
3538 /* Look up the attr */
3539 for (int i = 0; i < 16; i++)
3541 /* Use attr matches */
3542 if (hack[i] == buf[x]) a = (byte)i;
3545 /* Put the attr/char */
3546 Term_draw(x, y, a, c);
3552 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3560 // todo なぜこんな中途半端なところに? defineも…
3561 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3562 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3564 #define IM_FLAG_STR _("*", "* ")
3565 #define HAS_FLAG_STR _("+", "+ ")
3566 #define NO_FLAG_STR _("・", ". ")
3568 #define print_im_or_res_flag(IM, RES) \
3570 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3571 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3574 #define print_flag(TR) \
3576 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3580 /* XTRA HACK RESLIST */
3581 static void do_cmd_knowledge_inven_aux(player_type *creature_ptr, FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
3583 GAME_TEXT o_name[MAX_NLEN];
3584 BIT_FLAGS flgs[TR_FLAG_SIZE];
3586 if (!o_ptr->k_idx) return;
3587 if (o_ptr->tval != tval) return;
3589 /* Identified items only */
3590 if (!object_is_known(o_ptr)) return;
3593 * HACK:Ring of Lordly protection and Dragon equipment
3594 * have random resistances.
3596 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3597 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3598 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3599 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3600 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3601 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3602 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3603 || object_is_artifact(o_ptr);
3604 if (!is_special_item_type)
3610 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3612 while (o_name[i] && (i < 26))
3615 if (iskanji(o_name[i])) i++;
3624 o_name[i] = ' '; i++;
3630 fprintf(fff, "%s %s", where, o_name);
3632 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
3634 fputs(_("-------不明--------------- -------不明---------\n",
3635 "-------unknown------------ -------unknown------\n"), fff);
3639 object_flags_known(o_ptr, flgs);
3641 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3642 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3643 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3644 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3645 print_flag(TR_RES_POIS);
3646 print_flag(TR_RES_LITE);
3647 print_flag(TR_RES_DARK);
3648 print_flag(TR_RES_SHARDS);
3649 print_flag(TR_RES_SOUND);
3650 print_flag(TR_RES_NETHER);
3651 print_flag(TR_RES_NEXUS);
3652 print_flag(TR_RES_CHAOS);
3653 print_flag(TR_RES_DISEN);
3657 print_flag(TR_RES_BLIND);
3658 print_flag(TR_RES_FEAR);
3659 print_flag(TR_RES_CONF);
3660 print_flag(TR_FREE_ACT);
3661 print_flag(TR_SEE_INVIS);
3662 print_flag(TR_HOLD_EXP);
3663 print_flag(TR_TELEPATHY);
3664 print_flag(TR_SLOW_DIGEST);
3665 print_flag(TR_REGEN);
3666 print_flag(TR_LEVITATION);
3675 fprintf(fff, "%s\n", inven_res_label);
3680 * Display *ID* ed weapons/armors's resistances
3682 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3685 GAME_TEXT file_name[1024];
3687 OBJECT_TYPE_VALUE tval;
3693 /* Open a new file */
3694 fff = my_fopen_temp(file_name, 1024);
3697 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3702 fprintf(fff, "%s\n", inven_res_label);
3704 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3708 for (; j < 9; j++) fputc('\n', fff);
3710 fprintf(fff, "%s\n", inven_res_label);
3713 strcpy(where, _("装", "E "));
3714 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3716 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3719 strcpy(where, _("持", "I "));
3720 for (i = 0; i < INVEN_PACK; i++)
3722 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3725 st_ptr = &town_info[1].store[STORE_HOME];
3726 strcpy(where, _("家", "H "));
3727 for (i = 0; i < st_ptr->stock_num; i++)
3729 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3735 /* Display the file contents */
3736 (void)show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3741 void do_cmd_save_screen_html_aux(char *filename, int message)
3749 concptr html_head[] = {
3750 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3754 concptr html_foot[] = {
3756 "</body>\n</html>\n",
3761 Term_get_size(&wid, &hgt);
3763 /* File type is "TEXT" */
3764 FILE_TYPE(FILE_TYPE_TEXT);
3766 /* Append to the file */
3768 fff = my_fopen(filename, "w");
3774 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3781 if (message) screen_save();
3783 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3785 tmpfff = my_fopen(buf, "r");
3788 for (int i = 0; html_head[i]; i++)
3789 fputs(html_head[i], fff);
3793 bool is_first_line = TRUE;
3794 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3798 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3799 is_first_line = FALSE;
3803 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3805 fprintf(fff, "%s\n", buf);
3810 /* Dump the screen */
3811 for (TERM_LEN y = 0; y < hgt; y++)
3814 if (y != 0) fprintf(fff, "\n");
3817 TERM_COLOR a = 0, old_a = 0;
3819 for (TERM_LEN x = 0; x < wid - 1; x++)
3822 /* Get the attr/char */
3823 (void)(Term_what(x, y, &a, &c));
3827 case '&': cc = "&"; break;
3828 case '<': cc = "<"; break;
3829 case '>': cc = ">"; break;
3831 case 0x1f: c = '.'; break;
3832 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3837 if ((y == 0 && x == 0) || a != old_a)
3839 int rv = angband_color_table[a][1];
3840 int gv = angband_color_table[a][2];
3841 int bv = angband_color_table[a][3];
3842 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3843 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3848 fprintf(fff, "%s", cc);
3850 fprintf(fff, "%c", c);
3854 fprintf(fff, "</font>");
3858 for (int i = 0; html_foot[i]; i++)
3859 fputs(html_foot[i], fff);
3864 bool is_first_line = TRUE;
3865 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3869 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3870 is_first_line = FALSE;
3874 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3876 fprintf(fff, "%s\n", buf);
3889 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3898 * Hack -- save a screen dump to a file
3900 static void do_cmd_save_screen_html(void)
3902 char buf[1024], tmp[256] = "screen.html";
3904 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3906 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3910 do_cmd_save_screen_html_aux(buf, 1);
3915 * Redefinable "save_screen" action
3917 void(*screendump_aux)(void) = NULL;
3921 * Save a screen dump to a file
3922 * @param creature_ptr プレーヤーへの参照ポインタ
3925 void do_cmd_save_screen(player_type *creature_ptr)
3927 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3928 bool html_dump = FALSE;
3932 if (c == 'Y' || c == 'y')
3934 else if (c == 'H' || c == 'h')
3947 Term_get_size(&wid, &hgt);
3949 bool old_use_graphics = use_graphics;
3950 if (old_use_graphics)
3952 use_graphics = FALSE;
3953 reset_visuals(creature_ptr);
3954 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3955 handle_stuff(creature_ptr);
3960 do_cmd_save_screen_html();
3961 do_cmd_redraw(creature_ptr);
3964 /* Do we use a special screendump function ? */
3965 else if (screendump_aux)
3967 /* Dump the screen to a graphics file */
3968 (*screendump_aux)();
3970 else /* Dump the screen as text */
3974 SYMBOL_CODE c = ' ';
3977 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3979 /* File type is "TEXT" */
3980 FILE_TYPE(FILE_TYPE_TEXT);
3982 /* Append to the file */
3983 fff = my_fopen(buf, "w");
3987 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3994 /* Dump the screen */
3995 for (y = 0; y < hgt; y++)
3998 for (x = 0; x < wid - 1; x++)
4000 /* Get the attr/char */
4001 (void)(Term_what(x, y, &a, &c));
4011 fprintf(fff, "%s\n", buf);
4018 /* Dump the screen */
4019 for (y = 0; y < hgt; y++)
4022 for (x = 0; x < wid - 1; x++)
4024 /* Get the attr/char */
4025 (void)(Term_what(x, y, &a, &c));
4028 buf[x] = hack[a & 0x0F];
4035 fprintf(fff, "%s\n", buf);
4042 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4047 if (!old_use_graphics) return;
4049 use_graphics = TRUE;
4050 reset_visuals(creature_ptr);
4051 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4052 handle_stuff(creature_ptr);
4057 * todo okay = 既知のアーティファクト? と思われるが確証がない
4058 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4059 * Check the status of "artifacts"
4060 * @param player_ptr プレーヤーへの参照ポインタ
4063 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4065 /* Open a new file */
4067 GAME_TEXT file_name[1024];
4068 fff = my_fopen_temp(file_name, 1024);
4071 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4076 /* Allocate the "who" array */
4078 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4080 /* Allocate the "okay" array */
4082 C_MAKE(okay, max_a_idx, bool);
4084 /* Scan the artifacts */
4085 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4087 artifact_type *a_ptr = &a_info[k];
4092 /* Skip "empty" artifacts */
4093 if (!a_ptr->name) continue;
4095 /* Skip "uncreated" artifacts */
4096 if (!a_ptr->cur_num) continue;
4102 /* Check the dungeon */
4103 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4105 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4107 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4109 OBJECT_IDX this_o_idx, next_o_idx = 0;
4111 /* Scan all objects in the grid */
4112 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4115 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4116 next_o_idx = o_ptr->next_o_idx;
4118 /* Ignore non-artifacts */
4119 if (!object_is_fixed_artifact(o_ptr)) continue;
4121 /* Ignore known items */
4122 if (object_is_known(o_ptr)) continue;
4124 /* Note the artifact */
4125 okay[o_ptr->name1] = FALSE;
4130 /* Check the player_ptr->inventory_list and equipment */
4131 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4133 object_type *o_ptr = &player_ptr->inventory_list[i];
4135 /* Ignore non-objects */
4136 if (!o_ptr->k_idx) continue;
4138 /* Ignore non-artifacts */
4139 if (!object_is_fixed_artifact(o_ptr)) continue;
4141 /* Ignore known items */
4142 if (object_is_known(o_ptr)) continue;
4144 /* Note the artifact */
4145 okay[o_ptr->name1] = FALSE;
4149 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4151 if (okay[k]) who[n++] = k;
4155 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4157 /* Scan the artifacts */
4158 for (ARTIFACT_IDX k = 0; k < n; k++)
4160 artifact_type *a_ptr = &a_info[who[k]];
4161 GAME_TEXT base_name[MAX_NLEN];
4162 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4164 /* Obtain the base object type */
4165 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4174 /* Create fake object */
4175 object_prep(q_ptr, z);
4177 /* Make it an artifact */
4178 q_ptr->name1 = (byte)who[k];
4180 /* Display as if known */
4181 q_ptr->ident |= IDENT_STORE;
4183 /* Describe the artifact */
4184 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4187 /* Hack -- Build the artifact name */
4188 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4191 /* Free the "who" array */
4192 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4194 /* Free the "okay" array */
4195 C_KILL(okay, max_a_idx, bool);
4198 /* Display the file contents */
4199 (void)show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4205 * Display known uniques
4206 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4208 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4215 GAME_TEXT file_name[1024];
4218 int n_alive_surface = 0;
4219 int n_alive_over100 = 0;
4220 int n_alive_total = 0;
4223 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4225 /* Open a new file */
4226 fff = my_fopen_temp(file_name, 1024);
4230 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4235 /* Allocate the "who" array */
4236 C_MAKE(who, max_r_idx, MONRACE_IDX);
4238 /* Scan the monsters */
4240 for (IDX i = 1; i < max_r_idx; i++)
4242 monster_race *r_ptr = &r_info[i];
4245 if (!r_ptr->name) continue;
4247 /* Require unique monsters */
4248 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4250 /* Only display "known" uniques */
4251 if (!cheat_know && !r_ptr->r_sights) continue;
4253 /* Only print rarity <= 100 uniques */
4254 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4256 /* Only "alive" uniques */
4257 if (r_ptr->max_num == 0) continue;
4261 lev = (r_ptr->level - 1) / 10;
4265 if (max_lev < lev) max_lev = lev;
4267 else n_alive_over100++;
4269 else n_alive_surface++;
4271 /* Collect "appropriate" monsters */
4275 /* Sort the array by dungeon depth of monsters */
4276 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4278 if (n_alive_surface)
4280 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4281 n_alive_total += n_alive_surface;
4284 for (IDX i = 0; i <= max_lev; i++)
4286 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4287 n_alive_total += n_alive[i];
4290 if (n_alive_over100)
4292 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4293 n_alive_total += n_alive_over100;
4298 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4299 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4303 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4306 /* Scan the monster races */
4307 for (int k = 0; k < n; k++)
4309 monster_race *r_ptr = &r_info[who[k]];
4310 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4313 /* Free the "who" array */
4314 C_KILL(who, max_r_idx, s16b);
4317 /* Display the file contents */
4318 (void)show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4324 * Display weapon-exp
4326 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4328 /* Open a new file */
4330 GAME_TEXT file_name[1024];
4331 fff = my_fopen_temp(file_name, 1024);
4334 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4339 for (int i = 0; i < 5; i++)
4341 for (int num = 0; num < 64; num++)
4345 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4347 object_kind *k_ptr = &k_info[j];
4349 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4350 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4352 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4354 fprintf(fff, "%-25s ", tmp);
4355 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4356 else fprintf(fff, " ");
4357 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4358 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4367 /* Display the file contents */
4368 (void)show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4374 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4378 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4380 /* Open a new file */
4382 GAME_TEXT file_name[1024];
4383 fff = my_fopen_temp(file_name, 1024);
4386 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4391 if (creature_ptr->realm1 != REALM_NONE)
4393 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4394 for (SPELL_IDX i = 0; i < 32; i++)
4396 const magic_type *s_ptr;
4397 if (!is_magic(creature_ptr->realm1))
4399 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4403 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4406 if (s_ptr->slevel >= 99) continue;
4407 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4408 int exp_level = spell_exp_level(spell_exp);
4409 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4410 if (creature_ptr->realm1 == REALM_HISSATSU)
4411 fprintf(fff, "[--]");
4414 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4415 else fprintf(fff, " ");
4416 fprintf(fff, "%s", exp_level_str[exp_level]);
4419 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4424 if (creature_ptr->realm2 != REALM_NONE)
4426 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4427 for (SPELL_IDX i = 0; i < 32; i++)
4429 const magic_type *s_ptr;
4430 if (!is_magic(creature_ptr->realm1))
4432 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4436 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4439 if (s_ptr->slevel >= 99) continue;
4441 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4442 int exp_level = spell_exp_level(spell_exp);
4443 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4444 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4445 else fprintf(fff, " ");
4446 fprintf(fff, "%s", exp_level_str[exp_level]);
4447 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4454 /* Display the file contents */
4455 (void)show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4461 * @brief スキル情報を表示するコマンドのメインルーチン /
4465 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4467 char skill_name[GINOU_TEMPMAX][20] =
4469 _("マーシャルアーツ", "Martial Arts "),
4470 _("二刀流 ", "Dual Wielding "),
4471 _("乗馬 ", "Riding "),
4475 /* Open a new file */
4477 char file_name[1024];
4478 fff = my_fopen_temp(file_name, 1024);
4481 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4486 for (int i = 0; i < GINOU_TEMPMAX; i++)
4488 int skill_exp = creature_ptr->skill_exp[i];
4489 fprintf(fff, "%-20s ", skill_name[i]);
4490 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4491 else fprintf(fff, " ");
4492 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4493 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4499 /* Display the file contents */
4500 (void)show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4506 * @brief 現在のペットを表示するコマンドのメインルーチン /
4507 * Display current pets
4508 * @param creature_ptr プレーヤーへの参照ポインタ
4511 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4513 /* Open a new file */
4514 GAME_TEXT file_name[1024];
4516 fff = my_fopen_temp(file_name, 1024);
4519 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4524 /* Process the monsters (backwards) */
4525 monster_type *m_ptr;
4526 GAME_TEXT pet_name[MAX_NLEN];
4528 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4530 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4532 /* Ignore "dead" monsters */
4533 if (!monster_is_valid(m_ptr)) continue;
4535 /* Calculate "upkeep" for pets */
4536 if (!is_pet(m_ptr)) continue;
4539 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4540 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4543 int show_upkeep = calculate_upkeep(creature_ptr);
4545 fprintf(fff, "----------------------------------------------\n");
4547 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4549 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4551 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4555 /* Display the file contents */
4556 (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4562 * @brief 現在のペットを表示するコマンドのメインルーチン /
4563 * @param creature_ptr プレーヤーへの参照ポインタ
4566 * @note the player ghosts are ignored.
4568 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4570 /* Open a new file */
4572 GAME_TEXT file_name[1024];
4573 fff = my_fopen_temp(file_name, 1024);
4576 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4581 /* Allocate the "who" array */
4583 C_MAKE(who, max_r_idx, MONRACE_IDX);
4587 /* Monsters slain */
4588 for (int kk = 1; kk < max_r_idx; kk++)
4590 monster_race *r_ptr = &r_info[kk];
4592 if (r_ptr->flags1 & (RF1_UNIQUE))
4594 bool dead = (r_ptr->max_num == 0);
4603 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4605 if (this_monster > 0)
4607 total += this_monster;
4613 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4616 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4618 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4624 /* Scan the monsters */
4626 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4628 monster_race *r_ptr = &r_info[i];
4630 /* Use that monster */
4631 if (r_ptr->name) who[n++] = i;
4634 /* Sort the array by dungeon depth of monsters */
4636 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4638 /* Scan the monster races */
4639 for (int k = 0; k < n; k++)
4641 monster_race *r_ptr = &r_info[who[k]];
4643 if (r_ptr->flags1 & (RF1_UNIQUE))
4645 bool dead = (r_ptr->max_num == 0);
4649 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4656 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4658 if (this_monster <= 0) continue;
4661 /* p,tは人と数える by ita */
4662 if (my_strchr("pt", r_ptr->d_char))
4663 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4665 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4667 if (this_monster < 2)
4669 if (my_strstr(r_name + r_ptr->name, "coins"))
4671 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4675 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4681 strcpy(ToPlural, (r_name + r_ptr->name));
4682 plural_aux(ToPlural);
4683 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4686 total += this_monster;
4689 fprintf(fff, "----------------------------------------------\n");
4691 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4693 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4696 /* Free the "who" array */
4697 C_KILL(who, max_r_idx, s16b);
4700 /* Display the file contents */
4701 (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4707 * @brief モンスター情報リスト中のグループを表示する /
4708 * Display the object groups.
4712 * @param per_page リストの表示行
4713 * @param grp_idx グループのID配列
4714 * @param group_text グループ名の文字列配列
4715 * @param grp_cur 現在の選択ID
4716 * @param grp_top 現在の選択リスト最上部ID
4719 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)
4721 /* Display lines until done */
4722 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4724 /* Get the group index */
4725 int grp = grp_idx[grp_top + i];
4727 /* Choose a color */
4728 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4730 /* Erase the entire line */
4731 Term_erase(col, row + i, wid);
4733 /* Display the group label */
4734 c_put_str(attr, group_text[grp], row + i, col);
4740 * Move the cursor in a browser window
4742 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4743 IDX *list_cur, int list_cnt)
4748 IDX list = *list_cur;
4750 /* Extract direction */
4753 /* Hack -- scroll up full screen */
4758 /* Hack -- scroll down full screen */
4763 d = get_keymap_dir(ch);
4768 /* Diagonals - hack */
4769 if ((ddx[d] > 0) && ddy[d])
4774 Term_get_size(&wid, &hgt);
4776 browser_rows = hgt - 8;
4778 /* Browse group list */
4783 /* Move up or down */
4784 grp += ddy[d] * (browser_rows - 1);
4787 if (grp >= grp_cnt) grp = grp_cnt - 1;
4788 if (grp < 0) grp = 0;
4789 if (grp != old_grp) list = 0;
4792 /* Browse sub-list list */
4795 /* Move up or down */
4796 list += ddy[d] * browser_rows;
4799 if (list >= list_cnt) list = list_cnt - 1;
4800 if (list < 0) list = 0;
4812 if (col < 0) col = 0;
4813 if (col > 1) col = 1;
4820 /* Browse group list */
4825 /* Move up or down */
4829 if (grp >= grp_cnt) grp = grp_cnt - 1;
4830 if (grp < 0) grp = 0;
4831 if (grp != old_grp) list = 0;
4834 /* Browse sub-list list */
4837 /* Move up or down */
4838 list += (IDX)ddy[d];
4841 if (list >= list_cnt) list = list_cnt - 1;
4842 if (list < 0) list = 0;
4853 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4855 /* Clear the display lines */
4856 for (int i = 0; i < height; i++)
4858 Term_erase(col, row + i, width);
4861 /* Bigtile mode uses double width */
4862 if (use_bigtile) width /= 2;
4864 /* Display lines until done */
4865 for (int i = 0; i < height; i++)
4867 /* Display columns until done */
4868 for (int j = 0; j < width; j++)
4870 TERM_LEN x = col + j;
4871 TERM_LEN y = row + i;
4873 /* Bigtile mode uses double width */
4874 if (use_bigtile) x += j;
4876 TERM_COLOR ia = attr_top + i;
4877 SYMBOL_CODE ic = char_left + j;
4879 /* Ignore illegal characters */
4880 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4881 (!use_graphics && ic > 0x7f))
4887 /* Force correct code for both ASCII character and tile */
4888 if (c & 0x80) a |= 0x80;
4890 /* Display symbol */
4891 Term_queue_bigchar(x, y, a, c, 0, 0);
4898 * Place the cursor at the collect position for visual mode
4900 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4902 int i = (a & 0x7f) - attr_top;
4903 int j = c - char_left;
4905 TERM_LEN x = col + j;
4906 TERM_LEN y = row + i;
4908 /* Bigtile mode uses double width */
4909 if (use_bigtile) x += j;
4911 /* Place the cursor */
4917 * Do visual mode command -- Change symbols
4919 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4920 int height, int width,
4921 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4922 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4924 static TERM_COLOR attr_old = 0;
4925 static SYMBOL_CODE char_old = 0;
4930 if (*visual_list_ptr)
4933 *cur_attr_ptr = attr_old;
4934 *cur_char_ptr = char_old;
4935 *visual_list_ptr = FALSE;
4943 if (*visual_list_ptr)
4946 *visual_list_ptr = FALSE;
4947 *need_redraw = TRUE;
4955 if (!*visual_list_ptr)
4957 *visual_list_ptr = TRUE;
4959 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4960 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4962 attr_old = *cur_attr_ptr;
4963 char_old = *cur_char_ptr;
4974 /* Set the visual */
4975 attr_idx = *cur_attr_ptr;
4976 char_idx = *cur_char_ptr;
4978 /* Hack -- for feature lighting */
4979 for (i = 0; i < F_LIT_MAX; i++)
4981 attr_idx_feat[i] = 0;
4982 char_idx_feat[i] = 0;
4989 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4992 *cur_attr_ptr = attr_idx;
4993 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4994 if (!*visual_list_ptr) *need_redraw = TRUE;
5000 *cur_char_ptr = char_idx;
5001 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5002 if (!*visual_list_ptr) *need_redraw = TRUE;
5008 if (*visual_list_ptr)
5011 int d = get_keymap_dir(ch);
5012 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5013 SYMBOL_CODE c = *cur_char_ptr;
5015 if (use_bigtile) eff_width = width / 2;
5016 else eff_width = width;
5018 /* Restrict direction */
5019 if ((a == 0) && (ddy[d] < 0)) d = 0;
5020 if ((c == 0) && (ddx[d] < 0)) d = 0;
5021 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5022 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5024 a += (TERM_COLOR)ddy[d];
5025 c += (SYMBOL_CODE)ddx[d];
5027 /* Force correct code for both ASCII character and tile */
5028 if (c & 0x80) a |= 0x80;
5030 /* Set the visual */
5035 /* Move the frame */
5036 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5037 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5038 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5039 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5045 /* Visual mode command is not used */
5051 * Display the monsters in a group.
5053 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5054 int mon_cur, int mon_top, bool visual_only)
5056 /* Display lines until done */
5058 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5062 /* Get the race index */
5063 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5065 /* Access the race */
5066 monster_race *r_ptr = &r_info[r_idx];
5068 /* Choose a color */
5069 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5071 /* Display the name */
5072 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5074 /* Hack -- visual_list mode */
5077 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5080 if (current_world_ptr->wizard || visual_only)
5082 c_prt(attr, format("%d", r_idx), row + i, 62);
5085 /* Erase chars before overwritten by the race letter */
5086 Term_erase(69, row + i, 255);
5088 /* Display symbol */
5089 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5094 if (!(r_ptr->flags1 & RF1_UNIQUE))
5095 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5097 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5098 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5102 /* Clear remaining lines */
5103 for (; i < per_page; i++)
5105 Term_erase(col, row + i, 255);
5111 * todo 引数の詳細について加筆求む
5112 * Display known monsters.
5113 * @param creature_ptr プレーヤーへの参照ポインタ
5114 * @param need_redraw 画面の再描画が必要な時TRUE
5115 * @param visual_only ???
5116 * @param direct_r_idx モンスターID
5119 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5122 Term_get_size(&wid, &hgt);
5124 /* Allocate the "mon_idx" array */
5126 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5132 bool visual_list = FALSE;
5133 TERM_COLOR attr_top = 0;
5136 int browser_rows = hgt - 8;
5137 if (direct_r_idx < 0)
5139 mode = visual_only ? 0x03 : 0x01;
5141 /* Check every group */
5143 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5145 /* Measure the label */
5146 len = strlen(monster_group_text[i]);
5148 /* Save the maximum length */
5149 if (len > max) max = len;
5151 /* See if any monsters are known */
5152 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5154 /* Build a list of groups with known monsters */
5155 grp_idx[grp_cnt++] = i;
5163 mon_idx[0] = direct_r_idx;
5166 /* Terminate the list */
5169 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5170 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5173 /* Terminate the list */
5174 grp_idx[grp_cnt] = -1;
5176 mode = visual_only ? 0x02 : 0x00;
5177 IDX old_grp_cur = -1;
5190 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5191 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5192 prt(_("名前", "Name"), 4, max + 3);
5193 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5194 prt(_("文字", "Sym"), 4, 67);
5195 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5197 for (IDX i = 0; i < 78; i++)
5199 Term_putch(i, 5, TERM_WHITE, '=');
5202 if (direct_r_idx < 0)
5204 for (IDX i = 0; i < browser_rows; i++)
5206 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5213 if (direct_r_idx < 0)
5215 /* Scroll group list */
5216 if (grp_cur < grp_top) grp_top = grp_cur;
5217 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5219 /* Display a list of monster groups */
5220 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5222 if (old_grp_cur != grp_cur)
5224 old_grp_cur = grp_cur;
5226 /* Get a list of monsters in the current group */
5227 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5230 /* Scroll monster list */
5231 while (mon_cur < mon_top)
5232 mon_top = MAX(0, mon_top - browser_rows / 2);
5233 while (mon_cur >= mon_top + browser_rows)
5234 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5239 /* Display a list of monsters in the current group */
5240 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5246 /* Display a monster name */
5247 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5249 /* Display visual list below first monster */
5250 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5254 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5255 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5256 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5257 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5260 /* Get the current monster */
5261 monster_race *r_ptr;
5262 r_ptr = &r_info[mon_idx[mon_cur]];
5266 /* Mega Hack -- track this monster race */
5267 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5268 handle_stuff(creature_ptr);
5273 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5277 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5281 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5286 /* Do visual mode command if needed */
5287 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))
5289 if (direct_r_idx >= 0)
5315 /* Recall on screen */
5316 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5318 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5330 /* Move the cursor */
5331 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5338 /* Free the "mon_idx" array */
5339 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5344 * Display the objects in a group.
5346 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5347 int object_cur, int object_top, bool visual_only)
5349 /* Display lines until done */
5351 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5353 GAME_TEXT o_name[MAX_NLEN];
5356 object_kind *flavor_k_ptr;
5358 /* Get the object index */
5359 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5361 /* Access the object */
5362 object_kind *k_ptr = &k_info[k_idx];
5364 /* Choose a color */
5365 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5366 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5368 if (!visual_only && k_ptr->flavor)
5370 /* Appearance of this object is shuffled */
5371 flavor_k_ptr = &k_info[k_ptr->flavor];
5375 /* Appearance of this object is very normal */
5376 flavor_k_ptr = k_ptr;
5379 attr = ((i + object_top == object_cur) ? cursor : attr);
5381 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5384 strip_name(o_name, k_idx);
5389 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5392 /* Display the name */
5393 c_prt(attr, o_name, row + i, col);
5395 /* Hack -- visual_list mode */
5398 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);
5401 if (current_world_ptr->wizard || visual_only)
5403 c_prt(attr, format("%d", k_idx), row + i, 70);
5406 a = flavor_k_ptr->x_attr;
5407 c = flavor_k_ptr->x_char;
5409 /* Display symbol */
5410 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5413 /* Clear remaining lines */
5414 for (; i < per_page; i++)
5416 Term_erase(col, row + i, 255);
5422 * Describe fake object
5424 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5427 object_type object_type_body;
5428 o_ptr = &object_type_body;
5430 object_prep(o_ptr, k_idx);
5432 /* It's fully know */
5433 o_ptr->ident |= IDENT_KNOWN;
5434 handle_stuff(creature_ptr);
5436 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5438 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5444 * Display known objects
5446 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5448 IDX object_old, object_top;
5451 OBJECT_IDX *object_idx;
5453 bool visual_list = FALSE;
5454 TERM_COLOR attr_top = 0;
5459 Term_get_size(&wid, &hgt);
5461 int browser_rows = hgt - 8;
5463 /* Allocate the "object_idx" array */
5464 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5469 if (direct_k_idx < 0)
5471 mode = visual_only ? 0x03 : 0x01;
5473 /* Check every group */
5474 for (IDX i = 0; object_group_text[i] != NULL; i++)
5476 /* Measure the label */
5477 len = strlen(object_group_text[i]);
5479 /* Save the maximum length */
5480 if (len > max) max = len;
5482 /* See if any monsters are known */
5483 if (collect_objects(i, object_idx, mode))
5485 /* Build a list of groups with known monsters */
5486 grp_idx[grp_cnt++] = i;
5495 object_kind *k_ptr = &k_info[direct_k_idx];
5496 object_kind *flavor_k_ptr;
5498 if (!visual_only && k_ptr->flavor)
5500 /* Appearance of this object is shuffled */
5501 flavor_k_ptr = &k_info[k_ptr->flavor];
5505 /* Appearance of this object is very normal */
5506 flavor_k_ptr = k_ptr;
5509 object_idx[0] = direct_k_idx;
5510 object_old = direct_k_idx;
5513 /* Terminate the list */
5516 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5517 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5520 /* Terminate the list */
5521 grp_idx[grp_cnt] = -1;
5523 mode = visual_only ? 0x02 : 0x00;
5524 IDX old_grp_cur = -1;
5527 IDX object_cur = object_top = 0;
5533 object_kind *k_ptr, *flavor_k_ptr;
5540 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5541 if (direct_k_idx < 0) prt("グループ", 4, 0);
5542 prt("名前", 4, max + 3);
5543 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5546 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5547 if (direct_k_idx < 0) prt("Group", 4, 0);
5548 prt("Name", 4, max + 3);
5549 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5553 for (IDX i = 0; i < 78; i++)
5555 Term_putch(i, 5, TERM_WHITE, '=');
5558 if (direct_k_idx < 0)
5560 for (IDX i = 0; i < browser_rows; i++)
5562 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5569 if (direct_k_idx < 0)
5571 /* Scroll group list */
5572 if (grp_cur < grp_top) grp_top = grp_cur;
5573 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5575 /* Display a list of object groups */
5576 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5578 if (old_grp_cur != grp_cur)
5580 old_grp_cur = grp_cur;
5582 /* Get a list of objects in the current group */
5583 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5586 /* Scroll object list */
5587 while (object_cur < object_top)
5588 object_top = MAX(0, object_top - browser_rows / 2);
5589 while (object_cur >= object_top + browser_rows)
5590 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5595 /* Display a list of objects in the current group */
5596 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5600 object_top = object_cur;
5602 /* Display a list of objects in the current group */
5603 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5605 /* Display visual list below first object */
5606 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5609 /* Get the current object */
5610 k_ptr = &k_info[object_idx[object_cur]];
5612 if (!visual_only && k_ptr->flavor)
5614 /* Appearance of this object is shuffled */
5615 flavor_k_ptr = &k_info[k_ptr->flavor];
5619 /* Appearance of this object is very normal */
5620 flavor_k_ptr = k_ptr;
5625 prt(format("<方向>%s%s%s, ESC",
5626 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5627 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5628 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5631 prt(format("<dir>%s%s%s, ESC",
5632 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5633 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5634 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5640 /* Mega Hack -- track this object */
5641 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5643 /* The "current" object changed */
5644 if (object_old != object_idx[object_cur])
5646 handle_stuff(creature_ptr);
5648 /* Remember the "current" object */
5649 object_old = object_idx[object_cur];
5655 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5659 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5663 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5668 /* Do visual mode command if needed */
5669 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))
5671 if (direct_k_idx >= 0)
5696 /* Recall on screen */
5697 if (!visual_list && !visual_only && (grp_cnt > 0))
5699 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5707 /* Move the cursor */
5708 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5714 /* Free the "object_idx" array */
5715 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5720 * Display the features in a group.
5722 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5723 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5725 int lit_col[F_LIT_MAX], i;
5726 int f_idx_col = use_bigtile ? 62 : 64;
5728 /* Correct columns 1 and 4 */
5729 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5730 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5731 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5733 /* Display lines until done */
5734 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5737 FEAT_IDX f_idx = feat_idx[feat_top + i];
5738 feature_type *f_ptr = &f_info[f_idx];
5739 int row_i = row + i;
5741 /* Choose a color */
5742 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5744 /* Display the name */
5745 c_prt(attr, f_name + f_ptr->name, row_i, col);
5747 /* Hack -- visual_list mode */
5750 /* Display lighting level */
5751 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5753 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));
5755 if (current_world_ptr->wizard || visual_only)
5757 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5760 /* Display symbol */
5761 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);
5763 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5764 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5766 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5768 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5770 /* Mega-hack -- Use non-standard colour */
5771 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5773 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5777 /* Clear remaining lines */
5778 for (; i < per_page; i++)
5780 Term_erase(col, row + i, 255);
5786 * Interact with feature visuals.
5788 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5790 TERM_COLOR attr_old[F_LIT_MAX];
5791 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5792 SYMBOL_CODE char_old[F_LIT_MAX];
5793 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5796 Term_get_size(&wid, &hgt);
5798 /* Allocate the "feat_idx" array */
5800 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5806 FEAT_IDX grp_idx[100];
5807 TERM_COLOR attr_top = 0;
5808 bool visual_list = FALSE;
5810 TERM_LEN browser_rows = hgt - 8;
5811 if (direct_f_idx < 0)
5813 /* Check every group */
5814 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5816 /* Measure the label */
5817 len = strlen(feature_group_text[i]);
5819 /* Save the maximum length */
5820 if (len > max) max = len;
5822 /* See if any features are known */
5823 if (collect_features(feat_idx, 0x01))
5825 /* Build a list of groups with known features */
5826 grp_idx[grp_cnt++] = i;
5834 feature_type *f_ptr = &f_info[direct_f_idx];
5836 feat_idx[0] = direct_f_idx;
5839 /* Terminate the list */
5842 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5843 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5845 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5847 attr_old[i] = f_ptr->x_attr[i];
5848 char_old[i] = f_ptr->x_char[i];
5852 /* Terminate the list */
5853 grp_idx[grp_cnt] = -1;
5855 FEAT_IDX old_grp_cur = -1;
5856 FEAT_IDX grp_cur = 0;
5857 FEAT_IDX grp_top = 0;
5858 FEAT_IDX feat_cur = 0;
5859 FEAT_IDX feat_top = 0;
5860 TERM_LEN column = 0;
5863 TERM_COLOR *cur_attr_ptr;
5864 SYMBOL_CODE *cur_char_ptr;
5868 feature_type *f_ptr;
5874 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5875 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5876 prt(_("名前", "Name"), 4, max + 3);
5879 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5880 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5884 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5885 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5888 for (FEAT_IDX i = 0; i < 78; i++)
5890 Term_putch(i, 5, TERM_WHITE, '=');
5893 if (direct_f_idx < 0)
5895 for (FEAT_IDX i = 0; i < browser_rows; i++)
5897 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5904 if (direct_f_idx < 0)
5906 /* Scroll group list */
5907 if (grp_cur < grp_top) grp_top = grp_cur;
5908 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5910 /* Display a list of feature groups */
5911 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5913 if (old_grp_cur != grp_cur)
5915 old_grp_cur = grp_cur;
5917 /* Get a list of features in the current group */
5918 feat_cnt = collect_features(feat_idx, 0x00);
5921 /* Scroll feature list */
5922 while (feat_cur < feat_top)
5923 feat_top = MAX(0, feat_top - browser_rows / 2);
5924 while (feat_cur >= feat_top + browser_rows)
5925 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5930 /* Display a list of features in the current group */
5931 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5935 feat_top = feat_cur;
5937 /* Display a list of features in the current group */
5938 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5940 /* Display visual list below first object */
5941 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5945 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5946 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5947 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5950 /* Get the current feature */
5951 f_ptr = &f_info[feat_idx[feat_cur]];
5952 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5953 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5957 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5961 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5965 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5970 if (visual_list && ((ch == 'A') || (ch == 'a')))
5972 int prev_lighting_level = *lighting_level;
5976 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5977 else (*lighting_level)--;
5981 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5982 else (*lighting_level)++;
5985 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5986 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5988 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5989 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5994 else if ((ch == 'D') || (ch == 'd'))
5996 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5997 byte prev_x_char = f_ptr->x_char[*lighting_level];
5999 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6003 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6004 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6006 if (prev_x_char != f_ptr->x_char[*lighting_level])
6007 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6009 else *need_redraw = TRUE;
6014 /* Do visual mode command if needed */
6015 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))
6019 /* Restore previous visual settings */
6021 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6023 f_ptr->x_attr[i] = attr_old[i];
6024 f_ptr->x_char[i] = char_old[i];
6031 if (direct_f_idx >= 0) flag = TRUE;
6032 else *lighting_level = F_LIT_STANDARD;
6035 /* Preserve current visual settings */
6038 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6040 attr_old[i] = f_ptr->x_attr[i];
6041 char_old[i] = f_ptr->x_char[i];
6043 *lighting_level = F_LIT_STANDARD;
6050 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6052 attr_idx_feat[i] = f_ptr->x_attr[i];
6053 char_idx_feat[i] = f_ptr->x_char[i];
6062 /* Allow TERM_DARK text */
6063 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6065 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6066 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6084 /* Move the cursor */
6085 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6091 /* Free the "feat_idx" array */
6092 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6097 * List wanted monsters
6098 * @param creature_ptr プレーヤーへの参照ポインタ
6101 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6103 /* Open a new file */
6105 GAME_TEXT file_name[1024];
6106 fff = my_fopen_temp(file_name, 1024);
6109 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6114 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
6115 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6117 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6118 fprintf(fff, "----------------------------------------------\n");
6120 bool listed = FALSE;
6121 for (int i = 0; i < MAX_BOUNTY; i++)
6123 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6125 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6132 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
6137 /* Display the file contents */
6138 (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6143 * List virtues & status
6145 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6147 /* Open a new file */
6149 GAME_TEXT file_name[1024];
6150 fff = my_fopen_temp(file_name, 1024);
6153 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6158 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6159 dump_virtues(creature_ptr, fff);
6162 /* Display the file contents */
6163 (void)show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6170 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6172 /* Open a new file */
6174 GAME_TEXT file_name[1024];
6175 fff = my_fopen_temp(file_name, 1024);
6178 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6183 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6187 if (!d_info[i].maxdepth) continue;
6188 if (!max_dlv[i]) continue;
6189 if (d_info[i].final_guardian)
6191 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6193 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6195 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6200 /* Display the file contents */
6201 (void)show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6207 * List virtues & status
6210 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6212 /* Open a new file */
6214 GAME_TEXT file_name[1024];
6215 fff = my_fopen_temp(file_name, 1024);
6218 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6223 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6224 (2 * creature_ptr->hitdie +
6225 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6227 if (creature_ptr->knowledge & KNOW_HPRATE)
6228 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6229 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6231 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6232 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6234 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);
6235 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6238 dump_yourself(creature_ptr, fff);
6241 /* Display the file contents */
6242 (void)show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6248 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6249 * Print all active quests
6250 * @param creature_ptr プレーヤーへの参照ポインタ
6253 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6256 char rand_tmp_str[120] = "\0";
6257 GAME_TEXT name[MAX_NLEN];
6258 monster_race *r_ptr;
6259 int rand_level = 100;
6262 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6264 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6266 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6267 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6268 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6272 /* Set the quest number temporary */
6273 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6275 /* Clear the text */
6276 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6277 quest_text_line = 0;
6279 creature_ptr->current_floor_ptr->inside_quest = i;
6281 /* Get the quest text */
6282 init_flags = INIT_SHOW_TEXT;
6284 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6286 /* Reset the old quest number */
6287 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6289 /* No info from "silent" quests */
6290 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6294 if (quest[i].type != QUEST_TYPE_RANDOM)
6296 char note[80] = "\0";
6298 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6300 switch (quest[i].type)
6302 case QUEST_TYPE_KILL_LEVEL:
6303 case QUEST_TYPE_KILL_ANY_LEVEL:
6304 r_ptr = &r_info[quest[i].r_idx];
6305 strcpy(name, r_name + r_ptr->name);
6306 if (quest[i].max_num > 1)
6309 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6310 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6313 sprintf(note, " - kill %d %s, have killed %d.",
6314 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6318 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6321 case QUEST_TYPE_FIND_ARTIFACT:
6324 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6326 object_type *q_ptr = &forge;
6327 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6328 object_prep(q_ptr, k_idx);
6329 q_ptr->name1 = quest[i].k_idx;
6330 q_ptr->ident = IDENT_STORE;
6331 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6333 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
6335 case QUEST_TYPE_FIND_EXIT:
6336 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
6339 case QUEST_TYPE_KILL_NUMBER:
6341 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6342 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6344 sprintf(note, " - Kill %d monsters, have killed %d.",
6345 (int)quest[i].max_num, (int)quest[i].cur_num);
6349 case QUEST_TYPE_KILL_ALL:
6350 case QUEST_TYPE_TOWER:
6351 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6356 /* Print the quest info */
6357 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6358 quest[i].name, (int)quest[i].level, note);
6360 fputs(tmp_str, fff);
6362 if (quest[i].status == QUEST_STATUS_COMPLETED)
6364 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6365 fputs(tmp_str, fff);
6370 while (quest_text[k][0] && k < 10)
6372 fprintf(fff, " %s\n", quest_text[k]);
6379 /* QUEST_TYPE_RANDOM */
6380 if (quest[i].level >= rand_level)
6384 rand_level = quest[i].level;
6386 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6388 /* Print the quest info */
6389 r_ptr = &r_info[quest[i].r_idx];
6390 strcpy(name, r_name + r_ptr->name);
6392 if (quest[i].max_num <= 1)
6394 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6395 quest[i].name, (int)quest[i].level, name);
6400 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6401 quest[i].name, (int)quest[i].level,
6402 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6406 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6407 quest[i].name, (int)quest[i].level,
6408 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6412 /* Print the current random quest */
6413 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6415 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6419 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6422 char playtime_str[16];
6423 quest_type* const q_ptr = &quest[q_idx];
6425 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6426 if (is_fixed_quest_idx(q_idx))
6428 /* Set the quest number temporary */
6429 IDX old_quest = floor_ptr->inside_quest;
6431 floor_ptr->inside_quest = q_idx;
6434 init_flags = INIT_NAME_ONLY;
6436 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6438 /* Reset the old quest number */
6439 floor_ptr->inside_quest = old_quest;
6441 /* No info from "silent" quests */
6442 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6445 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6446 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6448 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
6450 /* Print the quest info */
6452 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6453 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6454 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6455 fputs(tmp_str, fff);
6459 /* Print the quest info */
6460 if (q_ptr->complev == 0)
6463 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6464 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6465 r_name + r_info[q_ptr->r_idx].name,
6466 (int)q_ptr->level, playtime_str);
6467 fputs(tmp_str, fff);
6472 _(" %-35s (%3d階) - レベル%2d - %s\n",
6473 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6474 r_name + r_info[q_ptr->r_idx].name,
6478 fputs(tmp_str, fff);
6484 * Print all finished quests
6485 * @param creature_ptr プレーヤーへの参照ポインタ
6486 * @param fff セーブファイル (展開済?)
6487 * @param quest_num[] 受注したことのあるクエスト群
6490 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6492 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6493 QUEST_IDX total = 0;
6494 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6496 QUEST_IDX q_idx = quest_num[i];
6497 quest_type* const q_ptr = &quest[q_idx];
6499 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6505 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6510 * Print all failed quests
6511 * @param creature_ptr プレーヤーへの参照ポインタ
6512 * @param fff セーブファイル (展開済?)
6513 * @param quest_num[] 受注したことのあるクエスト群
6516 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6518 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6519 QUEST_IDX total = 0;
6520 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6522 QUEST_IDX q_idx = quest_num[i];
6523 quest_type* const q_ptr = &quest[q_idx];
6525 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6526 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6532 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6537 * Print all random quests
6539 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6541 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6542 GAME_TEXT tmp_str[120];
6543 QUEST_IDX total = 0;
6544 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6546 /* No info from "silent" quests */
6547 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6549 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6553 /* Print the quest info */
6554 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6555 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6556 fputs(tmp_str, fff);
6560 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6564 * Print quest status of all active quests
6565 * @param creature_ptr プレーヤーへの参照ポインタ
6568 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6570 /* Open a new file */
6572 GAME_TEXT file_name[1024];
6573 fff = my_fopen_temp(file_name, 1024);
6576 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6581 /* Allocate Memory */
6583 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6585 /* Sort by compete level */
6586 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6588 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6590 /* Dump Quest Information */
6591 do_cmd_knowledge_quests_current(creature_ptr, fff);
6593 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6595 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6596 if (current_world_ptr->wizard)
6599 do_cmd_knowledge_quests_wiz_random(fff);
6604 /* Display the file contents */
6605 (void)show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6609 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6615 * @param player_ptr プレーヤーへの参照ポインタ
6618 static void do_cmd_knowledge_home(player_type *player_ptr)
6620 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6622 /* Open a new file */
6624 GAME_TEXT file_name[1024];
6625 fff = my_fopen_temp(file_name, 1024);
6628 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6633 /* Print all homes in the different towns */
6635 st_ptr = &town_info[1].store[STORE_HOME];
6637 /* Home -- if anything there */
6638 if (st_ptr->stock_num)
6643 /* Header with name of the town */
6644 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6646 /* Dump all available items */
6647 concptr paren = ")";
6648 GAME_TEXT o_name[MAX_NLEN];
6649 for (int i = 0; i < st_ptr->stock_num; i++)
6652 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6653 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6654 if (strlen(o_name) <= 80 - 3)
6656 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6662 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6663 if (iskanji(*t)) { t++; n++; }
6664 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6666 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6667 fprintf(fff, " %.77s\n", o_name + n);
6670 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6671 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6675 /* Add an empty line */
6676 fprintf(fff, "\n\n");
6681 /* Display the file contents */
6682 (void)show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6688 * Check the status of "autopick"
6690 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6692 /* Open a new file */
6694 GAME_TEXT file_name[1024];
6695 fff = my_fopen_temp(file_name, 1024);
6698 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6705 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6709 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6710 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6713 for (int k = 0; k < max_autopick; k++)
6716 byte act = autopick_list[k].action;
6717 if (act & DONT_AUTOPICK)
6719 tmp = _("放置", "Leave");
6721 else if (act & DO_AUTODESTROY)
6723 tmp = _("破壊", "Destroy");
6725 else if (act & DO_AUTOPICK)
6727 tmp = _("拾う", "Pickup");
6731 tmp = _("確認", "Query");
6734 if (act & DO_DISPLAY)
6735 fprintf(fff, "%11s", format("[%s]", tmp));
6737 fprintf(fff, "%11s", format("(%s)", tmp));
6739 tmp = autopick_line_from_entry(&autopick_list[k]);
6740 fprintf(fff, " %s", tmp);
6747 /* Display the file contents */
6748 (void)show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6754 * Interact with "knowledge"
6756 void do_cmd_knowledge(player_type *creature_ptr)
6759 bool need_redraw = FALSE;
6761 /* File type is "TEXT" */
6762 FILE_TYPE(FILE_TYPE_TEXT);
6765 /* Interact until done */
6770 /* Ask for a choice */
6771 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6772 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6774 /* Give some choices */
6778 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6779 prt("(2) 既知のアイテム の一覧", 7, 5);
6780 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6781 prt("(4) 既知のモンスター の一覧", 9, 5);
6782 prt("(5) 倒した敵の数 の一覧", 10, 5);
6783 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6784 prt("(7) 現在のペット の一覧", 12, 5);
6785 prt("(8) 我が家のアイテム の一覧", 13, 5);
6786 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6787 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6791 prt("(a) 自分に関する情報 の一覧", 6, 5);
6792 prt("(b) 突然変異 の一覧", 7, 5);
6793 prt("(c) 武器の経験値 の一覧", 8, 5);
6794 prt("(d) 魔法の経験値 の一覧", 9, 5);
6795 prt("(e) 技能の経験値 の一覧", 10, 5);
6796 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6797 prt("(g) 入ったダンジョン の一覧", 12, 5);
6798 prt("(h) 実行中のクエスト の一覧", 13, 5);
6799 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6804 prt("(1) Display known artifacts", 6, 5);
6805 prt("(2) Display known objects", 7, 5);
6806 prt("(3) Display remaining uniques", 8, 5);
6807 prt("(4) Display known monster", 9, 5);
6808 prt("(5) Display kill count", 10, 5);
6809 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6810 prt("(7) Display current pets", 12, 5);
6811 prt("(8) Display home inventory", 13, 5);
6812 prt("(9) Display *identified* equip.", 14, 5);
6813 prt("(0) Display terrain symbols.", 15, 5);
6817 prt("(a) Display about yourself", 6, 5);
6818 prt("(b) Display mutations", 7, 5);
6819 prt("(c) Display weapon proficiency", 8, 5);
6820 prt("(d) Display spell proficiency", 9, 5);
6821 prt("(e) Display misc. proficiency", 10, 5);
6822 prt("(f) Display virtues", 11, 5);
6823 prt("(g) Display dungeons", 12, 5);
6824 prt("(h) Display current quests", 13, 5);
6825 prt("(i) Display auto pick/destroy", 14, 5);
6829 prt(_("-続く-", "-more-"), 17, 8);
6830 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6831 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6832 /*prt("-) 前ページ", 21, 60);*/
6833 prt(_("コマンド:", "Command: "), 20, 0);
6836 if (i == ESCAPE) break;
6839 case ' ': /* Page change */
6843 case '1': /* Artifacts */
6844 do_cmd_knowledge_artifacts(creature_ptr);
6846 case '2': /* Objects */
6847 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6849 case '3': /* Uniques */
6850 do_cmd_knowledge_uniques(creature_ptr);
6852 case '4': /* Monsters */
6853 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6855 case '5': /* Kill count */
6856 do_cmd_knowledge_kill_count(creature_ptr);
6858 case '6': /* wanted */
6859 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6861 case '7': /* Pets */
6862 do_cmd_knowledge_pets(creature_ptr);
6864 case '8': /* Home */
6865 do_cmd_knowledge_home(creature_ptr);
6867 case '9': /* Resist list */
6868 do_cmd_knowledge_inven(creature_ptr);
6870 case '0': /* Feature list */
6872 IDX lighting_level = F_LIT_STANDARD;
6873 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6877 case 'a': /* Max stat */
6878 do_cmd_knowledge_stat(creature_ptr);
6880 case 'b': /* Mutations */
6881 do_cmd_knowledge_mutations(creature_ptr);
6883 case 'c': /* weapon-exp */
6884 do_cmd_knowledge_weapon_exp(creature_ptr);
6886 case 'd': /* spell-exp */
6887 do_cmd_knowledge_spell_exp(creature_ptr);
6889 case 'e': /* skill-exp */
6890 do_cmd_knowledge_skill_exp(creature_ptr);
6892 case 'f': /* Virtues */
6893 do_cmd_knowledge_virtues(creature_ptr);
6895 case 'g': /* Dungeon */
6896 do_cmd_knowledge_dungeon(creature_ptr);
6898 case 'h': /* Quests */
6899 do_cmd_knowledge_quests(creature_ptr);
6901 case 'i': /* Autopick */
6902 do_cmd_knowledge_autopick(creature_ptr);
6904 default: /* Unknown option */
6912 if (need_redraw) do_cmd_redraw(creature_ptr);
6917 * Check on the status of an active quest
6918 * @param creature_ptr プレーヤーへの参照ポインタ
6921 void do_cmd_checkquest(player_type *creature_ptr)
6923 /* File type is "TEXT" */
6924 FILE_TYPE(FILE_TYPE_TEXT);
6928 do_cmd_knowledge_quests(creature_ptr);
6934 * Display the time and date
6935 * @param creature_ptr プレーヤーへの参照ポインタ
6938 void do_cmd_time(player_type *creature_ptr)
6941 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6944 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6947 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6948 else strcpy(day_buf, "*****");
6950 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6951 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6955 if (!randint0(10) || creature_ptr->image)
6957 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6961 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6964 /* Open this file */
6966 fff = my_fopen(buf, "rt");
6970 /* Find this time */
6971 int full = hour * 100 + min;
6975 while (!my_fgets(fff, buf, sizeof(buf)))
6977 /* Ignore comments */
6978 if (!buf[0] || (buf[0] == '#')) continue;
6980 /* Ignore invalid lines */
6981 if (buf[1] != ':') continue;
6983 /* Process 'Start' */
6986 /* Extract the starting time */
6987 start = atoi(buf + 2);
6989 /* Assume valid for an hour */
6997 /* Extract the ending time */
6998 end = atoi(buf + 2);
7002 /* Ignore incorrect range */
7003 if ((start > full) || (full > end)) continue;
7005 /* Process 'Description' */
7010 /* Apply the randomizer */
7011 if (!randint0(num)) strcpy(desc, buf + 2);