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.
54 #include "player-effects.h"
55 #include "player-status.h"
56 #include "player-skill.h"
57 #include "player-personality.h"
64 #include "object-flavor.h"
65 #include "object-hook.h"
67 #include "monster-status.h"
68 #include "view-mainwindow.h"
69 #include "dungeon-file.h"
72 #include "objectkind.h"
73 #include "floor-town.h"
74 #include "view-mainwindow.h"
78 // Mark strings for auto dump
79 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
80 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
82 // Variables for auto dump
83 static FILE *auto_dump_stream;
84 static concptr auto_dump_mark;
85 static int auto_dump_line_num;
87 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
88 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
89 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
91 // Clipboard variables for copy&paste in visual mode
92 static TERM_COLOR attr_idx = 0;
93 static SYMBOL_CODE char_idx = 0;
95 /* Hack -- for feature lighting */
96 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
97 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
99 // Encode the screen colors
100 static char hack[17] = "dwsorgbuDWvyRGBU";
106 * @brief prf出力内容を消去する /
107 * Remove old lines automatically generated before.
108 * @param orig_file 消去を行うファイル名
110 static void remove_auto_dump(concptr orig_file)
112 FILE *tmp_fff, *orig_fff;
116 bool between_mark = FALSE;
117 bool changed = FALSE;
119 long header_location = 0;
120 char header_mark_str[80];
121 char footer_mark_str[80];
124 /* Prepare a header/footer mark string */
125 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
126 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
128 mark_len = strlen(footer_mark_str);
130 /* Open an old dump file in read-only mode */
131 orig_fff = my_fopen(orig_file, "r");
133 /* If original file does not exist, nothing to do */
134 if (!orig_fff) return;
136 /* Open a new (temporary) file */
137 tmp_fff = my_fopen_temp(tmp_file, 1024);
141 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
146 /* Loop for every line */
150 if (my_fgets(orig_fff, buf, sizeof(buf)))
152 /* Read error: Assume End of File */
155 * Was looking for the footer, but not found.
157 * Since automatic dump might be edited by hand,
158 * it's dangerous to kill these lines.
159 * Seek back to the next line of the (pseudo) header,
164 fseek(orig_fff, header_location, SEEK_SET);
165 between_mark = FALSE;
169 /* Success -- End the loop */
176 /* We are looking for the header mark of automatic dump */
179 /* Is this line a header? */
180 if (!strcmp(buf, header_mark_str))
182 /* Memorise seek point of this line */
183 header_location = ftell(orig_fff);
185 /* Initialize counter for number of lines */
188 /* Look for the footer from now */
191 /* There are some changes */
198 /* Copy orginally lines */
199 fprintf(tmp_fff, "%s\n", buf);
205 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
206 /* We are looking for the footer mark of automatic dump */
207 /* Is this line a footer? */
208 if (!strncmp(buf, footer_mark_str, mark_len))
213 * Compare the number of lines
215 * If there is an inconsistency between
216 * actual number of lines and the
217 * number here, the automatic dump
218 * might be edited by hand. So it's
219 * dangerous to kill these lines.
220 * Seek back to the next line of the
221 * (pseudo) header, and read again.
223 if (!sscanf(buf + mark_len, " (%d)", &tmp)
226 fseek(orig_fff, header_location, SEEK_SET);
229 /* Look for another header */
230 between_mark = FALSE;
235 /* Ignore old line, and count number of lines */
243 /* If there are some changes, overwrite the original file with new one */
246 /* Copy contents of temporary file */
247 tmp_fff = my_fopen(tmp_file, "r");
248 orig_fff = my_fopen(orig_file, "w");
250 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
251 fprintf(orig_fff, "%s\n", buf);
262 * @brief prfファイルのフォーマットに従った内容を出力する /
263 * Dump a formatted line, using "vstrnfmt()".
266 static void auto_dump_printf(concptr fmt, ...)
273 /* Begin the Varargs Stuff */
276 /* Format the args, save the length */
277 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
279 /* End the Varargs Stuff */
282 /* Count number of lines */
283 for (p = buf; *p; p++)
285 if (*p == '\n') auto_dump_line_num++;
289 fprintf(auto_dump_stream, "%s", buf);
294 * @brief prfファイルをファイルオープンする /
295 * Open file to append auto dump.
297 * @param mark 出力するヘッダマーク
298 * @return ファイルポインタを取得できたらTRUEを返す
300 static bool open_auto_dump(concptr buf, concptr mark)
302 char header_mark_str[80];
304 /* Save the mark string */
305 auto_dump_mark = mark;
307 /* Prepare a header mark string */
308 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
310 /* Remove old macro dumps */
311 remove_auto_dump(buf);
313 /* Append to the file */
314 auto_dump_stream = my_fopen(buf, "a");
317 if (!auto_dump_stream)
319 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
327 fprintf(auto_dump_stream, "%s\n", header_mark_str);
329 /* Initialize counter */
330 auto_dump_line_num = 0;
332 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
333 "# *Warning!* The lines below are an automatic dump.\n"));
334 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
335 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
340 * @brief prfファイルをファイルクローズする /
341 * Append foot part and close auto dump.
344 static void close_auto_dump(void)
346 char footer_mark_str[80];
348 /* Prepare a footer mark string */
349 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
351 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
352 "# *Warning!* The lines below are an automatic dump.\n"));
353 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
354 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
356 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
358 my_fclose(auto_dump_stream);
365 * @brief Return suffix of ordinal number
367 * @return pointer of suffix string.
369 concptr get_ordinal_number_suffix(int num)
371 num = ABS(num) % 100;
375 return (num == 11) ? "th" : "st";
377 return (num == 12) ? "th" : "nd";
379 return (num == 13) ? "th" : "rd";
388 * @brief 日記にメッセージを追加する /
389 * Take note to the diary.
390 * @param type 日記内容のID
391 * @param num 日記内容のIDに応じた数値
392 * @param note 日記内容のIDに応じた文字列参照ポインタ
395 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
399 GAME_TEXT file_name[MAX_NLEN];
401 concptr note_level = "";
402 bool do_level = TRUE;
403 char note_level_buf[40];
406 static bool disable_diary = FALSE;
408 extract_day_hour_min(creature_ptr, &day, &hour, &min);
410 if (disable_diary) return(-1);
412 if (type == DIARY_FIX_QUEST_C ||
413 type == DIARY_FIX_QUEST_F ||
414 type == DIARY_RAND_QUEST_C ||
415 type == DIARY_RAND_QUEST_F ||
416 type == DIARY_TO_QUEST)
420 old_quest = creature_ptr->current_floor_ptr->inside_quest;
421 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
423 /* Get the quest text */
424 init_flags = INIT_NAME_ONLY;
426 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
428 /* Reset the old quest number */
429 creature_ptr->current_floor_ptr->inside_quest = old_quest;
432 /* different filne name to avoid mixing */
433 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
434 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
436 /* File type is "TEXT" */
437 FILE_TYPE(FILE_TYPE_TEXT);
439 fff = my_fopen(buf, "a");
444 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
446 disable_diary = TRUE;
450 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
454 if (creature_ptr->current_floor_ptr->inside_arena)
455 note_level = _("アリーナ:", "Arane:");
456 else if (!creature_ptr->current_floor_ptr->dun_level)
457 note_level = _("地上:", "Surface:");
458 else if (q_idx && (is_fixed_quest_idx(q_idx)
459 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
460 note_level = _("クエスト:", "Quest:");
464 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
466 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
468 note_level = note_level_buf;
476 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
477 else fputs(_("*****日目\n", "Day *****\n"), fff);
481 case DIARY_DESCRIPTION:
485 fprintf(fff, "%s\n", note);
489 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
494 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
497 case DIARY_ART_SCROLL:
499 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
504 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
507 case DIARY_FIX_QUEST_C:
509 if (quest[num].flags & QUEST_FLAG_SILENT) break;
510 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
511 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
514 case DIARY_FIX_QUEST_F:
516 if (quest[num].flags & QUEST_FLAG_SILENT) break;
517 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
518 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
521 case DIARY_RAND_QUEST_C:
523 GAME_TEXT name[MAX_NLEN];
524 strcpy(name, r_name + r_info[quest[num].r_idx].name);
525 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
526 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
529 case DIARY_RAND_QUEST_F:
531 GAME_TEXT name[MAX_NLEN];
532 strcpy(name, r_name + r_info[quest[num].r_idx].name);
533 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
534 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
537 case DIARY_MAXDEAPTH:
539 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
540 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
541 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
542 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
547 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
548 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
549 _(d_name + d_info[num].name, (int)max_dlv[num]),
550 _((int)max_dlv[num], d_name + d_info[num].name));
556 if (q_idx && (is_fixed_quest_idx(q_idx)
557 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
559 to = _("地上", "the surface");
563 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
564 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
566 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
572 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
573 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
574 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
576 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
581 if (quest[num].flags & QUEST_FLAG_SILENT) break;
582 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
583 hour, min, note_level, quest[num].name);
586 case DIARY_TELEPORT_LEVEL:
588 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
589 hour, min, note_level);
594 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
599 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
607 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
608 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
611 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
612 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
614 if (num == MAX_ARENA_MONS)
616 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
617 " won all fights to become a Champion.\n"));
624 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
630 if (!creature_ptr->current_floor_ptr->dun_level)
631 to = _("地上", "the surface");
633 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
635 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
636 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
642 if (!creature_ptr->current_floor_ptr->dun_level)
643 to = _("地上", "the surface");
645 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
647 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
648 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
653 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
656 case DIARY_GAMESTART:
658 time_t ct = time((time_t*)0);
662 fprintf(fff, "%s %s", note, ctime(&ct));
665 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
668 case DIARY_NAMED_PET:
670 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
673 case RECORD_NAMED_PET_NAME:
674 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
676 case RECORD_NAMED_PET_UNNAME:
677 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
679 case RECORD_NAMED_PET_DISMISS:
680 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
682 case RECORD_NAMED_PET_DEATH:
683 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
685 case RECORD_NAMED_PET_MOVED:
686 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
688 case RECORD_NAMED_PET_LOST_SIGHT:
689 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
691 case RECORD_NAMED_PET_DESTROY:
692 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
694 case RECORD_NAMED_PET_EARTHQUAKE:
695 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
697 case RECORD_NAMED_PET_GENOCIDE:
698 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
700 case RECORD_NAMED_PET_WIZ_ZAP:
701 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
703 case RECORD_NAMED_PET_TELE_LEVEL:
704 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
706 case RECORD_NAMED_PET_BLAST:
707 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
709 case RECORD_NAMED_PET_HEAL_LEPER:
710 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
712 case RECORD_NAMED_PET_COMPACT:
713 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
715 case RECORD_NAMED_PET_LOSE_PARENT:
716 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
726 case DIARY_WIZARD_LOG:
727 fprintf(fff, "%s\n", note);
736 if (do_level) write_level = FALSE;
742 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
745 * @brief 日記のタイトル表記と内容出力 /
748 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
750 static void display_diary(player_type *creature_ptr)
752 char diary_title[256];
753 GAME_TEXT file_name[MAX_NLEN];
757 static const char subtitle[][30] = {
790 static const char subtitle[][51] = {
791 "Quest of The World's Toughest Body",
792 "Attack is the best form of defence.",
794 "An unexpected windfall",
795 "A drowning man will catch at a straw",
796 "Don't count your chickens before they are hatched.",
797 "It is no use crying over spilt milk.",
798 "Seeing is believing.",
799 "Strike the iron while it is hot.",
800 "I don't care what follows.",
801 "To dig a well to put out a house on fire.",
802 "Tomorrow is another day.",
803 "Easy come, easy go.",
804 "The more haste, the less speed.",
805 "Where there is life, there is hope.",
806 "There is no royal road to *WINNER*.",
807 "Danger past, God forgotten.",
808 "The best thing to do now is to run away.",
809 "Life is but an empty dream.",
810 "Dead men tell no tales.",
811 "A book that remains shut is but a block.",
812 "Misfortunes never come singly.",
813 "A little knowledge is a dangerous thing.",
814 "History repeats itself.",
815 "*WINNER* was not built in a day.",
816 "Ignorance is bliss.",
817 "To lose is to win?",
818 "No medicine can cure folly.",
819 "All good things come to an end.",
820 "M$ Empire strikes back.",
821 "To see is to believe",
823 "Quest of The World's Greatest Brain"
826 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
827 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
829 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
830 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
831 else if (IS_WIZARD_CLASS(creature_ptr))
832 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
833 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
836 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
838 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
841 /* Display the file contents */
842 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
847 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
850 static void add_diary_note(player_type *creature_ptr)
853 char bunshou[80] = "\0";
855 if (get_string(_("内容: ", "diary note: "), tmp, 79))
857 strcpy(bunshou, tmp);
858 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
863 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
866 static void do_cmd_last_get(player_type *creaute_ptr)
868 if (record_o_name[0] == '\0') return;
871 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
872 if (!get_check(buf)) return;
874 GAME_TURN turn_tmp = current_world_ptr->game_turn;
875 current_world_ptr->game_turn = record_turn;
876 sprintf(buf, _("%sを手に入れた。", "discover %s."), record_o_name);
877 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
878 current_world_ptr->game_turn = turn_tmp;
883 * @brief ファイル中の全日記記録を消去する /
886 static void do_cmd_erase_diary(void)
888 GAME_TEXT file_name[MAX_NLEN];
892 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
893 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
894 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
897 fff = my_fopen(buf, "w");
901 msg_format(_("記録を消去しました。", "deleted record."));
905 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
914 * @param crerature_ptr プレーヤーへの参照ポインタ
917 void do_cmd_diary(player_type *creature_ptr)
919 /* File type is "TEXT" */
920 FILE_TYPE(FILE_TYPE_TEXT);
923 /* Interact until done */
929 /* Ask for a choice */
930 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
932 /* Give some choices */
933 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
934 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
935 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
936 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
938 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
941 prt(_("コマンド:", "Command: "), 18, 0);
946 if (i == ESCAPE) break;
951 display_diary(creature_ptr);
954 add_diary_note(creature_ptr);
957 do_cmd_last_get(creature_ptr);
960 do_cmd_erase_diary();
964 prepare_movie_hooks();
966 default: /* Unknown option */
978 * @brief 画面を再描画するコマンドのメインルーチン
979 * Hack -- redraw the screen
980 * @param creature_ptr プレーヤーへの参照ポインタ
984 * This command performs various low level updates, clears all the "extra"
985 * windows, does a total redraw of the main window, and requests all of the
986 * interesting updates and redraws that I can think of.
988 * This command is also used to "instantiate" the results of the user
989 * selecting various things, such as graphics mode, so it must call
990 * the "TERM_XTRA_REACT" hook before redrawing the windows.
993 void do_cmd_redraw(player_type *creature_ptr)
995 Term_xtra(TERM_XTRA_REACT, 0);
997 /* Combine and Reorder the pack (later) */
998 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
999 creature_ptr->update |= (PU_TORCH);
1000 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1001 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1002 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1003 creature_ptr->update |= (PU_MONSTERS);
1005 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1007 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1008 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1011 handle_stuff(creature_ptr);
1013 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1015 /* Redraw every window */
1017 for (int j = 0; j < 8; j++)
1020 if (!angband_term[j]) continue;
1023 Term_activate(angband_term[j]);
1032 * @brief プレイヤーのステータス表示
1035 void do_cmd_player_status(player_type *creature_ptr)
1046 display_player(creature_ptr, mode);
1051 display_player(creature_ptr, mode);
1055 Term_putstr(2, 23, -1, TERM_WHITE,
1056 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1060 if (c == ESCAPE) break;
1065 get_name(creature_ptr);
1067 /* Process the player name */
1068 process_player_name(creature_ptr, FALSE);
1074 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1075 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1077 if (tmp[0] && (tmp[0] != ' '))
1079 file_character(creature_ptr, tmp);
1097 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1099 handle_stuff(creature_ptr);
1104 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1105 * Recall the most recent message
1108 void do_cmd_message_one(void)
1110 /* Recall one message */
1111 prt(format("> %s", message_str(0)), 0, 0);
1116 * @brief メッセージのログを表示するコマンドのメインルーチン
1117 * Recall the most recent message
1121 * Show previous messages to the user -BEN-
1123 * The screen format uses line 0 and 23 for headers and prompts,
1124 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1126 * This command shows you which commands you are viewing, and allows
1127 * you to "search" for strings in the recall.
1129 * Note that messages may be longer than 80 characters, but they are
1130 * displayed using "infinite" length, with a special sub-command to
1131 * "slide" the virtual display to the left or right.
1133 * Attempt to only hilite the matching portions of the string.
1136 void do_cmd_messages(int num_now)
1138 char shower_str[81];
1139 char finder_str[81];
1141 concptr shower = NULL;
1145 Term_get_size(&wid, &hgt);
1147 /* Number of message lines in a screen */
1148 num_lines = hgt - 4;
1151 strcpy(finder_str, "");
1154 strcpy(shower_str, "");
1156 /* Total messages */
1157 int n = message_num();
1159 /* Start on first message */
1164 /* Process requests until done */
1170 /* Dump up to 20 lines of messages */
1171 for (j = 0; (j < num_lines) && (i + j < n); j++)
1173 concptr msg = message_str(i + j);
1175 /* Dump the messages, bottom to top */
1176 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1178 if (!shower || !shower[0]) continue;
1180 /* Hilite "shower" */
1183 /* Display matches */
1184 while ((str = my_strstr(str, shower)) != NULL)
1186 int len = strlen(shower);
1188 /* Display the match */
1189 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1196 /* Erase remaining lines */
1197 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1199 /* Display header */
1201 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1202 i, i + j - 1, n), 0, 0);
1204 /* Display prompt (not very informative) */
1205 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1206 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1208 skey = inkey_special(TRUE);
1210 /* Exit on Escape */
1211 if (skey == ESCAPE) break;
1213 /* Hack -- Save the old index */
1218 /* Hack -- handle show */
1221 prt(_("強調: ", "Show: "), hgt - 1, 0);
1223 /* Get a "shower" string, or continue */
1224 strcpy(back_str, shower_str);
1225 if (askfor(shower_str, 80))
1228 shower = shower_str[0] ? shower_str : NULL;
1230 else strcpy(shower_str, back_str);
1234 /* Hack -- handle find */
1241 prt(_("検索: ", "Find: "), hgt - 1, 0);
1243 /* Get a "finder" string, or continue */
1244 strcpy(back_str, finder_str);
1245 if (!askfor(finder_str, 80))
1247 strcpy(finder_str, back_str);
1250 else if (!finder_str[0])
1252 shower = NULL; /* Stop showing */
1257 shower = finder_str;
1260 for (z = i + 1; z < n; z++)
1262 concptr msg = message_str(z);
1265 if (my_strstr(msg, finder_str))
1276 /* Recall 1 older message */
1278 /* Go to the oldest line */
1282 /* Recall 1 newer message */
1284 /* Go to the newest line */
1288 /* Recall 1 older message */
1293 /* Go older if legal */
1294 i = MIN(i + 1, n - num_lines);
1297 /* Recall 10 older messages */
1299 /* Go older if legal */
1300 i = MIN(i + 10, n - num_lines);
1303 /* Recall 20 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + num_lines, n - num_lines);
1312 /* Recall 20 newer messages */
1316 /* Go newer (if able) */
1317 i = MAX(0, i - num_lines);
1320 /* Recall 10 newer messages */
1322 /* Go newer (if able) */
1326 /* Recall 1 newer messages */
1329 /* Go newer (if able) */
1334 /* Hack -- Error of some kind */
1343 * @brief prefファイルを選択して処理する /
1344 * Ask for a "user pref line" and process it
1345 * @param creature_ptr プレーヤーへの参照ポインタ
1348 * Allow absolute file names?
1350 void do_cmd_pref(player_type *creature_ptr)
1355 /* Ask for a "user pref command" */
1356 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1358 /* Process that pref command */
1359 (void)process_pref_file_command(creature_ptr, buf);
1364 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1365 * @param creature_ptr プレーヤーへの参照ポインタ
1368 void do_cmd_reload_autopick(player_type *creature_ptr)
1370 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1371 /* Load the file with messages */
1372 autopick_load_pref(creature_ptr, TRUE);
1377 * @brief マクロ情報をprefファイルに保存する /
1378 * @param fname ファイル名
1381 static errr macro_dump(concptr fname)
1383 static concptr mark = "Macro Dump";
1385 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1387 /* File type is "TEXT" */
1388 FILE_TYPE(FILE_TYPE_TEXT);
1390 /* Append to the file */
1391 if (!open_auto_dump(buf, mark)) return -1;
1394 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1397 for (int i = 0; i < macro__num; i++)
1399 /* Extract the action */
1400 ascii_to_text(buf, macro__act[i]);
1402 /* Dump the macro */
1403 auto_dump_printf("A:%s\n", buf);
1405 /* Extract the action */
1406 ascii_to_text(buf, macro__pat[i]);
1408 /* Dump normal macros */
1409 auto_dump_printf("P:%s\n", buf);
1412 auto_dump_printf("\n");
1421 * @brief マクロのトリガーキーを取得する /
1422 * Hack -- ask for a "trigger" (see below)
1423 * @param buf キー表記を保管するバッファ
1427 * Note the complex use of the "inkey()" function from "util.c".
1429 * Note that both "flush()" calls are extremely important.
1432 static void do_cmd_macro_aux(char *buf)
1436 /* Do not process macros */
1442 /* Read the pattern */
1449 /* Do not process macros */
1452 /* Do not wait for keys */
1455 /* Attempt to read a key */
1464 /* Convert the trigger */
1466 ascii_to_text(tmp, buf);
1468 /* Hack -- display the trigger */
1469 Term_addstr(-1, TERM_WHITE, tmp);
1474 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1475 * Hack -- ask for a keymap "trigger" (see below)
1476 * @param buf キー表記を取得するバッファ
1480 * Note that both "flush()" calls are extremely important. This may
1481 * no longer be true, since "util.c" is much simpler now.
1484 static void do_cmd_macro_aux_keymap(char *buf)
1494 /* Convert to ascii */
1495 ascii_to_text(tmp, buf);
1497 /* Hack -- display the trigger */
1498 Term_addstr(-1, TERM_WHITE, tmp);
1505 * @brief キーマップをprefファイルにダンプする /
1506 * Hack -- append all keymaps to the given file
1507 * @param fname ファイルネーム
1511 static errr keymap_dump(concptr fname)
1513 static concptr mark = "Keymap Dump";
1520 if (rogue_like_commands)
1522 mode = KEYMAP_MODE_ROGUE;
1528 mode = KEYMAP_MODE_ORIG;
1531 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1533 /* File type is "TEXT" */
1534 FILE_TYPE(FILE_TYPE_TEXT);
1536 /* Append to the file */
1537 if (!open_auto_dump(buf, mark)) return -1;
1540 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1543 for (int i = 0; i < 256; i++)
1547 /* Loop up the keymap */
1548 act = keymap_act[mode][i];
1550 /* Skip empty keymaps */
1553 /* Encode the key */
1556 ascii_to_text(key, buf);
1558 /* Encode the action */
1559 ascii_to_text(buf, act);
1561 /* Dump the macro */
1562 auto_dump_printf("A:%s\n", buf);
1563 auto_dump_printf("C:%d:%s\n", mode, key);
1572 * @brief マクロを設定するコマンドのメインルーチン /
1573 * Interact with "macros"
1577 * Note that the macro "action" must be defined before the trigger.
1579 * Could use some helpful instructions on this page.
1582 void do_cmd_macros(player_type *creature_ptr)
1590 if (rogue_like_commands)
1592 mode = KEYMAP_MODE_ROGUE;
1598 mode = KEYMAP_MODE_ORIG;
1601 /* File type is "TEXT" */
1602 FILE_TYPE(FILE_TYPE_TEXT);
1606 /* Process requests until done */
1610 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1612 /* Describe that action */
1613 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1615 /* Analyze the current action */
1616 ascii_to_text(buf, macro__buf);
1618 /* Display the current action */
1623 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1624 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1625 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1626 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1627 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1628 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1629 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1630 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1631 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1632 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1635 prt(_("コマンド: ", "Command: "), 16, 0);
1640 if (i == ESCAPE) break;
1642 /* Load a 'macro' file */
1648 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1651 prt(_("ファイル: ", "File: "), 18, 0);
1653 /* Default filename */
1654 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1656 /* Ask for a file */
1657 if (!askfor(tmp, 80)) continue;
1659 /* Process the given filename */
1660 err = process_pref_file(creature_ptr, tmp);
1663 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1668 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1672 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1680 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1683 prt(_("ファイル: ", "File: "), 18, 0);
1685 /* Default filename */
1686 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1688 /* Ask for a file */
1689 if (!askfor(tmp, 80)) continue;
1691 /* Dump the macros */
1692 (void)macro_dump(tmp);
1695 msg_print(_("マクロを追加しました。", "Appended macros."));
1704 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1708 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1710 /* Get a macro trigger */
1711 do_cmd_macro_aux(buf);
1713 /* Acquire action */
1714 k = macro_find_exact(buf);
1720 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1726 /* Obtain the action */
1727 strcpy(macro__buf, macro__act[k]);
1729 /* Analyze the current action */
1730 ascii_to_text(buf, macro__buf);
1732 /* Display the current action */
1736 msg_print(_("マクロを確認しました。", "Found a macro."));
1740 /* Create a macro */
1744 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1747 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1749 /* Get a macro trigger */
1750 do_cmd_macro_aux(buf);
1754 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1755 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1758 prt(_("マクロ行動: ", "Action: "), 20, 0);
1760 /* Convert to text */
1761 ascii_to_text(tmp, macro__buf);
1763 /* Get an encoded action */
1764 if (askfor(tmp, 80))
1766 /* Convert to ascii */
1767 text_to_ascii(macro__buf, tmp);
1769 /* Link the macro */
1770 macro_add(buf, macro__buf);
1773 msg_print(_("マクロを追加しました。", "Added a macro."));
1777 /* Remove a macro */
1781 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1784 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1786 /* Get a macro trigger */
1787 do_cmd_macro_aux(buf);
1789 /* Link the macro */
1790 macro_add(buf, buf);
1793 msg_print(_("マクロを削除しました。", "Removed a macro."));
1800 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1803 prt(_("ファイル: ", "File: "), 18, 0);
1805 /* Default filename */
1806 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1808 /* Ask for a file */
1809 if (!askfor(tmp, 80)) continue;
1811 /* Dump the macros */
1812 (void)keymap_dump(tmp);
1815 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1818 /* Query a keymap */
1824 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1827 prt(_("押すキー: ", "Keypress: "), 18, 0);
1829 /* Get a keymap trigger */
1830 do_cmd_macro_aux_keymap(buf);
1832 /* Look up the keymap */
1833 act = keymap_act[mode][(byte)(buf[0])];
1839 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1845 /* Obtain the action */
1846 strcpy(macro__buf, act);
1848 /* Analyze the current action */
1849 ascii_to_text(buf, macro__buf);
1851 /* Display the current action */
1855 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1859 /* Create a keymap */
1863 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1866 prt(_("押すキー: ", "Keypress: "), 18, 0);
1868 /* Get a keymap trigger */
1869 do_cmd_macro_aux_keymap(buf);
1873 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1874 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1877 prt(_("行動: ", "Action: "), 20, 0);
1879 /* Convert to text */
1880 ascii_to_text(tmp, macro__buf);
1882 /* Get an encoded action */
1883 if (askfor(tmp, 80))
1885 /* Convert to ascii */
1886 text_to_ascii(macro__buf, tmp);
1888 /* Free old keymap */
1889 string_free(keymap_act[mode][(byte)(buf[0])]);
1891 /* Make new keymap */
1892 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1895 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1899 /* Remove a keymap */
1903 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1906 prt(_("押すキー: ", "Keypress: "), 18, 0);
1908 /* Get a keymap trigger */
1909 do_cmd_macro_aux_keymap(buf);
1911 /* Free old keymap */
1912 string_free(keymap_act[mode][(byte)(buf[0])]);
1914 /* Make new keymap */
1915 keymap_act[mode][(byte)(buf[0])] = NULL;
1918 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1921 /* Enter a new action */
1925 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1929 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1930 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1933 prt(_("マクロ行動: ", "Action: "), 20, 0);
1935 /* Hack -- limit the value */
1938 /* Get an encoded action */
1939 if (!askfor(buf, 80)) continue;
1941 /* Extract an action */
1942 text_to_ascii(macro__buf, buf);
1958 * @brief キャラクタ色の明暗表現
1960 static concptr lighting_level_str[F_LIT_MAX] =
1975 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1976 * @param i 指定対象となるキャラクタコード
1977 * @param num 指定されたビジュアルIDを返す参照ポインタ
1978 * @param max ビジュアルIDの最大数
1979 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1981 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1988 sprintf(str, "%d", *num);
1990 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
1993 tmp = (IDX)strtol(str, NULL, 0);
1994 if (tmp >= 0 && tmp < max)
1997 else if (isupper(i))
1998 *num = (*num + max - 1) % max;
2000 *num = (*num + 1) % max;
2006 * @brief キャラクタの変更メニュー表示
2007 * @param choice_msg 選択メッセージ
2010 static void print_visuals_menu(concptr choice_msg)
2012 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2014 /* Give some choices */
2015 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2016 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2017 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2018 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2019 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2020 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2021 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2022 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2023 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2024 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2025 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2028 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2033 * Interact with "visuals"
2035 void do_cmd_visuals(player_type *creature_ptr)
2040 bool need_redraw = FALSE;
2041 concptr empty_symbol = "<< ? >>";
2043 if (use_bigtile) empty_symbol = "<< ?? >>";
2045 /* File type is "TEXT" */
2046 FILE_TYPE(FILE_TYPE_TEXT);
2049 /* Interact until done */
2054 /* Ask for a choice */
2055 print_visuals_menu(NULL);
2060 if (i == ESCAPE) break;
2064 /* Load a 'pref' file */
2067 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2070 prt(_("ファイル: ", "File: "), 17, 0);
2072 /* Default filename */
2073 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2076 if (!askfor(tmp, 70)) continue;
2078 /* Process the given filename */
2079 (void)process_pref_file(creature_ptr, tmp);
2084 /* Dump monster attr/chars */
2087 static concptr mark = "Monster attr/chars";
2090 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2093 prt(_("ファイル: ", "File: "), 17, 0);
2095 /* Default filename */
2096 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2098 /* Get a filename */
2099 if (!askfor(tmp, 70)) continue;
2100 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2102 /* Append to the file */
2103 if (!open_auto_dump(buf, mark)) continue;
2106 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2109 for (i = 0; i < max_r_idx; i++)
2111 monster_race *r_ptr = &r_info[i];
2113 /* Skip non-entries */
2114 if (!r_ptr->name) continue;
2116 /* Dump a comment */
2117 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2119 /* Dump the monster attr/char info */
2120 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2121 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2127 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2132 /* Dump object attr/chars */
2135 static concptr mark = "Object attr/chars";
2136 KIND_OBJECT_IDX k_idx;
2139 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2142 prt(_("ファイル: ", "File: "), 17, 0);
2144 /* Default filename */
2145 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2147 /* Get a filename */
2148 if (!askfor(tmp, 70)) continue;
2149 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2151 /* Append to the file */
2152 if (!open_auto_dump(buf, mark)) continue;
2155 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2158 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2160 GAME_TEXT o_name[MAX_NLEN];
2161 object_kind *k_ptr = &k_info[k_idx];
2163 /* Skip non-entries */
2164 if (!k_ptr->name) continue;
2169 strip_name(o_name, k_idx);
2175 /* Prepare dummy object */
2176 object_prep(&forge, k_idx);
2178 /* Get un-shuffled flavor name */
2179 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2182 /* Dump a comment */
2183 auto_dump_printf("# %s\n", o_name);
2185 /* Dump the object attr/char info */
2186 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2187 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2193 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2198 /* Dump feature attr/chars */
2201 static concptr mark = "Feature attr/chars";
2204 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2207 prt(_("ファイル: ", "File: "), 17, 0);
2209 /* Default filename */
2210 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2212 /* Get a filename */
2213 if (!askfor(tmp, 70)) continue;
2214 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2216 /* Append to the file */
2217 if (!open_auto_dump(buf, mark)) continue;
2220 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2223 for (i = 0; i < max_f_idx; i++)
2225 feature_type *f_ptr = &f_info[i];
2227 /* Skip non-entries */
2228 if (!f_ptr->name) continue;
2230 /* Skip mimiccing features */
2231 if (f_ptr->mimic != i) continue;
2233 /* Dump a comment */
2234 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2236 /* Dump the feature attr/char info */
2237 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2238 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2239 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2240 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2246 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2251 /* Modify monster attr/chars (numeric operation) */
2254 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2255 static MONRACE_IDX r = 0;
2257 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2259 /* Hack -- query until done */
2262 monster_race *r_ptr = &r_info[r];
2266 TERM_COLOR da = r_ptr->d_attr;
2267 byte dc = r_ptr->d_char;
2268 TERM_COLOR ca = r_ptr->x_attr;
2269 byte cc = r_ptr->x_char;
2271 /* Label the object */
2272 Term_putstr(5, 17, -1, TERM_WHITE,
2273 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2275 /* Label the Default values */
2276 Term_putstr(10, 19, -1, TERM_WHITE,
2277 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2279 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2280 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2282 /* Label the Current values */
2283 Term_putstr(10, 20, -1, TERM_WHITE,
2284 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2286 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2287 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2290 Term_putstr(0, 22, -1, TERM_WHITE,
2291 _("コマンド (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): "));
2296 if (i == ESCAPE) break;
2298 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2299 else if (isupper(i)) c = 'a' + i - 'A';
2309 if (!cmd_visuals_aux(i, &r, max_r_idx))
2314 } while (!r_info[r].name);
2318 t = (int)r_ptr->x_attr;
2319 (void)cmd_visuals_aux(i, &t, 256);
2320 r_ptr->x_attr = (byte)t;
2324 t = (int)r_ptr->x_char;
2325 (void)cmd_visuals_aux(i, &t, 256);
2326 r_ptr->x_char = (byte)t;
2330 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2332 print_visuals_menu(choice_msg);
2340 /* Modify object attr/chars (numeric operation) */
2343 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2345 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2347 /* Hack -- query until done */
2350 object_kind *k_ptr = &k_info[k];
2354 TERM_COLOR da = k_ptr->d_attr;
2355 SYMBOL_CODE dc = k_ptr->d_char;
2356 TERM_COLOR ca = k_ptr->x_attr;
2357 SYMBOL_CODE cc = k_ptr->x_char;
2359 /* Label the object */
2360 Term_putstr(5, 17, -1, TERM_WHITE,
2361 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2362 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2364 /* Label the Default values */
2365 Term_putstr(10, 19, -1, TERM_WHITE,
2366 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2368 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2369 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2371 /* Label the Current values */
2372 Term_putstr(10, 20, -1, TERM_WHITE,
2373 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2375 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2376 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2379 Term_putstr(0, 22, -1, TERM_WHITE,
2380 _("コマンド (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): "));
2385 if (i == ESCAPE) break;
2387 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2388 else if (isupper(i)) c = 'a' + i - 'A';
2398 if (!cmd_visuals_aux(i, &k, max_k_idx))
2403 } while (!k_info[k].name);
2407 t = (int)k_ptr->x_attr;
2408 (void)cmd_visuals_aux(i, &t, 256);
2409 k_ptr->x_attr = (byte)t;
2413 t = (int)k_ptr->x_char;
2414 (void)cmd_visuals_aux(i, &t, 256);
2415 k_ptr->x_char = (byte)t;
2419 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2421 print_visuals_menu(choice_msg);
2429 /* Modify feature attr/chars (numeric operation) */
2432 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2434 static IDX lighting_level = F_LIT_STANDARD;
2435 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2437 /* Hack -- query until done */
2440 feature_type *f_ptr = &f_info[f];
2444 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2445 byte dc = f_ptr->d_char[lighting_level];
2446 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2447 byte cc = f_ptr->x_char[lighting_level];
2449 /* Label the object */
2451 Term_putstr(5, 17, -1, TERM_WHITE,
2452 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2453 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2455 /* Label the Default values */
2456 Term_putstr(10, 19, -1, TERM_WHITE,
2457 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2459 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2460 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2462 /* Label the Current values */
2464 Term_putstr(10, 20, -1, TERM_WHITE,
2465 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2467 Term_putstr(10, 20, -1, TERM_WHITE,
2468 format("Current attr/char = %3d / %3d", ca, cc));
2471 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2472 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2476 Term_putstr(0, 22, -1, TERM_WHITE,
2477 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2479 Term_putstr(0, 22, -1, TERM_WHITE,
2480 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2486 if (i == ESCAPE) break;
2488 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2489 else if (isupper(i)) c = 'a' + i - 'A';
2499 if (!cmd_visuals_aux(i, &f, max_f_idx))
2504 } while (!f_info[f].name || (f_info[f].mimic != f));
2508 t = (int)f_ptr->x_attr[lighting_level];
2509 (void)cmd_visuals_aux(i, &t, 256);
2510 f_ptr->x_attr[lighting_level] = (byte)t;
2514 t = (int)f_ptr->x_char[lighting_level];
2515 (void)cmd_visuals_aux(i, &t, 256);
2516 f_ptr->x_char[lighting_level] = (byte)t;
2520 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2523 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2527 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2529 print_visuals_menu(choice_msg);
2537 /* Modify monster attr/chars (visual mode) */
2539 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2542 /* Modify object attr/chars (visual mode) */
2544 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2547 /* Modify feature attr/chars (visual mode) */
2550 IDX lighting_level = F_LIT_STANDARD;
2551 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2559 reset_visuals(creature_ptr);
2561 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2565 /* Unknown option */
2576 if (need_redraw) do_cmd_redraw(creature_ptr);
2581 * Interact with "colors"
2583 void do_cmd_colors(player_type *creature_ptr)
2589 /* File type is "TEXT" */
2590 FILE_TYPE(FILE_TYPE_TEXT);
2594 /* Interact until done */
2599 /* Ask for a choice */
2600 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2602 /* Give some choices */
2603 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2604 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2605 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2608 prt(_("コマンド: ", "Command: "), 8, 0);
2612 if (i == ESCAPE) break;
2614 /* Load a 'pref' file */
2618 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2621 prt(_("ファイル: ", "File: "), 10, 0);
2624 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2627 if (!askfor(tmp, 70)) continue;
2629 /* Process the given filename */
2630 (void)process_pref_file(creature_ptr, tmp);
2632 /* Mega-Hack -- react to changes */
2633 Term_xtra(TERM_XTRA_REACT, 0);
2635 /* Mega-Hack -- redraw */
2642 static concptr mark = "Colors";
2645 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2648 prt(_("ファイル: ", "File: "), 10, 0);
2650 /* Default filename */
2651 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2653 /* Get a filename */
2654 if (!askfor(tmp, 70)) continue;
2655 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2657 /* Append to the file */
2658 if (!open_auto_dump(buf, mark)) continue;
2661 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2664 for (i = 0; i < 256; i++)
2666 int kv = angband_color_table[i][0];
2667 int rv = angband_color_table[i][1];
2668 int gv = angband_color_table[i][2];
2669 int bv = angband_color_table[i][3];
2671 concptr name = _("未知", "unknown");
2673 /* Skip non-entries */
2674 if (!kv && !rv && !gv && !bv) continue;
2676 /* Extract the color name */
2677 if (i < 16) name = color_names[i];
2679 /* Dump a comment */
2680 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2682 /* Dump the monster attr/char info */
2683 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2690 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2699 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2701 /* Hack -- query until done */
2708 /* Exhibit the normal colors */
2709 for (j = 0; j < 16; j++)
2711 /* Exhibit this color */
2712 Term_putstr(j * 4, 20, -1, a, "###");
2714 /* Exhibit all colors */
2715 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2718 /* Describe the color */
2719 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2721 /* Describe the color */
2722 Term_putstr(5, 10, -1, TERM_WHITE,
2723 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2725 /* Label the Current values */
2726 Term_putstr(5, 12, -1, TERM_WHITE,
2727 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2728 angband_color_table[a][0],
2729 angband_color_table[a][1],
2730 angband_color_table[a][2],
2731 angband_color_table[a][3]));
2734 Term_putstr(0, 14, -1, TERM_WHITE,
2735 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2740 if (i == ESCAPE) break;
2743 if (i == 'n') a = (byte)(a + 1);
2744 if (i == 'N') a = (byte)(a - 1);
2745 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2746 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2747 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2748 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2749 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2750 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2751 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2752 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2754 /* Hack -- react to changes */
2755 Term_xtra(TERM_XTRA_REACT, 0);
2757 /* Hack -- redraw */
2762 /* Unknown option */
2776 * Note something in the message recall
2778 void do_cmd_note(void)
2786 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2788 /* Ignore empty notes */
2789 if (!buf[0] || (buf[0] == ' ')) return;
2791 /* Add the note to the message recall */
2792 msg_format(_("メモ: %s", "Note: %s"), buf);
2797 * Mention the current version
2799 void do_cmd_version(void)
2801 #if FAKE_VER_EXTRA > 0
2802 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2803 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2805 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2806 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2812 * Array of feeling strings
2814 static concptr do_cmd_feeling_text[11] =
2816 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2817 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2818 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2819 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2820 _("とても悪い予感がする...", "You have a very bad feeling..."),
2821 _("悪い予感がする...", "You have a bad feeling..."),
2822 _("何か緊張する。", "You feel nervous."),
2823 _("少し不運な気がする...", "You feel your luck is turning..."),
2824 _("この場所は好きになれない。", "You don't like the look of this place."),
2825 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2826 _("なんて退屈なところだ...", "What a boring place...")
2829 static concptr do_cmd_feeling_text_combat[11] =
2831 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2832 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2833 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2834 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2835 _("とても悪い予感がする...", "You have a very bad feeling..."),
2836 _("悪い予感がする...", "You have a bad feeling..."),
2837 _("何か緊張する。", "You feel nervous."),
2838 _("少し不運な気がする...", "You feel your luck is turning..."),
2839 _("この場所は好きになれない。", "You don't like the look of this place."),
2840 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2841 _("なんて退屈なところだ...", "What a boring place...")
2844 static concptr do_cmd_feeling_text_lucky[11] =
2846 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2847 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2848 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2849 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2850 _("とても良い感じがする...", "You have a very good feeling..."),
2851 _("良い感じがする...", "You have a good feeling..."),
2852 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2853 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2854 _("見た感じ悪くはない...", "You like the look of this place..."),
2855 _("全然駄目ということはないが...", "This level can't be all bad..."),
2856 _("なんて退屈なところだ...", "What a boring place...")
2861 * Note that "feeling" is set to zero unless some time has passed.
2862 * Note that this is done when the level is GENERATED, not entered.
2864 void do_cmd_feeling(player_type *creature_ptr)
2866 if (creature_ptr->wild_mode) return;
2868 /* No useful feeling in quests */
2869 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2871 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2875 /* No useful feeling in town */
2876 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2878 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2880 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2884 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2888 /* No useful feeling in the wilderness */
2889 if (!creature_ptr->current_floor_ptr->dun_level)
2891 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2895 /* Display the feeling */
2896 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2897 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2898 else if (IS_ECHIZEN(creature_ptr))
2899 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2901 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2906 * Description of each monster group.
2908 static concptr monster_group_text[] =
2911 "ユニーク", /* "Uniques" */
2912 "乗馬可能なモンスター", /* "Riding" */
2913 "賞金首", /* "Wanted */
2914 "アンバーの王族", /* "Amberite" */
2943 /* "古代ドラゴン/ワイアーム", */
3004 /* "Ancient Dragon/Wyrm", */
3013 "Multi-Headed Reptile",
3018 "Reptile/Amphibian",
3019 "Spider/Scorpion/Tick",
3021 /* "Major Demon", */
3038 * Symbols of monsters in each group. Note the "Uniques" group
3039 * is handled differently.
3041 static concptr monster_group_char[] =
3098 "!$&()+./=>?[\\]`{|~",
3108 * todo 引数と戻り値について追記求む
3109 * Build a list of monster indexes in the given group.
3111 * mode & 0x01 : check for non-empty group
3112 * mode & 0x02 : visual operation only
3114 * @param creature_ptr プレーヤーへの参照ポインタ
3115 * @param grp_cur ???
3116 * @param mon_idx[] ???
3118 * @return The number of monsters in the group
3120 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3122 /* Get a list of x_char in this group */
3123 concptr group_char = monster_group_char[grp_cur];
3125 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3126 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3127 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3128 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3130 /* Check every race */
3132 for (IDX i = 0; i < max_r_idx; i++)
3134 /* Access the race */
3135 monster_race *r_ptr = &r_info[i];
3137 /* Skip empty race */
3138 if (!r_ptr->name) continue;
3140 /* Require known monsters */
3141 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3145 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3148 else if (grp_riding)
3150 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3153 else if (grp_wanted)
3155 bool wanted = FALSE;
3157 for (j = 0; j < MAX_BOUNTY; j++)
3159 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3160 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3166 if (!wanted) continue;
3169 else if (grp_amberite)
3171 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3176 /* Check for race in the group */
3177 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3181 mon_idx[mon_cnt++] = i;
3183 /* XXX Hack -- Just checking for non-empty group */
3184 if (mode & 0x01) break;
3187 /* Terminate the list */
3188 mon_idx[mon_cnt] = -1;
3191 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3193 /* Return the number of races */
3199 * Description of each monster group.
3201 static concptr object_group_text[] =
3204 "キノコ", /* "Mushrooms" */
3205 "薬", /* "Potions" */
3206 "油つぼ", /* "Flasks" */
3207 "巻物", /* "Scrolls" */
3209 "アミュレット", /* "Amulets" */
3210 "笛", /* "Whistle" */
3211 "光源", /* "Lanterns" */
3212 "魔法棒", /* "Wands" */
3215 "カード", /* "Cards" */
3226 "刀剣類", /* "Swords" */
3227 "鈍器", /* "Blunt Weapons" */
3228 "長柄武器", /* "Polearms" */
3229 "採掘道具", /* "Diggers" */
3230 "飛び道具", /* "Bows" */
3234 "軽装鎧", /* "Soft Armor" */
3235 "重装鎧", /* "Hard Armor" */
3236 "ドラゴン鎧", /* "Dragon Armor" */
3237 "盾", /* "Shields" */
3238 "クローク", /* "Cloaks" */
3239 "籠手", /* "Gloves" */
3240 "ヘルメット", /* "Helms" */
3242 "ブーツ", /* "Boots" */
3295 * TVALs of items in each group
3297 static byte object_group_tval[] =
3338 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3346 * Build a list of object indexes in the given group. Return the number
3347 * of objects in the group.
3349 * mode & 0x01 : check for non-empty group
3350 * mode & 0x02 : visual operation only
3352 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3354 KIND_OBJECT_IDX i, object_cnt = 0;
3357 /* Get a list of x_char in this group */
3358 byte group_tval = object_group_tval[grp_cur];
3360 /* Check every object */
3361 for (i = 0; i < max_k_idx; i++)
3363 /* Access the object */
3364 object_kind *k_ptr = &k_info[i];
3366 /* Skip empty objects */
3367 if (!k_ptr->name) continue;
3371 if (!current_world_ptr->wizard)
3373 /* Skip non-flavoured objects */
3374 if (!k_ptr->flavor) continue;
3376 /* Require objects ever seen */
3377 if (!k_ptr->aware) continue;
3380 /* Skip items with no distribution (special artifacts) */
3381 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3385 /* Check for objects in the group */
3386 if (TV_LIFE_BOOK == group_tval)
3388 /* Hack -- All spell books */
3389 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3391 /* Add the object */
3392 object_idx[object_cnt++] = i;
3396 else if (k_ptr->tval == group_tval)
3398 /* Add the object */
3399 object_idx[object_cnt++] = i;
3403 /* XXX Hack -- Just checking for non-empty group */
3404 if (mode & 0x01) break;
3407 /* Terminate the list */
3408 object_idx[object_cnt] = -1;
3410 /* Return the number of objects */
3416 * Description of each feature group.
3418 static concptr feature_group_text[] =
3426 * Build a list of feature indexes in the given group. Return the number
3427 * of features in the group.
3429 * mode & 0x01 : check for non-empty group
3431 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3433 /* Check every feature */
3434 FEAT_IDX feat_cnt = 0;
3435 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3437 feature_type *f_ptr = &f_info[i];
3439 /* Skip empty index */
3440 if (!f_ptr->name) continue;
3442 /* Skip mimiccing features */
3443 if (f_ptr->mimic != i) continue;
3446 feat_idx[feat_cnt++] = i;
3448 /* XXX Hack -- Just checking for non-empty group */
3449 if (mode & 0x01) break;
3452 /* Terminate the list */
3453 feat_idx[feat_cnt] = -1;
3455 /* Return the number of races */
3461 * Hack -- load a screen dump from a file
3463 void do_cmd_load_screen(void)
3467 SYMBOL_CODE c = ' ';
3473 Term_get_size(&wid, &hgt);
3474 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3476 /* Append to the file */
3477 fff = my_fopen(buf, "r");
3481 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3489 /* Load the screen */
3490 for (y = 0; okay; y++)
3492 /* Get a line of data including control code */
3493 if (!fgets(buf, 1024, fff)) okay = FALSE;
3495 /* Get the blank line */
3496 if (buf[0] == '\n' || buf[0] == '\0') break;
3498 /* Ignore too large screen image */
3499 if (y >= hgt) continue;
3502 for (x = 0; x < wid - 1; x++)
3505 if (buf[x] == '\n' || buf[x] == '\0') break;
3507 /* Put the attr/char */
3508 Term_draw(x, y, TERM_WHITE, buf[x]);
3512 /* Dump the screen */
3513 for (y = 0; okay; y++)
3515 /* Get a line of data including control code */
3516 if (!fgets(buf, 1024, fff)) okay = FALSE;
3518 /* Get the blank line */
3519 if (buf[0] == '\n' || buf[0] == '\0') break;
3521 /* Ignore too large screen image */
3522 if (y >= hgt) continue;
3525 for (x = 0; x < wid - 1; x++)
3528 if (buf[x] == '\n' || buf[x] == '\0') break;
3530 /* Get the attr/char */
3531 (void)(Term_what(x, y, &a, &c));
3533 /* Look up the attr */
3534 for (int i = 0; i < 16; i++)
3536 /* Use attr matches */
3537 if (hack[i] == buf[x]) a = (byte)i;
3540 /* Put the attr/char */
3541 Term_draw(x, y, a, c);
3547 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3555 // todo なぜこんな中途半端なところに? defineも…
3556 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3557 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3559 #define IM_FLAG_STR _("*", "* ")
3560 #define HAS_FLAG_STR _("+", "+ ")
3561 #define NO_FLAG_STR _("・", ". ")
3563 #define print_im_or_res_flag(IM, RES) \
3565 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3566 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3569 #define print_flag(TR) \
3571 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3575 /* XTRA HACK RESLIST */
3576 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)
3578 GAME_TEXT o_name[MAX_NLEN];
3579 BIT_FLAGS flgs[TR_FLAG_SIZE];
3581 if (!o_ptr->k_idx) return;
3582 if (o_ptr->tval != tval) return;
3584 /* Identified items only */
3585 if (!object_is_known(o_ptr)) return;
3588 * HACK:Ring of Lordly protection and Dragon equipment
3589 * have random resistances.
3591 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3592 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3593 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3594 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3595 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3596 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3597 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3598 || object_is_artifact(o_ptr);
3599 if (!is_special_item_type)
3605 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3607 while (o_name[i] && (i < 26))
3610 if (iskanji(o_name[i])) i++;
3619 o_name[i] = ' '; i++;
3625 fprintf(fff, "%s %s", where, o_name);
3627 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
3629 fputs(_("-------不明--------------- -------不明---------\n",
3630 "-------unknown------------ -------unknown------\n"), fff);
3634 object_flags_known(o_ptr, flgs);
3636 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3637 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3638 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3639 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3640 print_flag(TR_RES_POIS);
3641 print_flag(TR_RES_LITE);
3642 print_flag(TR_RES_DARK);
3643 print_flag(TR_RES_SHARDS);
3644 print_flag(TR_RES_SOUND);
3645 print_flag(TR_RES_NETHER);
3646 print_flag(TR_RES_NEXUS);
3647 print_flag(TR_RES_CHAOS);
3648 print_flag(TR_RES_DISEN);
3652 print_flag(TR_RES_BLIND);
3653 print_flag(TR_RES_FEAR);
3654 print_flag(TR_RES_CONF);
3655 print_flag(TR_FREE_ACT);
3656 print_flag(TR_SEE_INVIS);
3657 print_flag(TR_HOLD_EXP);
3658 print_flag(TR_TELEPATHY);
3659 print_flag(TR_SLOW_DIGEST);
3660 print_flag(TR_REGEN);
3661 print_flag(TR_LEVITATION);
3670 fprintf(fff, "%s\n", inven_res_label);
3675 * Display *ID* ed weapons/armors's resistances
3677 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3680 GAME_TEXT file_name[1024];
3682 OBJECT_TYPE_VALUE tval;
3688 /* Open a new file */
3689 fff = my_fopen_temp(file_name, 1024);
3692 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3697 fprintf(fff, "%s\n", inven_res_label);
3699 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3703 for (; j < 9; j++) fputc('\n', fff);
3705 fprintf(fff, "%s\n", inven_res_label);
3708 strcpy(where, _("装", "E "));
3709 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3711 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3714 strcpy(where, _("持", "I "));
3715 for (i = 0; i < INVEN_PACK; i++)
3717 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3720 st_ptr = &town_info[1].store[STORE_HOME];
3721 strcpy(where, _("家", "H "));
3722 for (i = 0; i < st_ptr->stock_num; i++)
3724 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3730 /* Display the file contents */
3731 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3736 void do_cmd_save_screen_html_aux(char *filename, int message)
3744 concptr html_head[] = {
3745 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3749 concptr html_foot[] = {
3751 "</body>\n</html>\n",
3756 Term_get_size(&wid, &hgt);
3758 /* File type is "TEXT" */
3759 FILE_TYPE(FILE_TYPE_TEXT);
3761 /* Append to the file */
3763 fff = my_fopen(filename, "w");
3769 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3776 if (message) screen_save();
3778 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3780 tmpfff = my_fopen(buf, "r");
3783 for (int i = 0; html_head[i]; i++)
3784 fputs(html_head[i], fff);
3788 bool is_first_line = TRUE;
3789 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3793 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3794 is_first_line = FALSE;
3798 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3800 fprintf(fff, "%s\n", buf);
3805 /* Dump the screen */
3806 for (TERM_LEN y = 0; y < hgt; y++)
3809 if (y != 0) fprintf(fff, "\n");
3812 TERM_COLOR a = 0, old_a = 0;
3814 for (TERM_LEN x = 0; x < wid - 1; x++)
3817 /* Get the attr/char */
3818 (void)(Term_what(x, y, &a, &c));
3822 case '&': cc = "&"; break;
3823 case '<': cc = "<"; break;
3824 case '>': cc = ">"; break;
3826 case 0x1f: c = '.'; break;
3827 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3832 if ((y == 0 && x == 0) || a != old_a)
3834 int rv = angband_color_table[a][1];
3835 int gv = angband_color_table[a][2];
3836 int bv = angband_color_table[a][3];
3837 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3838 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3843 fprintf(fff, "%s", cc);
3845 fprintf(fff, "%c", c);
3849 fprintf(fff, "</font>");
3853 for (int i = 0; html_foot[i]; i++)
3854 fputs(html_foot[i], fff);
3859 bool is_first_line = TRUE;
3860 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3864 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3865 is_first_line = FALSE;
3869 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3871 fprintf(fff, "%s\n", buf);
3884 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3893 * Hack -- save a screen dump to a file
3895 static void do_cmd_save_screen_html(void)
3897 char buf[1024], tmp[256] = "screen.html";
3899 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3901 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3905 do_cmd_save_screen_html_aux(buf, 1);
3910 * Redefinable "save_screen" action
3912 void(*screendump_aux)(void) = NULL;
3916 * Save a screen dump to a file
3917 * @param creature_ptr プレーヤーへの参照ポインタ
3920 void do_cmd_save_screen(player_type *creature_ptr)
3922 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3923 bool html_dump = FALSE;
3927 if (c == 'Y' || c == 'y')
3929 else if (c == 'H' || c == 'h')
3942 Term_get_size(&wid, &hgt);
3944 bool old_use_graphics = use_graphics;
3945 if (old_use_graphics)
3947 use_graphics = FALSE;
3948 reset_visuals(creature_ptr);
3949 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3950 handle_stuff(creature_ptr);
3955 do_cmd_save_screen_html();
3956 do_cmd_redraw(creature_ptr);
3959 /* Do we use a special screendump function ? */
3960 else if (screendump_aux)
3962 /* Dump the screen to a graphics file */
3963 (*screendump_aux)();
3965 else /* Dump the screen as text */
3969 SYMBOL_CODE c = ' ';
3972 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3974 /* File type is "TEXT" */
3975 FILE_TYPE(FILE_TYPE_TEXT);
3977 /* Append to the file */
3978 fff = my_fopen(buf, "w");
3982 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3989 /* Dump the screen */
3990 for (y = 0; y < hgt; y++)
3993 for (x = 0; x < wid - 1; x++)
3995 /* Get the attr/char */
3996 (void)(Term_what(x, y, &a, &c));
4006 fprintf(fff, "%s\n", buf);
4013 /* Dump the screen */
4014 for (y = 0; y < hgt; y++)
4017 for (x = 0; x < wid - 1; x++)
4019 /* Get the attr/char */
4020 (void)(Term_what(x, y, &a, &c));
4023 buf[x] = hack[a & 0x0F];
4030 fprintf(fff, "%s\n", buf);
4037 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4042 if (!old_use_graphics) return;
4044 use_graphics = TRUE;
4045 reset_visuals(creature_ptr);
4046 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4047 handle_stuff(creature_ptr);
4052 * todo okay = 既知のアーティファクト? と思われるが確証がない
4053 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4054 * Check the status of "artifacts"
4055 * @param player_ptr プレーヤーへの参照ポインタ
4058 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4060 /* Open a new file */
4062 GAME_TEXT file_name[1024];
4063 fff = my_fopen_temp(file_name, 1024);
4066 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4071 /* Allocate the "who" array */
4073 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4075 /* Allocate the "okay" array */
4077 C_MAKE(okay, max_a_idx, bool);
4079 /* Scan the artifacts */
4080 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4082 artifact_type *a_ptr = &a_info[k];
4087 /* Skip "empty" artifacts */
4088 if (!a_ptr->name) continue;
4090 /* Skip "uncreated" artifacts */
4091 if (!a_ptr->cur_num) continue;
4097 /* Check the dungeon */
4098 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4100 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4102 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4104 OBJECT_IDX this_o_idx, next_o_idx = 0;
4106 /* Scan all objects in the grid */
4107 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4110 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4111 next_o_idx = o_ptr->next_o_idx;
4113 /* Ignore non-artifacts */
4114 if (!object_is_fixed_artifact(o_ptr)) continue;
4116 /* Ignore known items */
4117 if (object_is_known(o_ptr)) continue;
4119 /* Note the artifact */
4120 okay[o_ptr->name1] = FALSE;
4125 /* Check the player_ptr->inventory_list and equipment */
4126 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4128 object_type *o_ptr = &player_ptr->inventory_list[i];
4130 /* Ignore non-objects */
4131 if (!o_ptr->k_idx) continue;
4133 /* Ignore non-artifacts */
4134 if (!object_is_fixed_artifact(o_ptr)) continue;
4136 /* Ignore known items */
4137 if (object_is_known(o_ptr)) continue;
4139 /* Note the artifact */
4140 okay[o_ptr->name1] = FALSE;
4144 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4146 if (okay[k]) who[n++] = k;
4150 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4152 /* Scan the artifacts */
4153 for (ARTIFACT_IDX k = 0; k < n; k++)
4155 artifact_type *a_ptr = &a_info[who[k]];
4156 GAME_TEXT base_name[MAX_NLEN];
4157 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4159 /* Obtain the base object type */
4160 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4169 /* Create fake object */
4170 object_prep(q_ptr, z);
4172 /* Make it an artifact */
4173 q_ptr->name1 = (byte)who[k];
4175 /* Display as if known */
4176 q_ptr->ident |= IDENT_STORE;
4178 /* Describe the artifact */
4179 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4182 /* Hack -- Build the artifact name */
4183 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4186 /* Free the "who" array */
4187 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4189 /* Free the "okay" array */
4190 C_KILL(okay, max_a_idx, bool);
4193 /* Display the file contents */
4194 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4200 * Display known uniques
4201 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4203 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4210 GAME_TEXT file_name[1024];
4213 int n_alive_surface = 0;
4214 int n_alive_over100 = 0;
4215 int n_alive_total = 0;
4218 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4220 /* Open a new file */
4221 fff = my_fopen_temp(file_name, 1024);
4225 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4230 /* Allocate the "who" array */
4231 C_MAKE(who, max_r_idx, MONRACE_IDX);
4233 /* Scan the monsters */
4235 for (IDX i = 1; i < max_r_idx; i++)
4237 monster_race *r_ptr = &r_info[i];
4240 if (!r_ptr->name) continue;
4242 /* Require unique monsters */
4243 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4245 /* Only display "known" uniques */
4246 if (!cheat_know && !r_ptr->r_sights) continue;
4248 /* Only print rarity <= 100 uniques */
4249 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4251 /* Only "alive" uniques */
4252 if (r_ptr->max_num == 0) continue;
4256 lev = (r_ptr->level - 1) / 10;
4260 if (max_lev < lev) max_lev = lev;
4262 else n_alive_over100++;
4264 else n_alive_surface++;
4266 /* Collect "appropriate" monsters */
4270 /* Sort the array by dungeon depth of monsters */
4271 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4273 if (n_alive_surface)
4275 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4276 n_alive_total += n_alive_surface;
4279 for (IDX i = 0; i <= max_lev; i++)
4281 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4282 n_alive_total += n_alive[i];
4285 if (n_alive_over100)
4287 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4288 n_alive_total += n_alive_over100;
4293 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4294 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4298 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4301 /* Scan the monster races */
4302 for (int k = 0; k < n; k++)
4304 monster_race *r_ptr = &r_info[who[k]];
4305 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4308 /* Free the "who" array */
4309 C_KILL(who, max_r_idx, s16b);
4312 /* Display the file contents */
4313 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4319 * Display weapon-exp
4321 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4323 /* Open a new file */
4325 GAME_TEXT file_name[1024];
4326 fff = my_fopen_temp(file_name, 1024);
4329 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4334 for (int i = 0; i < 5; i++)
4336 for (int num = 0; num < 64; num++)
4340 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4342 object_kind *k_ptr = &k_info[j];
4344 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4345 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4347 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4349 fprintf(fff, "%-25s ", tmp);
4350 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4351 else fprintf(fff, " ");
4352 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4353 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4362 /* Display the file contents */
4363 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4369 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4373 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4375 /* Open a new file */
4377 GAME_TEXT file_name[1024];
4378 fff = my_fopen_temp(file_name, 1024);
4381 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4386 if (creature_ptr->realm1 != REALM_NONE)
4388 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4389 for (SPELL_IDX i = 0; i < 32; i++)
4391 const magic_type *s_ptr;
4392 if (!is_magic(creature_ptr->realm1))
4394 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4398 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4401 if (s_ptr->slevel >= 99) continue;
4402 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4403 int exp_level = spell_exp_level(spell_exp);
4404 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4405 if (creature_ptr->realm1 == REALM_HISSATSU)
4406 fprintf(fff, "[--]");
4409 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4410 else fprintf(fff, " ");
4411 fprintf(fff, "%s", exp_level_str[exp_level]);
4414 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4419 if (creature_ptr->realm2 != REALM_NONE)
4421 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4422 for (SPELL_IDX i = 0; i < 32; i++)
4424 const magic_type *s_ptr;
4425 if (!is_magic(creature_ptr->realm1))
4427 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4431 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4434 if (s_ptr->slevel >= 99) continue;
4436 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4437 int exp_level = spell_exp_level(spell_exp);
4438 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4439 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4440 else fprintf(fff, " ");
4441 fprintf(fff, "%s", exp_level_str[exp_level]);
4442 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4449 /* Display the file contents */
4450 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4456 * @brief スキル情報を表示するコマンドのメインルーチン /
4460 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4462 char skill_name[GINOU_TEMPMAX][20] =
4464 _("マーシャルアーツ", "Martial Arts "),
4465 _("二刀流 ", "Dual Wielding "),
4466 _("乗馬 ", "Riding "),
4470 /* Open a new file */
4472 char file_name[1024];
4473 fff = my_fopen_temp(file_name, 1024);
4476 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4481 for (int i = 0; i < GINOU_TEMPMAX; i++)
4483 int skill_exp = creature_ptr->skill_exp[i];
4484 fprintf(fff, "%-20s ", skill_name[i]);
4485 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4486 else fprintf(fff, " ");
4487 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4488 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4494 /* Display the file contents */
4495 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4501 * @brief 現在のペットを表示するコマンドのメインルーチン /
4502 * Display current pets
4503 * @param creature_ptr プレーヤーへの参照ポインタ
4506 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4508 /* Open a new file */
4509 GAME_TEXT file_name[1024];
4511 fff = my_fopen_temp(file_name, 1024);
4514 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4519 /* Process the monsters (backwards) */
4520 monster_type *m_ptr;
4521 GAME_TEXT pet_name[MAX_NLEN];
4523 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4525 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4527 /* Ignore "dead" monsters */
4528 if (!monster_is_valid(m_ptr)) continue;
4530 /* Calculate "upkeep" for pets */
4531 if (!is_pet(m_ptr)) continue;
4534 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4535 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4538 int show_upkeep = calculate_upkeep(creature_ptr);
4540 fprintf(fff, "----------------------------------------------\n");
4542 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4544 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4546 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4550 /* Display the file contents */
4551 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4557 * @brief 現在のペットを表示するコマンドのメインルーチン /
4558 * @param creature_ptr プレーヤーへの参照ポインタ
4561 * @note the player ghosts are ignored.
4563 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4565 /* Open a new file */
4567 GAME_TEXT file_name[1024];
4568 fff = my_fopen_temp(file_name, 1024);
4571 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4576 /* Allocate the "who" array */
4578 C_MAKE(who, max_r_idx, MONRACE_IDX);
4582 /* Monsters slain */
4583 for (int kk = 1; kk < max_r_idx; kk++)
4585 monster_race *r_ptr = &r_info[kk];
4587 if (r_ptr->flags1 & (RF1_UNIQUE))
4589 bool dead = (r_ptr->max_num == 0);
4598 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4600 if (this_monster > 0)
4602 total += this_monster;
4608 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4611 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4613 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4619 /* Scan the monsters */
4621 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4623 monster_race *r_ptr = &r_info[i];
4625 /* Use that monster */
4626 if (r_ptr->name) who[n++] = i;
4629 /* Sort the array by dungeon depth of monsters */
4631 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4633 /* Scan the monster races */
4634 for (int k = 0; k < n; k++)
4636 monster_race *r_ptr = &r_info[who[k]];
4638 if (r_ptr->flags1 & (RF1_UNIQUE))
4640 bool dead = (r_ptr->max_num == 0);
4644 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4651 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4653 if (this_monster <= 0) continue;
4656 /* p,tは人と数える by ita */
4657 if (my_strchr("pt", r_ptr->d_char))
4658 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4660 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4662 if (this_monster < 2)
4664 if (my_strstr(r_name + r_ptr->name, "coins"))
4666 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4670 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4676 strcpy(ToPlural, (r_name + r_ptr->name));
4677 plural_aux(ToPlural);
4678 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4681 total += this_monster;
4684 fprintf(fff, "----------------------------------------------\n");
4686 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4688 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4691 /* Free the "who" array */
4692 C_KILL(who, max_r_idx, s16b);
4695 /* Display the file contents */
4696 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4702 * @brief モンスター情報リスト中のグループを表示する /
4703 * Display the object groups.
4707 * @param per_page リストの表示行
4708 * @param grp_idx グループのID配列
4709 * @param group_text グループ名の文字列配列
4710 * @param grp_cur 現在の選択ID
4711 * @param grp_top 現在の選択リスト最上部ID
4714 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)
4716 /* Display lines until done */
4717 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4719 /* Get the group index */
4720 int grp = grp_idx[grp_top + i];
4722 /* Choose a color */
4723 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4725 /* Erase the entire line */
4726 Term_erase(col, row + i, wid);
4728 /* Display the group label */
4729 c_put_str(attr, group_text[grp], row + i, col);
4735 * Move the cursor in a browser window
4737 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4738 IDX *list_cur, int list_cnt)
4743 IDX list = *list_cur;
4745 /* Extract direction */
4748 /* Hack -- scroll up full screen */
4753 /* Hack -- scroll down full screen */
4758 d = get_keymap_dir(ch);
4763 /* Diagonals - hack */
4764 if ((ddx[d] > 0) && ddy[d])
4769 Term_get_size(&wid, &hgt);
4771 browser_rows = hgt - 8;
4773 /* Browse group list */
4778 /* Move up or down */
4779 grp += ddy[d] * (browser_rows - 1);
4782 if (grp >= grp_cnt) grp = grp_cnt - 1;
4783 if (grp < 0) grp = 0;
4784 if (grp != old_grp) list = 0;
4787 /* Browse sub-list list */
4790 /* Move up or down */
4791 list += ddy[d] * browser_rows;
4794 if (list >= list_cnt) list = list_cnt - 1;
4795 if (list < 0) list = 0;
4807 if (col < 0) col = 0;
4808 if (col > 1) col = 1;
4815 /* Browse group list */
4820 /* Move up or down */
4824 if (grp >= grp_cnt) grp = grp_cnt - 1;
4825 if (grp < 0) grp = 0;
4826 if (grp != old_grp) list = 0;
4829 /* Browse sub-list list */
4832 /* Move up or down */
4833 list += (IDX)ddy[d];
4836 if (list >= list_cnt) list = list_cnt - 1;
4837 if (list < 0) list = 0;
4848 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4850 /* Clear the display lines */
4851 for (int i = 0; i < height; i++)
4853 Term_erase(col, row + i, width);
4856 /* Bigtile mode uses double width */
4857 if (use_bigtile) width /= 2;
4859 /* Display lines until done */
4860 for (int i = 0; i < height; i++)
4862 /* Display columns until done */
4863 for (int j = 0; j < width; j++)
4865 TERM_LEN x = col + j;
4866 TERM_LEN y = row + i;
4868 /* Bigtile mode uses double width */
4869 if (use_bigtile) x += j;
4871 TERM_COLOR ia = attr_top + i;
4872 SYMBOL_CODE ic = char_left + j;
4874 /* Ignore illegal characters */
4875 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4876 (!use_graphics && ic > 0x7f))
4882 /* Force correct code for both ASCII character and tile */
4883 if (c & 0x80) a |= 0x80;
4885 /* Display symbol */
4886 Term_queue_bigchar(x, y, a, c, 0, 0);
4893 * Place the cursor at the collect position for visual mode
4895 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4897 int i = (a & 0x7f) - attr_top;
4898 int j = c - char_left;
4900 TERM_LEN x = col + j;
4901 TERM_LEN y = row + i;
4903 /* Bigtile mode uses double width */
4904 if (use_bigtile) x += j;
4906 /* Place the cursor */
4912 * Do visual mode command -- Change symbols
4914 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4915 int height, int width,
4916 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4917 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4919 static TERM_COLOR attr_old = 0;
4920 static SYMBOL_CODE char_old = 0;
4925 if (*visual_list_ptr)
4928 *cur_attr_ptr = attr_old;
4929 *cur_char_ptr = char_old;
4930 *visual_list_ptr = FALSE;
4938 if (*visual_list_ptr)
4941 *visual_list_ptr = FALSE;
4942 *need_redraw = TRUE;
4950 if (!*visual_list_ptr)
4952 *visual_list_ptr = TRUE;
4954 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4955 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4957 attr_old = *cur_attr_ptr;
4958 char_old = *cur_char_ptr;
4969 /* Set the visual */
4970 attr_idx = *cur_attr_ptr;
4971 char_idx = *cur_char_ptr;
4973 /* Hack -- for feature lighting */
4974 for (i = 0; i < F_LIT_MAX; i++)
4976 attr_idx_feat[i] = 0;
4977 char_idx_feat[i] = 0;
4984 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4987 *cur_attr_ptr = attr_idx;
4988 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4989 if (!*visual_list_ptr) *need_redraw = TRUE;
4995 *cur_char_ptr = char_idx;
4996 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4997 if (!*visual_list_ptr) *need_redraw = TRUE;
5003 if (*visual_list_ptr)
5006 int d = get_keymap_dir(ch);
5007 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5008 SYMBOL_CODE c = *cur_char_ptr;
5010 if (use_bigtile) eff_width = width / 2;
5011 else eff_width = width;
5013 /* Restrict direction */
5014 if ((a == 0) && (ddy[d] < 0)) d = 0;
5015 if ((c == 0) && (ddx[d] < 0)) d = 0;
5016 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5017 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5019 a += (TERM_COLOR)ddy[d];
5020 c += (SYMBOL_CODE)ddx[d];
5022 /* Force correct code for both ASCII character and tile */
5023 if (c & 0x80) a |= 0x80;
5025 /* Set the visual */
5030 /* Move the frame */
5031 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5032 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5033 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5034 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5040 /* Visual mode command is not used */
5046 * Display the monsters in a group.
5048 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5049 int mon_cur, int mon_top, bool visual_only)
5051 /* Display lines until done */
5053 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5057 /* Get the race index */
5058 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5060 /* Access the race */
5061 monster_race *r_ptr = &r_info[r_idx];
5063 /* Choose a color */
5064 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5066 /* Display the name */
5067 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5069 /* Hack -- visual_list mode */
5072 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5075 if (current_world_ptr->wizard || visual_only)
5077 c_prt(attr, format("%d", r_idx), row + i, 62);
5080 /* Erase chars before overwritten by the race letter */
5081 Term_erase(69, row + i, 255);
5083 /* Display symbol */
5084 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5089 if (!(r_ptr->flags1 & RF1_UNIQUE))
5090 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5092 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5093 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5097 /* Clear remaining lines */
5098 for (; i < per_page; i++)
5100 Term_erase(col, row + i, 255);
5106 * todo 引数の詳細について加筆求む
5107 * Display known monsters.
5108 * @param creature_ptr プレーヤーへの参照ポインタ
5109 * @param need_redraw 画面の再描画が必要な時TRUE
5110 * @param visual_only ???
5111 * @param direct_r_idx モンスターID
5114 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5117 Term_get_size(&wid, &hgt);
5119 /* Allocate the "mon_idx" array */
5121 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5127 bool visual_list = FALSE;
5128 TERM_COLOR attr_top = 0;
5131 int browser_rows = hgt - 8;
5132 if (direct_r_idx < 0)
5134 mode = visual_only ? 0x03 : 0x01;
5136 /* Check every group */
5138 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5140 /* Measure the label */
5141 len = strlen(monster_group_text[i]);
5143 /* Save the maximum length */
5144 if (len > max) max = len;
5146 /* See if any monsters are known */
5147 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5149 /* Build a list of groups with known monsters */
5150 grp_idx[grp_cnt++] = i;
5158 mon_idx[0] = direct_r_idx;
5161 /* Terminate the list */
5164 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5165 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5168 /* Terminate the list */
5169 grp_idx[grp_cnt] = -1;
5171 mode = visual_only ? 0x02 : 0x00;
5172 IDX old_grp_cur = -1;
5185 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5186 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5187 prt(_("名前", "Name"), 4, max + 3);
5188 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5189 prt(_("文字", "Sym"), 4, 67);
5190 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5192 for (IDX i = 0; i < 78; i++)
5194 Term_putch(i, 5, TERM_WHITE, '=');
5197 if (direct_r_idx < 0)
5199 for (IDX i = 0; i < browser_rows; i++)
5201 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5208 if (direct_r_idx < 0)
5210 /* Scroll group list */
5211 if (grp_cur < grp_top) grp_top = grp_cur;
5212 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5214 /* Display a list of monster groups */
5215 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5217 if (old_grp_cur != grp_cur)
5219 old_grp_cur = grp_cur;
5221 /* Get a list of monsters in the current group */
5222 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5225 /* Scroll monster list */
5226 while (mon_cur < mon_top)
5227 mon_top = MAX(0, mon_top - browser_rows / 2);
5228 while (mon_cur >= mon_top + browser_rows)
5229 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5234 /* Display a list of monsters in the current group */
5235 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5241 /* Display a monster name */
5242 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5244 /* Display visual list below first monster */
5245 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5249 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5250 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5251 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5252 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5255 /* Get the current monster */
5256 monster_race *r_ptr;
5257 r_ptr = &r_info[mon_idx[mon_cur]];
5261 /* Mega Hack -- track this monster race */
5262 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5263 handle_stuff(creature_ptr);
5268 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5272 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5276 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5281 /* Do visual mode command if needed */
5282 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))
5284 if (direct_r_idx >= 0)
5310 /* Recall on screen */
5311 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5313 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5325 /* Move the cursor */
5326 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5333 /* Free the "mon_idx" array */
5334 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5339 * Display the objects in a group.
5341 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5342 int object_cur, int object_top, bool visual_only)
5344 /* Display lines until done */
5346 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5348 GAME_TEXT o_name[MAX_NLEN];
5351 object_kind *flavor_k_ptr;
5353 /* Get the object index */
5354 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5356 /* Access the object */
5357 object_kind *k_ptr = &k_info[k_idx];
5359 /* Choose a color */
5360 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5361 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5363 if (!visual_only && k_ptr->flavor)
5365 /* Appearance of this object is shuffled */
5366 flavor_k_ptr = &k_info[k_ptr->flavor];
5370 /* Appearance of this object is very normal */
5371 flavor_k_ptr = k_ptr;
5374 attr = ((i + object_top == object_cur) ? cursor : attr);
5376 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5379 strip_name(o_name, k_idx);
5384 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5387 /* Display the name */
5388 c_prt(attr, o_name, row + i, col);
5390 /* Hack -- visual_list mode */
5393 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);
5396 if (current_world_ptr->wizard || visual_only)
5398 c_prt(attr, format("%d", k_idx), row + i, 70);
5401 a = flavor_k_ptr->x_attr;
5402 c = flavor_k_ptr->x_char;
5404 /* Display symbol */
5405 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5408 /* Clear remaining lines */
5409 for (; i < per_page; i++)
5411 Term_erase(col, row + i, 255);
5417 * Describe fake object
5419 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5422 object_type object_type_body;
5423 o_ptr = &object_type_body;
5425 object_prep(o_ptr, k_idx);
5427 /* It's fully know */
5428 o_ptr->ident |= IDENT_KNOWN;
5429 handle_stuff(creature_ptr);
5431 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5433 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5439 * Display known objects
5441 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5443 IDX object_old, object_top;
5446 OBJECT_IDX *object_idx;
5448 bool visual_list = FALSE;
5449 TERM_COLOR attr_top = 0;
5454 Term_get_size(&wid, &hgt);
5456 int browser_rows = hgt - 8;
5458 /* Allocate the "object_idx" array */
5459 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5464 if (direct_k_idx < 0)
5466 mode = visual_only ? 0x03 : 0x01;
5468 /* Check every group */
5469 for (IDX i = 0; object_group_text[i] != NULL; i++)
5471 /* Measure the label */
5472 len = strlen(object_group_text[i]);
5474 /* Save the maximum length */
5475 if (len > max) max = len;
5477 /* See if any monsters are known */
5478 if (collect_objects(i, object_idx, mode))
5480 /* Build a list of groups with known monsters */
5481 grp_idx[grp_cnt++] = i;
5490 object_kind *k_ptr = &k_info[direct_k_idx];
5491 object_kind *flavor_k_ptr;
5493 if (!visual_only && k_ptr->flavor)
5495 /* Appearance of this object is shuffled */
5496 flavor_k_ptr = &k_info[k_ptr->flavor];
5500 /* Appearance of this object is very normal */
5501 flavor_k_ptr = k_ptr;
5504 object_idx[0] = direct_k_idx;
5505 object_old = direct_k_idx;
5508 /* Terminate the list */
5511 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5512 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5515 /* Terminate the list */
5516 grp_idx[grp_cnt] = -1;
5518 mode = visual_only ? 0x02 : 0x00;
5519 IDX old_grp_cur = -1;
5522 IDX object_cur = object_top = 0;
5528 object_kind *k_ptr, *flavor_k_ptr;
5535 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5536 if (direct_k_idx < 0) prt("グループ", 4, 0);
5537 prt("名前", 4, max + 3);
5538 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5541 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5542 if (direct_k_idx < 0) prt("Group", 4, 0);
5543 prt("Name", 4, max + 3);
5544 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5548 for (IDX i = 0; i < 78; i++)
5550 Term_putch(i, 5, TERM_WHITE, '=');
5553 if (direct_k_idx < 0)
5555 for (IDX i = 0; i < browser_rows; i++)
5557 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5564 if (direct_k_idx < 0)
5566 /* Scroll group list */
5567 if (grp_cur < grp_top) grp_top = grp_cur;
5568 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5570 /* Display a list of object groups */
5571 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5573 if (old_grp_cur != grp_cur)
5575 old_grp_cur = grp_cur;
5577 /* Get a list of objects in the current group */
5578 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5581 /* Scroll object list */
5582 while (object_cur < object_top)
5583 object_top = MAX(0, object_top - browser_rows / 2);
5584 while (object_cur >= object_top + browser_rows)
5585 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5590 /* Display a list of objects in the current group */
5591 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5595 object_top = object_cur;
5597 /* Display a list of objects in the current group */
5598 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5600 /* Display visual list below first object */
5601 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5604 /* Get the current object */
5605 k_ptr = &k_info[object_idx[object_cur]];
5607 if (!visual_only && k_ptr->flavor)
5609 /* Appearance of this object is shuffled */
5610 flavor_k_ptr = &k_info[k_ptr->flavor];
5614 /* Appearance of this object is very normal */
5615 flavor_k_ptr = k_ptr;
5620 prt(format("<方向>%s%s%s, ESC",
5621 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5622 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5623 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5626 prt(format("<dir>%s%s%s, ESC",
5627 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5628 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5629 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5635 /* Mega Hack -- track this object */
5636 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5638 /* The "current" object changed */
5639 if (object_old != object_idx[object_cur])
5641 handle_stuff(creature_ptr);
5643 /* Remember the "current" object */
5644 object_old = object_idx[object_cur];
5650 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5654 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5658 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5663 /* Do visual mode command if needed */
5664 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))
5666 if (direct_k_idx >= 0)
5691 /* Recall on screen */
5692 if (!visual_list && !visual_only && (grp_cnt > 0))
5694 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5702 /* Move the cursor */
5703 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5709 /* Free the "object_idx" array */
5710 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5715 * Display the features in a group.
5717 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5718 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5720 int lit_col[F_LIT_MAX], i;
5721 int f_idx_col = use_bigtile ? 62 : 64;
5723 /* Correct columns 1 and 4 */
5724 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5725 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5726 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5728 /* Display lines until done */
5729 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5732 FEAT_IDX f_idx = feat_idx[feat_top + i];
5733 feature_type *f_ptr = &f_info[f_idx];
5734 int row_i = row + i;
5736 /* Choose a color */
5737 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5739 /* Display the name */
5740 c_prt(attr, f_name + f_ptr->name, row_i, col);
5742 /* Hack -- visual_list mode */
5745 /* Display lighting level */
5746 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5748 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));
5750 if (current_world_ptr->wizard || visual_only)
5752 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5755 /* Display symbol */
5756 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);
5758 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5759 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5761 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5763 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5765 /* Mega-hack -- Use non-standard colour */
5766 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5768 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5772 /* Clear remaining lines */
5773 for (; i < per_page; i++)
5775 Term_erase(col, row + i, 255);
5781 * Interact with feature visuals.
5783 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5785 TERM_COLOR attr_old[F_LIT_MAX];
5786 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5787 SYMBOL_CODE char_old[F_LIT_MAX];
5788 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5791 Term_get_size(&wid, &hgt);
5793 /* Allocate the "feat_idx" array */
5795 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5801 FEAT_IDX grp_idx[100];
5802 TERM_COLOR attr_top = 0;
5803 bool visual_list = FALSE;
5805 TERM_LEN browser_rows = hgt - 8;
5806 if (direct_f_idx < 0)
5808 /* Check every group */
5809 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5811 /* Measure the label */
5812 len = strlen(feature_group_text[i]);
5814 /* Save the maximum length */
5815 if (len > max) max = len;
5817 /* See if any features are known */
5818 if (collect_features(feat_idx, 0x01))
5820 /* Build a list of groups with known features */
5821 grp_idx[grp_cnt++] = i;
5829 feature_type *f_ptr = &f_info[direct_f_idx];
5831 feat_idx[0] = direct_f_idx;
5834 /* Terminate the list */
5837 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5838 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5840 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5842 attr_old[i] = f_ptr->x_attr[i];
5843 char_old[i] = f_ptr->x_char[i];
5847 /* Terminate the list */
5848 grp_idx[grp_cnt] = -1;
5850 FEAT_IDX old_grp_cur = -1;
5851 FEAT_IDX grp_cur = 0;
5852 FEAT_IDX grp_top = 0;
5853 FEAT_IDX feat_cur = 0;
5854 FEAT_IDX feat_top = 0;
5855 TERM_LEN column = 0;
5858 TERM_COLOR *cur_attr_ptr;
5859 SYMBOL_CODE *cur_char_ptr;
5863 feature_type *f_ptr;
5869 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5870 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5871 prt(_("名前", "Name"), 4, max + 3);
5874 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5875 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5879 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5880 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5883 for (FEAT_IDX i = 0; i < 78; i++)
5885 Term_putch(i, 5, TERM_WHITE, '=');
5888 if (direct_f_idx < 0)
5890 for (FEAT_IDX i = 0; i < browser_rows; i++)
5892 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5899 if (direct_f_idx < 0)
5901 /* Scroll group list */
5902 if (grp_cur < grp_top) grp_top = grp_cur;
5903 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5905 /* Display a list of feature groups */
5906 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5908 if (old_grp_cur != grp_cur)
5910 old_grp_cur = grp_cur;
5912 /* Get a list of features in the current group */
5913 feat_cnt = collect_features(feat_idx, 0x00);
5916 /* Scroll feature list */
5917 while (feat_cur < feat_top)
5918 feat_top = MAX(0, feat_top - browser_rows / 2);
5919 while (feat_cur >= feat_top + browser_rows)
5920 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5925 /* Display a list of features in the current group */
5926 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5930 feat_top = feat_cur;
5932 /* Display a list of features in the current group */
5933 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5935 /* Display visual list below first object */
5936 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5940 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5941 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5942 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5945 /* Get the current feature */
5946 f_ptr = &f_info[feat_idx[feat_cur]];
5947 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5948 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5952 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5956 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5960 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5965 if (visual_list && ((ch == 'A') || (ch == 'a')))
5967 int prev_lighting_level = *lighting_level;
5971 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5972 else (*lighting_level)--;
5976 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5977 else (*lighting_level)++;
5980 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5981 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5983 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5984 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5989 else if ((ch == 'D') || (ch == 'd'))
5991 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
5992 byte prev_x_char = f_ptr->x_char[*lighting_level];
5994 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
5998 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
5999 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6001 if (prev_x_char != f_ptr->x_char[*lighting_level])
6002 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6004 else *need_redraw = TRUE;
6009 /* Do visual mode command if needed */
6010 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))
6014 /* Restore previous visual settings */
6016 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6018 f_ptr->x_attr[i] = attr_old[i];
6019 f_ptr->x_char[i] = char_old[i];
6026 if (direct_f_idx >= 0) flag = TRUE;
6027 else *lighting_level = F_LIT_STANDARD;
6030 /* Preserve current visual settings */
6033 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6035 attr_old[i] = f_ptr->x_attr[i];
6036 char_old[i] = f_ptr->x_char[i];
6038 *lighting_level = F_LIT_STANDARD;
6045 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6047 attr_idx_feat[i] = f_ptr->x_attr[i];
6048 char_idx_feat[i] = f_ptr->x_char[i];
6057 /* Allow TERM_DARK text */
6058 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6060 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6061 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6079 /* Move the cursor */
6080 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6086 /* Free the "feat_idx" array */
6087 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6092 * List wanted monsters
6093 * @param creature_ptr プレーヤーへの参照ポインタ
6096 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6098 /* Open a new file */
6100 GAME_TEXT file_name[1024];
6101 fff = my_fopen_temp(file_name, 1024);
6104 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6109 fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
6110 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6112 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6113 fprintf(fff, "----------------------------------------------\n");
6115 bool listed = FALSE;
6116 for (int i = 0; i < MAX_BOUNTY; i++)
6118 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6120 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6127 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
6132 /* Display the file contents */
6133 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6138 * List virtues & status
6140 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6142 /* Open a new file */
6144 GAME_TEXT file_name[1024];
6145 fff = my_fopen_temp(file_name, 1024);
6148 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6153 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6154 dump_virtues(creature_ptr, fff);
6157 /* Display the file contents */
6158 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6165 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6167 /* Open a new file */
6169 GAME_TEXT file_name[1024];
6170 fff = my_fopen_temp(file_name, 1024);
6173 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6178 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6182 if (!d_info[i].maxdepth) continue;
6183 if (!max_dlv[i]) continue;
6184 if (d_info[i].final_guardian)
6186 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6188 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6190 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6195 /* Display the file contents */
6196 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6202 * List virtues & status
6205 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6207 /* Open a new file */
6209 GAME_TEXT file_name[1024];
6210 fff = my_fopen_temp(file_name, 1024);
6213 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6218 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6219 (2 * creature_ptr->hitdie +
6220 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6222 if (creature_ptr->knowledge & KNOW_HPRATE)
6223 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6224 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6226 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6227 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6229 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);
6230 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6233 dump_yourself(creature_ptr, fff);
6236 /* Display the file contents */
6237 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6243 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6244 * Print all active quests
6245 * @param creature_ptr プレーヤーへの参照ポインタ
6248 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6251 char rand_tmp_str[120] = "\0";
6252 GAME_TEXT name[MAX_NLEN];
6253 monster_race *r_ptr;
6254 int rand_level = 100;
6257 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6259 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6261 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6262 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6263 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6267 /* Set the quest number temporary */
6268 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6270 /* Clear the text */
6271 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6272 quest_text_line = 0;
6274 creature_ptr->current_floor_ptr->inside_quest = i;
6276 /* Get the quest text */
6277 init_flags = INIT_SHOW_TEXT;
6279 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6281 /* Reset the old quest number */
6282 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6284 /* No info from "silent" quests */
6285 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6289 if (quest[i].type != QUEST_TYPE_RANDOM)
6291 char note[80] = "\0";
6293 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6295 switch (quest[i].type)
6297 case QUEST_TYPE_KILL_LEVEL:
6298 case QUEST_TYPE_KILL_ANY_LEVEL:
6299 r_ptr = &r_info[quest[i].r_idx];
6300 strcpy(name, r_name + r_ptr->name);
6301 if (quest[i].max_num > 1)
6304 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6305 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6308 sprintf(note, " - kill %d %s, have killed %d.",
6309 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6313 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6316 case QUEST_TYPE_FIND_ARTIFACT:
6319 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6321 object_type *q_ptr = &forge;
6322 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6323 object_prep(q_ptr, k_idx);
6324 q_ptr->name1 = quest[i].k_idx;
6325 q_ptr->ident = IDENT_STORE;
6326 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6328 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find %s."), name);
6330 case QUEST_TYPE_FIND_EXIT:
6331 sprintf(note, _(" - 出口に到達する。", " - Reach exit."));
6334 case QUEST_TYPE_KILL_NUMBER:
6336 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6337 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6339 sprintf(note, " - Kill %d monsters, have killed %d.",
6340 (int)quest[i].max_num, (int)quest[i].cur_num);
6344 case QUEST_TYPE_KILL_ALL:
6345 case QUEST_TYPE_TOWER:
6346 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6351 /* Print the quest info */
6352 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6353 quest[i].name, (int)quest[i].level, note);
6355 fputs(tmp_str, fff);
6357 if (quest[i].status == QUEST_STATUS_COMPLETED)
6359 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6360 fputs(tmp_str, fff);
6365 while (quest_text[k][0] && k < 10)
6367 fprintf(fff, " %s\n", quest_text[k]);
6374 /* QUEST_TYPE_RANDOM */
6375 if (quest[i].level >= rand_level)
6379 rand_level = quest[i].level;
6381 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6383 /* Print the quest info */
6384 r_ptr = &r_info[quest[i].r_idx];
6385 strcpy(name, r_name + r_ptr->name);
6387 if (quest[i].max_num <= 1)
6389 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6390 quest[i].name, (int)quest[i].level, name);
6395 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6396 quest[i].name, (int)quest[i].level,
6397 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6401 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6402 quest[i].name, (int)quest[i].level,
6403 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6407 /* Print the current random quest */
6408 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6410 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6414 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6417 char playtime_str[16];
6418 quest_type* const q_ptr = &quest[q_idx];
6420 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6421 if (is_fixed_quest_idx(q_idx))
6423 /* Set the quest number temporary */
6424 IDX old_quest = floor_ptr->inside_quest;
6426 floor_ptr->inside_quest = q_idx;
6429 init_flags = INIT_NAME_ONLY;
6431 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6433 /* Reset the old quest number */
6434 floor_ptr->inside_quest = old_quest;
6436 /* No info from "silent" quests */
6437 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6440 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6441 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6443 if (is_fixed_quest_idx(q_idx) || (q_ptr->r_idx == 0))
6445 /* Print the quest info */
6447 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6448 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6449 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6450 fputs(tmp_str, fff);
6454 /* Print the quest info */
6455 if (q_ptr->complev == 0)
6458 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6459 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6460 r_name + r_info[q_ptr->r_idx].name,
6461 (int)q_ptr->level, playtime_str);
6462 fputs(tmp_str, fff);
6467 _(" %-35s (%3d階) - レベル%2d - %s\n",
6468 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6469 r_name + r_info[q_ptr->r_idx].name,
6473 fputs(tmp_str, fff);
6479 * Print all finished quests
6480 * @param creature_ptr プレーヤーへの参照ポインタ
6481 * @param fff セーブファイル (展開済?)
6482 * @param quest_num[] 受注したことのあるクエスト群
6485 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6487 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6488 QUEST_IDX total = 0;
6489 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6491 QUEST_IDX q_idx = quest_num[i];
6492 quest_type* const q_ptr = &quest[q_idx];
6494 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6500 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6505 * Print all failed quests
6506 * @param creature_ptr プレーヤーへの参照ポインタ
6507 * @param fff セーブファイル (展開済?)
6508 * @param quest_num[] 受注したことのあるクエスト群
6511 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6513 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6514 QUEST_IDX total = 0;
6515 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6517 QUEST_IDX q_idx = quest_num[i];
6518 quest_type* const q_ptr = &quest[q_idx];
6520 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6521 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6527 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6532 * Print all random quests
6534 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6536 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6537 GAME_TEXT tmp_str[120];
6538 QUEST_IDX total = 0;
6539 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6541 /* No info from "silent" quests */
6542 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6544 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6548 /* Print the quest info */
6549 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6550 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6551 fputs(tmp_str, fff);
6555 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6559 * Print quest status of all active quests
6560 * @param creature_ptr プレーヤーへの参照ポインタ
6563 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6565 /* Open a new file */
6567 GAME_TEXT file_name[1024];
6568 fff = my_fopen_temp(file_name, 1024);
6571 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6576 /* Allocate Memory */
6578 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6580 /* Sort by compete level */
6581 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6583 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6585 /* Dump Quest Information */
6586 do_cmd_knowledge_quests_current(creature_ptr, fff);
6588 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6590 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6591 if (current_world_ptr->wizard)
6594 do_cmd_knowledge_quests_wiz_random(fff);
6599 /* Display the file contents */
6600 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6604 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6610 * @param player_ptr プレーヤーへの参照ポインタ
6613 static void do_cmd_knowledge_home(player_type *player_ptr)
6615 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6617 /* Open a new file */
6619 GAME_TEXT file_name[1024];
6620 fff = my_fopen_temp(file_name, 1024);
6623 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6628 /* Print all homes in the different towns */
6630 st_ptr = &town_info[1].store[STORE_HOME];
6632 /* Home -- if anything there */
6633 if (st_ptr->stock_num)
6638 /* Header with name of the town */
6639 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6641 /* Dump all available items */
6642 concptr paren = ")";
6643 GAME_TEXT o_name[MAX_NLEN];
6644 for (int i = 0; i < st_ptr->stock_num; i++)
6647 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6648 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6649 if (strlen(o_name) <= 80 - 3)
6651 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6657 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6658 if (iskanji(*t)) { t++; n++; }
6659 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6661 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6662 fprintf(fff, " %.77s\n", o_name + n);
6665 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6666 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6670 /* Add an empty line */
6671 fprintf(fff, "\n\n");
6676 /* Display the file contents */
6677 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6683 * Check the status of "autopick"
6685 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6687 /* Open a new file */
6689 GAME_TEXT file_name[1024];
6690 fff = my_fopen_temp(file_name, 1024);
6693 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6700 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6704 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6705 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6708 for (int k = 0; k < max_autopick; k++)
6711 byte act = autopick_list[k].action;
6712 if (act & DONT_AUTOPICK)
6714 tmp = _("放置", "Leave");
6716 else if (act & DO_AUTODESTROY)
6718 tmp = _("破壊", "Destroy");
6720 else if (act & DO_AUTOPICK)
6722 tmp = _("拾う", "Pickup");
6726 tmp = _("確認", "Query");
6729 if (act & DO_DISPLAY)
6730 fprintf(fff, "%11s", format("[%s]", tmp));
6732 fprintf(fff, "%11s", format("(%s)", tmp));
6734 tmp = autopick_line_from_entry(&autopick_list[k]);
6735 fprintf(fff, " %s", tmp);
6742 /* Display the file contents */
6743 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6749 * Interact with "knowledge"
6751 void do_cmd_knowledge(player_type *creature_ptr)
6754 bool need_redraw = FALSE;
6756 /* File type is "TEXT" */
6757 FILE_TYPE(FILE_TYPE_TEXT);
6760 /* Interact until done */
6765 /* Ask for a choice */
6766 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6767 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6769 /* Give some choices */
6773 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6774 prt("(2) 既知のアイテム の一覧", 7, 5);
6775 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6776 prt("(4) 既知のモンスター の一覧", 9, 5);
6777 prt("(5) 倒した敵の数 の一覧", 10, 5);
6778 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6779 prt("(7) 現在のペット の一覧", 12, 5);
6780 prt("(8) 我が家のアイテム の一覧", 13, 5);
6781 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6782 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6786 prt("(a) 自分に関する情報 の一覧", 6, 5);
6787 prt("(b) 突然変異 の一覧", 7, 5);
6788 prt("(c) 武器の経験値 の一覧", 8, 5);
6789 prt("(d) 魔法の経験値 の一覧", 9, 5);
6790 prt("(e) 技能の経験値 の一覧", 10, 5);
6791 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6792 prt("(g) 入ったダンジョン の一覧", 12, 5);
6793 prt("(h) 実行中のクエスト の一覧", 13, 5);
6794 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6799 prt("(1) Display known artifacts", 6, 5);
6800 prt("(2) Display known objects", 7, 5);
6801 prt("(3) Display remaining uniques", 8, 5);
6802 prt("(4) Display known monster", 9, 5);
6803 prt("(5) Display kill count", 10, 5);
6804 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6805 prt("(7) Display current pets", 12, 5);
6806 prt("(8) Display home inventory", 13, 5);
6807 prt("(9) Display *identified* equip.", 14, 5);
6808 prt("(0) Display terrain symbols.", 15, 5);
6812 prt("(a) Display about yourself", 6, 5);
6813 prt("(b) Display mutations", 7, 5);
6814 prt("(c) Display weapon proficiency", 8, 5);
6815 prt("(d) Display spell proficiency", 9, 5);
6816 prt("(e) Display misc. proficiency", 10, 5);
6817 prt("(f) Display virtues", 11, 5);
6818 prt("(g) Display dungeons", 12, 5);
6819 prt("(h) Display current quests", 13, 5);
6820 prt("(i) Display auto pick/destroy", 14, 5);
6824 prt(_("-続く-", "-more-"), 17, 8);
6825 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6826 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6827 /*prt("-) 前ページ", 21, 60);*/
6828 prt(_("コマンド:", "Command: "), 20, 0);
6831 if (i == ESCAPE) break;
6834 case ' ': /* Page change */
6838 case '1': /* Artifacts */
6839 do_cmd_knowledge_artifacts(creature_ptr);
6841 case '2': /* Objects */
6842 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6844 case '3': /* Uniques */
6845 do_cmd_knowledge_uniques(creature_ptr);
6847 case '4': /* Monsters */
6848 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6850 case '5': /* Kill count */
6851 do_cmd_knowledge_kill_count(creature_ptr);
6853 case '6': /* wanted */
6854 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6856 case '7': /* Pets */
6857 do_cmd_knowledge_pets(creature_ptr);
6859 case '8': /* Home */
6860 do_cmd_knowledge_home(creature_ptr);
6862 case '9': /* Resist list */
6863 do_cmd_knowledge_inven(creature_ptr);
6865 case '0': /* Feature list */
6867 IDX lighting_level = F_LIT_STANDARD;
6868 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6872 case 'a': /* Max stat */
6873 do_cmd_knowledge_stat(creature_ptr);
6875 case 'b': /* Mutations */
6876 do_cmd_knowledge_mutations(creature_ptr);
6878 case 'c': /* weapon-exp */
6879 do_cmd_knowledge_weapon_exp(creature_ptr);
6881 case 'd': /* spell-exp */
6882 do_cmd_knowledge_spell_exp(creature_ptr);
6884 case 'e': /* skill-exp */
6885 do_cmd_knowledge_skill_exp(creature_ptr);
6887 case 'f': /* Virtues */
6888 do_cmd_knowledge_virtues(creature_ptr);
6890 case 'g': /* Dungeon */
6891 do_cmd_knowledge_dungeon(creature_ptr);
6893 case 'h': /* Quests */
6894 do_cmd_knowledge_quests(creature_ptr);
6896 case 'i': /* Autopick */
6897 do_cmd_knowledge_autopick(creature_ptr);
6899 default: /* Unknown option */
6907 if (need_redraw) do_cmd_redraw(creature_ptr);
6912 * Check on the status of an active quest
6913 * @param creature_ptr プレーヤーへの参照ポインタ
6916 void do_cmd_checkquest(player_type *creature_ptr)
6918 /* File type is "TEXT" */
6919 FILE_TYPE(FILE_TYPE_TEXT);
6923 do_cmd_knowledge_quests(creature_ptr);
6929 * Display the time and date
6930 * @param creature_ptr プレーヤーへの参照ポインタ
6933 void do_cmd_time(player_type *creature_ptr)
6936 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6939 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6942 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6943 else strcpy(day_buf, "*****");
6945 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6946 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6950 if (!randint0(10) || creature_ptr->image)
6952 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6956 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6959 /* Open this file */
6961 fff = my_fopen(buf, "rt");
6965 /* Find this time */
6966 int full = hour * 100 + min;
6970 while (!my_fgets(fff, buf, sizeof(buf)))
6972 /* Ignore comments */
6973 if (!buf[0] || (buf[0] == '#')) continue;
6975 /* Ignore invalid lines */
6976 if (buf[1] != ':') continue;
6978 /* Process 'Start' */
6981 /* Extract the starting time */
6982 start = atoi(buf + 2);
6984 /* Assume valid for an hour */
6992 /* Extract the ending time */
6993 end = atoi(buf + 2);
6997 /* Ignore incorrect range */
6998 if ((start > full) || (full > end)) continue;
7000 /* Process 'Description' */
7005 /* Apply the randomizer */
7006 if (!randint0(num)) strcpy(desc, buf + 2);