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.
53 #include "player-effects.h"
54 #include "player-status.h"
55 #include "player-skill.h"
56 #include "player-personality.h"
63 #include "object-flavor.h"
64 #include "object-hook.h"
66 #include "monster-status.h"
67 #include "view-mainwindow.h"
68 #include "dungeon-file.h"
71 #include "objectkind.h"
72 #include "floor-town.h"
73 #include "view-mainwindow.h"
77 // Mark strings for auto dump
78 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
79 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
81 // Variables for auto dump
82 static FILE *auto_dump_stream;
83 static concptr auto_dump_mark;
84 static int auto_dump_line_num;
86 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
87 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
88 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
90 // Clipboard variables for copy&paste in visual mode
91 static TERM_COLOR attr_idx = 0;
92 static SYMBOL_CODE char_idx = 0;
94 /* Hack -- for feature lighting */
95 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
96 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
98 // Encode the screen colors
99 static char hack[17] = "dwsorgbuDWvyRGBU";
105 * @brief prf出力内容を消去する /
106 * Remove old lines automatically generated before.
107 * @param orig_file 消去を行うファイル名
109 static void remove_auto_dump(concptr orig_file)
111 FILE *tmp_fff, *orig_fff;
115 bool between_mark = FALSE;
116 bool changed = FALSE;
118 long header_location = 0;
119 char header_mark_str[80];
120 char footer_mark_str[80];
123 /* Prepare a header/footer mark string */
124 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
125 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
127 mark_len = strlen(footer_mark_str);
129 /* Open an old dump file in read-only mode */
130 orig_fff = my_fopen(orig_file, "r");
132 /* If original file does not exist, nothing to do */
133 if (!orig_fff) return;
135 /* Open a new (temporary) file */
136 tmp_fff = my_fopen_temp(tmp_file, 1024);
140 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
145 /* Loop for every line */
149 if (my_fgets(orig_fff, buf, sizeof(buf)))
151 /* Read error: Assume End of File */
154 * Was looking for the footer, but not found.
156 * Since automatic dump might be edited by hand,
157 * it's dangerous to kill these lines.
158 * Seek back to the next line of the (pseudo) header,
163 fseek(orig_fff, header_location, SEEK_SET);
164 between_mark = FALSE;
168 /* Success -- End the loop */
175 /* We are looking for the header mark of automatic dump */
178 /* Is this line a header? */
179 if (!strcmp(buf, header_mark_str))
181 /* Memorise seek point of this line */
182 header_location = ftell(orig_fff);
184 /* Initialize counter for number of lines */
187 /* Look for the footer from now */
190 /* There are some changes */
197 /* Copy orginally lines */
198 fprintf(tmp_fff, "%s\n", buf);
204 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
205 /* We are looking for the footer mark of automatic dump */
206 /* Is this line a footer? */
207 if (!strncmp(buf, footer_mark_str, mark_len))
212 * Compare the number of lines
214 * If there is an inconsistency between
215 * actual number of lines and the
216 * number here, the automatic dump
217 * might be edited by hand. So it's
218 * dangerous to kill these lines.
219 * Seek back to the next line of the
220 * (pseudo) header, and read again.
222 if (!sscanf(buf + mark_len, " (%d)", &tmp)
225 fseek(orig_fff, header_location, SEEK_SET);
228 /* Look for another header */
229 between_mark = FALSE;
234 /* Ignore old line, and count number of lines */
242 /* If there are some changes, overwrite the original file with new one */
245 /* Copy contents of temporary file */
246 tmp_fff = my_fopen(tmp_file, "r");
247 orig_fff = my_fopen(orig_file, "w");
249 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
250 fprintf(orig_fff, "%s\n", buf);
261 * @brief prfファイルのフォーマットに従った内容を出力する /
262 * Dump a formatted line, using "vstrnfmt()".
265 static void auto_dump_printf(concptr fmt, ...)
272 /* Begin the Varargs Stuff */
275 /* Format the args, save the length */
276 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
278 /* End the Varargs Stuff */
281 /* Count number of lines */
282 for (p = buf; *p; p++)
284 if (*p == '\n') auto_dump_line_num++;
288 fprintf(auto_dump_stream, "%s", buf);
293 * @brief prfファイルをファイルオープンする /
294 * Open file to append auto dump.
296 * @param mark 出力するヘッダマーク
297 * @return ファイルポインタを取得できたらTRUEを返す
299 static bool open_auto_dump(concptr buf, concptr mark)
301 char header_mark_str[80];
303 /* Save the mark string */
304 auto_dump_mark = mark;
306 /* Prepare a header mark string */
307 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
309 /* Remove old macro dumps */
310 remove_auto_dump(buf);
312 /* Append to the file */
313 auto_dump_stream = my_fopen(buf, "a");
316 if (!auto_dump_stream)
318 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
326 fprintf(auto_dump_stream, "%s\n", header_mark_str);
328 /* Initialize counter */
329 auto_dump_line_num = 0;
331 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
332 "# *Warning!* The lines below are an automatic dump.\n"));
333 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
334 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
339 * @brief prfファイルをファイルクローズする /
340 * Append foot part and close auto dump.
343 static void close_auto_dump(void)
345 char footer_mark_str[80];
347 /* Prepare a footer mark string */
348 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
350 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
351 "# *Warning!* The lines below are an automatic dump.\n"));
352 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
353 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
355 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
357 my_fclose(auto_dump_stream);
364 * @brief Return suffix of ordinal number
366 * @return pointer of suffix string.
368 concptr get_ordinal_number_suffix(int num)
370 num = ABS(num) % 100;
374 return (num == 11) ? "th" : "st";
376 return (num == 12) ? "th" : "nd";
378 return (num == 13) ? "th" : "rd";
387 * @brief 日記にメッセージを追加する /
388 * Take note to the diary.
389 * @param type 日記内容のID
390 * @param num 日記内容のIDに応じた数値
391 * @param note 日記内容のIDに応じた文字列参照ポインタ
394 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
398 GAME_TEXT file_name[MAX_NLEN];
400 concptr note_level = "";
401 bool do_level = TRUE;
402 char note_level_buf[40];
405 static bool disable_diary = FALSE;
407 extract_day_hour_min(creature_ptr, &day, &hour, &min);
409 if (disable_diary) return(-1);
411 if (type == DIARY_FIX_QUEST_C ||
412 type == DIARY_FIX_QUEST_F ||
413 type == DIARY_RAND_QUEST_C ||
414 type == DIARY_RAND_QUEST_F ||
415 type == DIARY_TO_QUEST)
419 old_quest = creature_ptr->current_floor_ptr->inside_quest;
420 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
422 /* Get the quest text */
423 init_flags = INIT_NAME_ONLY;
425 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
427 /* Reset the old quest number */
428 creature_ptr->current_floor_ptr->inside_quest = old_quest;
431 /* different filne name to avoid mixing */
432 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
433 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
435 /* File type is "TEXT" */
436 FILE_TYPE(FILE_TYPE_TEXT);
438 fff = my_fopen(buf, "a");
443 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
445 disable_diary = TRUE;
449 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
453 if (creature_ptr->current_floor_ptr->inside_arena)
454 note_level = _("アリーナ:", "Arane:");
455 else if (!creature_ptr->current_floor_ptr->dun_level)
456 note_level = _("地上:", "Surface:");
457 else if (q_idx && (is_fixed_quest_idx(q_idx)
458 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
459 note_level = _("クエスト:", "Quest:");
463 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
465 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
467 note_level = note_level_buf;
475 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
476 else fputs(_("*****日目\n", "Day *****\n"), fff);
480 case DIARY_DESCRIPTION:
484 fprintf(fff, "%s\n", note);
488 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
493 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
496 case DIARY_ART_SCROLL:
498 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
503 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
506 case DIARY_FIX_QUEST_C:
508 if (quest[num].flags & QUEST_FLAG_SILENT) break;
509 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
510 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
513 case DIARY_FIX_QUEST_F:
515 if (quest[num].flags & QUEST_FLAG_SILENT) break;
516 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
517 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
520 case DIARY_RAND_QUEST_C:
522 GAME_TEXT name[MAX_NLEN];
523 strcpy(name, r_name + r_info[quest[num].r_idx].name);
524 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
525 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
528 case DIARY_RAND_QUEST_F:
530 GAME_TEXT name[MAX_NLEN];
531 strcpy(name, r_name + r_info[quest[num].r_idx].name);
532 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
533 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
536 case DIARY_MAXDEAPTH:
538 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
539 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
540 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
541 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
546 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
547 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
548 _(d_name + d_info[num].name, (int)max_dlv[num]),
549 _((int)max_dlv[num], d_name + d_info[num].name));
555 if (q_idx && (is_fixed_quest_idx(q_idx)
556 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
558 to = _("地上", "the surface");
562 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
563 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
565 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
571 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
572 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
573 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
575 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
580 if (quest[num].flags & QUEST_FLAG_SILENT) break;
581 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
582 hour, min, note_level, quest[num].name);
585 case DIARY_TELEPORT_LEVEL:
587 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
588 hour, min, note_level);
593 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
598 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
606 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
607 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
610 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
611 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
613 if (num == MAX_ARENA_MONS)
615 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
616 " won all fights to become a Champion.\n"));
623 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
629 if (!creature_ptr->current_floor_ptr->dun_level)
630 to = _("地上", "the surface");
632 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
634 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
635 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
641 if (!creature_ptr->current_floor_ptr->dun_level)
642 to = _("地上", "the surface");
644 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
646 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
647 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
652 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
655 case DIARY_GAMESTART:
657 time_t ct = time((time_t*)0);
661 fprintf(fff, "%s %s", note, ctime(&ct));
664 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
667 case DIARY_NAMED_PET:
669 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
672 case RECORD_NAMED_PET_NAME:
673 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
675 case RECORD_NAMED_PET_UNNAME:
676 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
678 case RECORD_NAMED_PET_DISMISS:
679 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
681 case RECORD_NAMED_PET_DEATH:
682 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
684 case RECORD_NAMED_PET_MOVED:
685 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
687 case RECORD_NAMED_PET_LOST_SIGHT:
688 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
690 case RECORD_NAMED_PET_DESTROY:
691 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
693 case RECORD_NAMED_PET_EARTHQUAKE:
694 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
696 case RECORD_NAMED_PET_GENOCIDE:
697 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
699 case RECORD_NAMED_PET_WIZ_ZAP:
700 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
702 case RECORD_NAMED_PET_TELE_LEVEL:
703 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
705 case RECORD_NAMED_PET_BLAST:
706 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
708 case RECORD_NAMED_PET_HEAL_LEPER:
709 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
711 case RECORD_NAMED_PET_COMPACT:
712 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
714 case RECORD_NAMED_PET_LOSE_PARENT:
715 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
725 case DIARY_WIZARD_LOG:
726 fprintf(fff, "%s\n", note);
735 if (do_level) write_level = FALSE;
741 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
744 * @brief 日記のタイトル表記と内容出力 /
747 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
749 static void display_diary(player_type *creature_ptr)
751 char diary_title[256];
752 GAME_TEXT file_name[MAX_NLEN];
756 static const char subtitle[][30] = {
789 static const char subtitle[][51] = {
790 "Quest of The World's Toughest Body",
791 "Attack is the best form of defence.",
793 "An unexpected windfall",
794 "A drowning man will catch at a straw",
795 "Don't count your chickens before they are hatched.",
796 "It is no use crying over spilt milk.",
797 "Seeing is believing.",
798 "Strike the iron while it is hot.",
799 "I don't care what follows.",
800 "To dig a well to put out a house on fire.",
801 "Tomorrow is another day.",
802 "Easy come, easy go.",
803 "The more haste, the less speed.",
804 "Where there is life, there is hope.",
805 "There is no royal road to *WINNER*.",
806 "Danger past, God forgotten.",
807 "The best thing to do now is to run away.",
808 "Life is but an empty dream.",
809 "Dead men tell no tales.",
810 "A book that remains shut is but a block.",
811 "Misfortunes never come singly.",
812 "A little knowledge is a dangerous thing.",
813 "History repeats itself.",
814 "*WINNER* was not built in a day.",
815 "Ignorance is bliss.",
816 "To lose is to win?",
817 "No medicine can cure folly.",
818 "All good things come to an end.",
819 "M$ Empire strikes back.",
820 "To see is to believe",
822 "Quest of The World's Greatest Brain"
825 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
826 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
828 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
829 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
830 else if (IS_WIZARD_CLASS(creature_ptr))
831 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
832 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
835 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
837 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
840 /* Display the file contents */
841 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
846 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
849 static void add_diary_note(player_type *creature_ptr)
852 char bunshou[80] = "\0";
854 if (get_string(_("内容: ", "diary note: "), tmp, 79))
856 strcpy(bunshou, tmp);
857 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
862 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
865 static void do_cmd_last_get(player_type *creaute_ptr)
867 if (record_o_name[0] == '\0') return;
870 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
871 if (!get_check(buf)) return;
873 GAME_TURN turn_tmp = current_world_ptr->game_turn;
874 current_world_ptr->game_turn = record_turn;
875 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
876 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
877 current_world_ptr->game_turn = turn_tmp;
882 * @brief ファイル中の全日記記録を消去する /
885 static void do_cmd_erase_diary(void)
887 GAME_TEXT file_name[MAX_NLEN];
891 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
892 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
893 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
896 fff = my_fopen(buf, "w");
900 msg_format(_("記録を消去しました。", "deleted record."));
904 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
913 * @param crerature_ptr プレーヤーへの参照ポインタ
916 void do_cmd_diary(player_type *creature_ptr)
918 /* File type is "TEXT" */
919 FILE_TYPE(FILE_TYPE_TEXT);
922 /* Interact until done */
928 /* Ask for a choice */
929 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
931 /* Give some choices */
932 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
933 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
934 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
935 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
937 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
940 prt(_("コマンド:", "Command: "), 18, 0);
945 if (i == ESCAPE) break;
950 display_diary(creature_ptr);
953 add_diary_note(creature_ptr);
956 do_cmd_last_get(creature_ptr);
959 do_cmd_erase_diary();
963 prepare_movie_hooks();
965 default: /* Unknown option */
977 * @brief 画面を再描画するコマンドのメインルーチン
978 * Hack -- redraw the screen
979 * @param creature_ptr プレーヤーへの参照ポインタ
983 * This command performs various low level updates, clears all the "extra"
984 * windows, does a total redraw of the main window, and requests all of the
985 * interesting updates and redraws that I can think of.
987 * This command is also used to "instantiate" the results of the user
988 * selecting various things, such as graphics mode, so it must call
989 * the "TERM_XTRA_REACT" hook before redrawing the windows.
992 void do_cmd_redraw(player_type *creature_ptr)
994 Term_xtra(TERM_XTRA_REACT, 0);
996 /* Combine and Reorder the pack (later) */
997 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
998 creature_ptr->update |= (PU_TORCH);
999 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1000 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1001 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1002 creature_ptr->update |= (PU_MONSTERS);
1004 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1006 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1007 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1010 handle_stuff(creature_ptr);
1012 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1014 /* Redraw every window */
1016 for (int j = 0; j < 8; j++)
1019 if (!angband_term[j]) continue;
1022 Term_activate(angband_term[j]);
1031 * @brief プレイヤーのステータス表示
1034 void do_cmd_player_status(player_type *creature_ptr)
1045 display_player(creature_ptr, mode);
1050 display_player(creature_ptr, mode);
1054 Term_putstr(2, 23, -1, TERM_WHITE,
1055 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1059 if (c == ESCAPE) break;
1064 get_name(creature_ptr);
1066 /* Process the player name */
1067 process_player_name(creature_ptr, FALSE);
1073 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1074 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1076 if (tmp[0] && (tmp[0] != ' '))
1078 file_character(creature_ptr, tmp);
1096 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1098 handle_stuff(creature_ptr);
1103 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1104 * Recall the most recent message
1107 void do_cmd_message_one(void)
1109 /* Recall one message */
1110 prt(format("> %s", message_str(0)), 0, 0);
1115 * @brief メッセージのログを表示するコマンドのメインルーチン
1116 * Recall the most recent message
1120 * Show previous messages to the user -BEN-
1122 * The screen format uses line 0 and 23 for headers and prompts,
1123 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1125 * This command shows you which commands you are viewing, and allows
1126 * you to "search" for strings in the recall.
1128 * Note that messages may be longer than 80 characters, but they are
1129 * displayed using "infinite" length, with a special sub-command to
1130 * "slide" the virtual display to the left or right.
1132 * Attempt to only hilite the matching portions of the string.
1135 void do_cmd_messages(int num_now)
1137 char shower_str[81];
1138 char finder_str[81];
1140 concptr shower = NULL;
1144 Term_get_size(&wid, &hgt);
1146 /* Number of message lines in a screen */
1147 num_lines = hgt - 4;
1150 strcpy(finder_str, "");
1153 strcpy(shower_str, "");
1155 /* Total messages */
1156 int n = message_num();
1158 /* Start on first message */
1163 /* Process requests until done */
1169 /* Dump up to 20 lines of messages */
1170 for (j = 0; (j < num_lines) && (i + j < n); j++)
1172 concptr msg = message_str(i + j);
1174 /* Dump the messages, bottom to top */
1175 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1177 if (!shower || !shower[0]) continue;
1179 /* Hilite "shower" */
1182 /* Display matches */
1183 while ((str = my_strstr(str, shower)) != NULL)
1185 int len = strlen(shower);
1187 /* Display the match */
1188 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1195 /* Erase remaining lines */
1196 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1198 /* Display header */
1200 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1201 i, i + j - 1, n), 0, 0);
1203 /* Display prompt (not very informative) */
1204 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1205 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1207 skey = inkey_special(TRUE);
1209 /* Exit on Escape */
1210 if (skey == ESCAPE) break;
1212 /* Hack -- Save the old index */
1217 /* Hack -- handle show */
1220 prt(_("強調: ", "Show: "), hgt - 1, 0);
1222 /* Get a "shower" string, or continue */
1223 strcpy(back_str, shower_str);
1224 if (askfor(shower_str, 80))
1227 shower = shower_str[0] ? shower_str : NULL;
1229 else strcpy(shower_str, back_str);
1233 /* Hack -- handle find */
1240 prt(_("検索: ", "Find: "), hgt - 1, 0);
1242 /* Get a "finder" string, or continue */
1243 strcpy(back_str, finder_str);
1244 if (!askfor(finder_str, 80))
1246 strcpy(finder_str, back_str);
1249 else if (!finder_str[0])
1251 shower = NULL; /* Stop showing */
1256 shower = finder_str;
1259 for (z = i + 1; z < n; z++)
1261 concptr msg = message_str(z);
1264 if (my_strstr(msg, finder_str))
1275 /* Recall 1 older message */
1277 /* Go to the oldest line */
1281 /* Recall 1 newer message */
1283 /* Go to the newest line */
1287 /* Recall 1 older message */
1292 /* Go older if legal */
1293 i = MIN(i + 1, n - num_lines);
1296 /* Recall 10 older messages */
1298 /* Go older if legal */
1299 i = MIN(i + 10, n - num_lines);
1302 /* Recall 20 older messages */
1307 /* Go older if legal */
1308 i = MIN(i + num_lines, n - num_lines);
1311 /* Recall 20 newer messages */
1315 /* Go newer (if able) */
1316 i = MAX(0, i - num_lines);
1319 /* Recall 10 newer messages */
1321 /* Go newer (if able) */
1325 /* Recall 1 newer messages */
1328 /* Go newer (if able) */
1333 /* Hack -- Error of some kind */
1342 * @brief prefファイルを選択して処理する /
1343 * Ask for a "user pref line" and process it
1344 * @param creature_ptr プレーヤーへの参照ポインタ
1347 * Allow absolute file names?
1349 void do_cmd_pref(player_type *creature_ptr)
1354 /* Ask for a "user pref command" */
1355 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1357 /* Process that pref command */
1358 (void)process_pref_file_command(creature_ptr, buf);
1363 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1364 * @param creature_ptr プレーヤーへの参照ポインタ
1367 void do_cmd_reload_autopick(player_type *creature_ptr)
1369 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1370 /* Load the file with messages */
1371 autopick_load_pref(creature_ptr, TRUE);
1376 * @brief マクロ情報をprefファイルに保存する /
1377 * @param fname ファイル名
1380 static errr macro_dump(concptr fname)
1382 static concptr mark = "Macro Dump";
1384 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1386 /* File type is "TEXT" */
1387 FILE_TYPE(FILE_TYPE_TEXT);
1389 /* Append to the file */
1390 if (!open_auto_dump(buf, mark)) return -1;
1393 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1396 for (int i = 0; i < macro__num; i++)
1398 /* Extract the action */
1399 ascii_to_text(buf, macro__act[i]);
1401 /* Dump the macro */
1402 auto_dump_printf("A:%s\n", buf);
1404 /* Extract the action */
1405 ascii_to_text(buf, macro__pat[i]);
1407 /* Dump normal macros */
1408 auto_dump_printf("P:%s\n", buf);
1411 auto_dump_printf("\n");
1420 * @brief マクロのトリガーキーを取得する /
1421 * Hack -- ask for a "trigger" (see below)
1422 * @param buf キー表記を保管するバッファ
1426 * Note the complex use of the "inkey()" function from "util.c".
1428 * Note that both "flush()" calls are extremely important.
1431 static void do_cmd_macro_aux(char *buf)
1435 /* Do not process macros */
1441 /* Read the pattern */
1448 /* Do not process macros */
1451 /* Do not wait for keys */
1454 /* Attempt to read a key */
1463 /* Convert the trigger */
1465 ascii_to_text(tmp, buf);
1467 /* Hack -- display the trigger */
1468 Term_addstr(-1, TERM_WHITE, tmp);
1473 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1474 * Hack -- ask for a keymap "trigger" (see below)
1475 * @param buf キー表記を取得するバッファ
1479 * Note that both "flush()" calls are extremely important. This may
1480 * no longer be true, since "util.c" is much simpler now.
1483 static void do_cmd_macro_aux_keymap(char *buf)
1493 /* Convert to ascii */
1494 ascii_to_text(tmp, buf);
1496 /* Hack -- display the trigger */
1497 Term_addstr(-1, TERM_WHITE, tmp);
1504 * @brief キーマップをprefファイルにダンプする /
1505 * Hack -- append all keymaps to the given file
1506 * @param fname ファイルネーム
1510 static errr keymap_dump(concptr fname)
1512 static concptr mark = "Keymap Dump";
1519 if (rogue_like_commands)
1521 mode = KEYMAP_MODE_ROGUE;
1527 mode = KEYMAP_MODE_ORIG;
1530 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1532 /* File type is "TEXT" */
1533 FILE_TYPE(FILE_TYPE_TEXT);
1535 /* Append to the file */
1536 if (!open_auto_dump(buf, mark)) return -1;
1539 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1542 for (int i = 0; i < 256; i++)
1546 /* Loop up the keymap */
1547 act = keymap_act[mode][i];
1549 /* Skip empty keymaps */
1552 /* Encode the key */
1555 ascii_to_text(key, buf);
1557 /* Encode the action */
1558 ascii_to_text(buf, act);
1560 /* Dump the macro */
1561 auto_dump_printf("A:%s\n", buf);
1562 auto_dump_printf("C:%d:%s\n", mode, key);
1571 * @brief マクロを設定するコマンドのメインルーチン /
1572 * Interact with "macros"
1576 * Note that the macro "action" must be defined before the trigger.
1578 * Could use some helpful instructions on this page.
1581 void do_cmd_macros(player_type *creature_ptr)
1589 if (rogue_like_commands)
1591 mode = KEYMAP_MODE_ROGUE;
1597 mode = KEYMAP_MODE_ORIG;
1600 /* File type is "TEXT" */
1601 FILE_TYPE(FILE_TYPE_TEXT);
1605 /* Process requests until done */
1609 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1611 /* Describe that action */
1612 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1614 /* Analyze the current action */
1615 ascii_to_text(buf, macro__buf);
1617 /* Display the current action */
1622 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1623 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1624 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1625 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1626 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1627 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1628 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1629 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1630 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1631 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1634 prt(_("コマンド: ", "Command: "), 16, 0);
1639 if (i == ESCAPE) break;
1641 /* Load a 'macro' file */
1647 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1650 prt(_("ファイル: ", "File: "), 18, 0);
1652 /* Default filename */
1653 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1655 /* Ask for a file */
1656 if (!askfor(tmp, 80)) continue;
1658 /* Process the given filename */
1659 err = process_pref_file(creature_ptr, tmp);
1662 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1667 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1671 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1679 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1682 prt(_("ファイル: ", "File: "), 18, 0);
1684 /* Default filename */
1685 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1687 /* Ask for a file */
1688 if (!askfor(tmp, 80)) continue;
1690 /* Dump the macros */
1691 (void)macro_dump(tmp);
1694 msg_print(_("マクロを追加しました。", "Appended macros."));
1703 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1707 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1709 /* Get a macro trigger */
1710 do_cmd_macro_aux(buf);
1712 /* Acquire action */
1713 k = macro_find_exact(buf);
1719 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1725 /* Obtain the action */
1726 strcpy(macro__buf, macro__act[k]);
1728 /* Analyze the current action */
1729 ascii_to_text(buf, macro__buf);
1731 /* Display the current action */
1735 msg_print(_("マクロを確認しました。", "Found a macro."));
1739 /* Create a macro */
1743 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1746 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1748 /* Get a macro trigger */
1749 do_cmd_macro_aux(buf);
1753 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1754 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1757 prt(_("マクロ行動: ", "Action: "), 20, 0);
1759 /* Convert to text */
1760 ascii_to_text(tmp, macro__buf);
1762 /* Get an encoded action */
1763 if (askfor(tmp, 80))
1765 /* Convert to ascii */
1766 text_to_ascii(macro__buf, tmp);
1768 /* Link the macro */
1769 macro_add(buf, macro__buf);
1772 msg_print(_("マクロを追加しました。", "Added a macro."));
1776 /* Remove a macro */
1780 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1783 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1785 /* Get a macro trigger */
1786 do_cmd_macro_aux(buf);
1788 /* Link the macro */
1789 macro_add(buf, buf);
1792 msg_print(_("マクロを削除しました。", "Removed a macro."));
1799 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1802 prt(_("ファイル: ", "File: "), 18, 0);
1804 /* Default filename */
1805 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1807 /* Ask for a file */
1808 if (!askfor(tmp, 80)) continue;
1810 /* Dump the macros */
1811 (void)keymap_dump(tmp);
1814 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1817 /* Query a keymap */
1823 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1826 prt(_("押すキー: ", "Keypress: "), 18, 0);
1828 /* Get a keymap trigger */
1829 do_cmd_macro_aux_keymap(buf);
1831 /* Look up the keymap */
1832 act = keymap_act[mode][(byte)(buf[0])];
1838 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1844 /* Obtain the action */
1845 strcpy(macro__buf, act);
1847 /* Analyze the current action */
1848 ascii_to_text(buf, macro__buf);
1850 /* Display the current action */
1854 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1858 /* Create a keymap */
1862 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1865 prt(_("押すキー: ", "Keypress: "), 18, 0);
1867 /* Get a keymap trigger */
1868 do_cmd_macro_aux_keymap(buf);
1872 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1873 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1876 prt(_("行動: ", "Action: "), 20, 0);
1878 /* Convert to text */
1879 ascii_to_text(tmp, macro__buf);
1881 /* Get an encoded action */
1882 if (askfor(tmp, 80))
1884 /* Convert to ascii */
1885 text_to_ascii(macro__buf, tmp);
1887 /* Free old keymap */
1888 string_free(keymap_act[mode][(byte)(buf[0])]);
1890 /* Make new keymap */
1891 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1894 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1898 /* Remove a keymap */
1902 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1905 prt(_("押すキー: ", "Keypress: "), 18, 0);
1907 /* Get a keymap trigger */
1908 do_cmd_macro_aux_keymap(buf);
1910 /* Free old keymap */
1911 string_free(keymap_act[mode][(byte)(buf[0])]);
1913 /* Make new keymap */
1914 keymap_act[mode][(byte)(buf[0])] = NULL;
1917 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1920 /* Enter a new action */
1924 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1928 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1929 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1932 prt(_("マクロ行動: ", "Action: "), 20, 0);
1934 /* Hack -- limit the value */
1937 /* Get an encoded action */
1938 if (!askfor(buf, 80)) continue;
1940 /* Extract an action */
1941 text_to_ascii(macro__buf, buf);
1957 * @brief キャラクタ色の明暗表現
1959 static concptr lighting_level_str[F_LIT_MAX] =
1974 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1975 * @param i 指定対象となるキャラクタコード
1976 * @param num 指定されたビジュアルIDを返す参照ポインタ
1977 * @param max ビジュアルIDの最大数
1978 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1980 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1987 sprintf(str, "%d", *num);
1989 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1992 tmp = (IDX)strtol(str, NULL, 0);
1993 if (tmp >= 0 && tmp < max)
1996 else if (isupper(i))
1997 *num = (*num + max - 1) % max;
1999 *num = (*num + 1) % max;
2005 * @brief キャラクタの変更メニュー表示
2006 * @param choice_msg 選択メッセージ
2009 static void print_visuals_menu(concptr choice_msg)
2011 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2013 /* Give some choices */
2014 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2015 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2016 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2017 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2018 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2019 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2020 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2021 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2022 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2023 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2024 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2027 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2032 * Interact with "visuals"
2034 void do_cmd_visuals(player_type *creature_ptr)
2039 bool need_redraw = FALSE;
2040 concptr empty_symbol = "<< ? >>";
2042 if (use_bigtile) empty_symbol = "<< ?? >>";
2044 /* File type is "TEXT" */
2045 FILE_TYPE(FILE_TYPE_TEXT);
2048 /* Interact until done */
2053 /* Ask for a choice */
2054 print_visuals_menu(NULL);
2059 if (i == ESCAPE) break;
2063 /* Load a 'pref' file */
2066 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2069 prt(_("ファイル: ", "File: "), 17, 0);
2071 /* Default filename */
2072 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2075 if (!askfor(tmp, 70)) continue;
2077 /* Process the given filename */
2078 (void)process_pref_file(creature_ptr, tmp);
2083 /* Dump monster attr/chars */
2086 static concptr mark = "Monster attr/chars";
2089 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2092 prt(_("ファイル: ", "File: "), 17, 0);
2094 /* Default filename */
2095 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2097 /* Get a filename */
2098 if (!askfor(tmp, 70)) continue;
2099 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2101 /* Append to the file */
2102 if (!open_auto_dump(buf, mark)) continue;
2105 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2108 for (i = 0; i < max_r_idx; i++)
2110 monster_race *r_ptr = &r_info[i];
2112 /* Skip non-entries */
2113 if (!r_ptr->name) continue;
2115 /* Dump a comment */
2116 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2118 /* Dump the monster attr/char info */
2119 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2120 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2126 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2131 /* Dump object attr/chars */
2134 static concptr mark = "Object attr/chars";
2135 KIND_OBJECT_IDX k_idx;
2138 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2141 prt(_("ファイル: ", "File: "), 17, 0);
2143 /* Default filename */
2144 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2146 /* Get a filename */
2147 if (!askfor(tmp, 70)) continue;
2148 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2150 /* Append to the file */
2151 if (!open_auto_dump(buf, mark)) continue;
2154 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2157 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2159 GAME_TEXT o_name[MAX_NLEN];
2160 object_kind *k_ptr = &k_info[k_idx];
2162 /* Skip non-entries */
2163 if (!k_ptr->name) continue;
2168 strip_name(o_name, k_idx);
2174 /* Prepare dummy object */
2175 object_prep(&forge, k_idx);
2177 /* Get un-shuffled flavor name */
2178 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2181 /* Dump a comment */
2182 auto_dump_printf("# %s\n", o_name);
2184 /* Dump the object attr/char info */
2185 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2186 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2192 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2197 /* Dump feature attr/chars */
2200 static concptr mark = "Feature attr/chars";
2203 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2206 prt(_("ファイル: ", "File: "), 17, 0);
2208 /* Default filename */
2209 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2211 /* Get a filename */
2212 if (!askfor(tmp, 70)) continue;
2213 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2215 /* Append to the file */
2216 if (!open_auto_dump(buf, mark)) continue;
2219 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2222 for (i = 0; i < max_f_idx; i++)
2224 feature_type *f_ptr = &f_info[i];
2226 /* Skip non-entries */
2227 if (!f_ptr->name) continue;
2229 /* Skip mimiccing features */
2230 if (f_ptr->mimic != i) continue;
2232 /* Dump a comment */
2233 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2235 /* Dump the feature attr/char info */
2236 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2237 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2238 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2239 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2245 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2250 /* Modify monster attr/chars (numeric operation) */
2253 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2254 static MONRACE_IDX r = 0;
2256 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2258 /* Hack -- query until done */
2261 monster_race *r_ptr = &r_info[r];
2265 TERM_COLOR da = r_ptr->d_attr;
2266 byte dc = r_ptr->d_char;
2267 TERM_COLOR ca = r_ptr->x_attr;
2268 byte cc = r_ptr->x_char;
2270 /* Label the object */
2271 Term_putstr(5, 17, -1, TERM_WHITE,
2272 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2274 /* Label the Default values */
2275 Term_putstr(10, 19, -1, TERM_WHITE,
2276 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2278 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2279 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2281 /* Label the Current values */
2282 Term_putstr(10, 20, -1, TERM_WHITE,
2283 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2285 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2286 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2289 Term_putstr(0, 22, -1, TERM_WHITE,
2290 _("コマンド (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): "));
2295 if (i == ESCAPE) break;
2297 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2298 else if (isupper(i)) c = 'a' + i - 'A';
2308 if (!cmd_visuals_aux(i, &r, max_r_idx))
2313 } while (!r_info[r].name);
2317 t = (int)r_ptr->x_attr;
2318 (void)cmd_visuals_aux(i, &t, 256);
2319 r_ptr->x_attr = (byte)t;
2323 t = (int)r_ptr->x_char;
2324 (void)cmd_visuals_aux(i, &t, 256);
2325 r_ptr->x_char = (byte)t;
2329 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2331 print_visuals_menu(choice_msg);
2339 /* Modify object attr/chars (numeric operation) */
2342 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2344 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2346 /* Hack -- query until done */
2349 object_kind *k_ptr = &k_info[k];
2353 TERM_COLOR da = k_ptr->d_attr;
2354 SYMBOL_CODE dc = k_ptr->d_char;
2355 TERM_COLOR ca = k_ptr->x_attr;
2356 SYMBOL_CODE cc = k_ptr->x_char;
2358 /* Label the object */
2359 Term_putstr(5, 17, -1, TERM_WHITE,
2360 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2361 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2363 /* Label the Default values */
2364 Term_putstr(10, 19, -1, TERM_WHITE,
2365 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2367 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2368 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2370 /* Label the Current values */
2371 Term_putstr(10, 20, -1, TERM_WHITE,
2372 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2374 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2375 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2378 Term_putstr(0, 22, -1, TERM_WHITE,
2379 _("コマンド (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): "));
2384 if (i == ESCAPE) break;
2386 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2387 else if (isupper(i)) c = 'a' + i - 'A';
2397 if (!cmd_visuals_aux(i, &k, max_k_idx))
2402 } while (!k_info[k].name);
2406 t = (int)k_ptr->x_attr;
2407 (void)cmd_visuals_aux(i, &t, 256);
2408 k_ptr->x_attr = (byte)t;
2412 t = (int)k_ptr->x_char;
2413 (void)cmd_visuals_aux(i, &t, 256);
2414 k_ptr->x_char = (byte)t;
2418 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2420 print_visuals_menu(choice_msg);
2428 /* Modify feature attr/chars (numeric operation) */
2431 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2433 static IDX lighting_level = F_LIT_STANDARD;
2434 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2436 /* Hack -- query until done */
2439 feature_type *f_ptr = &f_info[f];
2443 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2444 byte dc = f_ptr->d_char[lighting_level];
2445 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2446 byte cc = f_ptr->x_char[lighting_level];
2448 /* Label the object */
2450 Term_putstr(5, 17, -1, TERM_WHITE,
2451 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2452 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2454 /* Label the Default values */
2455 Term_putstr(10, 19, -1, TERM_WHITE,
2456 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2458 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2459 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2461 /* Label the Current values */
2463 Term_putstr(10, 20, -1, TERM_WHITE,
2464 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2466 Term_putstr(10, 20, -1, TERM_WHITE,
2467 format("Current attr/char = %3d / %3d", ca, cc));
2470 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2471 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2475 Term_putstr(0, 22, -1, TERM_WHITE,
2476 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2478 Term_putstr(0, 22, -1, TERM_WHITE,
2479 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2485 if (i == ESCAPE) break;
2487 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2488 else if (isupper(i)) c = 'a' + i - 'A';
2498 if (!cmd_visuals_aux(i, &f, max_f_idx))
2503 } while (!f_info[f].name || (f_info[f].mimic != f));
2507 t = (int)f_ptr->x_attr[lighting_level];
2508 (void)cmd_visuals_aux(i, &t, 256);
2509 f_ptr->x_attr[lighting_level] = (byte)t;
2513 t = (int)f_ptr->x_char[lighting_level];
2514 (void)cmd_visuals_aux(i, &t, 256);
2515 f_ptr->x_char[lighting_level] = (byte)t;
2519 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2522 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2526 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2528 print_visuals_menu(choice_msg);
2536 /* Modify monster attr/chars (visual mode) */
2538 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2541 /* Modify object attr/chars (visual mode) */
2543 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2546 /* Modify feature attr/chars (visual mode) */
2549 IDX lighting_level = F_LIT_STANDARD;
2550 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2558 reset_visuals(creature_ptr);
2560 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2564 /* Unknown option */
2575 if (need_redraw) do_cmd_redraw(creature_ptr);
2580 * Interact with "colors"
2582 void do_cmd_colors(player_type *creature_ptr)
2588 /* File type is "TEXT" */
2589 FILE_TYPE(FILE_TYPE_TEXT);
2593 /* Interact until done */
2598 /* Ask for a choice */
2599 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2601 /* Give some choices */
2602 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2603 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2604 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2607 prt(_("コマンド: ", "Command: "), 8, 0);
2611 if (i == ESCAPE) break;
2613 /* Load a 'pref' file */
2617 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2620 prt(_("ファイル: ", "File: "), 10, 0);
2623 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2626 if (!askfor(tmp, 70)) continue;
2628 /* Process the given filename */
2629 (void)process_pref_file(creature_ptr, tmp);
2631 /* Mega-Hack -- react to changes */
2632 Term_xtra(TERM_XTRA_REACT, 0);
2634 /* Mega-Hack -- redraw */
2641 static concptr mark = "Colors";
2644 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2647 prt(_("ファイル: ", "File: "), 10, 0);
2649 /* Default filename */
2650 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2652 /* Get a filename */
2653 if (!askfor(tmp, 70)) continue;
2654 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2656 /* Append to the file */
2657 if (!open_auto_dump(buf, mark)) continue;
2660 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2663 for (i = 0; i < 256; i++)
2665 int kv = angband_color_table[i][0];
2666 int rv = angband_color_table[i][1];
2667 int gv = angband_color_table[i][2];
2668 int bv = angband_color_table[i][3];
2670 concptr name = _("未知", "unknown");
2672 /* Skip non-entries */
2673 if (!kv && !rv && !gv && !bv) continue;
2675 /* Extract the color name */
2676 if (i < 16) name = color_names[i];
2678 /* Dump a comment */
2679 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2681 /* Dump the monster attr/char info */
2682 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2689 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2698 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2700 /* Hack -- query until done */
2707 /* Exhibit the normal colors */
2708 for (j = 0; j < 16; j++)
2710 /* Exhibit this color */
2711 Term_putstr(j * 4, 20, -1, a, "###");
2713 /* Exhibit all colors */
2714 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2717 /* Describe the color */
2718 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2720 /* Describe the color */
2721 Term_putstr(5, 10, -1, TERM_WHITE,
2722 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2724 /* Label the Current values */
2725 Term_putstr(5, 12, -1, TERM_WHITE,
2726 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2727 angband_color_table[a][0],
2728 angband_color_table[a][1],
2729 angband_color_table[a][2],
2730 angband_color_table[a][3]));
2733 Term_putstr(0, 14, -1, TERM_WHITE,
2734 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2739 if (i == ESCAPE) break;
2742 if (i == 'n') a = (byte)(a + 1);
2743 if (i == 'N') a = (byte)(a - 1);
2744 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2745 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2746 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2747 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2748 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2749 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2750 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2751 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2753 /* Hack -- react to changes */
2754 Term_xtra(TERM_XTRA_REACT, 0);
2756 /* Hack -- redraw */
2761 /* Unknown option */
2775 * Note something in the message recall
2777 void do_cmd_note(void)
2785 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2787 /* Ignore empty notes */
2788 if (!buf[0] || (buf[0] == ' ')) return;
2790 /* Add the note to the message recall */
2791 msg_format(_("メモ: %s", "Note: %s"), buf);
2796 * Mention the current version
2798 void do_cmd_version(void)
2800 #if FAKE_VER_EXTRA > 0
2801 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2802 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2804 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2805 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2811 * Array of feeling strings
2813 static concptr do_cmd_feeling_text[11] =
2815 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2816 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2817 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2818 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2819 _("とても悪い予感がする...", "You have a very bad feeling..."),
2820 _("悪い予感がする...", "You have a bad feeling..."),
2821 _("何か緊張する。", "You feel nervous."),
2822 _("少し不運な気がする...", "You feel your luck is turning..."),
2823 _("この場所は好きになれない。", "You don't like the look of this place."),
2824 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2825 _("なんて退屈なところだ...", "What a boring place...")
2828 static concptr do_cmd_feeling_text_combat[11] =
2830 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2831 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2832 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2833 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2834 _("とても悪い予感がする...", "You have a very bad feeling..."),
2835 _("悪い予感がする...", "You have a bad feeling..."),
2836 _("何か緊張する。", "You feel nervous."),
2837 _("少し不運な気がする...", "You feel your luck is turning..."),
2838 _("この場所は好きになれない。", "You don't like the look of this place."),
2839 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2840 _("なんて退屈なところだ...", "What a boring place...")
2843 static concptr do_cmd_feeling_text_lucky[11] =
2845 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2846 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2847 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2848 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2849 _("とても良い感じがする...", "You have a very good feeling..."),
2850 _("良い感じがする...", "You have a good feeling..."),
2851 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2852 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2853 _("見た感じ悪くはない...", "You like the look of this place..."),
2854 _("全然駄目ということはないが...", "This level can't be all bad..."),
2855 _("なんて退屈なところだ...", "What a boring place...")
2860 * Note that "feeling" is set to zero unless some time has passed.
2861 * Note that this is done when the level is GENERATED, not entered.
2863 void do_cmd_feeling(player_type *creature_ptr)
2865 if (creature_ptr->wild_mode) return;
2867 /* No useful feeling in quests */
2868 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2870 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2874 /* No useful feeling in town */
2875 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2877 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2879 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2883 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2887 /* No useful feeling in the wilderness */
2888 if (!creature_ptr->current_floor_ptr->dun_level)
2890 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2894 /* Display the feeling */
2895 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2896 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2897 else if (IS_ECHIZEN(creature_ptr))
2898 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2900 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2905 * Description of each monster group.
2907 static concptr monster_group_text[] =
2910 "ユニーク", /* "Uniques" */
2911 "乗馬可能なモンスター", /* "Riding" */
2912 "賞金首", /* "Wanted */
2913 "アンバーの王族", /* "Amberite" */
2942 /* "古代ドラゴン/ワイアーム", */
3003 /* "Ancient Dragon/Wyrm", */
3012 "Multi-Headed Reptile",
3017 "Reptile/Amphibian",
3018 "Spider/Scorpion/Tick",
3020 /* "Major Demon", */
3037 * Symbols of monsters in each group. Note the "Uniques" group
3038 * is handled differently.
3040 static concptr monster_group_char[] =
3097 "!$&()+./=>?[\\]`{|~",
3107 * todo 引数と戻り値について追記求む
3108 * Build a list of monster indexes in the given group.
3110 * mode & 0x01 : check for non-empty group
3111 * mode & 0x02 : visual operation only
3113 * @param creature_ptr プレーヤーへの参照ポインタ
3114 * @param grp_cur ???
3115 * @param mon_idx[] ???
3117 * @return The number of monsters in the group
3119 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3121 /* Get a list of x_char in this group */
3122 concptr group_char = monster_group_char[grp_cur];
3124 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3125 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3126 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3127 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3129 /* Check every race */
3131 for (IDX i = 0; i < max_r_idx; i++)
3133 /* Access the race */
3134 monster_race *r_ptr = &r_info[i];
3136 /* Skip empty race */
3137 if (!r_ptr->name) continue;
3139 /* Require known monsters */
3140 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3144 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3147 else if (grp_riding)
3149 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3152 else if (grp_wanted)
3154 bool wanted = FALSE;
3156 for (j = 0; j < MAX_BOUNTY; j++)
3158 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3159 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3165 if (!wanted) continue;
3168 else if (grp_amberite)
3170 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3175 /* Check for race in the group */
3176 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3180 mon_idx[mon_cnt++] = i;
3182 /* XXX Hack -- Just checking for non-empty group */
3183 if (mode & 0x01) break;
3186 /* Terminate the list */
3187 mon_idx[mon_cnt] = -1;
3190 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3192 /* Return the number of races */
3198 * Description of each monster group.
3200 static concptr object_group_text[] =
3203 "キノコ", /* "Mushrooms" */
3204 "薬", /* "Potions" */
3205 "油つぼ", /* "Flasks" */
3206 "巻物", /* "Scrolls" */
3208 "アミュレット", /* "Amulets" */
3209 "笛", /* "Whistle" */
3210 "光源", /* "Lanterns" */
3211 "魔法棒", /* "Wands" */
3214 "カード", /* "Cards" */
3225 "刀剣類", /* "Swords" */
3226 "鈍器", /* "Blunt Weapons" */
3227 "長柄武器", /* "Polearms" */
3228 "採掘道具", /* "Diggers" */
3229 "飛び道具", /* "Bows" */
3233 "軽装鎧", /* "Soft Armor" */
3234 "重装鎧", /* "Hard Armor" */
3235 "ドラゴン鎧", /* "Dragon Armor" */
3236 "盾", /* "Shields" */
3237 "クローク", /* "Cloaks" */
3238 "籠手", /* "Gloves" */
3239 "ヘルメット", /* "Helms" */
3241 "ブーツ", /* "Boots" */
3294 * TVALs of items in each group
3296 static byte object_group_tval[] =
3337 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3345 * Build a list of object indexes in the given group. Return the number
3346 * of objects in the group.
3348 * mode & 0x01 : check for non-empty group
3349 * mode & 0x02 : visual operation only
3351 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3353 KIND_OBJECT_IDX i, object_cnt = 0;
3356 /* Get a list of x_char in this group */
3357 byte group_tval = object_group_tval[grp_cur];
3359 /* Check every object */
3360 for (i = 0; i < max_k_idx; i++)
3362 /* Access the object */
3363 object_kind *k_ptr = &k_info[i];
3365 /* Skip empty objects */
3366 if (!k_ptr->name) continue;
3370 if (!current_world_ptr->wizard)
3372 /* Skip non-flavoured objects */
3373 if (!k_ptr->flavor) continue;
3375 /* Require objects ever seen */
3376 if (!k_ptr->aware) continue;
3379 /* Skip items with no distribution (special artifacts) */
3380 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3384 /* Check for objects in the group */
3385 if (TV_LIFE_BOOK == group_tval)
3387 /* Hack -- All spell books */
3388 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3390 /* Add the object */
3391 object_idx[object_cnt++] = i;
3395 else if (k_ptr->tval == group_tval)
3397 /* Add the object */
3398 object_idx[object_cnt++] = i;
3402 /* XXX Hack -- Just checking for non-empty group */
3403 if (mode & 0x01) break;
3406 /* Terminate the list */
3407 object_idx[object_cnt] = -1;
3409 /* Return the number of objects */
3415 * Description of each feature group.
3417 static concptr feature_group_text[] =
3425 * Build a list of feature indexes in the given group. Return the number
3426 * of features in the group.
3428 * mode & 0x01 : check for non-empty group
3430 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3432 /* Check every feature */
3433 FEAT_IDX feat_cnt = 0;
3434 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3436 feature_type *f_ptr = &f_info[i];
3438 /* Skip empty index */
3439 if (!f_ptr->name) continue;
3441 /* Skip mimiccing features */
3442 if (f_ptr->mimic != i) continue;
3445 feat_idx[feat_cnt++] = i;
3447 /* XXX Hack -- Just checking for non-empty group */
3448 if (mode & 0x01) break;
3451 /* Terminate the list */
3452 feat_idx[feat_cnt] = -1;
3454 /* Return the number of races */
3460 * Hack -- load a screen dump from a file
3462 void do_cmd_load_screen(void)
3466 SYMBOL_CODE c = ' ';
3472 Term_get_size(&wid, &hgt);
3473 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3475 /* Append to the file */
3476 fff = my_fopen(buf, "r");
3480 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3488 /* Load the screen */
3489 for (y = 0; okay; y++)
3491 /* Get a line of data including control code */
3492 if (!fgets(buf, 1024, fff)) okay = FALSE;
3494 /* Get the blank line */
3495 if (buf[0] == '\n' || buf[0] == '\0') break;
3497 /* Ignore too large screen image */
3498 if (y >= hgt) continue;
3501 for (x = 0; x < wid - 1; x++)
3504 if (buf[x] == '\n' || buf[x] == '\0') break;
3506 /* Put the attr/char */
3507 Term_draw(x, y, TERM_WHITE, buf[x]);
3511 /* Dump the screen */
3512 for (y = 0; okay; y++)
3514 /* Get a line of data including control code */
3515 if (!fgets(buf, 1024, fff)) okay = FALSE;
3517 /* Get the blank line */
3518 if (buf[0] == '\n' || buf[0] == '\0') break;
3520 /* Ignore too large screen image */
3521 if (y >= hgt) continue;
3524 for (x = 0; x < wid - 1; x++)
3527 if (buf[x] == '\n' || buf[x] == '\0') break;
3529 /* Get the attr/char */
3530 (void)(Term_what(x, y, &a, &c));
3532 /* Look up the attr */
3533 for (int i = 0; i < 16; i++)
3535 /* Use attr matches */
3536 if (hack[i] == buf[x]) a = (byte_hack)i;
3539 /* Put the attr/char */
3540 Term_draw(x, y, a, c);
3546 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3554 // todo なぜこんな中途半端なところに? defineも…
3555 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3556 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3558 #define IM_FLAG_STR _("*", "* ")
3559 #define HAS_FLAG_STR _("+", "+ ")
3560 #define NO_FLAG_STR _("・", ". ")
3562 #define print_im_or_res_flag(IM, RES) \
3564 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3565 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3568 #define print_flag(TR) \
3570 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3574 /* XTRA HACK RESLIST */
3575 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)
3577 GAME_TEXT o_name[MAX_NLEN];
3578 BIT_FLAGS flgs[TR_FLAG_SIZE];
3580 if (!o_ptr->k_idx) return;
3581 if (o_ptr->tval != tval) return;
3583 /* Identified items only */
3584 if (!object_is_known(o_ptr)) return;
3587 * HACK:Ring of Lordly protection and Dragon equipment
3588 * have random resistances.
3590 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3591 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3592 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3593 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3594 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3595 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3596 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3597 || object_is_artifact(o_ptr);
3598 if (!is_special_item_type)
3604 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3606 while (o_name[i] && (i < 26))
3609 if (iskanji(o_name[i])) i++;
3618 o_name[i] = ' '; i++;
3624 fprintf(fff, "%s %s", where, o_name);
3626 if (!(o_ptr->ident & (IDENT_MENTAL)))
3628 fputs(_("-------不明--------------- -------不明---------\n",
3629 "-------unknown------------ -------unknown------\n"), fff);
3633 object_flags_known(o_ptr, flgs);
3635 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3636 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3637 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3638 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3639 print_flag(TR_RES_POIS);
3640 print_flag(TR_RES_LITE);
3641 print_flag(TR_RES_DARK);
3642 print_flag(TR_RES_SHARDS);
3643 print_flag(TR_RES_SOUND);
3644 print_flag(TR_RES_NETHER);
3645 print_flag(TR_RES_NEXUS);
3646 print_flag(TR_RES_CHAOS);
3647 print_flag(TR_RES_DISEN);
3651 print_flag(TR_RES_BLIND);
3652 print_flag(TR_RES_FEAR);
3653 print_flag(TR_RES_CONF);
3654 print_flag(TR_FREE_ACT);
3655 print_flag(TR_SEE_INVIS);
3656 print_flag(TR_HOLD_EXP);
3657 print_flag(TR_TELEPATHY);
3658 print_flag(TR_SLOW_DIGEST);
3659 print_flag(TR_REGEN);
3660 print_flag(TR_LEVITATION);
3669 fprintf(fff, "%s\n", inven_res_label);
3674 * Display *ID* ed weapons/armors's resistances
3676 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3679 GAME_TEXT file_name[1024];
3681 OBJECT_TYPE_VALUE tval;
3687 /* Open a new file */
3688 fff = my_fopen_temp(file_name, 1024);
3691 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3696 fprintf(fff, "%s\n", inven_res_label);
3698 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3702 for (; j < 9; j++) fputc('\n', fff);
3704 fprintf(fff, "%s\n", inven_res_label);
3707 strcpy(where, _("装", "E "));
3708 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3710 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3713 strcpy(where, _("持", "I "));
3714 for (i = 0; i < INVEN_PACK; i++)
3716 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3719 st_ptr = &town_info[1].store[STORE_HOME];
3720 strcpy(where, _("家", "H "));
3721 for (i = 0; i < st_ptr->stock_num; i++)
3723 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3729 /* Display the file contents */
3730 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3735 void do_cmd_save_screen_html_aux(char *filename, int message)
3743 concptr html_head[] = {
3744 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3748 concptr html_foot[] = {
3750 "</body>\n</html>\n",
3755 Term_get_size(&wid, &hgt);
3757 /* File type is "TEXT" */
3758 FILE_TYPE(FILE_TYPE_TEXT);
3760 /* Append to the file */
3762 fff = my_fopen(filename, "w");
3768 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3775 if (message) screen_save();
3777 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3779 tmpfff = my_fopen(buf, "r");
3782 for (int i = 0; html_head[i]; i++)
3783 fputs(html_head[i], fff);
3787 bool is_first_line = TRUE;
3788 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3792 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3793 is_first_line = FALSE;
3797 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3799 fprintf(fff, "%s\n", buf);
3804 /* Dump the screen */
3805 for (TERM_LEN y = 0; y < hgt; y++)
3808 if (y != 0) fprintf(fff, "\n");
3811 TERM_COLOR a = 0, old_a = 0;
3813 for (TERM_LEN x = 0; x < wid - 1; x++)
3816 /* Get the attr/char */
3817 (void)(Term_what(x, y, &a, &c));
3821 case '&': cc = "&"; break;
3822 case '<': cc = "<"; break;
3823 case '>': cc = ">"; break;
3825 case 0x1f: c = '.'; break;
3826 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3831 if ((y == 0 && x == 0) || a != old_a)
3833 int rv = angband_color_table[a][1];
3834 int gv = angband_color_table[a][2];
3835 int bv = angband_color_table[a][3];
3836 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3837 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3842 fprintf(fff, "%s", cc);
3844 fprintf(fff, "%c", c);
3848 fprintf(fff, "</font>");
3852 for (int i = 0; html_foot[i]; i++)
3853 fputs(html_foot[i], fff);
3858 bool is_first_line = TRUE;
3859 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3863 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3864 is_first_line = FALSE;
3868 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3870 fprintf(fff, "%s\n", buf);
3883 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3892 * Hack -- save a screen dump to a file
3894 static void do_cmd_save_screen_html(void)
3896 char buf[1024], tmp[256] = "screen.html";
3898 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3900 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3904 do_cmd_save_screen_html_aux(buf, 1);
3909 * Redefinable "save_screen" action
3911 void(*screendump_aux)(void) = NULL;
3915 * Save a screen dump to a file
3916 * @param creature_ptr プレーヤーへの参照ポインタ
3919 void do_cmd_save_screen(player_type *creature_ptr)
3921 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3922 bool html_dump = FALSE;
3926 if (c == 'Y' || c == 'y')
3928 else if (c == 'H' || c == 'h')
3941 Term_get_size(&wid, &hgt);
3943 bool old_use_graphics = use_graphics;
3944 if (old_use_graphics)
3946 use_graphics = FALSE;
3947 reset_visuals(creature_ptr);
3948 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3949 handle_stuff(creature_ptr);
3954 do_cmd_save_screen_html();
3955 do_cmd_redraw(creature_ptr);
3958 /* Do we use a special screendump function ? */
3959 else if (screendump_aux)
3961 /* Dump the screen to a graphics file */
3962 (*screendump_aux)();
3964 else /* Dump the screen as text */
3968 SYMBOL_CODE c = ' ';
3971 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3973 /* File type is "TEXT" */
3974 FILE_TYPE(FILE_TYPE_TEXT);
3976 /* Append to the file */
3977 fff = my_fopen(buf, "w");
3981 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3988 /* Dump the screen */
3989 for (y = 0; y < hgt; y++)
3992 for (x = 0; x < wid - 1; x++)
3994 /* Get the attr/char */
3995 (void)(Term_what(x, y, &a, &c));
4005 fprintf(fff, "%s\n", buf);
4012 /* Dump the screen */
4013 for (y = 0; y < hgt; y++)
4016 for (x = 0; x < wid - 1; x++)
4018 /* Get the attr/char */
4019 (void)(Term_what(x, y, &a, &c));
4022 buf[x] = hack[a & 0x0F];
4029 fprintf(fff, "%s\n", buf);
4036 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4041 if (!old_use_graphics) return;
4043 use_graphics = TRUE;
4044 reset_visuals(creature_ptr);
4045 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4046 handle_stuff(creature_ptr);
4051 * todo okay = 既知のアーティファクト? と思われるが確証がない
4052 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4053 * Check the status of "artifacts"
4054 * @param player_ptr プレーヤーへの参照ポインタ
4057 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4059 /* Open a new file */
4061 GAME_TEXT file_name[1024];
4062 fff = my_fopen_temp(file_name, 1024);
4065 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4070 /* Allocate the "who" array */
4072 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4074 /* Allocate the "okay" array */
4076 C_MAKE(okay, max_a_idx, bool);
4078 /* Scan the artifacts */
4079 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4081 artifact_type *a_ptr = &a_info[k];
4086 /* Skip "empty" artifacts */
4087 if (!a_ptr->name) continue;
4089 /* Skip "uncreated" artifacts */
4090 if (!a_ptr->cur_num) continue;
4096 /* Check the dungeon */
4097 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4099 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4101 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4103 OBJECT_IDX this_o_idx, next_o_idx = 0;
4105 /* Scan all objects in the grid */
4106 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4109 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4110 next_o_idx = o_ptr->next_o_idx;
4112 /* Ignore non-artifacts */
4113 if (!object_is_fixed_artifact(o_ptr)) continue;
4115 /* Ignore known items */
4116 if (object_is_known(o_ptr)) continue;
4118 /* Note the artifact */
4119 okay[o_ptr->name1] = FALSE;
4124 /* Check the player_ptr->inventory_list and equipment */
4125 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4127 object_type *o_ptr = &player_ptr->inventory_list[i];
4129 /* Ignore non-objects */
4130 if (!o_ptr->k_idx) continue;
4132 /* Ignore non-artifacts */
4133 if (!object_is_fixed_artifact(o_ptr)) continue;
4135 /* Ignore known items */
4136 if (object_is_known(o_ptr)) continue;
4138 /* Note the artifact */
4139 okay[o_ptr->name1] = FALSE;
4143 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4145 if (okay[k]) who[n++] = k;
4149 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4151 /* Scan the artifacts */
4152 for (ARTIFACT_IDX k = 0; k < n; k++)
4154 artifact_type *a_ptr = &a_info[who[k]];
4155 GAME_TEXT base_name[MAX_NLEN];
4156 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4158 /* Obtain the base object type */
4159 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4168 /* Create fake object */
4169 object_prep(q_ptr, z);
4171 /* Make it an artifact */
4172 q_ptr->name1 = (byte)who[k];
4174 /* Display as if known */
4175 q_ptr->ident |= IDENT_STORE;
4177 /* Describe the artifact */
4178 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4181 /* Hack -- Build the artifact name */
4182 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4185 /* Free the "who" array */
4186 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4188 /* Free the "okay" array */
4189 C_KILL(okay, max_a_idx, bool);
4192 /* Display the file contents */
4193 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4199 * Display known uniques
4200 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4202 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4209 GAME_TEXT file_name[1024];
4212 int n_alive_surface = 0;
4213 int n_alive_over100 = 0;
4214 int n_alive_total = 0;
4217 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4219 /* Open a new file */
4220 fff = my_fopen_temp(file_name, 1024);
4224 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4229 /* Allocate the "who" array */
4230 C_MAKE(who, max_r_idx, MONRACE_IDX);
4232 /* Scan the monsters */
4234 for (IDX i = 1; i < max_r_idx; i++)
4236 monster_race *r_ptr = &r_info[i];
4239 if (!r_ptr->name) continue;
4241 /* Require unique monsters */
4242 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4244 /* Only display "known" uniques */
4245 if (!cheat_know && !r_ptr->r_sights) continue;
4247 /* Only print rarity <= 100 uniques */
4248 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4250 /* Only "alive" uniques */
4251 if (r_ptr->max_num == 0) continue;
4255 lev = (r_ptr->level - 1) / 10;
4259 if (max_lev < lev) max_lev = lev;
4261 else n_alive_over100++;
4263 else n_alive_surface++;
4265 /* Collect "appropriate" monsters */
4269 /* Sort the array by dungeon depth of monsters */
4270 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4272 if (n_alive_surface)
4274 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4275 n_alive_total += n_alive_surface;
4278 for (IDX i = 0; i <= max_lev; i++)
4280 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4281 n_alive_total += n_alive[i];
4284 if (n_alive_over100)
4286 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4287 n_alive_total += n_alive_over100;
4292 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4293 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4297 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4300 /* Scan the monster races */
4301 for (int k = 0; k < n; k++)
4303 monster_race *r_ptr = &r_info[who[k]];
4304 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4307 /* Free the "who" array */
4308 C_KILL(who, max_r_idx, s16b);
4311 /* Display the file contents */
4312 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4318 * Display weapon-exp
4320 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4322 /* Open a new file */
4324 GAME_TEXT file_name[1024];
4325 fff = my_fopen_temp(file_name, 1024);
4328 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4333 for (int i = 0; i < 5; i++)
4335 for (int num = 0; num < 64; num++)
4339 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4341 object_kind *k_ptr = &k_info[j];
4343 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4344 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4346 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4348 fprintf(fff, "%-25s ", tmp);
4349 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4350 else fprintf(fff, " ");
4351 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4352 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4361 /* Display the file contents */
4362 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4368 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4372 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4374 /* Open a new file */
4376 GAME_TEXT file_name[1024];
4377 fff = my_fopen_temp(file_name, 1024);
4380 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4385 if (creature_ptr->realm1 != REALM_NONE)
4387 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4388 for (SPELL_IDX i = 0; i < 32; i++)
4390 const magic_type *s_ptr;
4391 if (!is_magic(creature_ptr->realm1))
4393 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4397 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4400 if (s_ptr->slevel >= 99) continue;
4401 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4402 int exp_level = spell_exp_level(spell_exp);
4403 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4404 if (creature_ptr->realm1 == REALM_HISSATSU)
4405 fprintf(fff, "[--]");
4408 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4409 else fprintf(fff, " ");
4410 fprintf(fff, "%s", exp_level_str[exp_level]);
4413 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4418 if (creature_ptr->realm2 != REALM_NONE)
4420 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4421 for (SPELL_IDX i = 0; i < 32; i++)
4423 const magic_type *s_ptr;
4424 if (!is_magic(creature_ptr->realm1))
4426 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4430 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4433 if (s_ptr->slevel >= 99) continue;
4435 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4436 int exp_level = spell_exp_level(spell_exp);
4437 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4438 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4439 else fprintf(fff, " ");
4440 fprintf(fff, "%s", exp_level_str[exp_level]);
4441 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4448 /* Display the file contents */
4449 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4455 * @brief スキル情報を表示するコマンドのメインルーチン /
4459 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4461 char skill_name[GINOU_TEMPMAX][20] =
4463 _("マーシャルアーツ", "Martial Arts "),
4464 _("二刀流 ", "Dual Wielding "),
4465 _("乗馬 ", "Riding "),
4469 /* Open a new file */
4471 char file_name[1024];
4472 fff = my_fopen_temp(file_name, 1024);
4475 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4480 for (int i = 0; i < GINOU_TEMPMAX; i++)
4482 int skill_exp = creature_ptr->skill_exp[i];
4483 fprintf(fff, "%-20s ", skill_name[i]);
4484 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4485 else fprintf(fff, " ");
4486 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4487 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4493 /* Display the file contents */
4494 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4500 * @brief 現在のペットを表示するコマンドのメインルーチン /
4501 * Display current pets
4502 * @param creature_ptr プレーヤーへの参照ポインタ
4505 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4507 /* Open a new file */
4508 GAME_TEXT file_name[1024];
4510 fff = my_fopen_temp(file_name, 1024);
4513 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4518 /* Process the monsters (backwards) */
4519 monster_type *m_ptr;
4520 GAME_TEXT pet_name[MAX_NLEN];
4522 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4524 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4526 /* Ignore "dead" monsters */
4527 if (!monster_is_valid(m_ptr)) continue;
4529 /* Calculate "upkeep" for pets */
4530 if (!is_pet(m_ptr)) continue;
4533 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4534 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4537 int show_upkeep = calculate_upkeep(creature_ptr);
4539 fprintf(fff, "----------------------------------------------\n");
4541 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4543 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4545 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4549 /* Display the file contents */
4550 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4556 * @brief 現在のペットを表示するコマンドのメインルーチン /
4557 * @param creature_ptr プレーヤーへの参照ポインタ
4560 * @note the player ghosts are ignored.
4562 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4564 /* Open a new file */
4566 GAME_TEXT file_name[1024];
4567 fff = my_fopen_temp(file_name, 1024);
4570 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4575 /* Allocate the "who" array */
4577 C_MAKE(who, max_r_idx, MONRACE_IDX);
4581 /* Monsters slain */
4582 for (int kk = 1; kk < max_r_idx; kk++)
4584 monster_race *r_ptr = &r_info[kk];
4586 if (r_ptr->flags1 & (RF1_UNIQUE))
4588 bool dead = (r_ptr->max_num == 0);
4597 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4599 if (this_monster > 0)
4601 total += this_monster;
4607 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4610 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4612 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4618 /* Scan the monsters */
4620 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4622 monster_race *r_ptr = &r_info[i];
4624 /* Use that monster */
4625 if (r_ptr->name) who[n++] = i;
4628 /* Sort the array by dungeon depth of monsters */
4630 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4632 /* Scan the monster races */
4633 for (int k = 0; k < n; k++)
4635 monster_race *r_ptr = &r_info[who[k]];
4637 if (r_ptr->flags1 & (RF1_UNIQUE))
4639 bool dead = (r_ptr->max_num == 0);
4643 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4650 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4652 if (this_monster <= 0) continue;
4655 /* p,tは人と数える by ita */
4656 if (my_strchr("pt", r_ptr->d_char))
4657 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4659 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4661 if (this_monster < 2)
4663 if (my_strstr(r_name + r_ptr->name, "coins"))
4665 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4669 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4675 strcpy(ToPlural, (r_name + r_ptr->name));
4676 plural_aux(ToPlural);
4677 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4680 total += this_monster;
4683 fprintf(fff, "----------------------------------------------\n");
4685 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4687 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4690 /* Free the "who" array */
4691 C_KILL(who, max_r_idx, s16b);
4694 /* Display the file contents */
4695 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4701 * @brief モンスター情報リスト中のグループを表示する /
4702 * Display the object groups.
4706 * @param per_page リストの表示行
4707 * @param grp_idx グループのID配列
4708 * @param group_text グループ名の文字列配列
4709 * @param grp_cur 現在の選択ID
4710 * @param grp_top 現在の選択リスト最上部ID
4713 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)
4715 /* Display lines until done */
4716 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4718 /* Get the group index */
4719 int grp = grp_idx[grp_top + i];
4721 /* Choose a color */
4722 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4724 /* Erase the entire line */
4725 Term_erase(col, row + i, wid);
4727 /* Display the group label */
4728 c_put_str(attr, group_text[grp], row + i, col);
4734 * Move the cursor in a browser window
4736 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4737 IDX *list_cur, int list_cnt)
4742 IDX list = *list_cur;
4744 /* Extract direction */
4747 /* Hack -- scroll up full screen */
4752 /* Hack -- scroll down full screen */
4757 d = get_keymap_dir(ch);
4762 /* Diagonals - hack */
4763 if ((ddx[d] > 0) && ddy[d])
4768 Term_get_size(&wid, &hgt);
4770 browser_rows = hgt - 8;
4772 /* Browse group list */
4777 /* Move up or down */
4778 grp += ddy[d] * (browser_rows - 1);
4781 if (grp >= grp_cnt) grp = grp_cnt - 1;
4782 if (grp < 0) grp = 0;
4783 if (grp != old_grp) list = 0;
4786 /* Browse sub-list list */
4789 /* Move up or down */
4790 list += ddy[d] * browser_rows;
4793 if (list >= list_cnt) list = list_cnt - 1;
4794 if (list < 0) list = 0;
4806 if (col < 0) col = 0;
4807 if (col > 1) col = 1;
4814 /* Browse group list */
4819 /* Move up or down */
4823 if (grp >= grp_cnt) grp = grp_cnt - 1;
4824 if (grp < 0) grp = 0;
4825 if (grp != old_grp) list = 0;
4828 /* Browse sub-list list */
4831 /* Move up or down */
4832 list += (IDX)ddy[d];
4835 if (list >= list_cnt) list = list_cnt - 1;
4836 if (list < 0) list = 0;
4847 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4849 /* Clear the display lines */
4850 for (int i = 0; i < height; i++)
4852 Term_erase(col, row + i, width);
4855 /* Bigtile mode uses double width */
4856 if (use_bigtile) width /= 2;
4858 /* Display lines until done */
4859 for (int i = 0; i < height; i++)
4861 /* Display columns until done */
4862 for (int j = 0; j < width; j++)
4864 TERM_LEN x = col + j;
4865 TERM_LEN y = row + i;
4867 /* Bigtile mode uses double width */
4868 if (use_bigtile) x += j;
4870 TERM_COLOR ia = attr_top + i;
4871 SYMBOL_CODE ic = char_left + j;
4873 /* Ignore illegal characters */
4874 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4875 (!use_graphics && ic > 0x7f))
4881 /* Force correct code for both ASCII character and tile */
4882 if (c & 0x80) a |= 0x80;
4884 /* Display symbol */
4885 Term_queue_bigchar(x, y, a, c, 0, 0);
4892 * Place the cursor at the collect position for visual mode
4894 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4896 int i = (a & 0x7f) - attr_top;
4897 int j = c - char_left;
4899 TERM_LEN x = col + j;
4900 TERM_LEN y = row + i;
4902 /* Bigtile mode uses double width */
4903 if (use_bigtile) x += j;
4905 /* Place the cursor */
4911 * Do visual mode command -- Change symbols
4913 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4914 int height, int width,
4915 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4916 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4918 static TERM_COLOR attr_old = 0;
4919 static SYMBOL_CODE char_old = 0;
4924 if (*visual_list_ptr)
4927 *cur_attr_ptr = attr_old;
4928 *cur_char_ptr = char_old;
4929 *visual_list_ptr = FALSE;
4937 if (*visual_list_ptr)
4940 *visual_list_ptr = FALSE;
4941 *need_redraw = TRUE;
4949 if (!*visual_list_ptr)
4951 *visual_list_ptr = TRUE;
4953 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4954 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4956 attr_old = *cur_attr_ptr;
4957 char_old = *cur_char_ptr;
4968 /* Set the visual */
4969 attr_idx = *cur_attr_ptr;
4970 char_idx = *cur_char_ptr;
4972 /* Hack -- for feature lighting */
4973 for (i = 0; i < F_LIT_MAX; i++)
4975 attr_idx_feat[i] = 0;
4976 char_idx_feat[i] = 0;
4983 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4986 *cur_attr_ptr = attr_idx;
4987 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4988 if (!*visual_list_ptr) *need_redraw = TRUE;
4994 *cur_char_ptr = char_idx;
4995 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4996 if (!*visual_list_ptr) *need_redraw = TRUE;
5002 if (*visual_list_ptr)
5005 int d = get_keymap_dir(ch);
5006 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5007 SYMBOL_CODE c = *cur_char_ptr;
5009 if (use_bigtile) eff_width = width / 2;
5010 else eff_width = width;
5012 /* Restrict direction */
5013 if ((a == 0) && (ddy[d] < 0)) d = 0;
5014 if ((c == 0) && (ddx[d] < 0)) d = 0;
5015 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5016 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5018 a += (TERM_COLOR)ddy[d];
5019 c += (SYMBOL_CODE)ddx[d];
5021 /* Force correct code for both ASCII character and tile */
5022 if (c & 0x80) a |= 0x80;
5024 /* Set the visual */
5029 /* Move the frame */
5030 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5031 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5032 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5033 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5039 /* Visual mode command is not used */
5045 * Display the monsters in a group.
5047 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5048 int mon_cur, int mon_top, bool visual_only)
5050 /* Display lines until done */
5052 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5056 /* Get the race index */
5057 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5059 /* Access the race */
5060 monster_race *r_ptr = &r_info[r_idx];
5062 /* Choose a color */
5063 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5065 /* Display the name */
5066 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5068 /* Hack -- visual_list mode */
5071 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5074 if (current_world_ptr->wizard || visual_only)
5076 c_prt(attr, format("%d", r_idx), row + i, 62);
5079 /* Erase chars before overwritten by the race letter */
5080 Term_erase(69, row + i, 255);
5082 /* Display symbol */
5083 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5088 if (!(r_ptr->flags1 & RF1_UNIQUE))
5089 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5091 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5092 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5096 /* Clear remaining lines */
5097 for (; i < per_page; i++)
5099 Term_erase(col, row + i, 255);
5105 * todo 引数の詳細について加筆求む
5106 * Display known monsters.
5107 * @param creature_ptr プレーヤーへの参照ポインタ
5108 * @param need_redraw 画面の再描画が必要な時TRUE
5109 * @param visual_only ???
5110 * @param direct_r_idx モンスターID
5113 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5116 Term_get_size(&wid, &hgt);
5118 /* Allocate the "mon_idx" array */
5120 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5126 bool visual_list = FALSE;
5127 TERM_COLOR attr_top = 0;
5130 int browser_rows = hgt - 8;
5131 if (direct_r_idx < 0)
5133 mode = visual_only ? 0x03 : 0x01;
5135 /* Check every group */
5137 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5139 /* Measure the label */
5140 len = strlen(monster_group_text[i]);
5142 /* Save the maximum length */
5143 if (len > max) max = len;
5145 /* See if any monsters are known */
5146 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5148 /* Build a list of groups with known monsters */
5149 grp_idx[grp_cnt++] = i;
5157 mon_idx[0] = direct_r_idx;
5160 /* Terminate the list */
5163 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5164 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5167 /* Terminate the list */
5168 grp_idx[grp_cnt] = -1;
5170 mode = visual_only ? 0x02 : 0x00;
5171 IDX old_grp_cur = -1;
5184 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5185 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5186 prt(_("名前", "Name"), 4, max + 3);
5187 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5188 prt(_("文字", "Sym"), 4, 67);
5189 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5191 for (IDX i = 0; i < 78; i++)
5193 Term_putch(i, 5, TERM_WHITE, '=');
5196 if (direct_r_idx < 0)
5198 for (IDX i = 0; i < browser_rows; i++)
5200 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5207 if (direct_r_idx < 0)
5209 /* Scroll group list */
5210 if (grp_cur < grp_top) grp_top = grp_cur;
5211 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5213 /* Display a list of monster groups */
5214 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5216 if (old_grp_cur != grp_cur)
5218 old_grp_cur = grp_cur;
5220 /* Get a list of monsters in the current group */
5221 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5224 /* Scroll monster list */
5225 while (mon_cur < mon_top)
5226 mon_top = MAX(0, mon_top - browser_rows / 2);
5227 while (mon_cur >= mon_top + browser_rows)
5228 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5233 /* Display a list of monsters in the current group */
5234 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5240 /* Display a monster name */
5241 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5243 /* Display visual list below first monster */
5244 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5248 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5249 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5250 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5251 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5254 /* Get the current monster */
5255 monster_race *r_ptr;
5256 r_ptr = &r_info[mon_idx[mon_cur]];
5260 /* Mega Hack -- track this monster race */
5261 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5262 handle_stuff(creature_ptr);
5267 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5271 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5275 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5280 /* Do visual mode command if needed */
5281 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))
5283 if (direct_r_idx >= 0)
5309 /* Recall on screen */
5310 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5312 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5324 /* Move the cursor */
5325 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5332 /* Free the "mon_idx" array */
5333 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5338 * Display the objects in a group.
5340 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5341 int object_cur, int object_top, bool visual_only)
5343 /* Display lines until done */
5345 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5347 GAME_TEXT o_name[MAX_NLEN];
5350 object_kind *flavor_k_ptr;
5352 /* Get the object index */
5353 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5355 /* Access the object */
5356 object_kind *k_ptr = &k_info[k_idx];
5358 /* Choose a color */
5359 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5360 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5362 if (!visual_only && k_ptr->flavor)
5364 /* Appearance of this object is shuffled */
5365 flavor_k_ptr = &k_info[k_ptr->flavor];
5369 /* Appearance of this object is very normal */
5370 flavor_k_ptr = k_ptr;
5373 attr = ((i + object_top == object_cur) ? cursor : attr);
5375 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5378 strip_name(o_name, k_idx);
5383 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5386 /* Display the name */
5387 c_prt(attr, o_name, row + i, col);
5389 /* Hack -- visual_list mode */
5392 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);
5395 if (current_world_ptr->wizard || visual_only)
5397 c_prt(attr, format("%d", k_idx), row + i, 70);
5400 a = flavor_k_ptr->x_attr;
5401 c = flavor_k_ptr->x_char;
5403 /* Display symbol */
5404 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5407 /* Clear remaining lines */
5408 for (; i < per_page; i++)
5410 Term_erase(col, row + i, 255);
5416 * Describe fake object
5418 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5421 object_type object_type_body;
5422 o_ptr = &object_type_body;
5424 object_prep(o_ptr, k_idx);
5426 /* It's fully know */
5427 o_ptr->ident |= IDENT_KNOWN;
5428 handle_stuff(creature_ptr);
5430 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5432 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5438 * Display known objects
5440 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5442 IDX object_old, object_top;
5445 OBJECT_IDX *object_idx;
5447 bool visual_list = FALSE;
5448 TERM_COLOR attr_top = 0;
5453 Term_get_size(&wid, &hgt);
5455 int browser_rows = hgt - 8;
5457 /* Allocate the "object_idx" array */
5458 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5463 if (direct_k_idx < 0)
5465 mode = visual_only ? 0x03 : 0x01;
5467 /* Check every group */
5468 for (IDX i = 0; object_group_text[i] != NULL; i++)
5470 /* Measure the label */
5471 len = strlen(object_group_text[i]);
5473 /* Save the maximum length */
5474 if (len > max) max = len;
5476 /* See if any monsters are known */
5477 if (collect_objects(i, object_idx, mode))
5479 /* Build a list of groups with known monsters */
5480 grp_idx[grp_cnt++] = i;
5489 object_kind *k_ptr = &k_info[direct_k_idx];
5490 object_kind *flavor_k_ptr;
5492 if (!visual_only && k_ptr->flavor)
5494 /* Appearance of this object is shuffled */
5495 flavor_k_ptr = &k_info[k_ptr->flavor];
5499 /* Appearance of this object is very normal */
5500 flavor_k_ptr = k_ptr;
5503 object_idx[0] = direct_k_idx;
5504 object_old = direct_k_idx;
5507 /* Terminate the list */
5510 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5511 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5514 /* Terminate the list */
5515 grp_idx[grp_cnt] = -1;
5517 mode = visual_only ? 0x02 : 0x00;
5518 IDX old_grp_cur = -1;
5521 IDX object_cur = object_top = 0;
5527 object_kind *k_ptr, *flavor_k_ptr;
5534 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5535 if (direct_k_idx < 0) prt("グループ", 4, 0);
5536 prt("名前", 4, max + 3);
5537 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5540 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5541 if (direct_k_idx < 0) prt("Group", 4, 0);
5542 prt("Name", 4, max + 3);
5543 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5547 for (IDX i = 0; i < 78; i++)
5549 Term_putch(i, 5, TERM_WHITE, '=');
5552 if (direct_k_idx < 0)
5554 for (IDX i = 0; i < browser_rows; i++)
5556 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5563 if (direct_k_idx < 0)
5565 /* Scroll group list */
5566 if (grp_cur < grp_top) grp_top = grp_cur;
5567 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5569 /* Display a list of object groups */
5570 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5572 if (old_grp_cur != grp_cur)
5574 old_grp_cur = grp_cur;
5576 /* Get a list of objects in the current group */
5577 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5580 /* Scroll object list */
5581 while (object_cur < object_top)
5582 object_top = MAX(0, object_top - browser_rows / 2);
5583 while (object_cur >= object_top + browser_rows)
5584 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5589 /* Display a list of objects in the current group */
5590 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5594 object_top = object_cur;
5596 /* Display a list of objects in the current group */
5597 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5599 /* Display visual list below first object */
5600 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5603 /* Get the current object */
5604 k_ptr = &k_info[object_idx[object_cur]];
5606 if (!visual_only && k_ptr->flavor)
5608 /* Appearance of this object is shuffled */
5609 flavor_k_ptr = &k_info[k_ptr->flavor];
5613 /* Appearance of this object is very normal */
5614 flavor_k_ptr = k_ptr;
5619 prt(format("<方向>%s%s%s, ESC",
5620 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5621 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5622 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5625 prt(format("<dir>%s%s%s, ESC",
5626 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5627 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5628 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5634 /* Mega Hack -- track this object */
5635 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5637 /* The "current" object changed */
5638 if (object_old != object_idx[object_cur])
5640 handle_stuff(creature_ptr);
5642 /* Remember the "current" object */
5643 object_old = object_idx[object_cur];
5649 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5653 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5657 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5662 /* Do visual mode command if needed */
5663 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))
5665 if (direct_k_idx >= 0)
5690 /* Recall on screen */
5691 if (!visual_list && !visual_only && (grp_cnt > 0))
5693 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5701 /* Move the cursor */
5702 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5708 /* Free the "object_idx" array */
5709 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5714 * Display the features in a group.
5716 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5717 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5719 int lit_col[F_LIT_MAX], i;
5720 int f_idx_col = use_bigtile ? 62 : 64;
5722 /* Correct columns 1 and 4 */
5723 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5724 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5725 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5727 /* Display lines until done */
5728 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5731 FEAT_IDX f_idx = feat_idx[feat_top + i];
5732 feature_type *f_ptr = &f_info[f_idx];
5733 int row_i = row + i;
5735 /* Choose a color */
5736 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5738 /* Display the name */
5739 c_prt(attr, f_name + f_ptr->name, row_i, col);
5741 /* Hack -- visual_list mode */
5744 /* Display lighting level */
5745 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5747 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));
5749 if (current_world_ptr->wizard || visual_only)
5751 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5754 /* Display symbol */
5755 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);
5757 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5758 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5760 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5762 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5764 /* Mega-hack -- Use non-standard colour */
5765 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5767 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5771 /* Clear remaining lines */
5772 for (; i < per_page; i++)
5774 Term_erase(col, row + i, 255);
5780 * Interact with feature visuals.
5782 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5784 TERM_COLOR attr_old[F_LIT_MAX];
5785 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5786 SYMBOL_CODE char_old[F_LIT_MAX];
5787 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5790 Term_get_size(&wid, &hgt);
5792 /* Allocate the "feat_idx" array */
5794 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5800 FEAT_IDX grp_idx[100];
5801 TERM_COLOR attr_top = 0;
5802 bool visual_list = FALSE;
5804 TERM_LEN browser_rows = hgt - 8;
5805 if (direct_f_idx < 0)
5807 /* Check every group */
5808 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5810 /* Measure the label */
5811 len = strlen(feature_group_text[i]);
5813 /* Save the maximum length */
5814 if (len > max) max = len;
5816 /* See if any features are known */
5817 if (collect_features(feat_idx, 0x01))
5819 /* Build a list of groups with known features */
5820 grp_idx[grp_cnt++] = i;
5828 feature_type *f_ptr = &f_info[direct_f_idx];
5830 feat_idx[0] = direct_f_idx;
5833 /* Terminate the list */
5836 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5837 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5839 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5841 attr_old[i] = f_ptr->x_attr[i];
5842 char_old[i] = f_ptr->x_char[i];
5846 /* Terminate the list */
5847 grp_idx[grp_cnt] = -1;
5849 FEAT_IDX old_grp_cur = -1;
5850 FEAT_IDX grp_cur = 0;
5851 FEAT_IDX grp_top = 0;
5852 FEAT_IDX feat_cur = 0;
5853 FEAT_IDX feat_top = 0;
5854 TERM_LEN column = 0;
5857 TERM_COLOR *cur_attr_ptr;
5858 SYMBOL_CODE *cur_char_ptr;
5862 feature_type *f_ptr;
5868 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5869 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5870 prt(_("名前", "Name"), 4, max + 3);
5873 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5874 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5878 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5879 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5882 for (FEAT_IDX i = 0; i < 78; i++)
5884 Term_putch(i, 5, TERM_WHITE, '=');
5887 if (direct_f_idx < 0)
5889 for (FEAT_IDX i = 0; i < browser_rows; i++)
5891 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5898 if (direct_f_idx < 0)
5900 /* Scroll group list */
5901 if (grp_cur < grp_top) grp_top = grp_cur;
5902 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5904 /* Display a list of feature groups */
5905 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5907 if (old_grp_cur != grp_cur)
5909 old_grp_cur = grp_cur;
5911 /* Get a list of features in the current group */
5912 feat_cnt = collect_features(feat_idx, 0x00);
5915 /* Scroll feature list */
5916 while (feat_cur < feat_top)
5917 feat_top = MAX(0, feat_top - browser_rows / 2);
5918 while (feat_cur >= feat_top + browser_rows)
5919 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5924 /* Display a list of features in the current group */
5925 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5929 feat_top = feat_cur;
5931 /* Display a list of features in the current group */
5932 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5934 /* Display visual list below first object */
5935 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5939 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5940 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5941 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5944 /* Get the current feature */
5945 f_ptr = &f_info[feat_idx[feat_cur]];
5946 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5947 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5951 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5955 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5959 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5964 if (visual_list && ((ch == 'A') || (ch == 'a')))
5966 int prev_lighting_level = *lighting_level;
5970 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5971 else (*lighting_level)--;
5975 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5976 else (*lighting_level)++;
5979 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5980 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5982 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5983 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5988 else if ((ch == 'D') || (ch == 'd'))
5990 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5991 byte prev_x_char = f_ptr->x_char[*lighting_level];
5993 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
5997 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
5998 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6000 if (prev_x_char != f_ptr->x_char[*lighting_level])
6001 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6003 else *need_redraw = TRUE;
6008 /* Do visual mode command if needed */
6009 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))
6013 /* Restore previous visual settings */
6015 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6017 f_ptr->x_attr[i] = attr_old[i];
6018 f_ptr->x_char[i] = char_old[i];
6025 if (direct_f_idx >= 0) flag = TRUE;
6026 else *lighting_level = F_LIT_STANDARD;
6029 /* Preserve current visual settings */
6032 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6034 attr_old[i] = f_ptr->x_attr[i];
6035 char_old[i] = f_ptr->x_char[i];
6037 *lighting_level = F_LIT_STANDARD;
6044 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6046 attr_idx_feat[i] = f_ptr->x_attr[i];
6047 char_idx_feat[i] = f_ptr->x_char[i];
6056 /* Allow TERM_DARK text */
6057 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6059 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6060 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6078 /* Move the cursor */
6079 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6085 /* Free the "feat_idx" array */
6086 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6091 * List wanted monsters
6092 * @param creature_ptr プレーヤーへの参照ポインタ
6095 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6097 /* Open a new file */
6099 GAME_TEXT file_name[1024];
6100 fff = my_fopen_temp(file_name, 1024);
6103 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6108 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
6109 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6111 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6112 fprintf(fff, "----------------------------------------------\n");
6114 bool listed = FALSE;
6115 for (int i = 0; i < MAX_BOUNTY; i++)
6117 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6119 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6126 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
6131 /* Display the file contents */
6132 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6137 * List virtues & status
6139 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6141 /* Open a new file */
6143 GAME_TEXT file_name[1024];
6144 fff = my_fopen_temp(file_name, 1024);
6147 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6152 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6153 dump_virtues(creature_ptr, fff);
6156 /* Display the file contents */
6157 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6164 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6166 /* Open a new file */
6168 GAME_TEXT file_name[1024];
6169 fff = my_fopen_temp(file_name, 1024);
6172 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6177 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6181 if (!d_info[i].maxdepth) continue;
6182 if (!max_dlv[i]) continue;
6183 if (d_info[i].final_guardian)
6185 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6187 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6189 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6194 /* Display the file contents */
6195 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6201 * List virtues & status
6204 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6206 /* Open a new file */
6208 GAME_TEXT file_name[1024];
6209 fff = my_fopen_temp(file_name, 1024);
6212 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6217 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6218 (2 * creature_ptr->hitdie +
6219 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6221 if (creature_ptr->knowledge & KNOW_HPRATE)
6222 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6223 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6225 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6226 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6228 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);
6229 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6232 dump_yourself(creature_ptr, fff);
6235 /* Display the file contents */
6236 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6242 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6243 * Print all active quests
6244 * @param creature_ptr プレーヤーへの参照ポインタ
6247 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6250 char rand_tmp_str[120] = "\0";
6251 GAME_TEXT name[MAX_NLEN];
6252 monster_race *r_ptr;
6253 int rand_level = 100;
6256 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6258 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6260 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6261 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6262 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6266 /* Set the quest number temporary */
6267 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6269 /* Clear the text */
6270 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6271 quest_text_line = 0;
6273 creature_ptr->current_floor_ptr->inside_quest = i;
6275 /* Get the quest text */
6276 init_flags = INIT_SHOW_TEXT;
6278 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6280 /* Reset the old quest number */
6281 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6283 /* No info from "silent" quests */
6284 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6288 if (quest[i].type != QUEST_TYPE_RANDOM)
6290 char note[80] = "\0";
6292 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6294 switch (quest[i].type)
6296 case QUEST_TYPE_KILL_LEVEL:
6297 case QUEST_TYPE_KILL_ANY_LEVEL:
6298 r_ptr = &r_info[quest[i].r_idx];
6299 strcpy(name, r_name + r_ptr->name);
6300 if (quest[i].max_num > 1)
6303 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6304 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6307 sprintf(note, " - kill %d %s, have killed %d.",
6308 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6312 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6315 case QUEST_TYPE_FIND_ARTIFACT:
6318 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6320 object_type *q_ptr = &forge;
6321 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6322 object_prep(q_ptr, k_idx);
6323 q_ptr->name1 = quest[i].k_idx;
6324 q_ptr->ident = IDENT_STORE;
6325 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6327 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
6329 case QUEST_TYPE_FIND_EXIT:
6330 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
6333 case QUEST_TYPE_KILL_NUMBER:
6335 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6336 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6338 sprintf(note, " - Kill %d monsters, have killed %d.",
6339 (int)quest[i].max_num, (int)quest[i].cur_num);
6343 case QUEST_TYPE_KILL_ALL:
6344 case QUEST_TYPE_TOWER:
6345 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6350 /* Print the quest info */
6351 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6352 quest[i].name, (int)quest[i].level, note);
6354 fputs(tmp_str, fff);
6356 if (quest[i].status == QUEST_STATUS_COMPLETED)
6358 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6359 fputs(tmp_str, fff);
6364 while (quest_text[k][0] && k < 10)
6366 fprintf(fff, " %s\n", quest_text[k]);
6373 /* QUEST_TYPE_RANDOM */
6374 if (quest[i].level >= rand_level)
6378 rand_level = quest[i].level;
6380 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6382 /* Print the quest info */
6383 r_ptr = &r_info[quest[i].r_idx];
6384 strcpy(name, r_name + r_ptr->name);
6386 if (quest[i].max_num <= 1)
6388 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6389 quest[i].name, (int)quest[i].level, name);
6394 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6395 quest[i].name, (int)quest[i].level,
6396 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6400 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6401 quest[i].name, (int)quest[i].level,
6402 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6406 /* Print the current random quest */
6407 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6409 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6413 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6416 char playtime_str[16];
6417 quest_type* const q_ptr = &quest[q_idx];
6419 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6420 if (is_fixed_quest_idx(q_idx))
6422 /* Set the quest number temporary */
6423 IDX old_quest = floor_ptr->inside_quest;
6425 floor_ptr->inside_quest = q_idx;
6428 init_flags = INIT_NAME_ONLY;
6430 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6432 /* Reset the old quest number */
6433 floor_ptr->inside_quest = old_quest;
6435 /* No info from "silent" quests */
6436 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6439 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6440 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6442 if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6444 /* Print the quest info */
6446 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6447 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6448 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6449 fputs(tmp_str, fff);
6453 /* Print the quest info */
6454 if (q_ptr->complev == 0)
6457 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6458 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6459 r_name + r_info[q_ptr->r_idx].name,
6460 (int)q_ptr->level, playtime_str);
6461 fputs(tmp_str, fff);
6466 _(" %-35s (%3d階) - レベル%2d - %s\n",
6467 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6468 r_name + r_info[q_ptr->r_idx].name,
6472 fputs(tmp_str, fff);
6478 * Print all finished quests
6479 * @param creature_ptr プレーヤーへの参照ポインタ
6480 * @param fff セーブファイル (展開済?)
6481 * @param quest_num[] 受注したことのあるクエスト群
6484 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6486 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6487 QUEST_IDX total = 0;
6488 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6490 QUEST_IDX q_idx = quest_num[i];
6491 quest_type* const q_ptr = &quest[q_idx];
6493 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6499 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6504 * Print all failed quests
6505 * @param creature_ptr プレーヤーへの参照ポインタ
6506 * @param fff セーブファイル (展開済?)
6507 * @param quest_num[] 受注したことのあるクエスト群
6510 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6512 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6513 QUEST_IDX total = 0;
6514 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6516 QUEST_IDX q_idx = quest_num[i];
6517 quest_type* const q_ptr = &quest[q_idx];
6519 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6520 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6526 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6531 * Print all random quests
6533 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6535 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6536 GAME_TEXT tmp_str[120];
6537 QUEST_IDX total = 0;
6538 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6540 /* No info from "silent" quests */
6541 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6543 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6547 /* Print the quest info */
6548 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6549 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6550 fputs(tmp_str, fff);
6554 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6558 * Print quest status of all active quests
6559 * @param creature_ptr プレーヤーへの参照ポインタ
6562 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6564 /* Open a new file */
6566 GAME_TEXT file_name[1024];
6567 fff = my_fopen_temp(file_name, 1024);
6570 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6575 /* Allocate Memory */
6577 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6579 /* Sort by compete level */
6580 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6582 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6584 /* Dump Quest Information */
6585 do_cmd_knowledge_quests_current(creature_ptr, fff);
6587 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6589 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6590 if (current_world_ptr->wizard)
6593 do_cmd_knowledge_quests_wiz_random(fff);
6598 /* Display the file contents */
6599 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6603 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6609 * @param player_ptr プレーヤーへの参照ポインタ
6612 static void do_cmd_knowledge_home(player_type *player_ptr)
6614 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6616 /* Open a new file */
6618 GAME_TEXT file_name[1024];
6619 fff = my_fopen_temp(file_name, 1024);
6622 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6627 /* Print all homes in the different towns */
6629 st_ptr = &town_info[1].store[STORE_HOME];
6631 /* Home -- if anything there */
6632 if (st_ptr->stock_num)
6637 /* Header with name of the town */
6638 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6640 /* Dump all available items */
6641 concptr paren = ")";
6642 GAME_TEXT o_name[MAX_NLEN];
6643 for (int i = 0; i < st_ptr->stock_num; i++)
6646 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6647 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6648 if (strlen(o_name) <= 80 - 3)
6650 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6656 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6657 if (iskanji(*t)) { t++; n++; }
6658 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6660 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6661 fprintf(fff, " %.77s\n", o_name + n);
6664 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6665 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6669 /* Add an empty line */
6670 fprintf(fff, "\n\n");
6675 /* Display the file contents */
6676 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6682 * Check the status of "autopick"
6684 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6686 /* Open a new file */
6688 GAME_TEXT file_name[1024];
6689 fff = my_fopen_temp(file_name, 1024);
6692 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6699 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6703 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6704 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6707 for (int k = 0; k < max_autopick; k++)
6710 byte act = autopick_list[k].action;
6711 if (act & DONT_AUTOPICK)
6713 tmp = _("放置", "Leave");
6715 else if (act & DO_AUTODESTROY)
6717 tmp = _("破壊", "Destroy");
6719 else if (act & DO_AUTOPICK)
6721 tmp = _("拾う", "Pickup");
6725 tmp = _("確認", "Query");
6728 if (act & DO_DISPLAY)
6729 fprintf(fff, "%11s", format("[%s]", tmp));
6731 fprintf(fff, "%11s", format("(%s)", tmp));
6733 tmp = autopick_line_from_entry(&autopick_list[k]);
6734 fprintf(fff, " %s", tmp);
6741 /* Display the file contents */
6742 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6748 * Interact with "knowledge"
6750 void do_cmd_knowledge(player_type *creature_ptr)
6753 bool need_redraw = FALSE;
6755 /* File type is "TEXT" */
6756 FILE_TYPE(FILE_TYPE_TEXT);
6759 /* Interact until done */
6764 /* Ask for a choice */
6765 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6766 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6768 /* Give some choices */
6772 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6773 prt("(2) 既知のアイテム の一覧", 7, 5);
6774 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6775 prt("(4) 既知のモンスター の一覧", 9, 5);
6776 prt("(5) 倒した敵の数 の一覧", 10, 5);
6777 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6778 prt("(7) 現在のペット の一覧", 12, 5);
6779 prt("(8) 我が家のアイテム の一覧", 13, 5);
6780 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6781 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6785 prt("(a) 自分に関する情報 の一覧", 6, 5);
6786 prt("(b) 突然変異 の一覧", 7, 5);
6787 prt("(c) 武器の経験値 の一覧", 8, 5);
6788 prt("(d) 魔法の経験値 の一覧", 9, 5);
6789 prt("(e) 技能の経験値 の一覧", 10, 5);
6790 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6791 prt("(g) 入ったダンジョン の一覧", 12, 5);
6792 prt("(h) 実行中のクエスト の一覧", 13, 5);
6793 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6798 prt("(1) Display known artifacts", 6, 5);
6799 prt("(2) Display known objects", 7, 5);
6800 prt("(3) Display remaining uniques", 8, 5);
6801 prt("(4) Display known monster", 9, 5);
6802 prt("(5) Display kill count", 10, 5);
6803 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6804 prt("(7) Display current pets", 12, 5);
6805 prt("(8) Display home inventory", 13, 5);
6806 prt("(9) Display *identified* equip.", 14, 5);
6807 prt("(0) Display terrain symbols.", 15, 5);
6811 prt("(a) Display about yourself", 6, 5);
6812 prt("(b) Display mutations", 7, 5);
6813 prt("(c) Display weapon proficiency", 8, 5);
6814 prt("(d) Display spell proficiency", 9, 5);
6815 prt("(e) Display misc. proficiency", 10, 5);
6816 prt("(f) Display virtues", 11, 5);
6817 prt("(g) Display dungeons", 12, 5);
6818 prt("(h) Display current quests", 13, 5);
6819 prt("(i) Display auto pick/destroy", 14, 5);
6823 prt(_("-続く-", "-more-"), 17, 8);
6824 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6825 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6826 /*prt("-) 前ページ", 21, 60);*/
6827 prt(_("コマンド:", "Command: "), 20, 0);
6830 if (i == ESCAPE) break;
6833 case ' ': /* Page change */
6837 case '1': /* Artifacts */
6838 do_cmd_knowledge_artifacts(creature_ptr);
6840 case '2': /* Objects */
6841 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6843 case '3': /* Uniques */
6844 do_cmd_knowledge_uniques(creature_ptr);
6846 case '4': /* Monsters */
6847 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6849 case '5': /* Kill count */
6850 do_cmd_knowledge_kill_count(creature_ptr);
6852 case '6': /* wanted */
6853 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6855 case '7': /* Pets */
6856 do_cmd_knowledge_pets(creature_ptr);
6858 case '8': /* Home */
6859 do_cmd_knowledge_home(creature_ptr);
6861 case '9': /* Resist list */
6862 do_cmd_knowledge_inven(creature_ptr);
6864 case '0': /* Feature list */
6866 IDX lighting_level = F_LIT_STANDARD;
6867 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6871 case 'a': /* Max stat */
6872 do_cmd_knowledge_stat(creature_ptr);
6874 case 'b': /* Mutations */
6875 do_cmd_knowledge_mutations(creature_ptr);
6877 case 'c': /* weapon-exp */
6878 do_cmd_knowledge_weapon_exp(creature_ptr);
6880 case 'd': /* spell-exp */
6881 do_cmd_knowledge_spell_exp(creature_ptr);
6883 case 'e': /* skill-exp */
6884 do_cmd_knowledge_skill_exp(creature_ptr);
6886 case 'f': /* Virtues */
6887 do_cmd_knowledge_virtues(creature_ptr);
6889 case 'g': /* Dungeon */
6890 do_cmd_knowledge_dungeon(creature_ptr);
6892 case 'h': /* Quests */
6893 do_cmd_knowledge_quests(creature_ptr);
6895 case 'i': /* Autopick */
6896 do_cmd_knowledge_autopick(creature_ptr);
6898 default: /* Unknown option */
6906 if (need_redraw) do_cmd_redraw(creature_ptr);
6911 * Check on the status of an active quest
6912 * @param creature_ptr プレーヤーへの参照ポインタ
6915 void do_cmd_checkquest(player_type *creature_ptr)
6917 /* File type is "TEXT" */
6918 FILE_TYPE(FILE_TYPE_TEXT);
6922 do_cmd_knowledge_quests(creature_ptr);
6928 * Display the time and date
6929 * @param creature_ptr プレーヤーへの参照ポインタ
6932 void do_cmd_time(player_type *creature_ptr)
6935 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6938 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6941 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6942 else strcpy(day_buf, "*****");
6944 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6945 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6949 if (!randint0(10) || creature_ptr->image)
6951 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6955 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6958 /* Open this file */
6960 fff = my_fopen(buf, "rt");
6964 /* Find this time */
6965 int full = hour * 100 + min;
6969 while (!my_fgets(fff, buf, sizeof(buf)))
6971 /* Ignore comments */
6972 if (!buf[0] || (buf[0] == '#')) continue;
6974 /* Ignore invalid lines */
6975 if (buf[1] != ':') continue;
6977 /* Process 'Start' */
6980 /* Extract the starting time */
6981 start = atoi(buf + 2);
6983 /* Assume valid for an hour */
6991 /* Extract the ending time */
6992 end = atoi(buf + 2);
6996 /* Ignore incorrect range */
6997 if ((start > full) || (full > end)) continue;
6999 /* Process 'Description' */
7004 /* Apply the randomizer */
7005 if (!randint0(num)) strcpy(desc, buf + 2);