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 "cmd-spell.h"
58 #include "player-effects.h"
59 #include "player-status.h"
60 #include "player-skill.h"
61 #include "player-personality.h"
68 #include "object-flavor.h"
69 #include "object-hook.h"
71 #include "monster-status.h"
73 #include "view-mainwindow.h"
74 #include "dungeon-file.h"
76 #include "player-class.h"
77 #include "player-move.h"
79 #include "objectkind.h"
80 #include "floor-town.h"
82 #include "view-mainwindow.h"
86 // Mark strings for auto dump
87 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
88 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
90 // Variables for auto dump
91 static FILE *auto_dump_stream;
92 static concptr auto_dump_mark;
93 static int auto_dump_line_num;
95 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
96 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
97 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
99 // Clipboard variables for copy&paste in visual mode
100 static TERM_COLOR attr_idx = 0;
101 static SYMBOL_CODE char_idx = 0;
103 /* Hack -- for feature lighting */
104 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
105 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
107 // Encode the screen colors
108 static char hack[17] = "dwsorgbuDWvyRGBU";
114 * @brief prf出力内容を消去する /
115 * Remove old lines automatically generated before.
116 * @param orig_file 消去を行うファイル名
118 static void remove_auto_dump(concptr orig_file)
120 FILE *tmp_fff, *orig_fff;
124 bool between_mark = FALSE;
125 bool changed = FALSE;
127 long header_location = 0;
128 char header_mark_str[80];
129 char footer_mark_str[80];
132 /* Prepare a header/footer mark string */
133 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
134 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
136 mark_len = strlen(footer_mark_str);
138 /* Open an old dump file in read-only mode */
139 orig_fff = my_fopen(orig_file, "r");
141 /* If original file does not exist, nothing to do */
142 if (!orig_fff) return;
144 /* Open a new (temporary) file */
145 tmp_fff = my_fopen_temp(tmp_file, 1024);
149 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
154 /* Loop for every line */
158 if (my_fgets(orig_fff, buf, sizeof(buf)))
160 /* Read error: Assume End of File */
163 * Was looking for the footer, but not found.
165 * Since automatic dump might be edited by hand,
166 * it's dangerous to kill these lines.
167 * Seek back to the next line of the (pseudo) header,
172 fseek(orig_fff, header_location, SEEK_SET);
173 between_mark = FALSE;
177 /* Success -- End the loop */
184 /* We are looking for the header mark of automatic dump */
187 /* Is this line a header? */
188 if (!strcmp(buf, header_mark_str))
190 /* Memorise seek point of this line */
191 header_location = ftell(orig_fff);
193 /* Initialize counter for number of lines */
196 /* Look for the footer from now */
199 /* There are some changes */
206 /* Copy orginally lines */
207 fprintf(tmp_fff, "%s\n", buf);
213 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
214 /* We are looking for the footer mark of automatic dump */
215 /* Is this line a footer? */
216 if (!strncmp(buf, footer_mark_str, mark_len))
221 * Compare the number of lines
223 * If there is an inconsistency between
224 * actual number of lines and the
225 * number here, the automatic dump
226 * might be edited by hand. So it's
227 * dangerous to kill these lines.
228 * Seek back to the next line of the
229 * (pseudo) header, and read again.
231 if (!sscanf(buf + mark_len, " (%d)", &tmp)
234 fseek(orig_fff, header_location, SEEK_SET);
237 /* Look for another header */
238 between_mark = FALSE;
243 /* Ignore old line, and count number of lines */
251 /* If there are some changes, overwrite the original file with new one */
254 /* Copy contents of temporary file */
255 tmp_fff = my_fopen(tmp_file, "r");
256 orig_fff = my_fopen(orig_file, "w");
258 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
259 fprintf(orig_fff, "%s\n", buf);
270 * @brief prfファイルのフォーマットに従った内容を出力する /
271 * Dump a formatted line, using "vstrnfmt()".
274 static void auto_dump_printf(concptr fmt, ...)
281 /* Begin the Varargs Stuff */
284 /* Format the args, save the length */
285 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
287 /* End the Varargs Stuff */
290 /* Count number of lines */
291 for (p = buf; *p; p++)
293 if (*p == '\n') auto_dump_line_num++;
297 fprintf(auto_dump_stream, "%s", buf);
302 * @brief prfファイルをファイルオープンする /
303 * Open file to append auto dump.
305 * @param mark 出力するヘッダマーク
306 * @return ファイルポインタを取得できたらTRUEを返す
308 static bool open_auto_dump(concptr buf, concptr mark)
310 char header_mark_str[80];
312 /* Save the mark string */
313 auto_dump_mark = mark;
315 /* Prepare a header mark string */
316 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
318 /* Remove old macro dumps */
319 remove_auto_dump(buf);
321 /* Append to the file */
322 auto_dump_stream = my_fopen(buf, "a");
325 if (!auto_dump_stream)
327 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
335 fprintf(auto_dump_stream, "%s\n", header_mark_str);
337 /* Initialize counter */
338 auto_dump_line_num = 0;
340 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
341 "# *Warning!* The lines below are an automatic dump.\n"));
342 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
343 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
348 * @brief prfファイルをファイルクローズする /
349 * Append foot part and close auto dump.
352 static void close_auto_dump(void)
354 char footer_mark_str[80];
356 /* Prepare a footer mark string */
357 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
359 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
360 "# *Warning!* The lines below are an automatic dump.\n"));
361 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
362 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
364 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
366 my_fclose(auto_dump_stream);
373 * @brief Return suffix of ordinal number
375 * @return pointer of suffix string.
377 concptr get_ordinal_number_suffix(int num)
379 num = ABS(num) % 100;
383 return (num == 11) ? "th" : "st";
385 return (num == 12) ? "th" : "nd";
387 return (num == 13) ? "th" : "rd";
396 * @brief 日記にメッセージを追加する /
397 * Take note to the diary.
398 * @param type 日記内容のID
399 * @param num 日記内容のIDに応じた数値
400 * @param note 日記内容のIDに応じた文字列参照ポインタ
403 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
407 GAME_TEXT file_name[MAX_NLEN];
409 concptr note_level = "";
410 bool do_level = TRUE;
411 char note_level_buf[40];
414 static bool disable_diary = FALSE;
416 extract_day_hour_min(creature_ptr, &day, &hour, &min);
418 if (disable_diary) return(-1);
420 if (type == DIARY_FIX_QUEST_C ||
421 type == DIARY_FIX_QUEST_F ||
422 type == DIARY_RAND_QUEST_C ||
423 type == DIARY_RAND_QUEST_F ||
424 type == DIARY_TO_QUEST)
428 old_quest = creature_ptr->current_floor_ptr->inside_quest;
429 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
431 /* Get the quest text */
432 init_flags = INIT_NAME_ONLY;
434 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
436 /* Reset the old quest number */
437 creature_ptr->current_floor_ptr->inside_quest = old_quest;
440 /* different filne name to avoid mixing */
441 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
442 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
444 /* File type is "TEXT" */
445 FILE_TYPE(FILE_TYPE_TEXT);
447 fff = my_fopen(buf, "a");
452 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporarily."), buf);
454 disable_diary = TRUE;
458 q_idx = quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level);
462 if (creature_ptr->current_floor_ptr->inside_arena)
463 note_level = _("アリーナ:", "Arane:");
464 else if (!creature_ptr->current_floor_ptr->dun_level)
465 note_level = _("地上:", "Surface:");
466 else if (q_idx && (is_fixed_quest_idx(q_idx)
467 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
468 note_level = _("クエスト:", "Quest:");
472 sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
474 sprintf(note_level_buf, "%s L%d:", d_name + d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
476 note_level = note_level_buf;
484 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
485 else fputs(_("*****日目\n", "Day *****\n"), fff);
489 case DIARY_DESCRIPTION:
493 fprintf(fff, "%s\n", note);
497 fprintf(fff, " %2d:%02d %20s %s\n", hour, min, note_level, note);
502 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
505 case DIARY_ART_SCROLL:
507 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
512 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
515 case DIARY_FIX_QUEST_C:
517 if (quest[num].flags & QUEST_FLAG_SILENT) break;
518 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
519 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
522 case DIARY_FIX_QUEST_F:
524 if (quest[num].flags & QUEST_FLAG_SILENT) break;
525 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
526 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
529 case DIARY_RAND_QUEST_C:
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 completed random quest '%s'\n"), hour, min, note_level, name);
537 case DIARY_RAND_QUEST_F:
539 GAME_TEXT name[MAX_NLEN];
540 strcpy(name, r_name + r_info[quest[num].r_idx].name);
541 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
542 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
545 case DIARY_MAXDEAPTH:
547 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
548 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
549 _(d_name + d_info[creature_ptr->dungeon_idx].name, num),
550 _(num, d_name + d_info[creature_ptr->dungeon_idx].name));
555 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
556 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
557 _(d_name + d_info[num].name, (int)max_dlv[num]),
558 _((int)max_dlv[num], d_name + d_info[num].name));
564 if (q_idx && (is_fixed_quest_idx(q_idx)
565 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
567 to = _("地上", "the surface");
571 if (!(creature_ptr->current_floor_ptr->dun_level + num)) to = _("地上", "the surface");
572 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level + num);
574 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
580 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
581 hour, min, note_level, _(d_name + d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]),
582 _((int)max_dlv[creature_ptr->dungeon_idx], d_name + d_info[creature_ptr->dungeon_idx].name));
584 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
589 if (quest[num].flags & QUEST_FLAG_SILENT) break;
590 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
591 hour, min, note_level, quest[num].name);
594 case DIARY_TELEPORT_LEVEL:
596 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
597 hour, min, note_level);
602 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
607 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
615 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
616 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
619 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
620 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
622 if (num == MAX_ARENA_MONS)
624 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
625 " won all fight to become a Chanpion.\n"));
632 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
638 if (!creature_ptr->current_floor_ptr->dun_level)
639 to = _("地上", "the surface");
641 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
643 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
644 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
650 if (!creature_ptr->current_floor_ptr->dun_level)
651 to = _("地上", "the surface");
653 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name + d_info[creature_ptr->dungeon_idx].name);
655 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
656 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
661 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
664 case DIARY_GAMESTART:
666 time_t ct = time((time_t*)0);
670 fprintf(fff, "%s %s", note, ctime(&ct));
673 fprintf(fff, " %2d:%02d %20s %s %s", hour, min, note_level, note, ctime(&ct));
676 case DIARY_NAMED_PET:
678 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
681 case RECORD_NAMED_PET_NAME:
682 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
684 case RECORD_NAMED_PET_UNNAME:
685 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
687 case RECORD_NAMED_PET_DISMISS:
688 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
690 case RECORD_NAMED_PET_DEATH:
691 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
693 case RECORD_NAMED_PET_MOVED:
694 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
696 case RECORD_NAMED_PET_LOST_SIGHT:
697 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
699 case RECORD_NAMED_PET_DESTROY:
700 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was killed by *destruction*.\n"), note);
702 case RECORD_NAMED_PET_EARTHQUAKE:
703 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
705 case RECORD_NAMED_PET_GENOCIDE:
706 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was a victim of genocide.\n"), note);
708 case RECORD_NAMED_PET_WIZ_ZAP:
709 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
711 case RECORD_NAMED_PET_TELE_LEVEL:
712 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was lost after teleporting a level.\n"), note);
714 case RECORD_NAMED_PET_BLAST:
715 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
717 case RECORD_NAMED_PET_HEAL_LEPER:
718 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
720 case RECORD_NAMED_PET_COMPACT:
721 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was lost when the monster list was pruned.\n"), note);
723 case RECORD_NAMED_PET_LOSE_PARENT:
724 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because its summoner left.\n"), note);
734 case DIARY_WIZARD_LOG:
735 fprintf(fff, "%s\n", note);
744 if (do_level) write_level = FALSE;
750 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
753 * @brief 日記のタイトル表記と内容出力 /
756 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
758 static void display_diary(player_type *creature_ptr)
760 char diary_title[256];
761 GAME_TEXT file_name[MAX_NLEN];
765 static const char subtitle[][30] = {
798 static const char subtitle[][51] = {
799 "Quest of The World's Toughest Body",
800 "Attack is the best form of defence.",
802 "An unexpected windfall",
803 "A drowning man will catch at a straw",
804 "Don't count your chickens before they are hatched.",
805 "It is no use crying over spilt milk.",
806 "Seeing is believing.",
807 "Strike the iron while it is hot.",
808 "I don't care what follows.",
809 "To dig a well to put out a house on fire.",
810 "Tomorrow is another day.",
811 "Easy come, easy go.",
812 "The more haste, the less speed.",
813 "Where there is life, there is hope.",
814 "There is no royal road to *WINNER*.",
815 "Danger past, God forgotten.",
816 "The best thing to do now is to run away.",
817 "Life is but an empty dream.",
818 "Dead men tell no tales.",
819 "A book that remains shut is but a block.",
820 "Misfortunes never come singly.",
821 "A little knowledge is a dangerous thing.",
822 "History repeats itself.",
823 "*WINNER* was not built in a day.",
824 "Ignorance is bliss.",
825 "To lose is to win?",
826 "No medicine can cure folly.",
827 "All good things come to an end.",
828 "M$ Empire strikes back.",
829 "To see is to believe",
831 "Quest of The World's Greatest Brain"
834 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
835 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
837 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
838 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
839 else if (IS_WIZARD_CLASS(creature_ptr))
840 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
841 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
844 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
846 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
849 /* Display the file contents */
850 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
855 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
858 static void add_diary_note(player_type *creature_ptr)
861 char bunshou[80] = "\0";
863 if (get_string(_("内容: ", "diary note: "), tmp, 79))
865 strcpy(bunshou, tmp);
866 exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, bunshou);
871 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
874 static void do_cmd_last_get(player_type *creaute_ptr)
876 if (record_o_name[0] == '\0') return;
879 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
880 if (!get_check(buf)) return;
882 GAME_TURN turn_tmp = current_world_ptr->game_turn;
883 current_world_ptr->game_turn = record_turn;
884 sprintf(buf, _("%sを手に入れた。", "descover %s."), record_o_name);
885 exe_write_diary(creaute_ptr, DIARY_DESCRIPTION, 0, buf);
886 current_world_ptr->game_turn = turn_tmp;
891 * @brief ファイル中の全日記記録を消去する /
894 static void do_cmd_erase_diary(void)
896 GAME_TEXT file_name[MAX_NLEN];
900 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
901 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
902 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
905 fff = my_fopen(buf, "w");
909 msg_format(_("記録を消去しました。", "deleted record."));
913 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
922 * @param crerature_ptr プレーヤーへの参照ポインタ
925 void do_cmd_diary(player_type *creature_ptr)
927 /* File type is "TEXT" */
928 FILE_TYPE(FILE_TYPE_TEXT);
931 /* Interact until done */
937 /* Ask for a choice */
938 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
940 /* Give some choices */
941 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
942 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
943 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record the last item you got or identified"), 6, 5);
944 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
946 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
949 prt(_("コマンド:", "Command: "), 18, 0);
954 if (i == ESCAPE) break;
959 display_diary(creature_ptr);
962 add_diary_note(creature_ptr);
965 do_cmd_last_get(creature_ptr);
968 do_cmd_erase_diary();
972 prepare_movie_hooks();
974 default: /* Unknown option */
986 * @brief 画面を再描画するコマンドのメインルーチン
987 * Hack -- redraw the screen
988 * @param creature_ptr プレーヤーへの参照ポインタ
992 * This command performs various low level updates, clears all the "extra"
993 * windows, does a total redraw of the main window, and requests all of the
994 * interesting updates and redraws that I can think of.
996 * This command is also used to "instantiate" the results of the user
997 * selecting various things, such as graphics mode, so it must call
998 * the "TERM_XTRA_REACT" hook before redrawing the windows.
1001 void do_cmd_redraw(player_type *creature_ptr)
1003 Term_xtra(TERM_XTRA_REACT, 0);
1005 /* Combine and Reorder the pack (later) */
1006 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1007 creature_ptr->update |= (PU_TORCH);
1008 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1009 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1010 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1011 creature_ptr->update |= (PU_MONSTERS);
1013 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1015 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1016 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1019 handle_stuff(creature_ptr);
1021 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1023 /* Redraw every window */
1025 for (int j = 0; j < 8; j++)
1028 if (!angband_term[j]) continue;
1031 Term_activate(angband_term[j]);
1040 * @brief プレイヤーのステータス表示
1043 void do_cmd_player_status(player_type *creature_ptr)
1054 display_player(creature_ptr, mode);
1059 display_player(creature_ptr, mode);
1063 Term_putstr(2, 23, -1, TERM_WHITE,
1064 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1068 if (c == ESCAPE) break;
1073 get_name(creature_ptr);
1075 /* Process the player name */
1076 process_player_name(creature_ptr, FALSE);
1082 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1083 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1085 if (tmp[0] && (tmp[0] != ' '))
1087 file_character(creature_ptr, tmp);
1105 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1107 handle_stuff(creature_ptr);
1112 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1113 * Recall the most recent message
1116 void do_cmd_message_one(void)
1118 /* Recall one message */
1119 prt(format("> %s", message_str(0)), 0, 0);
1124 * @brief メッセージのログを表示するコマンドのメインルーチン
1125 * Recall the most recent message
1129 * Show previous messages to the user -BEN-
1131 * The screen format uses line 0 and 23 for headers and prompts,
1132 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1134 * This command shows you which commands you are viewing, and allows
1135 * you to "search" for strings in the recall.
1137 * Note that messages may be longer than 80 characters, but they are
1138 * displayed using "infinite" length, with a special sub-command to
1139 * "slide" the virtual display to the left or right.
1141 * Attempt to only hilite the matching portions of the string.
1144 void do_cmd_messages(int num_now)
1146 char shower_str[81];
1147 char finder_str[81];
1149 concptr shower = NULL;
1153 Term_get_size(&wid, &hgt);
1155 /* Number of message lines in a screen */
1156 num_lines = hgt - 4;
1159 strcpy(finder_str, "");
1162 strcpy(shower_str, "");
1164 /* Total messages */
1165 int n = message_num();
1167 /* Start on first message */
1172 /* Process requests until done */
1178 /* Dump up to 20 lines of messages */
1179 for (j = 0; (j < num_lines) && (i + j < n); j++)
1181 concptr msg = message_str(i + j);
1183 /* Dump the messages, bottom to top */
1184 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1186 if (!shower || !shower[0]) continue;
1188 /* Hilite "shower" */
1191 /* Display matches */
1192 while ((str = my_strstr(str, shower)) != NULL)
1194 int len = strlen(shower);
1196 /* Display the match */
1197 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1204 /* Erase remaining lines */
1205 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1207 /* Display header */
1209 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1210 i, i + j - 1, n), 0, 0);
1212 /* Display prompt (not very informative) */
1213 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1214 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1216 skey = inkey_special(TRUE);
1218 /* Exit on Escape */
1219 if (skey == ESCAPE) break;
1221 /* Hack -- Save the old index */
1226 /* Hack -- handle show */
1229 prt(_("強調: ", "Show: "), hgt - 1, 0);
1231 /* Get a "shower" string, or continue */
1232 strcpy(back_str, shower_str);
1233 if (askfor(shower_str, 80))
1236 shower = shower_str[0] ? shower_str : NULL;
1238 else strcpy(shower_str, back_str);
1242 /* Hack -- handle find */
1249 prt(_("検索: ", "Find: "), hgt - 1, 0);
1251 /* Get a "finder" string, or continue */
1252 strcpy(back_str, finder_str);
1253 if (!askfor(finder_str, 80))
1255 strcpy(finder_str, back_str);
1258 else if (!finder_str[0])
1260 shower = NULL; /* Stop showing */
1265 shower = finder_str;
1268 for (z = i + 1; z < n; z++)
1270 concptr msg = message_str(z);
1273 if (my_strstr(msg, finder_str))
1284 /* Recall 1 older message */
1286 /* Go to the oldest line */
1290 /* Recall 1 newer message */
1292 /* Go to the newest line */
1296 /* Recall 1 older message */
1301 /* Go older if legal */
1302 i = MIN(i + 1, n - num_lines);
1305 /* Recall 10 older messages */
1307 /* Go older if legal */
1308 i = MIN(i + 10, n - num_lines);
1311 /* Recall 20 older messages */
1316 /* Go older if legal */
1317 i = MIN(i + num_lines, n - num_lines);
1320 /* Recall 20 newer messages */
1324 /* Go newer (if able) */
1325 i = MAX(0, i - num_lines);
1328 /* Recall 10 newer messages */
1330 /* Go newer (if able) */
1334 /* Recall 1 newer messages */
1337 /* Go newer (if able) */
1342 /* Hack -- Error of some kind */
1351 * @brief prefファイルを選択して処理する /
1352 * Ask for a "user pref line" and process it
1353 * @param creature_ptr プレーヤーへの参照ポインタ
1356 * Allow absolute file names?
1358 void do_cmd_pref(player_type *creature_ptr)
1363 /* Ask for a "user pref command" */
1364 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1366 /* Process that pref command */
1367 (void)process_pref_file_command(creature_ptr, buf);
1372 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1373 * @param creature_ptr プレーヤーへの参照ポインタ
1376 void do_cmd_reload_autopick(player_type *creature_ptr)
1378 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1379 /* Load the file with messages */
1380 autopick_load_pref(creature_ptr, TRUE);
1387 * @brief マクロ情報をprefファイルに保存する /
1388 * @param fname ファイル名
1391 static errr macro_dump(concptr fname)
1393 static concptr mark = "Macro Dump";
1395 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1397 /* File type is "TEXT" */
1398 FILE_TYPE(FILE_TYPE_TEXT);
1400 /* Append to the file */
1401 if (!open_auto_dump(buf, mark)) return -1;
1404 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1407 for (int i = 0; i < macro__num; i++)
1409 /* Extract the action */
1410 ascii_to_text(buf, macro__act[i]);
1412 /* Dump the macro */
1413 auto_dump_printf("A:%s\n", buf);
1415 /* Extract the action */
1416 ascii_to_text(buf, macro__pat[i]);
1418 /* Dump normal macros */
1419 auto_dump_printf("P:%s\n", buf);
1422 auto_dump_printf("\n");
1431 * @brief マクロのトリガーキーを取得する /
1432 * Hack -- ask for a "trigger" (see below)
1433 * @param buf キー表記を保管するバッファ
1437 * Note the complex use of the "inkey()" function from "util.c".
1439 * Note that both "flush()" calls are extremely important.
1442 static void do_cmd_macro_aux(char *buf)
1446 /* Do not process macros */
1452 /* Read the pattern */
1459 /* Do not process macros */
1462 /* Do not wait for keys */
1465 /* Attempt to read a key */
1474 /* Convert the trigger */
1476 ascii_to_text(tmp, buf);
1478 /* Hack -- display the trigger */
1479 Term_addstr(-1, TERM_WHITE, tmp);
1485 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1486 * Hack -- ask for a keymap "trigger" (see below)
1487 * @param buf キー表記を取得するバッファ
1491 * Note that both "flush()" calls are extremely important. This may
1492 * no longer be true, since "util.c" is much simpler now.
1495 static void do_cmd_macro_aux_keymap(char *buf)
1505 /* Convert to ascii */
1506 ascii_to_text(tmp, buf);
1508 /* Hack -- display the trigger */
1509 Term_addstr(-1, TERM_WHITE, tmp);
1516 * @brief キーマップをprefファイルにダンプする /
1517 * Hack -- append all keymaps to the given file
1518 * @param fname ファイルネーム
1522 static errr keymap_dump(concptr fname)
1524 static concptr mark = "Keymap Dump";
1531 if (rogue_like_commands)
1533 mode = KEYMAP_MODE_ROGUE;
1539 mode = KEYMAP_MODE_ORIG;
1542 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1544 /* File type is "TEXT" */
1545 FILE_TYPE(FILE_TYPE_TEXT);
1547 /* Append to the file */
1548 if (!open_auto_dump(buf, mark)) return -1;
1551 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1554 for (int i = 0; i < 256; i++)
1558 /* Loop up the keymap */
1559 act = keymap_act[mode][i];
1561 /* Skip empty keymaps */
1564 /* Encode the key */
1567 ascii_to_text(key, buf);
1569 /* Encode the action */
1570 ascii_to_text(buf, act);
1572 /* Dump the macro */
1573 auto_dump_printf("A:%s\n", buf);
1574 auto_dump_printf("C:%d:%s\n", mode, key);
1583 * @brief マクロを設定するコマンドのメインルーチン /
1584 * Interact with "macros"
1588 * Note that the macro "action" must be defined before the trigger.
1590 * Could use some helpful instructions on this page.
1593 void do_cmd_macros(player_type *creature_ptr)
1601 if (rogue_like_commands)
1603 mode = KEYMAP_MODE_ROGUE;
1609 mode = KEYMAP_MODE_ORIG;
1612 /* File type is "TEXT" */
1613 FILE_TYPE(FILE_TYPE_TEXT);
1617 /* Process requests until done */
1621 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1623 /* Describe that action */
1624 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1626 /* Analyze the current action */
1627 ascii_to_text(buf, macro__buf);
1629 /* Display the current action */
1634 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1636 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1637 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1638 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1639 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1640 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1641 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1642 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1643 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1644 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1645 #endif /* ALLOW_MACROS */
1648 prt(_("コマンド: ", "Command: "), 16, 0);
1653 if (i == ESCAPE) break;
1655 /* Load a 'macro' file */
1661 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1664 prt(_("ファイル: ", "File: "), 18, 0);
1666 /* Default filename */
1667 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1669 /* Ask for a file */
1670 if (!askfor(tmp, 80)) continue;
1672 /* Process the given filename */
1673 err = process_pref_file(creature_ptr, tmp);
1676 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1681 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1685 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1694 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1697 prt(_("ファイル: ", "File: "), 18, 0);
1699 /* Default filename */
1700 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1702 /* Ask for a file */
1703 if (!askfor(tmp, 80)) continue;
1705 /* Dump the macros */
1706 (void)macro_dump(tmp);
1709 msg_print(_("マクロを追加しました。", "Appended macros."));
1718 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1722 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1724 /* Get a macro trigger */
1725 do_cmd_macro_aux(buf);
1727 /* Acquire action */
1728 k = macro_find_exact(buf);
1734 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1740 /* Obtain the action */
1741 strcpy(macro__buf, macro__act[k]);
1743 /* Analyze the current action */
1744 ascii_to_text(buf, macro__buf);
1746 /* Display the current action */
1750 msg_print(_("マクロを確認しました。", "Found a macro."));
1754 /* Create a macro */
1758 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1761 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1763 /* Get a macro trigger */
1764 do_cmd_macro_aux(buf);
1768 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1769 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1772 prt(_("マクロ行動: ", "Action: "), 20, 0);
1774 /* Convert to text */
1775 ascii_to_text(tmp, macro__buf);
1777 /* Get an encoded action */
1778 if (askfor(tmp, 80))
1780 /* Convert to ascii */
1781 text_to_ascii(macro__buf, tmp);
1783 /* Link the macro */
1784 macro_add(buf, macro__buf);
1787 msg_print(_("マクロを追加しました。", "Added a macro."));
1791 /* Remove a macro */
1795 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1798 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1800 /* Get a macro trigger */
1801 do_cmd_macro_aux(buf);
1803 /* Link the macro */
1804 macro_add(buf, buf);
1807 msg_print(_("マクロを削除しました。", "Removed a macro."));
1814 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1817 prt(_("ファイル: ", "File: "), 18, 0);
1819 /* Default filename */
1820 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1822 /* Ask for a file */
1823 if (!askfor(tmp, 80)) continue;
1825 /* Dump the macros */
1826 (void)keymap_dump(tmp);
1829 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1832 /* Query a keymap */
1838 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1841 prt(_("押すキー: ", "Keypress: "), 18, 0);
1843 /* Get a keymap trigger */
1844 do_cmd_macro_aux_keymap(buf);
1846 /* Look up the keymap */
1847 act = keymap_act[mode][(byte)(buf[0])];
1853 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1859 /* Obtain the action */
1860 strcpy(macro__buf, act);
1862 /* Analyze the current action */
1863 ascii_to_text(buf, macro__buf);
1865 /* Display the current action */
1869 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1873 /* Create a keymap */
1877 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1880 prt(_("押すキー: ", "Keypress: "), 18, 0);
1882 /* Get a keymap trigger */
1883 do_cmd_macro_aux_keymap(buf);
1887 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1888 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1891 prt(_("行動: ", "Action: "), 20, 0);
1893 /* Convert to text */
1894 ascii_to_text(tmp, macro__buf);
1896 /* Get an encoded action */
1897 if (askfor(tmp, 80))
1899 /* Convert to ascii */
1900 text_to_ascii(macro__buf, tmp);
1902 /* Free old keymap */
1903 string_free(keymap_act[mode][(byte)(buf[0])]);
1905 /* Make new keymap */
1906 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1909 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1913 /* Remove a keymap */
1917 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1920 prt(_("押すキー: ", "Keypress: "), 18, 0);
1922 /* Get a keymap trigger */
1923 do_cmd_macro_aux_keymap(buf);
1925 /* Free old keymap */
1926 string_free(keymap_act[mode][(byte)(buf[0])]);
1928 /* Make new keymap */
1929 keymap_act[mode][(byte)(buf[0])] = NULL;
1932 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1935 /* Enter a new action */
1939 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1943 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1944 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1947 prt(_("マクロ行動: ", "Action: "), 20, 0);
1949 /* Hack -- limit the value */
1952 /* Get an encoded action */
1953 if (!askfor(buf, 80)) continue;
1955 /* Extract an action */
1956 text_to_ascii(macro__buf, buf);
1958 #endif /* ALLOW_MACROS */
1973 * @brief キャラクタ色の明暗表現
1975 static concptr lighting_level_str[F_LIT_MAX] =
1990 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1991 * @param i 指定対象となるキャラクタコード
1992 * @param num 指定されたビジュアルIDを返す参照ポインタ
1993 * @param max ビジュアルIDの最大数
1994 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1996 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2003 sprintf(str, "%d", *num);
2005 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
2008 tmp = (IDX)strtol(str, NULL, 0);
2009 if (tmp >= 0 && tmp < max)
2012 else if (isupper(i))
2013 *num = (*num + max - 1) % max;
2015 *num = (*num + 1) % max;
2021 * @brief キャラクタの変更メニュー表示
2022 * @param choice_msg 選択メッセージ
2025 static void print_visuals_menu(concptr choice_msg)
2027 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2029 /* Give some choices */
2030 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2032 #ifdef ALLOW_VISUALS
2033 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2034 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2035 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2036 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2037 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2038 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2039 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2040 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2041 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2042 #endif /* ALLOW_VISUALS */
2044 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2047 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2052 * Interact with "visuals"
2054 void do_cmd_visuals(player_type *creature_ptr)
2059 bool need_redraw = FALSE;
2060 concptr empty_symbol = "<< ? >>";
2062 if (use_bigtile) empty_symbol = "<< ?? >>";
2064 /* File type is "TEXT" */
2065 FILE_TYPE(FILE_TYPE_TEXT);
2068 /* Interact until done */
2073 /* Ask for a choice */
2074 print_visuals_menu(NULL);
2079 if (i == ESCAPE) break;
2083 /* Load a 'pref' file */
2086 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2089 prt(_("ファイル: ", "File: "), 17, 0);
2091 /* Default filename */
2092 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2095 if (!askfor(tmp, 70)) continue;
2097 /* Process the given filename */
2098 (void)process_pref_file(creature_ptr, tmp);
2103 #ifdef ALLOW_VISUALS
2105 /* Dump monster attr/chars */
2108 static concptr mark = "Monster attr/chars";
2111 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2114 prt(_("ファイル: ", "File: "), 17, 0);
2116 /* Default filename */
2117 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2119 /* Get a filename */
2120 if (!askfor(tmp, 70)) continue;
2121 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2123 /* Append to the file */
2124 if (!open_auto_dump(buf, mark)) continue;
2127 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2130 for (i = 0; i < max_r_idx; i++)
2132 monster_race *r_ptr = &r_info[i];
2134 /* Skip non-entries */
2135 if (!r_ptr->name) continue;
2137 /* Dump a comment */
2138 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2140 /* Dump the monster attr/char info */
2141 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2142 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2148 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2153 /* Dump object attr/chars */
2156 static concptr mark = "Object attr/chars";
2157 KIND_OBJECT_IDX k_idx;
2160 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2163 prt(_("ファイル: ", "File: "), 17, 0);
2165 /* Default filename */
2166 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2168 /* Get a filename */
2169 if (!askfor(tmp, 70)) continue;
2170 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2172 /* Append to the file */
2173 if (!open_auto_dump(buf, mark)) continue;
2176 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2179 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2181 GAME_TEXT o_name[MAX_NLEN];
2182 object_kind *k_ptr = &k_info[k_idx];
2184 /* Skip non-entries */
2185 if (!k_ptr->name) continue;
2190 strip_name(o_name, k_idx);
2196 /* Prepare dummy object */
2197 object_prep(&forge, k_idx);
2199 /* Get un-shuffled flavor name */
2200 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2203 /* Dump a comment */
2204 auto_dump_printf("# %s\n", o_name);
2206 /* Dump the object attr/char info */
2207 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2208 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2214 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2219 /* Dump feature attr/chars */
2222 static concptr mark = "Feature attr/chars";
2225 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2228 prt(_("ファイル: ", "File: "), 17, 0);
2230 /* Default filename */
2231 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2233 /* Get a filename */
2234 if (!askfor(tmp, 70)) continue;
2235 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2237 /* Append to the file */
2238 if (!open_auto_dump(buf, mark)) continue;
2241 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2244 for (i = 0; i < max_f_idx; i++)
2246 feature_type *f_ptr = &f_info[i];
2248 /* Skip non-entries */
2249 if (!f_ptr->name) continue;
2251 /* Skip mimiccing features */
2252 if (f_ptr->mimic != i) continue;
2254 /* Dump a comment */
2255 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2257 /* Dump the feature attr/char info */
2258 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2259 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2260 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2261 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2267 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2272 /* Modify monster attr/chars (numeric operation) */
2275 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2276 static MONRACE_IDX r = 0;
2278 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2280 /* Hack -- query until done */
2283 monster_race *r_ptr = &r_info[r];
2287 TERM_COLOR da = r_ptr->d_attr;
2288 byte dc = r_ptr->d_char;
2289 TERM_COLOR ca = r_ptr->x_attr;
2290 byte cc = r_ptr->x_char;
2292 /* Label the object */
2293 Term_putstr(5, 17, -1, TERM_WHITE,
2294 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2296 /* Label the Default values */
2297 Term_putstr(10, 19, -1, TERM_WHITE,
2298 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2300 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2301 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2303 /* Label the Current values */
2304 Term_putstr(10, 20, -1, TERM_WHITE,
2305 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2307 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2308 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2311 Term_putstr(0, 22, -1, TERM_WHITE,
2312 _("コマンド (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): "));
2317 if (i == ESCAPE) break;
2319 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2320 else if (isupper(i)) c = 'a' + i - 'A';
2330 if (!cmd_visuals_aux(i, &r, max_r_idx))
2335 } while (!r_info[r].name);
2339 t = (int)r_ptr->x_attr;
2340 (void)cmd_visuals_aux(i, &t, 256);
2341 r_ptr->x_attr = (byte)t;
2345 t = (int)r_ptr->x_char;
2346 (void)cmd_visuals_aux(i, &t, 256);
2347 r_ptr->x_char = (byte)t;
2351 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2353 print_visuals_menu(choice_msg);
2361 /* Modify object attr/chars (numeric operation) */
2364 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2366 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2368 /* Hack -- query until done */
2371 object_kind *k_ptr = &k_info[k];
2375 TERM_COLOR da = k_ptr->d_attr;
2376 SYMBOL_CODE dc = k_ptr->d_char;
2377 TERM_COLOR ca = k_ptr->x_attr;
2378 SYMBOL_CODE cc = k_ptr->x_char;
2380 /* Label the object */
2381 Term_putstr(5, 17, -1, TERM_WHITE,
2382 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2383 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2385 /* Label the Default values */
2386 Term_putstr(10, 19, -1, TERM_WHITE,
2387 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2389 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2390 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2392 /* Label the Current values */
2393 Term_putstr(10, 20, -1, TERM_WHITE,
2394 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2396 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2397 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2400 Term_putstr(0, 22, -1, TERM_WHITE,
2401 _("コマンド (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): "));
2406 if (i == ESCAPE) break;
2408 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2409 else if (isupper(i)) c = 'a' + i - 'A';
2419 if (!cmd_visuals_aux(i, &k, max_k_idx))
2424 } while (!k_info[k].name);
2428 t = (int)k_ptr->x_attr;
2429 (void)cmd_visuals_aux(i, &t, 256);
2430 k_ptr->x_attr = (byte)t;
2434 t = (int)k_ptr->x_char;
2435 (void)cmd_visuals_aux(i, &t, 256);
2436 k_ptr->x_char = (byte)t;
2440 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2442 print_visuals_menu(choice_msg);
2450 /* Modify feature attr/chars (numeric operation) */
2453 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2455 static IDX lighting_level = F_LIT_STANDARD;
2456 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2458 /* Hack -- query until done */
2461 feature_type *f_ptr = &f_info[f];
2465 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2466 byte dc = f_ptr->d_char[lighting_level];
2467 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2468 byte cc = f_ptr->x_char[lighting_level];
2470 /* Label the object */
2472 Term_putstr(5, 17, -1, TERM_WHITE,
2473 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2474 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2476 /* Label the Default values */
2477 Term_putstr(10, 19, -1, TERM_WHITE,
2478 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2480 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2481 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2483 /* Label the Current values */
2485 Term_putstr(10, 20, -1, TERM_WHITE,
2486 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2488 Term_putstr(10, 20, -1, TERM_WHITE,
2489 format("Current attr/char = %3d / %3d", ca, cc));
2492 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2493 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2497 Term_putstr(0, 22, -1, TERM_WHITE,
2498 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2500 Term_putstr(0, 22, -1, TERM_WHITE,
2501 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2507 if (i == ESCAPE) break;
2509 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2510 else if (isupper(i)) c = 'a' + i - 'A';
2520 if (!cmd_visuals_aux(i, &f, max_f_idx))
2525 } while (!f_info[f].name || (f_info[f].mimic != f));
2529 t = (int)f_ptr->x_attr[lighting_level];
2530 (void)cmd_visuals_aux(i, &t, 256);
2531 f_ptr->x_attr[lighting_level] = (byte)t;
2535 t = (int)f_ptr->x_char[lighting_level];
2536 (void)cmd_visuals_aux(i, &t, 256);
2537 f_ptr->x_char[lighting_level] = (byte)t;
2541 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2544 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2548 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2550 print_visuals_menu(choice_msg);
2558 /* Modify monster attr/chars (visual mode) */
2560 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2563 /* Modify object attr/chars (visual mode) */
2565 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2568 /* Modify feature attr/chars (visual mode) */
2571 IDX lighting_level = F_LIT_STANDARD;
2572 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2576 #endif /* ALLOW_VISUALS */
2582 reset_visuals(creature_ptr);
2584 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2588 /* Unknown option */
2599 if (need_redraw) do_cmd_redraw(creature_ptr);
2604 * Interact with "colors"
2606 void do_cmd_colors(player_type *creature_ptr)
2612 /* File type is "TEXT" */
2613 FILE_TYPE(FILE_TYPE_TEXT);
2617 /* Interact until done */
2622 /* Ask for a choice */
2623 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2625 /* Give some choices */
2626 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2629 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2630 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2634 prt(_("コマンド: ", "Command: "), 8, 0);
2638 if (i == ESCAPE) break;
2640 /* Load a 'pref' file */
2644 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2647 prt(_("ファイル: ", "File: "), 10, 0);
2650 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2653 if (!askfor(tmp, 70)) continue;
2655 /* Process the given filename */
2656 (void)process_pref_file(creature_ptr, tmp);
2658 /* Mega-Hack -- react to changes */
2659 Term_xtra(TERM_XTRA_REACT, 0);
2661 /* Mega-Hack -- redraw */
2670 static concptr mark = "Colors";
2673 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2676 prt(_("ファイル: ", "File: "), 10, 0);
2678 /* Default filename */
2679 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2681 /* Get a filename */
2682 if (!askfor(tmp, 70)) continue;
2683 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2685 /* Append to the file */
2686 if (!open_auto_dump(buf, mark)) continue;
2689 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2692 for (i = 0; i < 256; i++)
2694 int kv = angband_color_table[i][0];
2695 int rv = angband_color_table[i][1];
2696 int gv = angband_color_table[i][2];
2697 int bv = angband_color_table[i][3];
2699 concptr name = _("未知", "unknown");
2701 /* Skip non-entries */
2702 if (!kv && !rv && !gv && !bv) continue;
2704 /* Extract the color name */
2705 if (i < 16) name = color_names[i];
2707 /* Dump a comment */
2708 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2710 /* Dump the monster attr/char info */
2711 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2718 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2727 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2729 /* Hack -- query until done */
2736 /* Exhibit the normal colors */
2737 for (j = 0; j < 16; j++)
2739 /* Exhibit this color */
2740 Term_putstr(j * 4, 20, -1, a, "###");
2742 /* Exhibit all colors */
2743 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2746 /* Describe the color */
2747 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2749 /* Describe the color */
2750 Term_putstr(5, 10, -1, TERM_WHITE,
2751 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2753 /* Label the Current values */
2754 Term_putstr(5, 12, -1, TERM_WHITE,
2755 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2756 angband_color_table[a][0],
2757 angband_color_table[a][1],
2758 angband_color_table[a][2],
2759 angband_color_table[a][3]));
2762 Term_putstr(0, 14, -1, TERM_WHITE,
2763 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2768 if (i == ESCAPE) break;
2771 if (i == 'n') a = (byte)(a + 1);
2772 if (i == 'N') a = (byte)(a - 1);
2773 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2774 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2775 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2776 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2777 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2778 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2779 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2780 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2782 /* Hack -- react to changes */
2783 Term_xtra(TERM_XTRA_REACT, 0);
2785 /* Hack -- redraw */
2792 /* Unknown option */
2806 * Note something in the message recall
2808 void do_cmd_note(void)
2816 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2818 /* Ignore empty notes */
2819 if (!buf[0] || (buf[0] == ' ')) return;
2821 /* Add the note to the message recall */
2822 msg_format(_("メモ: %s", "Note: %s"), buf);
2827 * Mention the current version
2829 void do_cmd_version(void)
2831 #if FAKE_VER_EXTRA > 0
2832 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2833 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2835 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2836 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2842 * Array of feeling strings
2844 static concptr do_cmd_feeling_text[11] =
2846 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2847 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2848 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2849 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2850 _("とても悪い予感がする...", "You have a very bad feeling..."),
2851 _("悪い予感がする...", "You have a bad feeling..."),
2852 _("何か緊張する。", "You feel nervous."),
2853 _("少し不運な気がする...", "You feel your luck is turning..."),
2854 _("この場所は好きになれない。", "You don't like the look of this place."),
2855 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2856 _("なんて退屈なところだ...", "What a boring place...")
2859 static concptr do_cmd_feeling_text_combat[11] =
2861 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2862 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2863 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2864 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2865 _("とても悪い予感がする...", "You have a very bad feeling..."),
2866 _("悪い予感がする...", "You have a bad feeling..."),
2867 _("何か緊張する。", "You feel nervous."),
2868 _("少し不運な気がする...", "You feel your luck is turning..."),
2869 _("この場所は好きになれない。", "You don't like the look of this place."),
2870 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2871 _("なんて退屈なところだ...", "What a boring place...")
2874 static concptr do_cmd_feeling_text_lucky[11] =
2876 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2877 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2878 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2879 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2880 _("とても良い感じがする...", "You have a very good feeling..."),
2881 _("良い感じがする...", "You have a good feeling..."),
2882 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2883 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2884 _("見た感じ悪くはない...", "You like the look of this place..."),
2885 _("全然駄目ということはないが...", "This level can't be all bad..."),
2886 _("なんて退屈なところだ...", "What a boring place...")
2891 * Note that "feeling" is set to zero unless some time has passed.
2892 * Note that this is done when the level is GENERATED, not entered.
2894 void do_cmd_feeling(player_type *creature_ptr)
2896 if (creature_ptr->wild_mode) return;
2898 /* No useful feeling in quests */
2899 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2901 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2905 /* No useful feeling in town */
2906 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2908 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2910 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2914 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2918 /* No useful feeling in the wilderness */
2919 if (!creature_ptr->current_floor_ptr->dun_level)
2921 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2925 /* Display the feeling */
2926 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2927 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2928 else if (creature_ptr->pseikaku == SEIKAKU_COMBAT ||
2929 creature_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
2930 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2932 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2937 * Description of each monster group.
2939 static concptr monster_group_text[] =
2942 "ユニーク", /* "Uniques" */
2943 "乗馬可能なモンスター", /* "Riding" */
2944 "賞金首", /* "Wanted */
2945 "アンバーの王族", /* "Ambertite" */
2974 /* "古代ドラゴン/ワイアーム", */
3035 /* "Ancient Dragon/Wyrm", */
3044 "Multi-Headed Reptile",
3049 "Reptile/Amphibian",
3050 "Spider/Scorpion/Tick",
3052 /* "Major Demon", */
3069 * Symbols of monsters in each group. Note the "Uniques" group
3070 * is handled differently.
3072 static concptr monster_group_char[] =
3129 "!$&()+./=>?[\\]`{|~",
3139 * todo 引数と戻り値について追記求む
3140 * Build a list of monster indexes in the given group.
3142 * mode & 0x01 : check for non-empty group
3143 * mode & 0x02 : visual operation only
3145 * @param creature_ptr プレーヤーへの参照ポインタ
3146 * @param grp_cur ???
3147 * @param mon_idx[] ???
3149 * @return The number of monsters in the group
3151 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3153 /* Get a list of x_char in this group */
3154 concptr group_char = monster_group_char[grp_cur];
3156 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3157 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3158 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3159 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3161 /* Check every race */
3163 for (IDX i = 0; i < max_r_idx; i++)
3165 /* Access the race */
3166 monster_race *r_ptr = &r_info[i];
3168 /* Skip empty race */
3169 if (!r_ptr->name) continue;
3171 /* Require known monsters */
3172 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3176 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3179 else if (grp_riding)
3181 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3184 else if (grp_wanted)
3186 bool wanted = FALSE;
3188 for (j = 0; j < MAX_BOUNTY; j++)
3190 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3191 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3197 if (!wanted) continue;
3200 else if (grp_amberite)
3202 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3207 /* Check for race in the group */
3208 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3212 mon_idx[mon_cnt++] = i;
3214 /* XXX Hack -- Just checking for non-empty group */
3215 if (mode & 0x01) break;
3218 /* Terminate the list */
3219 mon_idx[mon_cnt] = -1;
3222 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3224 /* Return the number of races */
3230 * Description of each monster group.
3232 static concptr object_group_text[] =
3235 "キノコ", /* "Mushrooms" */
3236 "薬", /* "Potions" */
3237 "油つぼ", /* "Flasks" */
3238 "巻物", /* "Scrolls" */
3240 "アミュレット", /* "Amulets" */
3241 "笛", /* "Whistle" */
3242 "光源", /* "Lanterns" */
3243 "魔法棒", /* "Wands" */
3246 "カード", /* "Cards" */
3257 "刀剣類", /* "Swords" */
3258 "鈍器", /* "Blunt Weapons" */
3259 "長柄武器", /* "Polearms" */
3260 "採掘道具", /* "Diggers" */
3261 "飛び道具", /* "Bows" */
3265 "軽装鎧", /* "Soft Armor" */
3266 "重装鎧", /* "Hard Armor" */
3267 "ドラゴン鎧", /* "Dragon Armor" */
3268 "盾", /* "Shields" */
3269 "クローク", /* "Cloaks" */
3270 "籠手", /* "Gloves" */
3271 "ヘルメット", /* "Helms" */
3273 "ブーツ", /* "Boots" */
3326 * TVALs of items in each group
3328 static byte object_group_tval[] =
3369 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3377 * Build a list of object indexes in the given group. Return the number
3378 * of objects in the group.
3380 * mode & 0x01 : check for non-empty group
3381 * mode & 0x02 : visual operation only
3383 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3385 KIND_OBJECT_IDX i, object_cnt = 0;
3388 /* Get a list of x_char in this group */
3389 byte group_tval = object_group_tval[grp_cur];
3391 /* Check every object */
3392 for (i = 0; i < max_k_idx; i++)
3394 /* Access the object */
3395 object_kind *k_ptr = &k_info[i];
3397 /* Skip empty objects */
3398 if (!k_ptr->name) continue;
3402 if (!current_world_ptr->wizard)
3404 /* Skip non-flavoured objects */
3405 if (!k_ptr->flavor) continue;
3407 /* Require objects ever seen */
3408 if (!k_ptr->aware) continue;
3411 /* Skip items with no distribution (special artifacts) */
3412 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3416 /* Check for objects in the group */
3417 if (TV_LIFE_BOOK == group_tval)
3419 /* Hack -- All spell books */
3420 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3422 /* Add the object */
3423 object_idx[object_cnt++] = i;
3427 else if (k_ptr->tval == group_tval)
3429 /* Add the object */
3430 object_idx[object_cnt++] = i;
3434 /* XXX Hack -- Just checking for non-empty group */
3435 if (mode & 0x01) break;
3438 /* Terminate the list */
3439 object_idx[object_cnt] = -1;
3441 /* Return the number of objects */
3447 * Description of each feature group.
3449 static concptr feature_group_text[] =
3457 * Build a list of feature indexes in the given group. Return the number
3458 * of features in the group.
3460 * mode & 0x01 : check for non-empty group
3462 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3464 /* Check every feature */
3465 FEAT_IDX feat_cnt = 0;
3466 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3468 feature_type *f_ptr = &f_info[i];
3470 /* Skip empty index */
3471 if (!f_ptr->name) continue;
3473 /* Skip mimiccing features */
3474 if (f_ptr->mimic != i) continue;
3477 feat_idx[feat_cnt++] = i;
3479 /* XXX Hack -- Just checking for non-empty group */
3480 if (mode & 0x01) break;
3483 /* Terminate the list */
3484 feat_idx[feat_cnt] = -1;
3486 /* Return the number of races */
3492 * Hack -- load a screen dump from a file
3494 void do_cmd_load_screen(void)
3498 SYMBOL_CODE c = ' ';
3504 Term_get_size(&wid, &hgt);
3505 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3507 /* Append to the file */
3508 fff = my_fopen(buf, "r");
3512 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3520 /* Load the screen */
3521 for (y = 0; okay; y++)
3523 /* Get a line of data including control code */
3524 if (!fgets(buf, 1024, fff)) okay = FALSE;
3526 /* Get the blank line */
3527 if (buf[0] == '\n' || buf[0] == '\0') break;
3529 /* Ignore too large screen image */
3530 if (y >= hgt) continue;
3533 for (x = 0; x < wid - 1; x++)
3536 if (buf[x] == '\n' || buf[x] == '\0') break;
3538 /* Put the attr/char */
3539 Term_draw(x, y, TERM_WHITE, buf[x]);
3543 /* Dump the screen */
3544 for (y = 0; okay; y++)
3546 /* Get a line of data including control code */
3547 if (!fgets(buf, 1024, fff)) okay = FALSE;
3549 /* Get the blank line */
3550 if (buf[0] == '\n' || buf[0] == '\0') break;
3552 /* Ignore too large screen image */
3553 if (y >= hgt) continue;
3556 for (x = 0; x < wid - 1; x++)
3559 if (buf[x] == '\n' || buf[x] == '\0') break;
3561 /* Get the attr/char */
3562 (void)(Term_what(x, y, &a, &c));
3564 /* Look up the attr */
3565 for (int i = 0; i < 16; i++)
3567 /* Use attr matches */
3568 if (hack[i] == buf[x]) a = (byte_hack)i;
3571 /* Put the attr/char */
3572 Term_draw(x, y, a, c);
3578 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3586 // todo なぜこんな中途半端なところに? defineも…
3587 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3588 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3590 #define IM_FLAG_STR _("*", "* ")
3591 #define HAS_FLAG_STR _("+", "+ ")
3592 #define NO_FLAG_STR _("・", ". ")
3594 #define print_im_or_res_flag(IM, RES) \
3596 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3597 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3600 #define print_flag(TR) \
3602 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3606 /* XTRA HACK RESLIST */
3607 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)
3609 GAME_TEXT o_name[MAX_NLEN];
3610 BIT_FLAGS flgs[TR_FLAG_SIZE];
3612 if (!o_ptr->k_idx) return;
3613 if (o_ptr->tval != tval) return;
3615 /* Identified items only */
3616 if (!object_is_known(o_ptr)) return;
3619 * HACK:Ring of Lordly protection and Dragon equipment
3620 * have random resistances.
3622 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3623 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3624 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3625 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3626 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3627 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3628 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3629 || object_is_artifact(o_ptr);
3630 if (!is_special_item_type)
3636 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3638 while (o_name[i] && (i < 26))
3641 if (iskanji(o_name[i])) i++;
3650 o_name[i] = ' '; i++;
3656 fprintf(fff, "%s %s", where, o_name);
3658 if (!(o_ptr->ident & (IDENT_MENTAL)))
3660 fputs(_("-------不明--------------- -------不明---------\n",
3661 "-------unknown------------ -------unknown------\n"), fff);
3665 object_flags_known(o_ptr, flgs);
3667 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3668 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3669 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3670 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3671 print_flag(TR_RES_POIS);
3672 print_flag(TR_RES_LITE);
3673 print_flag(TR_RES_DARK);
3674 print_flag(TR_RES_SHARDS);
3675 print_flag(TR_RES_SOUND);
3676 print_flag(TR_RES_NETHER);
3677 print_flag(TR_RES_NEXUS);
3678 print_flag(TR_RES_CHAOS);
3679 print_flag(TR_RES_DISEN);
3683 print_flag(TR_RES_BLIND);
3684 print_flag(TR_RES_FEAR);
3685 print_flag(TR_RES_CONF);
3686 print_flag(TR_FREE_ACT);
3687 print_flag(TR_SEE_INVIS);
3688 print_flag(TR_HOLD_EXP);
3689 print_flag(TR_TELEPATHY);
3690 print_flag(TR_SLOW_DIGEST);
3691 print_flag(TR_REGEN);
3692 print_flag(TR_LEVITATION);
3701 fprintf(fff, "%s\n", inven_res_label);
3706 * Display *ID* ed weapons/armors's resistances
3708 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3711 GAME_TEXT file_name[1024];
3713 OBJECT_TYPE_VALUE tval;
3719 /* Open a new file */
3720 fff = my_fopen_temp(file_name, 1024);
3723 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3728 fprintf(fff, "%s\n", inven_res_label);
3730 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3734 for (; j < 9; j++) fputc('\n', fff);
3736 fprintf(fff, "%s\n", inven_res_label);
3739 strcpy(where, _("装", "E "));
3740 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3742 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3745 strcpy(where, _("持", "I "));
3746 for (i = 0; i < INVEN_PACK; i++)
3748 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3751 st_ptr = &town_info[1].store[STORE_HOME];
3752 strcpy(where, _("家", "H "));
3753 for (i = 0; i < st_ptr->stock_num; i++)
3755 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3761 /* Display the file contents */
3762 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3767 void do_cmd_save_screen_html_aux(char *filename, int message)
3775 concptr html_head[] = {
3776 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3780 concptr html_foot[] = {
3782 "</body>\n</html>\n",
3787 Term_get_size(&wid, &hgt);
3789 /* File type is "TEXT" */
3790 FILE_TYPE(FILE_TYPE_TEXT);
3792 /* Append to the file */
3794 fff = my_fopen(filename, "w");
3800 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3807 if (message) screen_save();
3809 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3811 tmpfff = my_fopen(buf, "r");
3814 for (int i = 0; html_head[i]; i++)
3815 fputs(html_head[i], fff);
3819 bool is_first_line = TRUE;
3820 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3824 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3825 is_first_line = FALSE;
3829 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3831 fprintf(fff, "%s\n", buf);
3836 /* Dump the screen */
3837 for (TERM_LEN y = 0; y < hgt; y++)
3840 if (y != 0) fprintf(fff, "\n");
3843 TERM_COLOR a = 0, old_a = 0;
3845 for (TERM_LEN x = 0; x < wid - 1; x++)
3848 /* Get the attr/char */
3849 (void)(Term_what(x, y, &a, &c));
3853 case '&': cc = "&"; break;
3854 case '<': cc = "<"; break;
3855 case '>': cc = ">"; break;
3857 case 0x1f: c = '.'; break;
3858 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3863 if ((y == 0 && x == 0) || a != old_a)
3865 int rv = angband_color_table[a][1];
3866 int gv = angband_color_table[a][2];
3867 int bv = angband_color_table[a][3];
3868 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3869 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3874 fprintf(fff, "%s", cc);
3876 fprintf(fff, "%c", c);
3880 fprintf(fff, "</font>");
3884 for (int i = 0; html_foot[i]; i++)
3885 fputs(html_foot[i], fff);
3890 bool is_first_line = TRUE;
3891 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3895 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3896 is_first_line = FALSE;
3900 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3902 fprintf(fff, "%s\n", buf);
3915 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3924 * Hack -- save a screen dump to a file
3926 static void do_cmd_save_screen_html(void)
3928 char buf[1024], tmp[256] = "screen.html";
3930 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3932 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3936 do_cmd_save_screen_html_aux(buf, 1);
3941 * Redefinable "save_screen" action
3943 void(*screendump_aux)(void) = NULL;
3947 * Save a screen dump to a file
3948 * @param creature_ptr プレーヤーへの参照ポインタ
3951 void do_cmd_save_screen(player_type *creature_ptr)
3953 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3954 bool html_dump = FALSE;
3958 if (c == 'Y' || c == 'y')
3960 else if (c == 'H' || c == 'h')
3973 Term_get_size(&wid, &hgt);
3975 bool old_use_graphics = use_graphics;
3976 if (old_use_graphics)
3978 use_graphics = FALSE;
3979 reset_visuals(creature_ptr);
3980 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3981 handle_stuff(creature_ptr);
3986 do_cmd_save_screen_html();
3987 do_cmd_redraw(creature_ptr);
3990 /* Do we use a special screendump function ? */
3991 else if (screendump_aux)
3993 /* Dump the screen to a graphics file */
3994 (*screendump_aux)();
3996 else /* Dump the screen as text */
4000 SYMBOL_CODE c = ' ';
4003 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4005 /* File type is "TEXT" */
4006 FILE_TYPE(FILE_TYPE_TEXT);
4008 /* Append to the file */
4009 fff = my_fopen(buf, "w");
4013 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
4020 /* Dump the screen */
4021 for (y = 0; y < hgt; y++)
4024 for (x = 0; x < wid - 1; x++)
4026 /* Get the attr/char */
4027 (void)(Term_what(x, y, &a, &c));
4037 fprintf(fff, "%s\n", buf);
4044 /* Dump the screen */
4045 for (y = 0; y < hgt; y++)
4048 for (x = 0; x < wid - 1; x++)
4050 /* Get the attr/char */
4051 (void)(Term_what(x, y, &a, &c));
4054 buf[x] = hack[a & 0x0F];
4061 fprintf(fff, "%s\n", buf);
4068 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4073 if (!old_use_graphics) return;
4075 use_graphics = TRUE;
4076 reset_visuals(creature_ptr);
4077 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4078 handle_stuff(creature_ptr);
4083 * todo okay = 既知のアーティファクト? と思われるが確証がない
4084 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4085 * Check the status of "artifacts"
4086 * @param player_ptr プレーヤーへの参照ポインタ
4089 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4091 /* Open a new file */
4093 GAME_TEXT file_name[1024];
4094 fff = my_fopen_temp(file_name, 1024);
4097 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4102 /* Allocate the "who" array */
4104 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4106 /* Allocate the "okay" array */
4108 C_MAKE(okay, max_a_idx, bool);
4110 /* Scan the artifacts */
4111 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4113 artifact_type *a_ptr = &a_info[k];
4118 /* Skip "empty" artifacts */
4119 if (!a_ptr->name) continue;
4121 /* Skip "uncreated" artifacts */
4122 if (!a_ptr->cur_num) continue;
4128 /* Check the dungeon */
4129 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4131 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4133 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4135 OBJECT_IDX this_o_idx, next_o_idx = 0;
4137 /* Scan all objects in the grid */
4138 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4141 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4142 next_o_idx = o_ptr->next_o_idx;
4144 /* Ignore non-artifacts */
4145 if (!object_is_fixed_artifact(o_ptr)) continue;
4147 /* Ignore known items */
4148 if (object_is_known(o_ptr)) continue;
4150 /* Note the artifact */
4151 okay[o_ptr->name1] = FALSE;
4156 /* Check the player_ptr->inventory_list and equipment */
4157 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4159 object_type *o_ptr = &player_ptr->inventory_list[i];
4161 /* Ignore non-objects */
4162 if (!o_ptr->k_idx) continue;
4164 /* Ignore non-artifacts */
4165 if (!object_is_fixed_artifact(o_ptr)) continue;
4167 /* Ignore known items */
4168 if (object_is_known(o_ptr)) continue;
4170 /* Note the artifact */
4171 okay[o_ptr->name1] = FALSE;
4175 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4177 if (okay[k]) who[n++] = k;
4181 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4183 /* Scan the artifacts */
4184 for (ARTIFACT_IDX k = 0; k < n; k++)
4186 artifact_type *a_ptr = &a_info[who[k]];
4187 GAME_TEXT base_name[MAX_NLEN];
4188 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4190 /* Obtain the base object type */
4191 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4200 /* Create fake object */
4201 object_prep(q_ptr, z);
4203 /* Make it an artifact */
4204 q_ptr->name1 = (byte)who[k];
4206 /* Display as if known */
4207 q_ptr->ident |= IDENT_STORE;
4209 /* Describe the artifact */
4210 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4213 /* Hack -- Build the artifact name */
4214 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4217 /* Free the "who" array */
4218 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4220 /* Free the "okay" array */
4221 C_KILL(okay, max_a_idx, bool);
4224 /* Display the file contents */
4225 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4231 * Display known uniques
4232 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4234 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4241 GAME_TEXT file_name[1024];
4244 int n_alive_surface = 0;
4245 int n_alive_over100 = 0;
4246 int n_alive_total = 0;
4249 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4251 /* Open a new file */
4252 fff = my_fopen_temp(file_name, 1024);
4256 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4261 /* Allocate the "who" array */
4262 C_MAKE(who, max_r_idx, MONRACE_IDX);
4264 /* Scan the monsters */
4266 for (IDX i = 1; i < max_r_idx; i++)
4268 monster_race *r_ptr = &r_info[i];
4271 if (!r_ptr->name) continue;
4273 /* Require unique monsters */
4274 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4276 /* Only display "known" uniques */
4277 if (!cheat_know && !r_ptr->r_sights) continue;
4279 /* Only print rarity <= 100 uniques */
4280 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4282 /* Only "alive" uniques */
4283 if (r_ptr->max_num == 0) continue;
4287 lev = (r_ptr->level - 1) / 10;
4291 if (max_lev < lev) max_lev = lev;
4293 else n_alive_over100++;
4295 else n_alive_surface++;
4297 /* Collect "appropriate" monsters */
4301 /* Sort the array by dungeon depth of monsters */
4302 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4304 if (n_alive_surface)
4306 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4307 n_alive_total += n_alive_surface;
4310 for (IDX i = 0; i <= max_lev; i++)
4312 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4313 n_alive_total += n_alive[i];
4316 if (n_alive_over100)
4318 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4319 n_alive_total += n_alive_over100;
4324 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4325 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4329 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4332 /* Scan the monster races */
4333 for (int k = 0; k < n; k++)
4335 monster_race *r_ptr = &r_info[who[k]];
4336 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4339 /* Free the "who" array */
4340 C_KILL(who, max_r_idx, s16b);
4343 /* Display the file contents */
4344 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4350 * Display weapon-exp
4352 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4354 /* Open a new file */
4356 GAME_TEXT file_name[1024];
4357 fff = my_fopen_temp(file_name, 1024);
4360 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4365 for (int i = 0; i < 5; i++)
4367 for (int num = 0; num < 64; num++)
4371 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4373 object_kind *k_ptr = &k_info[j];
4375 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4376 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4378 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4380 fprintf(fff, "%-25s ", tmp);
4381 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4382 else fprintf(fff, " ");
4383 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4384 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4393 /* Display the file contents */
4394 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4400 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4404 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4406 /* Open a new file */
4408 GAME_TEXT file_name[1024];
4409 fff = my_fopen_temp(file_name, 1024);
4412 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4417 if (creature_ptr->realm1 != REALM_NONE)
4419 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4420 for (SPELL_IDX i = 0; i < 32; i++)
4422 const magic_type *s_ptr;
4423 if (!is_magic(creature_ptr->realm1))
4425 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4429 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4432 if (s_ptr->slevel >= 99) continue;
4433 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4434 int exp_level = spell_exp_level(spell_exp);
4435 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4436 if (creature_ptr->realm1 == REALM_HISSATSU)
4437 fprintf(fff, "[--]");
4440 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4441 else fprintf(fff, " ");
4442 fprintf(fff, "%s", exp_level_str[exp_level]);
4445 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4450 if (creature_ptr->realm2 != REALM_NONE)
4452 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4453 for (SPELL_IDX i = 0; i < 32; i++)
4455 const magic_type *s_ptr;
4456 if (!is_magic(creature_ptr->realm1))
4458 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4462 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4465 if (s_ptr->slevel >= 99) continue;
4467 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4468 int exp_level = spell_exp_level(spell_exp);
4469 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4470 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4471 else fprintf(fff, " ");
4472 fprintf(fff, "%s", exp_level_str[exp_level]);
4473 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4480 /* Display the file contents */
4481 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4487 * @brief スキル情報を表示するコマンドのメインルーチン /
4491 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4493 char skill_name[GINOU_TEMPMAX][20] =
4495 _("マーシャルアーツ", "Martial Arts "),
4496 _("二刀流 ", "Dual Wielding "),
4497 _("乗馬 ", "Riding "),
4501 /* Open a new file */
4503 char file_name[1024];
4504 fff = my_fopen_temp(file_name, 1024);
4507 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4512 for (int i = 0; i < GINOU_TEMPMAX; i++)
4514 int skill_exp = creature_ptr->skill_exp[i];
4515 fprintf(fff, "%-20s ", skill_name[i]);
4516 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4517 else fprintf(fff, " ");
4518 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4519 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4525 /* Display the file contents */
4526 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4532 * @brief 現在のペットを表示するコマンドのメインルーチン /
4533 * Display current pets
4534 * @param creature_ptr プレーヤーへの参照ポインタ
4537 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4539 /* Open a new file */
4540 GAME_TEXT file_name[1024];
4542 fff = my_fopen_temp(file_name, 1024);
4545 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4550 /* Process the monsters (backwards) */
4551 monster_type *m_ptr;
4552 GAME_TEXT pet_name[MAX_NLEN];
4554 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4556 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4558 /* Ignore "dead" monsters */
4559 if (!monster_is_valid(m_ptr)) continue;
4561 /* Calculate "upkeep" for pets */
4562 if (!is_pet(m_ptr)) continue;
4565 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4566 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4569 int show_upkeep = calculate_upkeep(creature_ptr);
4571 fprintf(fff, "----------------------------------------------\n");
4573 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4575 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4577 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4581 /* Display the file contents */
4582 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4588 * @brief 現在のペットを表示するコマンドのメインルーチン /
4589 * @param creature_ptr プレーヤーへの参照ポインタ
4592 * @note the player ghosts are ignored.
4594 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4596 /* Open a new file */
4598 GAME_TEXT file_name[1024];
4599 fff = my_fopen_temp(file_name, 1024);
4602 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4607 /* Allocate the "who" array */
4609 C_MAKE(who, max_r_idx, MONRACE_IDX);
4613 /* Monsters slain */
4614 for (int kk = 1; kk < max_r_idx; kk++)
4616 monster_race *r_ptr = &r_info[kk];
4618 if (r_ptr->flags1 & (RF1_UNIQUE))
4620 bool dead = (r_ptr->max_num == 0);
4629 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4631 if (this_monster > 0)
4633 total += this_monster;
4639 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4642 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4644 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4650 /* Scan the monsters */
4652 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4654 monster_race *r_ptr = &r_info[i];
4656 /* Use that monster */
4657 if (r_ptr->name) who[n++] = i;
4660 /* Sort the array by dungeon depth of monsters */
4662 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4664 /* Scan the monster races */
4665 for (int k = 0; k < n; k++)
4667 monster_race *r_ptr = &r_info[who[k]];
4669 if (r_ptr->flags1 & (RF1_UNIQUE))
4671 bool dead = (r_ptr->max_num == 0);
4675 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4682 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4684 if (this_monster <= 0) continue;
4687 /* p,tは人と数える by ita */
4688 if (my_strchr("pt", r_ptr->d_char))
4689 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4691 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4693 if (this_monster < 2)
4695 if (my_strstr(r_name + r_ptr->name, "coins"))
4697 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4701 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4707 strcpy(ToPlural, (r_name + r_ptr->name));
4708 plural_aux(ToPlural);
4709 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4712 total += this_monster;
4715 fprintf(fff, "----------------------------------------------\n");
4717 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4719 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4722 /* Free the "who" array */
4723 C_KILL(who, max_r_idx, s16b);
4726 /* Display the file contents */
4727 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4733 * @brief モンスター情報リスト中のグループを表示する /
4734 * Display the object groups.
4738 * @param per_page リストの表示行
4739 * @param grp_idx グループのID配列
4740 * @param group_text グループ名の文字列配列
4741 * @param grp_cur 現在の選択ID
4742 * @param grp_top 現在の選択リスト最上部ID
4745 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)
4747 /* Display lines until done */
4748 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4750 /* Get the group index */
4751 int grp = grp_idx[grp_top + i];
4753 /* Choose a color */
4754 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4756 /* Erase the entire line */
4757 Term_erase(col, row + i, wid);
4759 /* Display the group label */
4760 c_put_str(attr, group_text[grp], row + i, col);
4766 * Move the cursor in a browser window
4768 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4769 IDX *list_cur, int list_cnt)
4774 IDX list = *list_cur;
4776 /* Extract direction */
4779 /* Hack -- scroll up full screen */
4784 /* Hack -- scroll down full screen */
4789 d = get_keymap_dir(ch);
4794 /* Diagonals - hack */
4795 if ((ddx[d] > 0) && ddy[d])
4800 Term_get_size(&wid, &hgt);
4802 browser_rows = hgt - 8;
4804 /* Browse group list */
4809 /* Move up or down */
4810 grp += ddy[d] * (browser_rows - 1);
4813 if (grp >= grp_cnt) grp = grp_cnt - 1;
4814 if (grp < 0) grp = 0;
4815 if (grp != old_grp) list = 0;
4818 /* Browse sub-list list */
4821 /* Move up or down */
4822 list += ddy[d] * browser_rows;
4825 if (list >= list_cnt) list = list_cnt - 1;
4826 if (list < 0) list = 0;
4838 if (col < 0) col = 0;
4839 if (col > 1) col = 1;
4846 /* Browse group list */
4851 /* Move up or down */
4855 if (grp >= grp_cnt) grp = grp_cnt - 1;
4856 if (grp < 0) grp = 0;
4857 if (grp != old_grp) list = 0;
4860 /* Browse sub-list list */
4863 /* Move up or down */
4864 list += (IDX)ddy[d];
4867 if (list >= list_cnt) list = list_cnt - 1;
4868 if (list < 0) list = 0;
4879 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4881 /* Clear the display lines */
4882 for (int i = 0; i < height; i++)
4884 Term_erase(col, row + i, width);
4887 /* Bigtile mode uses double width */
4888 if (use_bigtile) width /= 2;
4890 /* Display lines until done */
4891 for (int i = 0; i < height; i++)
4893 /* Display columns until done */
4894 for (int j = 0; j < width; j++)
4896 TERM_LEN x = col + j;
4897 TERM_LEN y = row + i;
4899 /* Bigtile mode uses double width */
4900 if (use_bigtile) x += j;
4902 TERM_COLOR ia = attr_top + i;
4903 SYMBOL_CODE ic = char_left + j;
4905 /* Ignore illegal characters */
4906 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4907 (!use_graphics && ic > 0x7f))
4913 /* Force correct code for both ASCII character and tile */
4914 if (c & 0x80) a |= 0x80;
4916 /* Display symbol */
4917 Term_queue_bigchar(x, y, a, c, 0, 0);
4924 * Place the cursor at the collect position for visual mode
4926 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4928 int i = (a & 0x7f) - attr_top;
4929 int j = c - char_left;
4931 TERM_LEN x = col + j;
4932 TERM_LEN y = row + i;
4934 /* Bigtile mode uses double width */
4935 if (use_bigtile) x += j;
4937 /* Place the cursor */
4943 * Do visual mode command -- Change symbols
4945 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4946 int height, int width,
4947 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4948 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4950 static TERM_COLOR attr_old = 0;
4951 static SYMBOL_CODE char_old = 0;
4956 if (*visual_list_ptr)
4959 *cur_attr_ptr = attr_old;
4960 *cur_char_ptr = char_old;
4961 *visual_list_ptr = FALSE;
4969 if (*visual_list_ptr)
4972 *visual_list_ptr = FALSE;
4973 *need_redraw = TRUE;
4981 if (!*visual_list_ptr)
4983 *visual_list_ptr = TRUE;
4985 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4986 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4988 attr_old = *cur_attr_ptr;
4989 char_old = *cur_char_ptr;
5000 /* Set the visual */
5001 attr_idx = *cur_attr_ptr;
5002 char_idx = *cur_char_ptr;
5004 /* Hack -- for feature lighting */
5005 for (i = 0; i < F_LIT_MAX; i++)
5007 attr_idx_feat[i] = 0;
5008 char_idx_feat[i] = 0;
5015 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
5018 *cur_attr_ptr = attr_idx;
5019 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5020 if (!*visual_list_ptr) *need_redraw = TRUE;
5026 *cur_char_ptr = char_idx;
5027 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5028 if (!*visual_list_ptr) *need_redraw = TRUE;
5034 if (*visual_list_ptr)
5037 int d = get_keymap_dir(ch);
5038 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5039 SYMBOL_CODE c = *cur_char_ptr;
5041 if (use_bigtile) eff_width = width / 2;
5042 else eff_width = width;
5044 /* Restrict direction */
5045 if ((a == 0) && (ddy[d] < 0)) d = 0;
5046 if ((c == 0) && (ddx[d] < 0)) d = 0;
5047 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5048 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5050 a += (TERM_COLOR)ddy[d];
5051 c += (SYMBOL_CODE)ddx[d];
5053 /* Force correct code for both ASCII character and tile */
5054 if (c & 0x80) a |= 0x80;
5056 /* Set the visual */
5061 /* Move the frame */
5062 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5063 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5064 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5065 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5071 /* Visual mode command is not used */
5077 * Display the monsters in a group.
5079 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5080 int mon_cur, int mon_top, bool visual_only)
5082 /* Display lines until done */
5084 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5088 /* Get the race index */
5089 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5091 /* Access the race */
5092 monster_race *r_ptr = &r_info[r_idx];
5094 /* Choose a color */
5095 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5097 /* Display the name */
5098 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5100 /* Hack -- visual_list mode */
5103 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5106 if (current_world_ptr->wizard || visual_only)
5108 c_prt(attr, format("%d", r_idx), row + i, 62);
5111 /* Erase chars before overwritten by the race letter */
5112 Term_erase(69, row + i, 255);
5114 /* Display symbol */
5115 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5120 if (!(r_ptr->flags1 & RF1_UNIQUE))
5121 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5123 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5124 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5128 /* Clear remaining lines */
5129 for (; i < per_page; i++)
5131 Term_erase(col, row + i, 255);
5137 * todo 引数の詳細について加筆求む
5138 * Display known monsters.
5139 * @param creature_ptr プレーヤーへの参照ポインタ
5140 * @param need_redraw 画面の再描画が必要な時TRUE
5141 * @param visual_only ???
5142 * @param direct_r_idx モンスターID
5145 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5148 Term_get_size(&wid, &hgt);
5150 /* Allocate the "mon_idx" array */
5152 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5158 bool visual_list = FALSE;
5159 TERM_COLOR attr_top = 0;
5162 int browser_rows = hgt - 8;
5163 if (direct_r_idx < 0)
5165 mode = visual_only ? 0x03 : 0x01;
5167 /* Check every group */
5169 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5171 /* Measure the label */
5172 len = strlen(monster_group_text[i]);
5174 /* Save the maximum length */
5175 if (len > max) max = len;
5177 /* See if any monsters are known */
5178 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5180 /* Build a list of groups with known monsters */
5181 grp_idx[grp_cnt++] = i;
5189 mon_idx[0] = direct_r_idx;
5192 /* Terminate the list */
5195 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5196 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5199 /* Terminate the list */
5200 grp_idx[grp_cnt] = -1;
5202 mode = visual_only ? 0x02 : 0x00;
5203 IDX old_grp_cur = -1;
5216 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5217 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5218 prt(_("名前", "Name"), 4, max + 3);
5219 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5220 prt(_("文字", "Sym"), 4, 67);
5221 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5223 for (IDX i = 0; i < 78; i++)
5225 Term_putch(i, 5, TERM_WHITE, '=');
5228 if (direct_r_idx < 0)
5230 for (IDX i = 0; i < browser_rows; i++)
5232 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5239 if (direct_r_idx < 0)
5241 /* Scroll group list */
5242 if (grp_cur < grp_top) grp_top = grp_cur;
5243 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5245 /* Display a list of monster groups */
5246 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5248 if (old_grp_cur != grp_cur)
5250 old_grp_cur = grp_cur;
5252 /* Get a list of monsters in the current group */
5253 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5256 /* Scroll monster list */
5257 while (mon_cur < mon_top)
5258 mon_top = MAX(0, mon_top - browser_rows / 2);
5259 while (mon_cur >= mon_top + browser_rows)
5260 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5265 /* Display a list of monsters in the current group */
5266 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5272 /* Display a monster name */
5273 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5275 /* Display visual list below first monster */
5276 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5280 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5281 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5282 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5283 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5286 /* Get the current monster */
5287 monster_race *r_ptr;
5288 r_ptr = &r_info[mon_idx[mon_cur]];
5292 /* Mega Hack -- track this monster race */
5293 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5294 handle_stuff(creature_ptr);
5299 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5303 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5307 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5312 /* Do visual mode command if needed */
5313 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))
5315 if (direct_r_idx >= 0)
5341 /* Recall on screen */
5342 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5344 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5356 /* Move the cursor */
5357 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5364 /* Free the "mon_idx" array */
5365 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5370 * Display the objects in a group.
5372 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5373 int object_cur, int object_top, bool visual_only)
5375 /* Display lines until done */
5377 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5379 GAME_TEXT o_name[MAX_NLEN];
5382 object_kind *flavor_k_ptr;
5384 /* Get the object index */
5385 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5387 /* Access the object */
5388 object_kind *k_ptr = &k_info[k_idx];
5390 /* Choose a color */
5391 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5392 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5394 if (!visual_only && k_ptr->flavor)
5396 /* Appearance of this object is shuffled */
5397 flavor_k_ptr = &k_info[k_ptr->flavor];
5401 /* Appearance of this object is very normal */
5402 flavor_k_ptr = k_ptr;
5405 attr = ((i + object_top == object_cur) ? cursor : attr);
5407 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5410 strip_name(o_name, k_idx);
5415 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5418 /* Display the name */
5419 c_prt(attr, o_name, row + i, col);
5421 /* Hack -- visual_list mode */
5424 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);
5427 if (current_world_ptr->wizard || visual_only)
5429 c_prt(attr, format("%d", k_idx), row + i, 70);
5432 a = flavor_k_ptr->x_attr;
5433 c = flavor_k_ptr->x_char;
5435 /* Display symbol */
5436 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5439 /* Clear remaining lines */
5440 for (; i < per_page; i++)
5442 Term_erase(col, row + i, 255);
5448 * Describe fake object
5450 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5453 object_type object_type_body;
5454 o_ptr = &object_type_body;
5456 object_prep(o_ptr, k_idx);
5458 /* It's fully know */
5459 o_ptr->ident |= IDENT_KNOWN;
5460 handle_stuff(creature_ptr);
5462 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5464 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5470 * Display known objects
5472 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5474 IDX object_old, object_top;
5477 OBJECT_IDX *object_idx;
5479 bool visual_list = FALSE;
5480 TERM_COLOR attr_top = 0;
5485 Term_get_size(&wid, &hgt);
5487 int browser_rows = hgt - 8;
5489 /* Allocate the "object_idx" array */
5490 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5495 if (direct_k_idx < 0)
5497 mode = visual_only ? 0x03 : 0x01;
5499 /* Check every group */
5500 for (IDX i = 0; object_group_text[i] != NULL; i++)
5502 /* Measure the label */
5503 len = strlen(object_group_text[i]);
5505 /* Save the maximum length */
5506 if (len > max) max = len;
5508 /* See if any monsters are known */
5509 if (collect_objects(i, object_idx, mode))
5511 /* Build a list of groups with known monsters */
5512 grp_idx[grp_cnt++] = i;
5521 object_kind *k_ptr = &k_info[direct_k_idx];
5522 object_kind *flavor_k_ptr;
5524 if (!visual_only && k_ptr->flavor)
5526 /* Appearance of this object is shuffled */
5527 flavor_k_ptr = &k_info[k_ptr->flavor];
5531 /* Appearance of this object is very normal */
5532 flavor_k_ptr = k_ptr;
5535 object_idx[0] = direct_k_idx;
5536 object_old = direct_k_idx;
5539 /* Terminate the list */
5542 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5543 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5546 /* Terminate the list */
5547 grp_idx[grp_cnt] = -1;
5549 mode = visual_only ? 0x02 : 0x00;
5550 IDX old_grp_cur = -1;
5553 IDX object_cur = object_top = 0;
5559 object_kind *k_ptr, *flavor_k_ptr;
5566 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5567 if (direct_k_idx < 0) prt("グループ", 4, 0);
5568 prt("名前", 4, max + 3);
5569 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5572 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5573 if (direct_k_idx < 0) prt("Group", 4, 0);
5574 prt("Name", 4, max + 3);
5575 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5579 for (IDX i = 0; i < 78; i++)
5581 Term_putch(i, 5, TERM_WHITE, '=');
5584 if (direct_k_idx < 0)
5586 for (IDX i = 0; i < browser_rows; i++)
5588 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5595 if (direct_k_idx < 0)
5597 /* Scroll group list */
5598 if (grp_cur < grp_top) grp_top = grp_cur;
5599 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5601 /* Display a list of object groups */
5602 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5604 if (old_grp_cur != grp_cur)
5606 old_grp_cur = grp_cur;
5608 /* Get a list of objects in the current group */
5609 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5612 /* Scroll object list */
5613 while (object_cur < object_top)
5614 object_top = MAX(0, object_top - browser_rows / 2);
5615 while (object_cur >= object_top + browser_rows)
5616 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5621 /* Display a list of objects in the current group */
5622 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5626 object_top = object_cur;
5628 /* Display a list of objects in the current group */
5629 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5631 /* Display visual list below first object */
5632 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5635 /* Get the current object */
5636 k_ptr = &k_info[object_idx[object_cur]];
5638 if (!visual_only && k_ptr->flavor)
5640 /* Appearance of this object is shuffled */
5641 flavor_k_ptr = &k_info[k_ptr->flavor];
5645 /* Appearance of this object is very normal */
5646 flavor_k_ptr = k_ptr;
5651 prt(format("<方向>%s%s%s, ESC",
5652 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5653 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5654 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5657 prt(format("<dir>%s%s%s, ESC",
5658 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5659 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5660 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5666 /* Mega Hack -- track this object */
5667 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5669 /* The "current" object changed */
5670 if (object_old != object_idx[object_cur])
5672 handle_stuff(creature_ptr);
5674 /* Remember the "current" object */
5675 object_old = object_idx[object_cur];
5681 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5685 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5689 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5694 /* Do visual mode command if needed */
5695 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))
5697 if (direct_k_idx >= 0)
5722 /* Recall on screen */
5723 if (!visual_list && !visual_only && (grp_cnt > 0))
5725 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5733 /* Move the cursor */
5734 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5740 /* Free the "object_idx" array */
5741 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5746 * Display the features in a group.
5748 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5749 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5751 int lit_col[F_LIT_MAX], i;
5752 int f_idx_col = use_bigtile ? 62 : 64;
5754 /* Correct columns 1 and 4 */
5755 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5756 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5757 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5759 /* Display lines until done */
5760 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5763 FEAT_IDX f_idx = feat_idx[feat_top + i];
5764 feature_type *f_ptr = &f_info[f_idx];
5765 int row_i = row + i;
5767 /* Choose a color */
5768 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5770 /* Display the name */
5771 c_prt(attr, f_name + f_ptr->name, row_i, col);
5773 /* Hack -- visual_list mode */
5776 /* Display lighting level */
5777 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5779 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));
5781 if (current_world_ptr->wizard || visual_only)
5783 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5786 /* Display symbol */
5787 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);
5789 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5790 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5792 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5794 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5796 /* Mega-hack -- Use non-standard colour */
5797 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5799 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5803 /* Clear remaining lines */
5804 for (; i < per_page; i++)
5806 Term_erase(col, row + i, 255);
5812 * Interact with feature visuals.
5814 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5816 TERM_COLOR attr_old[F_LIT_MAX];
5817 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5818 SYMBOL_CODE char_old[F_LIT_MAX];
5819 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5822 Term_get_size(&wid, &hgt);
5824 /* Allocate the "feat_idx" array */
5826 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5832 FEAT_IDX grp_idx[100];
5833 TERM_COLOR attr_top = 0;
5834 bool visual_list = FALSE;
5836 TERM_LEN browser_rows = hgt - 8;
5837 if (direct_f_idx < 0)
5839 /* Check every group */
5840 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5842 /* Measure the label */
5843 len = strlen(feature_group_text[i]);
5845 /* Save the maximum length */
5846 if (len > max) max = len;
5848 /* See if any features are known */
5849 if (collect_features(feat_idx, 0x01))
5851 /* Build a list of groups with known features */
5852 grp_idx[grp_cnt++] = i;
5860 feature_type *f_ptr = &f_info[direct_f_idx];
5862 feat_idx[0] = direct_f_idx;
5865 /* Terminate the list */
5868 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5869 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5871 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5873 attr_old[i] = f_ptr->x_attr[i];
5874 char_old[i] = f_ptr->x_char[i];
5878 /* Terminate the list */
5879 grp_idx[grp_cnt] = -1;
5881 FEAT_IDX old_grp_cur = -1;
5882 FEAT_IDX grp_cur = 0;
5883 FEAT_IDX grp_top = 0;
5884 FEAT_IDX feat_cur = 0;
5885 FEAT_IDX feat_top = 0;
5886 TERM_LEN column = 0;
5889 TERM_COLOR *cur_attr_ptr;
5890 SYMBOL_CODE *cur_char_ptr;
5894 feature_type *f_ptr;
5900 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5901 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5902 prt(_("名前", "Name"), 4, max + 3);
5905 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5906 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5910 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5911 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5914 for (FEAT_IDX i = 0; i < 78; i++)
5916 Term_putch(i, 5, TERM_WHITE, '=');
5919 if (direct_f_idx < 0)
5921 for (FEAT_IDX i = 0; i < browser_rows; i++)
5923 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5930 if (direct_f_idx < 0)
5932 /* Scroll group list */
5933 if (grp_cur < grp_top) grp_top = grp_cur;
5934 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5936 /* Display a list of feature groups */
5937 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5939 if (old_grp_cur != grp_cur)
5941 old_grp_cur = grp_cur;
5943 /* Get a list of features in the current group */
5944 feat_cnt = collect_features(feat_idx, 0x00);
5947 /* Scroll feature list */
5948 while (feat_cur < feat_top)
5949 feat_top = MAX(0, feat_top - browser_rows / 2);
5950 while (feat_cur >= feat_top + browser_rows)
5951 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5956 /* Display a list of features in the current group */
5957 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5961 feat_top = feat_cur;
5963 /* Display a list of features in the current group */
5964 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5966 /* Display visual list below first object */
5967 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5971 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5972 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5973 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5976 /* Get the current feature */
5977 f_ptr = &f_info[feat_idx[feat_cur]];
5978 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5979 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5983 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5987 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5991 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5996 if (visual_list && ((ch == 'A') || (ch == 'a')))
5998 int prev_lighting_level = *lighting_level;
6002 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
6003 else (*lighting_level)--;
6007 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
6008 else (*lighting_level)++;
6011 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
6012 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6014 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
6015 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6020 else if ((ch == 'D') || (ch == 'd'))
6022 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
6023 byte prev_x_char = f_ptr->x_char[*lighting_level];
6025 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6029 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6030 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6032 if (prev_x_char != f_ptr->x_char[*lighting_level])
6033 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6035 else *need_redraw = TRUE;
6040 /* Do visual mode command if needed */
6041 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))
6045 /* Restore previous visual settings */
6047 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6049 f_ptr->x_attr[i] = attr_old[i];
6050 f_ptr->x_char[i] = char_old[i];
6057 if (direct_f_idx >= 0) flag = TRUE;
6058 else *lighting_level = F_LIT_STANDARD;
6061 /* Preserve current visual settings */
6064 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6066 attr_old[i] = f_ptr->x_attr[i];
6067 char_old[i] = f_ptr->x_char[i];
6069 *lighting_level = F_LIT_STANDARD;
6076 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6078 attr_idx_feat[i] = f_ptr->x_attr[i];
6079 char_idx_feat[i] = f_ptr->x_char[i];
6088 /* Allow TERM_DARK text */
6089 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6091 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6092 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6110 /* Move the cursor */
6111 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6117 /* Free the "feat_idx" array */
6118 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6123 * List wanted monsters
6124 * @param creature_ptr プレーヤーへの参照ポインタ
6127 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6129 /* Open a new file */
6131 GAME_TEXT file_name[1024];
6132 fff = my_fopen_temp(file_name, 1024);
6135 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6140 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
6141 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6143 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6144 fprintf(fff, "----------------------------------------------\n");
6146 bool listed = FALSE;
6147 for (int i = 0; i < MAX_BOUNTY; i++)
6149 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6151 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6158 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
6163 /* Display the file contents */
6164 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6169 * List virtues & status
6171 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6173 /* Open a new file */
6175 GAME_TEXT file_name[1024];
6176 fff = my_fopen_temp(file_name, 1024);
6179 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6184 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment(creature_ptr));
6185 dump_virtues(creature_ptr, fff);
6188 /* Display the file contents */
6189 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6196 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6198 /* Open a new file */
6200 GAME_TEXT file_name[1024];
6201 fff = my_fopen_temp(file_name, 1024);
6204 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6209 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6213 if (!d_info[i].maxdepth) continue;
6214 if (!max_dlv[i]) continue;
6215 if (d_info[i].final_guardian)
6217 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6219 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6221 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6226 /* Display the file contents */
6227 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6233 * List virtues & status
6236 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6238 /* Open a new file */
6240 GAME_TEXT file_name[1024];
6241 fff = my_fopen_temp(file_name, 1024);
6244 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6249 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6250 (2 * creature_ptr->hitdie +
6251 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6253 if (creature_ptr->knowledge & KNOW_HPRATE)
6254 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6255 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6257 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6258 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6260 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);
6261 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6264 dump_yourself(creature_ptr, fff);
6267 /* Display the file contents */
6268 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6274 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6275 * Print all active quests
6276 * @param creature_ptr プレーヤーへの参照ポインタ
6279 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6282 char rand_tmp_str[120] = "\0";
6283 GAME_TEXT name[MAX_NLEN];
6284 monster_race *r_ptr;
6285 int rand_level = 100;
6288 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6290 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6292 bool is_no_print = quest[i].status != QUEST_STATUS_TAKEN;
6293 is_no_print &= (quest[i].status != QUEST_STATUS_STAGE_COMPLETED) || (quest[i].type != QUEST_TYPE_TOWER);
6294 is_no_print &= quest[i].status == QUEST_STATUS_COMPLETED;
6298 /* Set the quest number temporary */
6299 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6301 /* Clear the text */
6302 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6303 quest_text_line = 0;
6305 creature_ptr->current_floor_ptr->inside_quest = i;
6307 /* Get the quest text */
6308 init_flags = INIT_SHOW_TEXT;
6310 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6312 /* Reset the old quest number */
6313 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6315 /* No info from "silent" quests */
6316 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6320 if (quest[i].type != QUEST_TYPE_RANDOM)
6322 char note[80] = "\0";
6324 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6326 switch (quest[i].type)
6328 case QUEST_TYPE_KILL_LEVEL:
6329 case QUEST_TYPE_KILL_ANY_LEVEL:
6330 r_ptr = &r_info[quest[i].r_idx];
6331 strcpy(name, r_name + r_ptr->name);
6332 if (quest[i].max_num > 1)
6335 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6336 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6339 sprintf(note, " - kill %d %s, have killed %d.",
6340 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6344 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6347 case QUEST_TYPE_FIND_ARTIFACT:
6350 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6352 object_type *q_ptr = &forge;
6353 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6354 object_prep(q_ptr, k_idx);
6355 q_ptr->name1 = quest[i].k_idx;
6356 q_ptr->ident = IDENT_STORE;
6357 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6359 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find out %s."), name);
6361 case QUEST_TYPE_FIND_EXIT:
6362 sprintf(note, _(" - 出口に到達する。", " - Reach to Exit."));
6365 case QUEST_TYPE_KILL_NUMBER:
6367 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6368 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6370 sprintf(note, " - Kill %d monsters, have killed %d.",
6371 (int)quest[i].max_num, (int)quest[i].cur_num);
6375 case QUEST_TYPE_KILL_ALL:
6376 case QUEST_TYPE_TOWER:
6377 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6382 /* Print the quest info */
6383 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6384 quest[i].name, (int)quest[i].level, note);
6386 fputs(tmp_str, fff);
6388 if (quest[i].status == QUEST_STATUS_COMPLETED)
6390 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6391 fputs(tmp_str, fff);
6396 while (quest_text[k][0] && k < 10)
6398 fprintf(fff, " %s\n", quest_text[k]);
6405 /* QUEST_TYPE_RANDOM */
6406 if (quest[i].level >= rand_level)
6410 rand_level = quest[i].level;
6412 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6414 /* Print the quest info */
6415 r_ptr = &r_info[quest[i].r_idx];
6416 strcpy(name, r_name + r_ptr->name);
6418 if (quest[i].max_num <= 1)
6420 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6421 quest[i].name, (int)quest[i].level, name);
6426 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6427 quest[i].name, (int)quest[i].level,
6428 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6432 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6433 quest[i].name, (int)quest[i].level,
6434 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6438 /* Print the current random quest */
6439 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6441 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6445 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6448 char playtime_str[16];
6449 quest_type* const q_ptr = &quest[q_idx];
6451 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6452 if (is_fixed_quest_idx(q_idx))
6454 /* Set the quest number temporary */
6455 IDX old_quest = floor_ptr->inside_quest;
6457 floor_ptr->inside_quest = q_idx;
6460 init_flags = INIT_NAME_ONLY;
6462 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6464 /* Reset the old quest number */
6465 floor_ptr->inside_quest = old_quest;
6467 /* No info from "silent" quests */
6468 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6471 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6472 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6474 if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6476 /* Print the quest info */
6478 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6479 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6480 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6481 fputs(tmp_str, fff);
6485 /* Print the quest info */
6486 if (q_ptr->complev == 0)
6489 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6490 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6491 r_name + r_info[q_ptr->r_idx].name,
6492 (int)q_ptr->level, playtime_str);
6493 fputs(tmp_str, fff);
6498 _(" %-35s (%3d階) - レベル%2d - %s\n",
6499 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6500 r_name + r_info[q_ptr->r_idx].name,
6504 fputs(tmp_str, fff);
6510 * Print all finished quests
6511 * @param creature_ptr プレーヤーへの参照ポインタ
6512 * @param fff セーブファイル (展開済?)
6513 * @param quest_num[] 受注したことのあるクエスト群
6516 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6518 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6519 QUEST_IDX total = 0;
6520 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6522 QUEST_IDX q_idx = quest_num[i];
6523 quest_type* const q_ptr = &quest[q_idx];
6525 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6531 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6536 * Print all failed quests
6537 * @param creature_ptr プレーヤーへの参照ポインタ
6538 * @param fff セーブファイル (展開済?)
6539 * @param quest_num[] 受注したことのあるクエスト群
6542 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6544 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6545 QUEST_IDX total = 0;
6546 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6548 QUEST_IDX q_idx = quest_num[i];
6549 quest_type* const q_ptr = &quest[q_idx];
6551 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6552 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6558 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6563 * Print all random quests
6565 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6567 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6568 GAME_TEXT tmp_str[120];
6569 QUEST_IDX total = 0;
6570 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6572 /* No info from "silent" quests */
6573 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6575 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6579 /* Print the quest info */
6580 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6581 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6582 fputs(tmp_str, fff);
6586 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6590 * Print quest status of all active quests
6591 * @param creature_ptr プレーヤーへの参照ポインタ
6594 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6596 /* Open a new file */
6598 GAME_TEXT file_name[1024];
6599 fff = my_fopen_temp(file_name, 1024);
6602 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6607 /* Allocate Memory */
6609 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6611 /* Sort by compete level */
6612 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6614 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6616 /* Dump Quest Information */
6617 do_cmd_knowledge_quests_current(creature_ptr, fff);
6619 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6621 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6622 if (current_world_ptr->wizard)
6625 do_cmd_knowledge_quests_wiz_random(fff);
6630 /* Display the file contents */
6631 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6635 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6641 * @param player_ptr プレーヤーへの参照ポインタ
6644 static void do_cmd_knowledge_home(player_type *player_ptr)
6646 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6648 /* Open a new file */
6650 GAME_TEXT file_name[1024];
6651 fff = my_fopen_temp(file_name, 1024);
6654 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6659 /* Print all homes in the different towns */
6661 st_ptr = &town_info[1].store[STORE_HOME];
6663 /* Home -- if anything there */
6664 if (st_ptr->stock_num)
6669 /* Header with name of the town */
6670 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6672 /* Dump all available items */
6673 concptr paren = ")";
6674 GAME_TEXT o_name[MAX_NLEN];
6675 for (int i = 0; i < st_ptr->stock_num; i++)
6678 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6679 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6680 if (strlen(o_name) <= 80 - 3)
6682 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6688 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6689 if (iskanji(*t)) { t++; n++; }
6690 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6692 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6693 fprintf(fff, " %.77s\n", o_name + n);
6696 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6697 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6701 /* Add an empty line */
6702 fprintf(fff, "\n\n");
6707 /* Display the file contents */
6708 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6714 * Check the status of "autopick"
6716 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6718 /* Open a new file */
6720 GAME_TEXT file_name[1024];
6721 fff = my_fopen_temp(file_name, 1024);
6724 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6731 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6735 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6736 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6739 for (int k = 0; k < max_autopick; k++)
6742 byte act = autopick_list[k].action;
6743 if (act & DONT_AUTOPICK)
6745 tmp = _("放置", "Leave");
6747 else if (act & DO_AUTODESTROY)
6749 tmp = _("破壊", "Destroy");
6751 else if (act & DO_AUTOPICK)
6753 tmp = _("拾う", "Pickup");
6757 tmp = _("確認", "Query");
6760 if (act & DO_DISPLAY)
6761 fprintf(fff, "%11s", format("[%s]", tmp));
6763 fprintf(fff, "%11s", format("(%s)", tmp));
6765 tmp = autopick_line_from_entry(&autopick_list[k]);
6766 fprintf(fff, " %s", tmp);
6773 /* Display the file contents */
6774 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6780 * Interact with "knowledge"
6782 void do_cmd_knowledge(player_type *creature_ptr)
6785 bool need_redraw = FALSE;
6787 /* File type is "TEXT" */
6788 FILE_TYPE(FILE_TYPE_TEXT);
6791 /* Interact until done */
6796 /* Ask for a choice */
6797 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6798 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6800 /* Give some choices */
6804 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6805 prt("(2) 既知のアイテム の一覧", 7, 5);
6806 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6807 prt("(4) 既知のモンスター の一覧", 9, 5);
6808 prt("(5) 倒した敵の数 の一覧", 10, 5);
6809 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6810 prt("(7) 現在のペット の一覧", 12, 5);
6811 prt("(8) 我が家のアイテム の一覧", 13, 5);
6812 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6813 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6817 prt("(a) 自分に関する情報 の一覧", 6, 5);
6818 prt("(b) 突然変異 の一覧", 7, 5);
6819 prt("(c) 武器の経験値 の一覧", 8, 5);
6820 prt("(d) 魔法の経験値 の一覧", 9, 5);
6821 prt("(e) 技能の経験値 の一覧", 10, 5);
6822 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6823 prt("(g) 入ったダンジョン の一覧", 12, 5);
6824 prt("(h) 実行中のクエスト の一覧", 13, 5);
6825 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6830 prt("(1) Display known artifacts", 6, 5);
6831 prt("(2) Display known objects", 7, 5);
6832 prt("(3) Display remaining uniques", 8, 5);
6833 prt("(4) Display known monster", 9, 5);
6834 prt("(5) Display kill count", 10, 5);
6835 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6836 prt("(7) Display current pets", 12, 5);
6837 prt("(8) Display home inventory", 13, 5);
6838 prt("(9) Display *identified* equip.", 14, 5);
6839 prt("(0) Display terrain symbols.", 15, 5);
6843 prt("(a) Display about yourself", 6, 5);
6844 prt("(b) Display mutations", 7, 5);
6845 prt("(c) Display weapon proficiency", 8, 5);
6846 prt("(d) Display spell proficiency", 9, 5);
6847 prt("(e) Display misc. proficiency", 10, 5);
6848 prt("(f) Display virtues", 11, 5);
6849 prt("(g) Display dungeons", 12, 5);
6850 prt("(h) Display current quests", 13, 5);
6851 prt("(i) Display auto pick/destroy", 14, 5);
6855 prt(_("-続く-", "-more-"), 17, 8);
6856 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6857 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6858 /*prt("-) 前ページ", 21, 60);*/
6859 prt(_("コマンド:", "Command: "), 20, 0);
6862 if (i == ESCAPE) break;
6865 case ' ': /* Page change */
6869 case '1': /* Artifacts */
6870 do_cmd_knowledge_artifacts(creature_ptr);
6872 case '2': /* Objects */
6873 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6875 case '3': /* Uniques */
6876 do_cmd_knowledge_uniques(creature_ptr);
6878 case '4': /* Monsters */
6879 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6881 case '5': /* Kill count */
6882 do_cmd_knowledge_kill_count(creature_ptr);
6884 case '6': /* wanted */
6885 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6887 case '7': /* Pets */
6888 do_cmd_knowledge_pets(creature_ptr);
6890 case '8': /* Home */
6891 do_cmd_knowledge_home(creature_ptr);
6893 case '9': /* Resist list */
6894 do_cmd_knowledge_inven(creature_ptr);
6896 case '0': /* Feature list */
6898 IDX lighting_level = F_LIT_STANDARD;
6899 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6903 case 'a': /* Max stat */
6904 do_cmd_knowledge_stat(creature_ptr);
6906 case 'b': /* Mutations */
6907 do_cmd_knowledge_mutations(creature_ptr);
6909 case 'c': /* weapon-exp */
6910 do_cmd_knowledge_weapon_exp(creature_ptr);
6912 case 'd': /* spell-exp */
6913 do_cmd_knowledge_spell_exp(creature_ptr);
6915 case 'e': /* skill-exp */
6916 do_cmd_knowledge_skill_exp(creature_ptr);
6918 case 'f': /* Virtues */
6919 do_cmd_knowledge_virtues(creature_ptr);
6921 case 'g': /* Dungeon */
6922 do_cmd_knowledge_dungeon(creature_ptr);
6924 case 'h': /* Quests */
6925 do_cmd_knowledge_quests(creature_ptr);
6927 case 'i': /* Autopick */
6928 do_cmd_knowledge_autopick(creature_ptr);
6930 default: /* Unknown option */
6938 if (need_redraw) do_cmd_redraw(creature_ptr);
6943 * Check on the status of an active quest
6944 * @param creature_ptr プレーヤーへの参照ポインタ
6947 void do_cmd_checkquest(player_type *creature_ptr)
6949 /* File type is "TEXT" */
6950 FILE_TYPE(FILE_TYPE_TEXT);
6954 do_cmd_knowledge_quests(creature_ptr);
6960 * Display the time and date
6961 * @param creature_ptr プレーヤーへの参照ポインタ
6964 void do_cmd_time(player_type *creature_ptr)
6967 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6970 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6973 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6974 else strcpy(day_buf, "*****");
6976 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6977 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6981 if (!randint0(10) || creature_ptr->image)
6983 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6987 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6990 /* Open this file */
6992 fff = my_fopen(buf, "rt");
6996 /* Find this time */
6997 int full = hour * 100 + min;
7001 while (!my_fgets(fff, buf, sizeof(buf)))
7003 /* Ignore comments */
7004 if (!buf[0] || (buf[0] == '#')) continue;
7006 /* Ignore invalid lines */
7007 if (buf[1] != ':') continue;
7009 /* Process 'Start' */
7012 /* Extract the starting time */
7013 start = atoi(buf + 2);
7015 /* Assume valid for an hour */
7023 /* Extract the ending time */
7024 end = atoi(buf + 2);
7028 /* Ignore incorrect range */
7029 if ((start > full) || (full > end)) continue;
7031 /* Process 'Description' */
7036 /* Apply the randomizer */
7037 if (!randint0(num)) strcpy(desc, buf + 2);