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);
1385 * @brief マクロ情報をprefファイルに保存する /
1386 * @param fname ファイル名
1389 static errr macro_dump(concptr fname)
1391 static concptr mark = "Macro Dump";
1393 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1395 /* File type is "TEXT" */
1396 FILE_TYPE(FILE_TYPE_TEXT);
1398 /* Append to the file */
1399 if (!open_auto_dump(buf, mark)) return -1;
1402 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1405 for (int i = 0; i < macro__num; i++)
1407 /* Extract the action */
1408 ascii_to_text(buf, macro__act[i]);
1410 /* Dump the macro */
1411 auto_dump_printf("A:%s\n", buf);
1413 /* Extract the action */
1414 ascii_to_text(buf, macro__pat[i]);
1416 /* Dump normal macros */
1417 auto_dump_printf("P:%s\n", buf);
1420 auto_dump_printf("\n");
1429 * @brief マクロのトリガーキーを取得する /
1430 * Hack -- ask for a "trigger" (see below)
1431 * @param buf キー表記を保管するバッファ
1435 * Note the complex use of the "inkey()" function from "util.c".
1437 * Note that both "flush()" calls are extremely important.
1440 static void do_cmd_macro_aux(char *buf)
1444 /* Do not process macros */
1450 /* Read the pattern */
1457 /* Do not process macros */
1460 /* Do not wait for keys */
1463 /* Attempt to read a key */
1472 /* Convert the trigger */
1474 ascii_to_text(tmp, buf);
1476 /* Hack -- display the trigger */
1477 Term_addstr(-1, TERM_WHITE, tmp);
1482 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1483 * Hack -- ask for a keymap "trigger" (see below)
1484 * @param buf キー表記を取得するバッファ
1488 * Note that both "flush()" calls are extremely important. This may
1489 * no longer be true, since "util.c" is much simpler now.
1492 static void do_cmd_macro_aux_keymap(char *buf)
1502 /* Convert to ascii */
1503 ascii_to_text(tmp, buf);
1505 /* Hack -- display the trigger */
1506 Term_addstr(-1, TERM_WHITE, tmp);
1513 * @brief キーマップをprefファイルにダンプする /
1514 * Hack -- append all keymaps to the given file
1515 * @param fname ファイルネーム
1519 static errr keymap_dump(concptr fname)
1521 static concptr mark = "Keymap Dump";
1528 if (rogue_like_commands)
1530 mode = KEYMAP_MODE_ROGUE;
1536 mode = KEYMAP_MODE_ORIG;
1539 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1541 /* File type is "TEXT" */
1542 FILE_TYPE(FILE_TYPE_TEXT);
1544 /* Append to the file */
1545 if (!open_auto_dump(buf, mark)) return -1;
1548 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1551 for (int i = 0; i < 256; i++)
1555 /* Loop up the keymap */
1556 act = keymap_act[mode][i];
1558 /* Skip empty keymaps */
1561 /* Encode the key */
1564 ascii_to_text(key, buf);
1566 /* Encode the action */
1567 ascii_to_text(buf, act);
1569 /* Dump the macro */
1570 auto_dump_printf("A:%s\n", buf);
1571 auto_dump_printf("C:%d:%s\n", mode, key);
1580 * @brief マクロを設定するコマンドのメインルーチン /
1581 * Interact with "macros"
1585 * Note that the macro "action" must be defined before the trigger.
1587 * Could use some helpful instructions on this page.
1590 void do_cmd_macros(player_type *creature_ptr)
1598 if (rogue_like_commands)
1600 mode = KEYMAP_MODE_ROGUE;
1606 mode = KEYMAP_MODE_ORIG;
1609 /* File type is "TEXT" */
1610 FILE_TYPE(FILE_TYPE_TEXT);
1614 /* Process requests until done */
1618 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1620 /* Describe that action */
1621 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1623 /* Analyze the current action */
1624 ascii_to_text(buf, macro__buf);
1626 /* Display the current action */
1631 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1632 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1633 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1634 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1635 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1636 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1637 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1638 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1639 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1640 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1643 prt(_("コマンド: ", "Command: "), 16, 0);
1648 if (i == ESCAPE) break;
1650 /* Load a 'macro' file */
1656 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1659 prt(_("ファイル: ", "File: "), 18, 0);
1661 /* Default filename */
1662 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1664 /* Ask for a file */
1665 if (!askfor(tmp, 80)) continue;
1667 /* Process the given filename */
1668 err = process_pref_file(creature_ptr, tmp);
1671 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1676 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1680 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1688 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1691 prt(_("ファイル: ", "File: "), 18, 0);
1693 /* Default filename */
1694 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1696 /* Ask for a file */
1697 if (!askfor(tmp, 80)) continue;
1699 /* Dump the macros */
1700 (void)macro_dump(tmp);
1703 msg_print(_("マクロを追加しました。", "Appended macros."));
1712 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1716 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1718 /* Get a macro trigger */
1719 do_cmd_macro_aux(buf);
1721 /* Acquire action */
1722 k = macro_find_exact(buf);
1728 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1734 /* Obtain the action */
1735 strcpy(macro__buf, macro__act[k]);
1737 /* Analyze the current action */
1738 ascii_to_text(buf, macro__buf);
1740 /* Display the current action */
1744 msg_print(_("マクロを確認しました。", "Found a macro."));
1748 /* Create a macro */
1752 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1755 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1757 /* Get a macro trigger */
1758 do_cmd_macro_aux(buf);
1762 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1763 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1766 prt(_("マクロ行動: ", "Action: "), 20, 0);
1768 /* Convert to text */
1769 ascii_to_text(tmp, macro__buf);
1771 /* Get an encoded action */
1772 if (askfor(tmp, 80))
1774 /* Convert to ascii */
1775 text_to_ascii(macro__buf, tmp);
1777 /* Link the macro */
1778 macro_add(buf, macro__buf);
1781 msg_print(_("マクロを追加しました。", "Added a macro."));
1785 /* Remove a macro */
1789 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1792 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1794 /* Get a macro trigger */
1795 do_cmd_macro_aux(buf);
1797 /* Link the macro */
1798 macro_add(buf, buf);
1801 msg_print(_("マクロを削除しました。", "Removed a macro."));
1808 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1811 prt(_("ファイル: ", "File: "), 18, 0);
1813 /* Default filename */
1814 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1816 /* Ask for a file */
1817 if (!askfor(tmp, 80)) continue;
1819 /* Dump the macros */
1820 (void)keymap_dump(tmp);
1823 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1826 /* Query a keymap */
1832 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1835 prt(_("押すキー: ", "Keypress: "), 18, 0);
1837 /* Get a keymap trigger */
1838 do_cmd_macro_aux_keymap(buf);
1840 /* Look up the keymap */
1841 act = keymap_act[mode][(byte)(buf[0])];
1847 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1853 /* Obtain the action */
1854 strcpy(macro__buf, act);
1856 /* Analyze the current action */
1857 ascii_to_text(buf, macro__buf);
1859 /* Display the current action */
1863 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1867 /* Create a keymap */
1871 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1874 prt(_("押すキー: ", "Keypress: "), 18, 0);
1876 /* Get a keymap trigger */
1877 do_cmd_macro_aux_keymap(buf);
1881 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1882 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1885 prt(_("行動: ", "Action: "), 20, 0);
1887 /* Convert to text */
1888 ascii_to_text(tmp, macro__buf);
1890 /* Get an encoded action */
1891 if (askfor(tmp, 80))
1893 /* Convert to ascii */
1894 text_to_ascii(macro__buf, tmp);
1896 /* Free old keymap */
1897 string_free(keymap_act[mode][(byte)(buf[0])]);
1899 /* Make new keymap */
1900 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1903 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1907 /* Remove a keymap */
1911 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1914 prt(_("押すキー: ", "Keypress: "), 18, 0);
1916 /* Get a keymap trigger */
1917 do_cmd_macro_aux_keymap(buf);
1919 /* Free old keymap */
1920 string_free(keymap_act[mode][(byte)(buf[0])]);
1922 /* Make new keymap */
1923 keymap_act[mode][(byte)(buf[0])] = NULL;
1926 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1929 /* Enter a new action */
1933 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1937 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1938 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1941 prt(_("マクロ行動: ", "Action: "), 20, 0);
1943 /* Hack -- limit the value */
1946 /* Get an encoded action */
1947 if (!askfor(buf, 80)) continue;
1949 /* Extract an action */
1950 text_to_ascii(macro__buf, buf);
1966 * @brief キャラクタ色の明暗表現
1968 static concptr lighting_level_str[F_LIT_MAX] =
1983 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1984 * @param i 指定対象となるキャラクタコード
1985 * @param num 指定されたビジュアルIDを返す参照ポインタ
1986 * @param max ビジュアルIDの最大数
1987 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1989 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1996 sprintf(str, "%d", *num);
1998 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
2001 tmp = (IDX)strtol(str, NULL, 0);
2002 if (tmp >= 0 && tmp < max)
2005 else if (isupper(i))
2006 *num = (*num + max - 1) % max;
2008 *num = (*num + 1) % max;
2014 * @brief キャラクタの変更メニュー表示
2015 * @param choice_msg 選択メッセージ
2018 static void print_visuals_menu(concptr choice_msg)
2020 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2022 /* Give some choices */
2023 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2024 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2025 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2026 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2027 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2028 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2029 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2030 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2031 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2032 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2033 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2036 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2041 * Interact with "visuals"
2043 void do_cmd_visuals(player_type *creature_ptr)
2048 bool need_redraw = FALSE;
2049 concptr empty_symbol = "<< ? >>";
2051 if (use_bigtile) empty_symbol = "<< ?? >>";
2053 /* File type is "TEXT" */
2054 FILE_TYPE(FILE_TYPE_TEXT);
2057 /* Interact until done */
2062 /* Ask for a choice */
2063 print_visuals_menu(NULL);
2068 if (i == ESCAPE) break;
2072 /* Load a 'pref' file */
2075 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2078 prt(_("ファイル: ", "File: "), 17, 0);
2080 /* Default filename */
2081 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2084 if (!askfor(tmp, 70)) continue;
2086 /* Process the given filename */
2087 (void)process_pref_file(creature_ptr, tmp);
2092 /* Dump monster attr/chars */
2095 static concptr mark = "Monster attr/chars";
2098 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2101 prt(_("ファイル: ", "File: "), 17, 0);
2103 /* Default filename */
2104 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2106 /* Get a filename */
2107 if (!askfor(tmp, 70)) continue;
2108 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2110 /* Append to the file */
2111 if (!open_auto_dump(buf, mark)) continue;
2114 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2117 for (i = 0; i < max_r_idx; i++)
2119 monster_race *r_ptr = &r_info[i];
2121 /* Skip non-entries */
2122 if (!r_ptr->name) continue;
2124 /* Dump a comment */
2125 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2127 /* Dump the monster attr/char info */
2128 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2129 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2135 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2140 /* Dump object attr/chars */
2143 static concptr mark = "Object attr/chars";
2144 KIND_OBJECT_IDX k_idx;
2147 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2150 prt(_("ファイル: ", "File: "), 17, 0);
2152 /* Default filename */
2153 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2155 /* Get a filename */
2156 if (!askfor(tmp, 70)) continue;
2157 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2159 /* Append to the file */
2160 if (!open_auto_dump(buf, mark)) continue;
2163 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2166 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2168 GAME_TEXT o_name[MAX_NLEN];
2169 object_kind *k_ptr = &k_info[k_idx];
2171 /* Skip non-entries */
2172 if (!k_ptr->name) continue;
2177 strip_name(o_name, k_idx);
2183 /* Prepare dummy object */
2184 object_prep(&forge, k_idx);
2186 /* Get un-shuffled flavor name */
2187 object_desc(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
2190 /* Dump a comment */
2191 auto_dump_printf("# %s\n", o_name);
2193 /* Dump the object attr/char info */
2194 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2195 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2201 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2206 /* Dump feature attr/chars */
2209 static concptr mark = "Feature attr/chars";
2212 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2215 prt(_("ファイル: ", "File: "), 17, 0);
2217 /* Default filename */
2218 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2220 /* Get a filename */
2221 if (!askfor(tmp, 70)) continue;
2222 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2224 /* Append to the file */
2225 if (!open_auto_dump(buf, mark)) continue;
2228 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2231 for (i = 0; i < max_f_idx; i++)
2233 feature_type *f_ptr = &f_info[i];
2235 /* Skip non-entries */
2236 if (!f_ptr->name) continue;
2238 /* Skip mimiccing features */
2239 if (f_ptr->mimic != i) continue;
2241 /* Dump a comment */
2242 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2244 /* Dump the feature attr/char info */
2245 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2246 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2247 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2248 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2254 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2259 /* Modify monster attr/chars (numeric operation) */
2262 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2263 static MONRACE_IDX r = 0;
2265 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2267 /* Hack -- query until done */
2270 monster_race *r_ptr = &r_info[r];
2274 TERM_COLOR da = r_ptr->d_attr;
2275 byte dc = r_ptr->d_char;
2276 TERM_COLOR ca = r_ptr->x_attr;
2277 byte cc = r_ptr->x_char;
2279 /* Label the object */
2280 Term_putstr(5, 17, -1, TERM_WHITE,
2281 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2283 /* Label the Default values */
2284 Term_putstr(10, 19, -1, TERM_WHITE,
2285 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2287 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2288 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2290 /* Label the Current values */
2291 Term_putstr(10, 20, -1, TERM_WHITE,
2292 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2294 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2295 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2298 Term_putstr(0, 22, -1, TERM_WHITE,
2299 _("コマンド (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): "));
2304 if (i == ESCAPE) break;
2306 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2307 else if (isupper(i)) c = 'a' + i - 'A';
2317 if (!cmd_visuals_aux(i, &r, max_r_idx))
2322 } while (!r_info[r].name);
2326 t = (int)r_ptr->x_attr;
2327 (void)cmd_visuals_aux(i, &t, 256);
2328 r_ptr->x_attr = (byte)t;
2332 t = (int)r_ptr->x_char;
2333 (void)cmd_visuals_aux(i, &t, 256);
2334 r_ptr->x_char = (byte)t;
2338 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2340 print_visuals_menu(choice_msg);
2348 /* Modify object attr/chars (numeric operation) */
2351 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2353 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2355 /* Hack -- query until done */
2358 object_kind *k_ptr = &k_info[k];
2362 TERM_COLOR da = k_ptr->d_attr;
2363 SYMBOL_CODE dc = k_ptr->d_char;
2364 TERM_COLOR ca = k_ptr->x_attr;
2365 SYMBOL_CODE cc = k_ptr->x_char;
2367 /* Label the object */
2368 Term_putstr(5, 17, -1, TERM_WHITE,
2369 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2370 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2372 /* Label the Default values */
2373 Term_putstr(10, 19, -1, TERM_WHITE,
2374 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2376 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2377 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2379 /* Label the Current values */
2380 Term_putstr(10, 20, -1, TERM_WHITE,
2381 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2383 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2384 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2387 Term_putstr(0, 22, -1, TERM_WHITE,
2388 _("コマンド (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): "));
2393 if (i == ESCAPE) break;
2395 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2396 else if (isupper(i)) c = 'a' + i - 'A';
2406 if (!cmd_visuals_aux(i, &k, max_k_idx))
2411 } while (!k_info[k].name);
2415 t = (int)k_ptr->x_attr;
2416 (void)cmd_visuals_aux(i, &t, 256);
2417 k_ptr->x_attr = (byte)t;
2421 t = (int)k_ptr->x_char;
2422 (void)cmd_visuals_aux(i, &t, 256);
2423 k_ptr->x_char = (byte)t;
2427 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2429 print_visuals_menu(choice_msg);
2437 /* Modify feature attr/chars (numeric operation) */
2440 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2442 static IDX lighting_level = F_LIT_STANDARD;
2443 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2445 /* Hack -- query until done */
2448 feature_type *f_ptr = &f_info[f];
2452 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2453 byte dc = f_ptr->d_char[lighting_level];
2454 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2455 byte cc = f_ptr->x_char[lighting_level];
2457 /* Label the object */
2459 Term_putstr(5, 17, -1, TERM_WHITE,
2460 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2461 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2463 /* Label the Default values */
2464 Term_putstr(10, 19, -1, TERM_WHITE,
2465 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2467 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2468 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2470 /* Label the Current values */
2472 Term_putstr(10, 20, -1, TERM_WHITE,
2473 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2475 Term_putstr(10, 20, -1, TERM_WHITE,
2476 format("Current attr/char = %3d / %3d", ca, cc));
2479 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2480 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2484 Term_putstr(0, 22, -1, TERM_WHITE,
2485 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2487 Term_putstr(0, 22, -1, TERM_WHITE,
2488 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2494 if (i == ESCAPE) break;
2496 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2497 else if (isupper(i)) c = 'a' + i - 'A';
2507 if (!cmd_visuals_aux(i, &f, max_f_idx))
2512 } while (!f_info[f].name || (f_info[f].mimic != f));
2516 t = (int)f_ptr->x_attr[lighting_level];
2517 (void)cmd_visuals_aux(i, &t, 256);
2518 f_ptr->x_attr[lighting_level] = (byte)t;
2522 t = (int)f_ptr->x_char[lighting_level];
2523 (void)cmd_visuals_aux(i, &t, 256);
2524 f_ptr->x_char[lighting_level] = (byte)t;
2528 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2531 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2535 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2537 print_visuals_menu(choice_msg);
2545 /* Modify monster attr/chars (visual mode) */
2547 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2550 /* Modify object attr/chars (visual mode) */
2552 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2555 /* Modify feature attr/chars (visual mode) */
2558 IDX lighting_level = F_LIT_STANDARD;
2559 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2567 reset_visuals(creature_ptr);
2569 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2573 /* Unknown option */
2584 if (need_redraw) do_cmd_redraw(creature_ptr);
2589 * Interact with "colors"
2591 void do_cmd_colors(player_type *creature_ptr)
2597 /* File type is "TEXT" */
2598 FILE_TYPE(FILE_TYPE_TEXT);
2602 /* Interact until done */
2607 /* Ask for a choice */
2608 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2610 /* Give some choices */
2611 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2612 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2613 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2616 prt(_("コマンド: ", "Command: "), 8, 0);
2620 if (i == ESCAPE) break;
2622 /* Load a 'pref' file */
2626 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2629 prt(_("ファイル: ", "File: "), 10, 0);
2632 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2635 if (!askfor(tmp, 70)) continue;
2637 /* Process the given filename */
2638 (void)process_pref_file(creature_ptr, tmp);
2640 /* Mega-Hack -- react to changes */
2641 Term_xtra(TERM_XTRA_REACT, 0);
2643 /* Mega-Hack -- redraw */
2650 static concptr mark = "Colors";
2653 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2656 prt(_("ファイル: ", "File: "), 10, 0);
2658 /* Default filename */
2659 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2661 /* Get a filename */
2662 if (!askfor(tmp, 70)) continue;
2663 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2665 /* Append to the file */
2666 if (!open_auto_dump(buf, mark)) continue;
2669 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2672 for (i = 0; i < 256; i++)
2674 int kv = angband_color_table[i][0];
2675 int rv = angband_color_table[i][1];
2676 int gv = angband_color_table[i][2];
2677 int bv = angband_color_table[i][3];
2679 concptr name = _("未知", "unknown");
2681 /* Skip non-entries */
2682 if (!kv && !rv && !gv && !bv) continue;
2684 /* Extract the color name */
2685 if (i < 16) name = color_names[i];
2687 /* Dump a comment */
2688 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2690 /* Dump the monster attr/char info */
2691 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2698 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2707 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2709 /* Hack -- query until done */
2716 /* Exhibit the normal colors */
2717 for (j = 0; j < 16; j++)
2719 /* Exhibit this color */
2720 Term_putstr(j * 4, 20, -1, a, "###");
2722 /* Exhibit all colors */
2723 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2726 /* Describe the color */
2727 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2729 /* Describe the color */
2730 Term_putstr(5, 10, -1, TERM_WHITE,
2731 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2733 /* Label the Current values */
2734 Term_putstr(5, 12, -1, TERM_WHITE,
2735 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2736 angband_color_table[a][0],
2737 angband_color_table[a][1],
2738 angband_color_table[a][2],
2739 angband_color_table[a][3]));
2742 Term_putstr(0, 14, -1, TERM_WHITE,
2743 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2748 if (i == ESCAPE) break;
2751 if (i == 'n') a = (byte)(a + 1);
2752 if (i == 'N') a = (byte)(a - 1);
2753 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2754 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2755 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2756 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2757 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2758 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2759 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2760 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2762 /* Hack -- react to changes */
2763 Term_xtra(TERM_XTRA_REACT, 0);
2765 /* Hack -- redraw */
2770 /* Unknown option */
2784 * Note something in the message recall
2786 void do_cmd_note(void)
2794 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2796 /* Ignore empty notes */
2797 if (!buf[0] || (buf[0] == ' ')) return;
2799 /* Add the note to the message recall */
2800 msg_format(_("メモ: %s", "Note: %s"), buf);
2805 * Mention the current version
2807 void do_cmd_version(void)
2809 #if FAKE_VER_EXTRA > 0
2810 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2811 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2813 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2814 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2820 * Array of feeling strings
2822 static concptr do_cmd_feeling_text[11] =
2824 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2825 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2826 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2827 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2828 _("とても悪い予感がする...", "You have a very bad feeling..."),
2829 _("悪い予感がする...", "You have a bad feeling..."),
2830 _("何か緊張する。", "You feel nervous."),
2831 _("少し不運な気がする...", "You feel your luck is turning..."),
2832 _("この場所は好きになれない。", "You don't like the look of this place."),
2833 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2834 _("なんて退屈なところだ...", "What a boring place...")
2837 static concptr do_cmd_feeling_text_combat[11] =
2839 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2840 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2841 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2842 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2843 _("とても悪い予感がする...", "You have a very bad feeling..."),
2844 _("悪い予感がする...", "You have a bad feeling..."),
2845 _("何か緊張する。", "You feel nervous."),
2846 _("少し不運な気がする...", "You feel your luck is turning..."),
2847 _("この場所は好きになれない。", "You don't like the look of this place."),
2848 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2849 _("なんて退屈なところだ...", "What a boring place...")
2852 static concptr do_cmd_feeling_text_lucky[11] =
2854 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2855 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2856 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2857 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2858 _("とても良い感じがする...", "You have a very good feeling..."),
2859 _("良い感じがする...", "You have a good feeling..."),
2860 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2861 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2862 _("見た感じ悪くはない...", "You like the look of this place..."),
2863 _("全然駄目ということはないが...", "This level can't be all bad..."),
2864 _("なんて退屈なところだ...", "What a boring place...")
2869 * Note that "feeling" is set to zero unless some time has passed.
2870 * Note that this is done when the level is GENERATED, not entered.
2872 void do_cmd_feeling(player_type *creature_ptr)
2874 if (creature_ptr->wild_mode) return;
2876 /* No useful feeling in quests */
2877 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2879 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2883 /* No useful feeling in town */
2884 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2886 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2888 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2892 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2896 /* No useful feeling in the wilderness */
2897 if (!creature_ptr->current_floor_ptr->dun_level)
2899 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2903 /* Display the feeling */
2904 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2905 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2906 else if (creature_ptr->pseikaku == SEIKAKU_COMBAT ||
2907 creature_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
2908 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2910 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2915 * Description of each monster group.
2917 static concptr monster_group_text[] =
2920 "ユニーク", /* "Uniques" */
2921 "乗馬可能なモンスター", /* "Riding" */
2922 "賞金首", /* "Wanted */
2923 "アンバーの王族", /* "Ambertite" */
2952 /* "古代ドラゴン/ワイアーム", */
3013 /* "Ancient Dragon/Wyrm", */
3022 "Multi-Headed Reptile",
3027 "Reptile/Amphibian",
3028 "Spider/Scorpion/Tick",
3030 /* "Major Demon", */
3047 * Symbols of monsters in each group. Note the "Uniques" group
3048 * is handled differently.
3050 static concptr monster_group_char[] =
3107 "!$&()+./=>?[\\]`{|~",
3117 * todo 引数と戻り値について追記求む
3118 * Build a list of monster indexes in the given group.
3120 * mode & 0x01 : check for non-empty group
3121 * mode & 0x02 : visual operation only
3123 * @param creature_ptr プレーヤーへの参照ポインタ
3124 * @param grp_cur ???
3125 * @param mon_idx[] ???
3127 * @return The number of monsters in the group
3129 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3131 /* Get a list of x_char in this group */
3132 concptr group_char = monster_group_char[grp_cur];
3134 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3135 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3136 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3137 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3139 /* Check every race */
3141 for (IDX i = 0; i < max_r_idx; i++)
3143 /* Access the race */
3144 monster_race *r_ptr = &r_info[i];
3146 /* Skip empty race */
3147 if (!r_ptr->name) continue;
3149 /* Require known monsters */
3150 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3154 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3157 else if (grp_riding)
3159 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3162 else if (grp_wanted)
3164 bool wanted = FALSE;
3166 for (j = 0; j < MAX_BOUNTY; j++)
3168 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3169 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3175 if (!wanted) continue;
3178 else if (grp_amberite)
3180 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3185 /* Check for race in the group */
3186 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3190 mon_idx[mon_cnt++] = i;
3192 /* XXX Hack -- Just checking for non-empty group */
3193 if (mode & 0x01) break;
3196 /* Terminate the list */
3197 mon_idx[mon_cnt] = -1;
3200 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3202 /* Return the number of races */
3208 * Description of each monster group.
3210 static concptr object_group_text[] =
3213 "キノコ", /* "Mushrooms" */
3214 "薬", /* "Potions" */
3215 "油つぼ", /* "Flasks" */
3216 "巻物", /* "Scrolls" */
3218 "アミュレット", /* "Amulets" */
3219 "笛", /* "Whistle" */
3220 "光源", /* "Lanterns" */
3221 "魔法棒", /* "Wands" */
3224 "カード", /* "Cards" */
3235 "刀剣類", /* "Swords" */
3236 "鈍器", /* "Blunt Weapons" */
3237 "長柄武器", /* "Polearms" */
3238 "採掘道具", /* "Diggers" */
3239 "飛び道具", /* "Bows" */
3243 "軽装鎧", /* "Soft Armor" */
3244 "重装鎧", /* "Hard Armor" */
3245 "ドラゴン鎧", /* "Dragon Armor" */
3246 "盾", /* "Shields" */
3247 "クローク", /* "Cloaks" */
3248 "籠手", /* "Gloves" */
3249 "ヘルメット", /* "Helms" */
3251 "ブーツ", /* "Boots" */
3304 * TVALs of items in each group
3306 static byte object_group_tval[] =
3347 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3355 * Build a list of object indexes in the given group. Return the number
3356 * of objects in the group.
3358 * mode & 0x01 : check for non-empty group
3359 * mode & 0x02 : visual operation only
3361 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3363 KIND_OBJECT_IDX i, object_cnt = 0;
3366 /* Get a list of x_char in this group */
3367 byte group_tval = object_group_tval[grp_cur];
3369 /* Check every object */
3370 for (i = 0; i < max_k_idx; i++)
3372 /* Access the object */
3373 object_kind *k_ptr = &k_info[i];
3375 /* Skip empty objects */
3376 if (!k_ptr->name) continue;
3380 if (!current_world_ptr->wizard)
3382 /* Skip non-flavoured objects */
3383 if (!k_ptr->flavor) continue;
3385 /* Require objects ever seen */
3386 if (!k_ptr->aware) continue;
3389 /* Skip items with no distribution (special artifacts) */
3390 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3394 /* Check for objects in the group */
3395 if (TV_LIFE_BOOK == group_tval)
3397 /* Hack -- All spell books */
3398 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3400 /* Add the object */
3401 object_idx[object_cnt++] = i;
3405 else if (k_ptr->tval == group_tval)
3407 /* Add the object */
3408 object_idx[object_cnt++] = i;
3412 /* XXX Hack -- Just checking for non-empty group */
3413 if (mode & 0x01) break;
3416 /* Terminate the list */
3417 object_idx[object_cnt] = -1;
3419 /* Return the number of objects */
3425 * Description of each feature group.
3427 static concptr feature_group_text[] =
3435 * Build a list of feature indexes in the given group. Return the number
3436 * of features in the group.
3438 * mode & 0x01 : check for non-empty group
3440 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3442 /* Check every feature */
3443 FEAT_IDX feat_cnt = 0;
3444 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3446 feature_type *f_ptr = &f_info[i];
3448 /* Skip empty index */
3449 if (!f_ptr->name) continue;
3451 /* Skip mimiccing features */
3452 if (f_ptr->mimic != i) continue;
3455 feat_idx[feat_cnt++] = i;
3457 /* XXX Hack -- Just checking for non-empty group */
3458 if (mode & 0x01) break;
3461 /* Terminate the list */
3462 feat_idx[feat_cnt] = -1;
3464 /* Return the number of races */
3470 * Hack -- load a screen dump from a file
3472 void do_cmd_load_screen(void)
3476 SYMBOL_CODE c = ' ';
3482 Term_get_size(&wid, &hgt);
3483 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3485 /* Append to the file */
3486 fff = my_fopen(buf, "r");
3490 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3498 /* Load the screen */
3499 for (y = 0; okay; y++)
3501 /* Get a line of data including control code */
3502 if (!fgets(buf, 1024, fff)) okay = FALSE;
3504 /* Get the blank line */
3505 if (buf[0] == '\n' || buf[0] == '\0') break;
3507 /* Ignore too large screen image */
3508 if (y >= hgt) continue;
3511 for (x = 0; x < wid - 1; x++)
3514 if (buf[x] == '\n' || buf[x] == '\0') break;
3516 /* Put the attr/char */
3517 Term_draw(x, y, TERM_WHITE, buf[x]);
3521 /* Dump the screen */
3522 for (y = 0; okay; y++)
3524 /* Get a line of data including control code */
3525 if (!fgets(buf, 1024, fff)) okay = FALSE;
3527 /* Get the blank line */
3528 if (buf[0] == '\n' || buf[0] == '\0') break;
3530 /* Ignore too large screen image */
3531 if (y >= hgt) continue;
3534 for (x = 0; x < wid - 1; x++)
3537 if (buf[x] == '\n' || buf[x] == '\0') break;
3539 /* Get the attr/char */
3540 (void)(Term_what(x, y, &a, &c));
3542 /* Look up the attr */
3543 for (int i = 0; i < 16; i++)
3545 /* Use attr matches */
3546 if (hack[i] == buf[x]) a = (byte_hack)i;
3549 /* Put the attr/char */
3550 Term_draw(x, y, a, c);
3556 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3564 // todo なぜこんな中途半端なところに? defineも…
3565 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3566 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3568 #define IM_FLAG_STR _("*", "* ")
3569 #define HAS_FLAG_STR _("+", "+ ")
3570 #define NO_FLAG_STR _("・", ". ")
3572 #define print_im_or_res_flag(IM, RES) \
3574 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3575 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3578 #define print_flag(TR) \
3580 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3584 /* XTRA HACK RESLIST */
3585 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)
3587 GAME_TEXT o_name[MAX_NLEN];
3588 BIT_FLAGS flgs[TR_FLAG_SIZE];
3590 if (!o_ptr->k_idx) return;
3591 if (o_ptr->tval != tval) return;
3593 /* Identified items only */
3594 if (!object_is_known(o_ptr)) return;
3597 * HACK:Ring of Lordly protection and Dragon equipment
3598 * have random resistances.
3600 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3601 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3602 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3603 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3604 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3605 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3606 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3607 || object_is_artifact(o_ptr);
3608 if (!is_special_item_type)
3614 object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
3616 while (o_name[i] && (i < 26))
3619 if (iskanji(o_name[i])) i++;
3628 o_name[i] = ' '; i++;
3634 fprintf(fff, "%s %s", where, o_name);
3636 if (!(o_ptr->ident & (IDENT_MENTAL)))
3638 fputs(_("-------不明--------------- -------不明---------\n",
3639 "-------unknown------------ -------unknown------\n"), fff);
3643 object_flags_known(o_ptr, flgs);
3645 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3646 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3647 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3648 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3649 print_flag(TR_RES_POIS);
3650 print_flag(TR_RES_LITE);
3651 print_flag(TR_RES_DARK);
3652 print_flag(TR_RES_SHARDS);
3653 print_flag(TR_RES_SOUND);
3654 print_flag(TR_RES_NETHER);
3655 print_flag(TR_RES_NEXUS);
3656 print_flag(TR_RES_CHAOS);
3657 print_flag(TR_RES_DISEN);
3661 print_flag(TR_RES_BLIND);
3662 print_flag(TR_RES_FEAR);
3663 print_flag(TR_RES_CONF);
3664 print_flag(TR_FREE_ACT);
3665 print_flag(TR_SEE_INVIS);
3666 print_flag(TR_HOLD_EXP);
3667 print_flag(TR_TELEPATHY);
3668 print_flag(TR_SLOW_DIGEST);
3669 print_flag(TR_REGEN);
3670 print_flag(TR_LEVITATION);
3679 fprintf(fff, "%s\n", inven_res_label);
3684 * Display *ID* ed weapons/armors's resistances
3686 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3689 GAME_TEXT file_name[1024];
3691 OBJECT_TYPE_VALUE tval;
3697 /* Open a new file */
3698 fff = my_fopen_temp(file_name, 1024);
3701 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3706 fprintf(fff, "%s\n", inven_res_label);
3708 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3712 for (; j < 9; j++) fputc('\n', fff);
3714 fprintf(fff, "%s\n", inven_res_label);
3717 strcpy(where, _("装", "E "));
3718 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3720 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3723 strcpy(where, _("持", "I "));
3724 for (i = 0; i < INVEN_PACK; i++)
3726 do_cmd_knowledge_inven_aux(creature_ptr, fff, &creature_ptr->inventory_list[i], &j, tval, where);
3729 st_ptr = &town_info[1].store[STORE_HOME];
3730 strcpy(where, _("家", "H "));
3731 for (i = 0; i < st_ptr->stock_num; i++)
3733 do_cmd_knowledge_inven_aux(creature_ptr, fff, &st_ptr->stock[i], &j, tval, where);
3739 /* Display the file contents */
3740 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3745 void do_cmd_save_screen_html_aux(char *filename, int message)
3753 concptr html_head[] = {
3754 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3758 concptr html_foot[] = {
3760 "</body>\n</html>\n",
3765 Term_get_size(&wid, &hgt);
3767 /* File type is "TEXT" */
3768 FILE_TYPE(FILE_TYPE_TEXT);
3770 /* Append to the file */
3772 fff = my_fopen(filename, "w");
3778 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3785 if (message) screen_save();
3787 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3789 tmpfff = my_fopen(buf, "r");
3792 for (int i = 0; html_head[i]; i++)
3793 fputs(html_head[i], fff);
3797 bool is_first_line = TRUE;
3798 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3802 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3803 is_first_line = FALSE;
3807 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3809 fprintf(fff, "%s\n", buf);
3814 /* Dump the screen */
3815 for (TERM_LEN y = 0; y < hgt; y++)
3818 if (y != 0) fprintf(fff, "\n");
3821 TERM_COLOR a = 0, old_a = 0;
3823 for (TERM_LEN x = 0; x < wid - 1; x++)
3826 /* Get the attr/char */
3827 (void)(Term_what(x, y, &a, &c));
3831 case '&': cc = "&"; break;
3832 case '<': cc = "<"; break;
3833 case '>': cc = ">"; break;
3835 case 0x1f: c = '.'; break;
3836 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3841 if ((y == 0 && x == 0) || a != old_a)
3843 int rv = angband_color_table[a][1];
3844 int gv = angband_color_table[a][2];
3845 int bv = angband_color_table[a][3];
3846 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3847 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3852 fprintf(fff, "%s", cc);
3854 fprintf(fff, "%c", c);
3858 fprintf(fff, "</font>");
3862 for (int i = 0; html_foot[i]; i++)
3863 fputs(html_foot[i], fff);
3868 bool is_first_line = TRUE;
3869 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3873 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3874 is_first_line = FALSE;
3878 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3880 fprintf(fff, "%s\n", buf);
3893 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3902 * Hack -- save a screen dump to a file
3904 static void do_cmd_save_screen_html(void)
3906 char buf[1024], tmp[256] = "screen.html";
3908 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3910 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3914 do_cmd_save_screen_html_aux(buf, 1);
3919 * Redefinable "save_screen" action
3921 void(*screendump_aux)(void) = NULL;
3925 * Save a screen dump to a file
3926 * @param creature_ptr プレーヤーへの参照ポインタ
3929 void do_cmd_save_screen(player_type *creature_ptr)
3931 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3932 bool html_dump = FALSE;
3936 if (c == 'Y' || c == 'y')
3938 else if (c == 'H' || c == 'h')
3951 Term_get_size(&wid, &hgt);
3953 bool old_use_graphics = use_graphics;
3954 if (old_use_graphics)
3956 use_graphics = FALSE;
3957 reset_visuals(creature_ptr);
3958 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3959 handle_stuff(creature_ptr);
3964 do_cmd_save_screen_html();
3965 do_cmd_redraw(creature_ptr);
3968 /* Do we use a special screendump function ? */
3969 else if (screendump_aux)
3971 /* Dump the screen to a graphics file */
3972 (*screendump_aux)();
3974 else /* Dump the screen as text */
3978 SYMBOL_CODE c = ' ';
3981 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3983 /* File type is "TEXT" */
3984 FILE_TYPE(FILE_TYPE_TEXT);
3986 /* Append to the file */
3987 fff = my_fopen(buf, "w");
3991 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
3998 /* Dump the screen */
3999 for (y = 0; y < hgt; y++)
4002 for (x = 0; x < wid - 1; x++)
4004 /* Get the attr/char */
4005 (void)(Term_what(x, y, &a, &c));
4015 fprintf(fff, "%s\n", buf);
4022 /* Dump the screen */
4023 for (y = 0; y < hgt; y++)
4026 for (x = 0; x < wid - 1; x++)
4028 /* Get the attr/char */
4029 (void)(Term_what(x, y, &a, &c));
4032 buf[x] = hack[a & 0x0F];
4039 fprintf(fff, "%s\n", buf);
4046 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4051 if (!old_use_graphics) return;
4053 use_graphics = TRUE;
4054 reset_visuals(creature_ptr);
4055 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4056 handle_stuff(creature_ptr);
4061 * todo okay = 既知のアーティファクト? と思われるが確証がない
4062 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4063 * Check the status of "artifacts"
4064 * @param player_ptr プレーヤーへの参照ポインタ
4067 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4069 /* Open a new file */
4071 GAME_TEXT file_name[1024];
4072 fff = my_fopen_temp(file_name, 1024);
4075 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4080 /* Allocate the "who" array */
4082 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4084 /* Allocate the "okay" array */
4086 C_MAKE(okay, max_a_idx, bool);
4088 /* Scan the artifacts */
4089 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4091 artifact_type *a_ptr = &a_info[k];
4096 /* Skip "empty" artifacts */
4097 if (!a_ptr->name) continue;
4099 /* Skip "uncreated" artifacts */
4100 if (!a_ptr->cur_num) continue;
4106 /* Check the dungeon */
4107 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4109 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4111 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4113 OBJECT_IDX this_o_idx, next_o_idx = 0;
4115 /* Scan all objects in the grid */
4116 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4119 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4120 next_o_idx = o_ptr->next_o_idx;
4122 /* Ignore non-artifacts */
4123 if (!object_is_fixed_artifact(o_ptr)) continue;
4125 /* Ignore known items */
4126 if (object_is_known(o_ptr)) continue;
4128 /* Note the artifact */
4129 okay[o_ptr->name1] = FALSE;
4134 /* Check the player_ptr->inventory_list and equipment */
4135 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4137 object_type *o_ptr = &player_ptr->inventory_list[i];
4139 /* Ignore non-objects */
4140 if (!o_ptr->k_idx) continue;
4142 /* Ignore non-artifacts */
4143 if (!object_is_fixed_artifact(o_ptr)) continue;
4145 /* Ignore known items */
4146 if (object_is_known(o_ptr)) continue;
4148 /* Note the artifact */
4149 okay[o_ptr->name1] = FALSE;
4153 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4155 if (okay[k]) who[n++] = k;
4159 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4161 /* Scan the artifacts */
4162 for (ARTIFACT_IDX k = 0; k < n; k++)
4164 artifact_type *a_ptr = &a_info[who[k]];
4165 GAME_TEXT base_name[MAX_NLEN];
4166 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4168 /* Obtain the base object type */
4169 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4178 /* Create fake object */
4179 object_prep(q_ptr, z);
4181 /* Make it an artifact */
4182 q_ptr->name1 = (byte)who[k];
4184 /* Display as if known */
4185 q_ptr->ident |= IDENT_STORE;
4187 /* Describe the artifact */
4188 object_desc(player_ptr, base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4191 /* Hack -- Build the artifact name */
4192 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4195 /* Free the "who" array */
4196 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4198 /* Free the "okay" array */
4199 C_KILL(okay, max_a_idx, bool);
4202 /* Display the file contents */
4203 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4209 * Display known uniques
4210 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4212 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4219 GAME_TEXT file_name[1024];
4222 int n_alive_surface = 0;
4223 int n_alive_over100 = 0;
4224 int n_alive_total = 0;
4227 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4229 /* Open a new file */
4230 fff = my_fopen_temp(file_name, 1024);
4234 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4239 /* Allocate the "who" array */
4240 C_MAKE(who, max_r_idx, MONRACE_IDX);
4242 /* Scan the monsters */
4244 for (IDX i = 1; i < max_r_idx; i++)
4246 monster_race *r_ptr = &r_info[i];
4249 if (!r_ptr->name) continue;
4251 /* Require unique monsters */
4252 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4254 /* Only display "known" uniques */
4255 if (!cheat_know && !r_ptr->r_sights) continue;
4257 /* Only print rarity <= 100 uniques */
4258 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4260 /* Only "alive" uniques */
4261 if (r_ptr->max_num == 0) continue;
4265 lev = (r_ptr->level - 1) / 10;
4269 if (max_lev < lev) max_lev = lev;
4271 else n_alive_over100++;
4273 else n_alive_surface++;
4275 /* Collect "appropriate" monsters */
4279 /* Sort the array by dungeon depth of monsters */
4280 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4282 if (n_alive_surface)
4284 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4285 n_alive_total += n_alive_surface;
4288 for (IDX i = 0; i <= max_lev; i++)
4290 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4291 n_alive_total += n_alive[i];
4294 if (n_alive_over100)
4296 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4297 n_alive_total += n_alive_over100;
4302 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4303 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4307 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4310 /* Scan the monster races */
4311 for (int k = 0; k < n; k++)
4313 monster_race *r_ptr = &r_info[who[k]];
4314 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4317 /* Free the "who" array */
4318 C_KILL(who, max_r_idx, s16b);
4321 /* Display the file contents */
4322 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4328 * Display weapon-exp
4330 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4332 /* Open a new file */
4334 GAME_TEXT file_name[1024];
4335 fff = my_fopen_temp(file_name, 1024);
4338 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4343 for (int i = 0; i < 5; i++)
4345 for (int num = 0; num < 64; num++)
4349 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4351 object_kind *k_ptr = &k_info[j];
4353 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4354 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4356 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4358 fprintf(fff, "%-25s ", tmp);
4359 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4360 else fprintf(fff, " ");
4361 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4362 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4371 /* Display the file contents */
4372 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4378 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4382 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4384 /* Open a new file */
4386 GAME_TEXT file_name[1024];
4387 fff = my_fopen_temp(file_name, 1024);
4390 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4395 if (creature_ptr->realm1 != REALM_NONE)
4397 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4398 for (SPELL_IDX i = 0; i < 32; i++)
4400 const magic_type *s_ptr;
4401 if (!is_magic(creature_ptr->realm1))
4403 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4407 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4410 if (s_ptr->slevel >= 99) continue;
4411 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4412 int exp_level = spell_exp_level(spell_exp);
4413 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4414 if (creature_ptr->realm1 == REALM_HISSATSU)
4415 fprintf(fff, "[--]");
4418 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4419 else fprintf(fff, " ");
4420 fprintf(fff, "%s", exp_level_str[exp_level]);
4423 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4428 if (creature_ptr->realm2 != REALM_NONE)
4430 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4431 for (SPELL_IDX i = 0; i < 32; i++)
4433 const magic_type *s_ptr;
4434 if (!is_magic(creature_ptr->realm1))
4436 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4440 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4443 if (s_ptr->slevel >= 99) continue;
4445 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4446 int exp_level = spell_exp_level(spell_exp);
4447 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4448 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4449 else fprintf(fff, " ");
4450 fprintf(fff, "%s", exp_level_str[exp_level]);
4451 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4458 /* Display the file contents */
4459 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4465 * @brief スキル情報を表示するコマンドのメインルーチン /
4469 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4471 char skill_name[GINOU_TEMPMAX][20] =
4473 _("マーシャルアーツ", "Martial Arts "),
4474 _("二刀流 ", "Dual Wielding "),
4475 _("乗馬 ", "Riding "),
4479 /* Open a new file */
4481 char file_name[1024];
4482 fff = my_fopen_temp(file_name, 1024);
4485 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4490 for (int i = 0; i < GINOU_TEMPMAX; i++)
4492 int skill_exp = creature_ptr->skill_exp[i];
4493 fprintf(fff, "%-20s ", skill_name[i]);
4494 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4495 else fprintf(fff, " ");
4496 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4497 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4503 /* Display the file contents */
4504 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4510 * @brief 現在のペットを表示するコマンドのメインルーチン /
4511 * Display current pets
4512 * @param creature_ptr プレーヤーへの参照ポインタ
4515 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4517 /* Open a new file */
4518 GAME_TEXT file_name[1024];
4520 fff = my_fopen_temp(file_name, 1024);
4523 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4528 /* Process the monsters (backwards) */
4529 monster_type *m_ptr;
4530 GAME_TEXT pet_name[MAX_NLEN];
4532 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4534 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4536 /* Ignore "dead" monsters */
4537 if (!monster_is_valid(m_ptr)) continue;
4539 /* Calculate "upkeep" for pets */
4540 if (!is_pet(m_ptr)) continue;
4543 monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4544 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4547 int show_upkeep = calculate_upkeep(creature_ptr);
4549 fprintf(fff, "----------------------------------------------\n");
4551 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4553 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4555 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4559 /* Display the file contents */
4560 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4566 * @brief 現在のペットを表示するコマンドのメインルーチン /
4567 * @param creature_ptr プレーヤーへの参照ポインタ
4570 * @note the player ghosts are ignored.
4572 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4574 /* Open a new file */
4576 GAME_TEXT file_name[1024];
4577 fff = my_fopen_temp(file_name, 1024);
4580 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4585 /* Allocate the "who" array */
4587 C_MAKE(who, max_r_idx, MONRACE_IDX);
4591 /* Monsters slain */
4592 for (int kk = 1; kk < max_r_idx; kk++)
4594 monster_race *r_ptr = &r_info[kk];
4596 if (r_ptr->flags1 & (RF1_UNIQUE))
4598 bool dead = (r_ptr->max_num == 0);
4607 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4609 if (this_monster > 0)
4611 total += this_monster;
4617 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4620 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4622 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4628 /* Scan the monsters */
4630 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4632 monster_race *r_ptr = &r_info[i];
4634 /* Use that monster */
4635 if (r_ptr->name) who[n++] = i;
4638 /* Sort the array by dungeon depth of monsters */
4640 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4642 /* Scan the monster races */
4643 for (int k = 0; k < n; k++)
4645 monster_race *r_ptr = &r_info[who[k]];
4647 if (r_ptr->flags1 & (RF1_UNIQUE))
4649 bool dead = (r_ptr->max_num == 0);
4653 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4660 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4662 if (this_monster <= 0) continue;
4665 /* p,tは人と数える by ita */
4666 if (my_strchr("pt", r_ptr->d_char))
4667 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4669 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4671 if (this_monster < 2)
4673 if (my_strstr(r_name + r_ptr->name, "coins"))
4675 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4679 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4685 strcpy(ToPlural, (r_name + r_ptr->name));
4686 plural_aux(ToPlural);
4687 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4690 total += this_monster;
4693 fprintf(fff, "----------------------------------------------\n");
4695 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4697 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4700 /* Free the "who" array */
4701 C_KILL(who, max_r_idx, s16b);
4704 /* Display the file contents */
4705 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4711 * @brief モンスター情報リスト中のグループを表示する /
4712 * Display the object groups.
4716 * @param per_page リストの表示行
4717 * @param grp_idx グループのID配列
4718 * @param group_text グループ名の文字列配列
4719 * @param grp_cur 現在の選択ID
4720 * @param grp_top 現在の選択リスト最上部ID
4723 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)
4725 /* Display lines until done */
4726 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4728 /* Get the group index */
4729 int grp = grp_idx[grp_top + i];
4731 /* Choose a color */
4732 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4734 /* Erase the entire line */
4735 Term_erase(col, row + i, wid);
4737 /* Display the group label */
4738 c_put_str(attr, group_text[grp], row + i, col);
4744 * Move the cursor in a browser window
4746 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4747 IDX *list_cur, int list_cnt)
4752 IDX list = *list_cur;
4754 /* Extract direction */
4757 /* Hack -- scroll up full screen */
4762 /* Hack -- scroll down full screen */
4767 d = get_keymap_dir(ch);
4772 /* Diagonals - hack */
4773 if ((ddx[d] > 0) && ddy[d])
4778 Term_get_size(&wid, &hgt);
4780 browser_rows = hgt - 8;
4782 /* Browse group list */
4787 /* Move up or down */
4788 grp += ddy[d] * (browser_rows - 1);
4791 if (grp >= grp_cnt) grp = grp_cnt - 1;
4792 if (grp < 0) grp = 0;
4793 if (grp != old_grp) list = 0;
4796 /* Browse sub-list list */
4799 /* Move up or down */
4800 list += ddy[d] * browser_rows;
4803 if (list >= list_cnt) list = list_cnt - 1;
4804 if (list < 0) list = 0;
4816 if (col < 0) col = 0;
4817 if (col > 1) col = 1;
4824 /* Browse group list */
4829 /* Move up or down */
4833 if (grp >= grp_cnt) grp = grp_cnt - 1;
4834 if (grp < 0) grp = 0;
4835 if (grp != old_grp) list = 0;
4838 /* Browse sub-list list */
4841 /* Move up or down */
4842 list += (IDX)ddy[d];
4845 if (list >= list_cnt) list = list_cnt - 1;
4846 if (list < 0) list = 0;
4857 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4859 /* Clear the display lines */
4860 for (int i = 0; i < height; i++)
4862 Term_erase(col, row + i, width);
4865 /* Bigtile mode uses double width */
4866 if (use_bigtile) width /= 2;
4868 /* Display lines until done */
4869 for (int i = 0; i < height; i++)
4871 /* Display columns until done */
4872 for (int j = 0; j < width; j++)
4874 TERM_LEN x = col + j;
4875 TERM_LEN y = row + i;
4877 /* Bigtile mode uses double width */
4878 if (use_bigtile) x += j;
4880 TERM_COLOR ia = attr_top + i;
4881 SYMBOL_CODE ic = char_left + j;
4883 /* Ignore illegal characters */
4884 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4885 (!use_graphics && ic > 0x7f))
4891 /* Force correct code for both ASCII character and tile */
4892 if (c & 0x80) a |= 0x80;
4894 /* Display symbol */
4895 Term_queue_bigchar(x, y, a, c, 0, 0);
4902 * Place the cursor at the collect position for visual mode
4904 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4906 int i = (a & 0x7f) - attr_top;
4907 int j = c - char_left;
4909 TERM_LEN x = col + j;
4910 TERM_LEN y = row + i;
4912 /* Bigtile mode uses double width */
4913 if (use_bigtile) x += j;
4915 /* Place the cursor */
4921 * Do visual mode command -- Change symbols
4923 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4924 int height, int width,
4925 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4926 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4928 static TERM_COLOR attr_old = 0;
4929 static SYMBOL_CODE char_old = 0;
4934 if (*visual_list_ptr)
4937 *cur_attr_ptr = attr_old;
4938 *cur_char_ptr = char_old;
4939 *visual_list_ptr = FALSE;
4947 if (*visual_list_ptr)
4950 *visual_list_ptr = FALSE;
4951 *need_redraw = TRUE;
4959 if (!*visual_list_ptr)
4961 *visual_list_ptr = TRUE;
4963 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4964 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4966 attr_old = *cur_attr_ptr;
4967 char_old = *cur_char_ptr;
4978 /* Set the visual */
4979 attr_idx = *cur_attr_ptr;
4980 char_idx = *cur_char_ptr;
4982 /* Hack -- for feature lighting */
4983 for (i = 0; i < F_LIT_MAX; i++)
4985 attr_idx_feat[i] = 0;
4986 char_idx_feat[i] = 0;
4993 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
4996 *cur_attr_ptr = attr_idx;
4997 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4998 if (!*visual_list_ptr) *need_redraw = TRUE;
5004 *cur_char_ptr = char_idx;
5005 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5006 if (!*visual_list_ptr) *need_redraw = TRUE;
5012 if (*visual_list_ptr)
5015 int d = get_keymap_dir(ch);
5016 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5017 SYMBOL_CODE c = *cur_char_ptr;
5019 if (use_bigtile) eff_width = width / 2;
5020 else eff_width = width;
5022 /* Restrict direction */
5023 if ((a == 0) && (ddy[d] < 0)) d = 0;
5024 if ((c == 0) && (ddx[d] < 0)) d = 0;
5025 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5026 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5028 a += (TERM_COLOR)ddy[d];
5029 c += (SYMBOL_CODE)ddx[d];
5031 /* Force correct code for both ASCII character and tile */
5032 if (c & 0x80) a |= 0x80;
5034 /* Set the visual */
5039 /* Move the frame */
5040 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5041 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5042 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5043 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5049 /* Visual mode command is not used */
5055 * Display the monsters in a group.
5057 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5058 int mon_cur, int mon_top, bool visual_only)
5060 /* Display lines until done */
5062 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5066 /* Get the race index */
5067 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5069 /* Access the race */
5070 monster_race *r_ptr = &r_info[r_idx];
5072 /* Choose a color */
5073 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5075 /* Display the name */
5076 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5078 /* Hack -- visual_list mode */
5081 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5084 if (current_world_ptr->wizard || visual_only)
5086 c_prt(attr, format("%d", r_idx), row + i, 62);
5089 /* Erase chars before overwritten by the race letter */
5090 Term_erase(69, row + i, 255);
5092 /* Display symbol */
5093 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5098 if (!(r_ptr->flags1 & RF1_UNIQUE))
5099 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5101 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5102 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5106 /* Clear remaining lines */
5107 for (; i < per_page; i++)
5109 Term_erase(col, row + i, 255);
5115 * todo 引数の詳細について加筆求む
5116 * Display known monsters.
5117 * @param creature_ptr プレーヤーへの参照ポインタ
5118 * @param need_redraw 画面の再描画が必要な時TRUE
5119 * @param visual_only ???
5120 * @param direct_r_idx モンスターID
5123 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5126 Term_get_size(&wid, &hgt);
5128 /* Allocate the "mon_idx" array */
5130 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5136 bool visual_list = FALSE;
5137 TERM_COLOR attr_top = 0;
5140 int browser_rows = hgt - 8;
5141 if (direct_r_idx < 0)
5143 mode = visual_only ? 0x03 : 0x01;
5145 /* Check every group */
5147 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5149 /* Measure the label */
5150 len = strlen(monster_group_text[i]);
5152 /* Save the maximum length */
5153 if (len > max) max = len;
5155 /* See if any monsters are known */
5156 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5158 /* Build a list of groups with known monsters */
5159 grp_idx[grp_cnt++] = i;
5167 mon_idx[0] = direct_r_idx;
5170 /* Terminate the list */
5173 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5174 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5177 /* Terminate the list */
5178 grp_idx[grp_cnt] = -1;
5180 mode = visual_only ? 0x02 : 0x00;
5181 IDX old_grp_cur = -1;
5194 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5195 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5196 prt(_("名前", "Name"), 4, max + 3);
5197 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5198 prt(_("文字", "Sym"), 4, 67);
5199 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5201 for (IDX i = 0; i < 78; i++)
5203 Term_putch(i, 5, TERM_WHITE, '=');
5206 if (direct_r_idx < 0)
5208 for (IDX i = 0; i < browser_rows; i++)
5210 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5217 if (direct_r_idx < 0)
5219 /* Scroll group list */
5220 if (grp_cur < grp_top) grp_top = grp_cur;
5221 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5223 /* Display a list of monster groups */
5224 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5226 if (old_grp_cur != grp_cur)
5228 old_grp_cur = grp_cur;
5230 /* Get a list of monsters in the current group */
5231 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5234 /* Scroll monster list */
5235 while (mon_cur < mon_top)
5236 mon_top = MAX(0, mon_top - browser_rows / 2);
5237 while (mon_cur >= mon_top + browser_rows)
5238 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5243 /* Display a list of monsters in the current group */
5244 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5250 /* Display a monster name */
5251 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5253 /* Display visual list below first monster */
5254 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5258 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5259 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5260 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5261 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5264 /* Get the current monster */
5265 monster_race *r_ptr;
5266 r_ptr = &r_info[mon_idx[mon_cur]];
5270 /* Mega Hack -- track this monster race */
5271 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5272 handle_stuff(creature_ptr);
5277 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5281 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5285 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5290 /* Do visual mode command if needed */
5291 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))
5293 if (direct_r_idx >= 0)
5319 /* Recall on screen */
5320 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5322 screen_roff(creature_ptr, mon_idx[mon_cur], 0);
5334 /* Move the cursor */
5335 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5342 /* Free the "mon_idx" array */
5343 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5348 * Display the objects in a group.
5350 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5351 int object_cur, int object_top, bool visual_only)
5353 /* Display lines until done */
5355 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5357 GAME_TEXT o_name[MAX_NLEN];
5360 object_kind *flavor_k_ptr;
5362 /* Get the object index */
5363 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5365 /* Access the object */
5366 object_kind *k_ptr = &k_info[k_idx];
5368 /* Choose a color */
5369 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5370 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5372 if (!visual_only && k_ptr->flavor)
5374 /* Appearance of this object is shuffled */
5375 flavor_k_ptr = &k_info[k_ptr->flavor];
5379 /* Appearance of this object is very normal */
5380 flavor_k_ptr = k_ptr;
5383 attr = ((i + object_top == object_cur) ? cursor : attr);
5385 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5388 strip_name(o_name, k_idx);
5393 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5396 /* Display the name */
5397 c_prt(attr, o_name, row + i, col);
5399 /* Hack -- visual_list mode */
5402 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);
5405 if (current_world_ptr->wizard || visual_only)
5407 c_prt(attr, format("%d", k_idx), row + i, 70);
5410 a = flavor_k_ptr->x_attr;
5411 c = flavor_k_ptr->x_char;
5413 /* Display symbol */
5414 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5417 /* Clear remaining lines */
5418 for (; i < per_page; i++)
5420 Term_erase(col, row + i, 255);
5426 * Describe fake object
5428 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5431 object_type object_type_body;
5432 o_ptr = &object_type_body;
5434 object_prep(o_ptr, k_idx);
5436 /* It's fully know */
5437 o_ptr->ident |= IDENT_KNOWN;
5438 handle_stuff(creature_ptr);
5440 if (screen_object(creature_ptr, o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5442 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5448 * Display known objects
5450 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5452 IDX object_old, object_top;
5455 OBJECT_IDX *object_idx;
5457 bool visual_list = FALSE;
5458 TERM_COLOR attr_top = 0;
5463 Term_get_size(&wid, &hgt);
5465 int browser_rows = hgt - 8;
5467 /* Allocate the "object_idx" array */
5468 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5473 if (direct_k_idx < 0)
5475 mode = visual_only ? 0x03 : 0x01;
5477 /* Check every group */
5478 for (IDX i = 0; object_group_text[i] != NULL; i++)
5480 /* Measure the label */
5481 len = strlen(object_group_text[i]);
5483 /* Save the maximum length */
5484 if (len > max) max = len;
5486 /* See if any monsters are known */
5487 if (collect_objects(i, object_idx, mode))
5489 /* Build a list of groups with known monsters */
5490 grp_idx[grp_cnt++] = i;
5499 object_kind *k_ptr = &k_info[direct_k_idx];
5500 object_kind *flavor_k_ptr;
5502 if (!visual_only && k_ptr->flavor)
5504 /* Appearance of this object is shuffled */
5505 flavor_k_ptr = &k_info[k_ptr->flavor];
5509 /* Appearance of this object is very normal */
5510 flavor_k_ptr = k_ptr;
5513 object_idx[0] = direct_k_idx;
5514 object_old = direct_k_idx;
5517 /* Terminate the list */
5520 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5521 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5524 /* Terminate the list */
5525 grp_idx[grp_cnt] = -1;
5527 mode = visual_only ? 0x02 : 0x00;
5528 IDX old_grp_cur = -1;
5531 IDX object_cur = object_top = 0;
5537 object_kind *k_ptr, *flavor_k_ptr;
5544 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5545 if (direct_k_idx < 0) prt("グループ", 4, 0);
5546 prt("名前", 4, max + 3);
5547 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5550 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5551 if (direct_k_idx < 0) prt("Group", 4, 0);
5552 prt("Name", 4, max + 3);
5553 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5557 for (IDX i = 0; i < 78; i++)
5559 Term_putch(i, 5, TERM_WHITE, '=');
5562 if (direct_k_idx < 0)
5564 for (IDX i = 0; i < browser_rows; i++)
5566 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5573 if (direct_k_idx < 0)
5575 /* Scroll group list */
5576 if (grp_cur < grp_top) grp_top = grp_cur;
5577 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5579 /* Display a list of object groups */
5580 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5582 if (old_grp_cur != grp_cur)
5584 old_grp_cur = grp_cur;
5586 /* Get a list of objects in the current group */
5587 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5590 /* Scroll object list */
5591 while (object_cur < object_top)
5592 object_top = MAX(0, object_top - browser_rows / 2);
5593 while (object_cur >= object_top + browser_rows)
5594 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5599 /* Display a list of objects in the current group */
5600 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5604 object_top = object_cur;
5606 /* Display a list of objects in the current group */
5607 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5609 /* Display visual list below first object */
5610 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5613 /* Get the current object */
5614 k_ptr = &k_info[object_idx[object_cur]];
5616 if (!visual_only && k_ptr->flavor)
5618 /* Appearance of this object is shuffled */
5619 flavor_k_ptr = &k_info[k_ptr->flavor];
5623 /* Appearance of this object is very normal */
5624 flavor_k_ptr = k_ptr;
5629 prt(format("<方向>%s%s%s, ESC",
5630 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5631 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5632 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5635 prt(format("<dir>%s%s%s, ESC",
5636 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5637 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5638 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5644 /* Mega Hack -- track this object */
5645 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5647 /* The "current" object changed */
5648 if (object_old != object_idx[object_cur])
5650 handle_stuff(creature_ptr);
5652 /* Remember the "current" object */
5653 object_old = object_idx[object_cur];
5659 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5663 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5667 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5672 /* Do visual mode command if needed */
5673 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))
5675 if (direct_k_idx >= 0)
5700 /* Recall on screen */
5701 if (!visual_list && !visual_only && (grp_cnt > 0))
5703 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5711 /* Move the cursor */
5712 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5718 /* Free the "object_idx" array */
5719 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5724 * Display the features in a group.
5726 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5727 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5729 int lit_col[F_LIT_MAX], i;
5730 int f_idx_col = use_bigtile ? 62 : 64;
5732 /* Correct columns 1 and 4 */
5733 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5734 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5735 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5737 /* Display lines until done */
5738 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5741 FEAT_IDX f_idx = feat_idx[feat_top + i];
5742 feature_type *f_ptr = &f_info[f_idx];
5743 int row_i = row + i;
5745 /* Choose a color */
5746 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5748 /* Display the name */
5749 c_prt(attr, f_name + f_ptr->name, row_i, col);
5751 /* Hack -- visual_list mode */
5754 /* Display lighting level */
5755 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5757 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));
5759 if (current_world_ptr->wizard || visual_only)
5761 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5764 /* Display symbol */
5765 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);
5767 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5768 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5770 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5772 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5774 /* Mega-hack -- Use non-standard colour */
5775 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5777 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5781 /* Clear remaining lines */
5782 for (; i < per_page; i++)
5784 Term_erase(col, row + i, 255);
5790 * Interact with feature visuals.
5792 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5794 TERM_COLOR attr_old[F_LIT_MAX];
5795 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5796 SYMBOL_CODE char_old[F_LIT_MAX];
5797 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5800 Term_get_size(&wid, &hgt);
5802 /* Allocate the "feat_idx" array */
5804 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5810 FEAT_IDX grp_idx[100];
5811 TERM_COLOR attr_top = 0;
5812 bool visual_list = FALSE;
5814 TERM_LEN browser_rows = hgt - 8;
5815 if (direct_f_idx < 0)
5817 /* Check every group */
5818 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5820 /* Measure the label */
5821 len = strlen(feature_group_text[i]);
5823 /* Save the maximum length */
5824 if (len > max) max = len;
5826 /* See if any features are known */
5827 if (collect_features(feat_idx, 0x01))
5829 /* Build a list of groups with known features */
5830 grp_idx[grp_cnt++] = i;
5838 feature_type *f_ptr = &f_info[direct_f_idx];
5840 feat_idx[0] = direct_f_idx;
5843 /* Terminate the list */
5846 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5847 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5849 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5851 attr_old[i] = f_ptr->x_attr[i];
5852 char_old[i] = f_ptr->x_char[i];
5856 /* Terminate the list */
5857 grp_idx[grp_cnt] = -1;
5859 FEAT_IDX old_grp_cur = -1;
5860 FEAT_IDX grp_cur = 0;
5861 FEAT_IDX grp_top = 0;
5862 FEAT_IDX feat_cur = 0;
5863 FEAT_IDX feat_top = 0;
5864 TERM_LEN column = 0;
5867 TERM_COLOR *cur_attr_ptr;
5868 SYMBOL_CODE *cur_char_ptr;
5872 feature_type *f_ptr;
5878 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5879 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5880 prt(_("名前", "Name"), 4, max + 3);
5883 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5884 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5888 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5889 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5892 for (FEAT_IDX i = 0; i < 78; i++)
5894 Term_putch(i, 5, TERM_WHITE, '=');
5897 if (direct_f_idx < 0)
5899 for (FEAT_IDX i = 0; i < browser_rows; i++)
5901 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5908 if (direct_f_idx < 0)
5910 /* Scroll group list */
5911 if (grp_cur < grp_top) grp_top = grp_cur;
5912 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5914 /* Display a list of feature groups */
5915 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5917 if (old_grp_cur != grp_cur)
5919 old_grp_cur = grp_cur;
5921 /* Get a list of features in the current group */
5922 feat_cnt = collect_features(feat_idx, 0x00);
5925 /* Scroll feature list */
5926 while (feat_cur < feat_top)
5927 feat_top = MAX(0, feat_top - browser_rows / 2);
5928 while (feat_cur >= feat_top + browser_rows)
5929 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5934 /* Display a list of features in the current group */
5935 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5939 feat_top = feat_cur;
5941 /* Display a list of features in the current group */
5942 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5944 /* Display visual list below first object */
5945 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5949 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5950 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5951 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5954 /* Get the current feature */
5955 f_ptr = &f_info[feat_idx[feat_cur]];
5956 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5957 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5961 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5965 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5969 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5974 if (visual_list && ((ch == 'A') || (ch == 'a')))
5976 int prev_lighting_level = *lighting_level;
5980 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
5981 else (*lighting_level)--;
5985 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
5986 else (*lighting_level)++;
5989 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
5990 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
5992 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
5993 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
5998 else if ((ch == 'D') || (ch == 'd'))
6000 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
6001 byte prev_x_char = f_ptr->x_char[*lighting_level];
6003 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6007 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6008 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6010 if (prev_x_char != f_ptr->x_char[*lighting_level])
6011 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6013 else *need_redraw = TRUE;
6018 /* Do visual mode command if needed */
6019 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))
6023 /* Restore previous visual settings */
6025 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6027 f_ptr->x_attr[i] = attr_old[i];
6028 f_ptr->x_char[i] = char_old[i];
6035 if (direct_f_idx >= 0) flag = TRUE;
6036 else *lighting_level = F_LIT_STANDARD;
6039 /* Preserve current visual settings */
6042 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6044 attr_old[i] = f_ptr->x_attr[i];
6045 char_old[i] = f_ptr->x_char[i];
6047 *lighting_level = F_LIT_STANDARD;
6054 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6056 attr_idx_feat[i] = f_ptr->x_attr[i];
6057 char_idx_feat[i] = f_ptr->x_char[i];
6066 /* Allow TERM_DARK text */
6067 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6069 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6070 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6088 /* Move the cursor */
6089 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6095 /* Free the "feat_idx" array */
6096 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6101 * List wanted monsters
6102 * @param creature_ptr プレーヤーへの参照ポインタ
6105 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6107 /* Open a new file */
6109 GAME_TEXT file_name[1024];
6110 fff = my_fopen_temp(file_name, 1024);
6113 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6118 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
6119 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6121 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6122 fprintf(fff, "----------------------------------------------\n");
6124 bool listed = FALSE;
6125 for (int i = 0; i < MAX_BOUNTY; i++)
6127 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6129 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6136 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
6141 /* Display the file contents */
6142 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6147 * List virtues & status
6149 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6151 /* Open a new file */
6153 GAME_TEXT file_name[1024];
6154 fff = my_fopen_temp(file_name, 1024);
6157 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6162 fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), your_alignment(creature_ptr));
6163 dump_virtues(creature_ptr, fff);
6166 /* Display the file contents */
6167 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6174 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6176 /* Open a new file */
6178 GAME_TEXT file_name[1024];
6179 fff = my_fopen_temp(file_name, 1024);
6182 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6187 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6191 if (!d_info[i].maxdepth) continue;
6192 if (!max_dlv[i]) continue;
6193 if (d_info[i].final_guardian)
6195 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6197 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6199 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6204 /* Display the file contents */
6205 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6211 * List virtues & status
6214 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6216 /* Open a new file */
6218 GAME_TEXT file_name[1024];
6219 fff = my_fopen_temp(file_name, 1024);
6222 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6227 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6228 (2 * creature_ptr->hitdie +
6229 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6231 if (creature_ptr->knowledge & KNOW_HPRATE)
6232 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6233 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6235 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6236 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6238 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);
6239 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6242 dump_yourself(creature_ptr, fff);
6245 /* Display the file contents */
6246 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6252 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6253 * Print all active quests
6254 * @param creature_ptr プレーヤーへの参照ポインタ
6257 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6260 char rand_tmp_str[120] = "\0";
6261 GAME_TEXT name[MAX_NLEN];
6262 monster_race *r_ptr;
6263 int rand_level = 100;
6266 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6268 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6270 bool is_print = quest[i].status == QUEST_STATUS_TAKEN;
6271 is_print |= (quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER);
6272 is_print |= quest[i].status == QUEST_STATUS_COMPLETED;
6276 /* Set the quest number temporary */
6277 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6279 /* Clear the text */
6280 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6281 quest_text_line = 0;
6283 creature_ptr->current_floor_ptr->inside_quest = i;
6285 /* Get the quest text */
6286 init_flags = INIT_SHOW_TEXT;
6288 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6290 /* Reset the old quest number */
6291 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6293 /* No info from "silent" quests */
6294 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6298 if (quest[i].type != QUEST_TYPE_RANDOM)
6300 char note[80] = "\0";
6302 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6304 switch (quest[i].type)
6306 case QUEST_TYPE_KILL_LEVEL:
6307 case QUEST_TYPE_KILL_ANY_LEVEL:
6308 r_ptr = &r_info[quest[i].r_idx];
6309 strcpy(name, r_name + r_ptr->name);
6310 if (quest[i].max_num > 1)
6313 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6314 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6317 sprintf(note, " - kill %d %s, have killed %d.",
6318 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6322 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6325 case QUEST_TYPE_FIND_ARTIFACT:
6328 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6330 object_type *q_ptr = &forge;
6331 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6332 object_prep(q_ptr, k_idx);
6333 q_ptr->name1 = quest[i].k_idx;
6334 q_ptr->ident = IDENT_STORE;
6335 object_desc(creature_ptr, name, q_ptr, OD_NAME_ONLY);
6337 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find out %s."), name);
6339 case QUEST_TYPE_FIND_EXIT:
6340 sprintf(note, _(" - 出口に到達する。", " - Reach to Exit."));
6343 case QUEST_TYPE_KILL_NUMBER:
6345 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6346 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6348 sprintf(note, " - Kill %d monsters, have killed %d.",
6349 (int)quest[i].max_num, (int)quest[i].cur_num);
6353 case QUEST_TYPE_KILL_ALL:
6354 case QUEST_TYPE_TOWER:
6355 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6360 /* Print the quest info */
6361 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6362 quest[i].name, (int)quest[i].level, note);
6364 fputs(tmp_str, fff);
6366 if (quest[i].status == QUEST_STATUS_COMPLETED)
6368 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6369 fputs(tmp_str, fff);
6374 while (quest_text[k][0] && k < 10)
6376 fprintf(fff, " %s\n", quest_text[k]);
6383 /* QUEST_TYPE_RANDOM */
6384 if (quest[i].level >= rand_level)
6388 rand_level = quest[i].level;
6390 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6392 /* Print the quest info */
6393 r_ptr = &r_info[quest[i].r_idx];
6394 strcpy(name, r_name + r_ptr->name);
6396 if (quest[i].max_num <= 1)
6398 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6399 quest[i].name, (int)quest[i].level, name);
6404 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6405 quest[i].name, (int)quest[i].level,
6406 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6410 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6411 quest[i].name, (int)quest[i].level,
6412 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6416 /* Print the current random quest */
6417 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6419 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6423 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6426 char playtime_str[16];
6427 quest_type* const q_ptr = &quest[q_idx];
6429 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6430 if (is_fixed_quest_idx(q_idx))
6432 /* Set the quest number temporary */
6433 IDX old_quest = floor_ptr->inside_quest;
6435 floor_ptr->inside_quest = q_idx;
6438 init_flags = INIT_NAME_ONLY;
6440 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6442 /* Reset the old quest number */
6443 floor_ptr->inside_quest = old_quest;
6445 /* No info from "silent" quests */
6446 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6449 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6450 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6452 if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6454 /* Print the quest info */
6456 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6457 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6458 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6459 fputs(tmp_str, fff);
6463 /* Print the quest info */
6464 if (q_ptr->complev == 0)
6467 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6468 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6469 r_name + r_info[q_ptr->r_idx].name,
6470 (int)q_ptr->level, playtime_str);
6471 fputs(tmp_str, fff);
6476 _(" %-35s (%3d階) - レベル%2d - %s\n",
6477 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6478 r_name + r_info[q_ptr->r_idx].name,
6482 fputs(tmp_str, fff);
6488 * Print all finished quests
6489 * @param creature_ptr プレーヤーへの参照ポインタ
6490 * @param fff セーブファイル (展開済?)
6491 * @param quest_num[] 受注したことのあるクエスト群
6494 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6496 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6497 QUEST_IDX total = 0;
6498 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6500 QUEST_IDX q_idx = quest_num[i];
6501 quest_type* const q_ptr = &quest[q_idx];
6503 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6509 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6514 * Print all failed quests
6515 * @param creature_ptr プレーヤーへの参照ポインタ
6516 * @param fff セーブファイル (展開済?)
6517 * @param quest_num[] 受注したことのあるクエスト群
6520 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6522 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6523 QUEST_IDX total = 0;
6524 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6526 QUEST_IDX q_idx = quest_num[i];
6527 quest_type* const q_ptr = &quest[q_idx];
6529 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6530 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6536 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6541 * Print all random quests
6543 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6545 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6546 GAME_TEXT tmp_str[120];
6547 QUEST_IDX total = 0;
6548 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6550 /* No info from "silent" quests */
6551 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6553 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6557 /* Print the quest info */
6558 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6559 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6560 fputs(tmp_str, fff);
6564 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6568 * Print quest status of all active quests
6569 * @param creature_ptr プレーヤーへの参照ポインタ
6572 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6574 /* Open a new file */
6576 GAME_TEXT file_name[1024];
6577 fff = my_fopen_temp(file_name, 1024);
6580 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6585 /* Allocate Memory */
6587 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6589 /* Sort by compete level */
6590 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6592 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6594 /* Dump Quest Information */
6595 do_cmd_knowledge_quests_current(creature_ptr, fff);
6597 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6599 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6600 if (current_world_ptr->wizard)
6603 do_cmd_knowledge_quests_wiz_random(fff);
6608 /* Display the file contents */
6609 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6613 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6619 * @param player_ptr プレーヤーへの参照ポインタ
6622 static void do_cmd_knowledge_home(player_type *player_ptr)
6624 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6626 /* Open a new file */
6628 GAME_TEXT file_name[1024];
6629 fff = my_fopen_temp(file_name, 1024);
6632 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6637 /* Print all homes in the different towns */
6639 st_ptr = &town_info[1].store[STORE_HOME];
6641 /* Home -- if anything there */
6642 if (st_ptr->stock_num)
6647 /* Header with name of the town */
6648 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6650 /* Dump all available items */
6651 concptr paren = ")";
6652 GAME_TEXT o_name[MAX_NLEN];
6653 for (int i = 0; i < st_ptr->stock_num; i++)
6656 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6657 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6658 if (strlen(o_name) <= 80 - 3)
6660 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6666 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6667 if (iskanji(*t)) { t++; n++; }
6668 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6670 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6671 fprintf(fff, " %.77s\n", o_name + n);
6674 object_desc(player_ptr, o_name, &st_ptr->stock[i], 0);
6675 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6679 /* Add an empty line */
6680 fprintf(fff, "\n\n");
6685 /* Display the file contents */
6686 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6692 * Check the status of "autopick"
6694 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6696 /* Open a new file */
6698 GAME_TEXT file_name[1024];
6699 fff = my_fopen_temp(file_name, 1024);
6702 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6709 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6713 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6714 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6717 for (int k = 0; k < max_autopick; k++)
6720 byte act = autopick_list[k].action;
6721 if (act & DONT_AUTOPICK)
6723 tmp = _("放置", "Leave");
6725 else if (act & DO_AUTODESTROY)
6727 tmp = _("破壊", "Destroy");
6729 else if (act & DO_AUTOPICK)
6731 tmp = _("拾う", "Pickup");
6735 tmp = _("確認", "Query");
6738 if (act & DO_DISPLAY)
6739 fprintf(fff, "%11s", format("[%s]", tmp));
6741 fprintf(fff, "%11s", format("(%s)", tmp));
6743 tmp = autopick_line_from_entry(&autopick_list[k]);
6744 fprintf(fff, " %s", tmp);
6751 /* Display the file contents */
6752 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6758 * Interact with "knowledge"
6760 void do_cmd_knowledge(player_type *creature_ptr)
6763 bool need_redraw = FALSE;
6765 /* File type is "TEXT" */
6766 FILE_TYPE(FILE_TYPE_TEXT);
6769 /* Interact until done */
6774 /* Ask for a choice */
6775 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6776 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6778 /* Give some choices */
6782 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6783 prt("(2) 既知のアイテム の一覧", 7, 5);
6784 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6785 prt("(4) 既知のモンスター の一覧", 9, 5);
6786 prt("(5) 倒した敵の数 の一覧", 10, 5);
6787 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6788 prt("(7) 現在のペット の一覧", 12, 5);
6789 prt("(8) 我が家のアイテム の一覧", 13, 5);
6790 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6791 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6795 prt("(a) 自分に関する情報 の一覧", 6, 5);
6796 prt("(b) 突然変異 の一覧", 7, 5);
6797 prt("(c) 武器の経験値 の一覧", 8, 5);
6798 prt("(d) 魔法の経験値 の一覧", 9, 5);
6799 prt("(e) 技能の経験値 の一覧", 10, 5);
6800 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6801 prt("(g) 入ったダンジョン の一覧", 12, 5);
6802 prt("(h) 実行中のクエスト の一覧", 13, 5);
6803 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6808 prt("(1) Display known artifacts", 6, 5);
6809 prt("(2) Display known objects", 7, 5);
6810 prt("(3) Display remaining uniques", 8, 5);
6811 prt("(4) Display known monster", 9, 5);
6812 prt("(5) Display kill count", 10, 5);
6813 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6814 prt("(7) Display current pets", 12, 5);
6815 prt("(8) Display home inventory", 13, 5);
6816 prt("(9) Display *identified* equip.", 14, 5);
6817 prt("(0) Display terrain symbols.", 15, 5);
6821 prt("(a) Display about yourself", 6, 5);
6822 prt("(b) Display mutations", 7, 5);
6823 prt("(c) Display weapon proficiency", 8, 5);
6824 prt("(d) Display spell proficiency", 9, 5);
6825 prt("(e) Display misc. proficiency", 10, 5);
6826 prt("(f) Display virtues", 11, 5);
6827 prt("(g) Display dungeons", 12, 5);
6828 prt("(h) Display current quests", 13, 5);
6829 prt("(i) Display auto pick/destroy", 14, 5);
6833 prt(_("-続く-", "-more-"), 17, 8);
6834 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6835 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6836 /*prt("-) 前ページ", 21, 60);*/
6837 prt(_("コマンド:", "Command: "), 20, 0);
6840 if (i == ESCAPE) break;
6843 case ' ': /* Page change */
6847 case '1': /* Artifacts */
6848 do_cmd_knowledge_artifacts(creature_ptr);
6850 case '2': /* Objects */
6851 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6853 case '3': /* Uniques */
6854 do_cmd_knowledge_uniques(creature_ptr);
6856 case '4': /* Monsters */
6857 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6859 case '5': /* Kill count */
6860 do_cmd_knowledge_kill_count(creature_ptr);
6862 case '6': /* wanted */
6863 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6865 case '7': /* Pets */
6866 do_cmd_knowledge_pets(creature_ptr);
6868 case '8': /* Home */
6869 do_cmd_knowledge_home(creature_ptr);
6871 case '9': /* Resist list */
6872 do_cmd_knowledge_inven(creature_ptr);
6874 case '0': /* Feature list */
6876 IDX lighting_level = F_LIT_STANDARD;
6877 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6881 case 'a': /* Max stat */
6882 do_cmd_knowledge_stat(creature_ptr);
6884 case 'b': /* Mutations */
6885 do_cmd_knowledge_mutations(creature_ptr);
6887 case 'c': /* weapon-exp */
6888 do_cmd_knowledge_weapon_exp(creature_ptr);
6890 case 'd': /* spell-exp */
6891 do_cmd_knowledge_spell_exp(creature_ptr);
6893 case 'e': /* skill-exp */
6894 do_cmd_knowledge_skill_exp(creature_ptr);
6896 case 'f': /* Virtues */
6897 do_cmd_knowledge_virtues(creature_ptr);
6899 case 'g': /* Dungeon */
6900 do_cmd_knowledge_dungeon(creature_ptr);
6902 case 'h': /* Quests */
6903 do_cmd_knowledge_quests(creature_ptr);
6905 case 'i': /* Autopick */
6906 do_cmd_knowledge_autopick(creature_ptr);
6908 default: /* Unknown option */
6916 if (need_redraw) do_cmd_redraw(creature_ptr);
6921 * Check on the status of an active quest
6922 * @param creature_ptr プレーヤーへの参照ポインタ
6925 void do_cmd_checkquest(player_type *creature_ptr)
6927 /* File type is "TEXT" */
6928 FILE_TYPE(FILE_TYPE_TEXT);
6932 do_cmd_knowledge_quests(creature_ptr);
6938 * Display the time and date
6939 * @param creature_ptr プレーヤーへの参照ポインタ
6942 void do_cmd_time(player_type *creature_ptr)
6945 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6948 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6951 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6952 else strcpy(day_buf, "*****");
6954 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6955 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6959 if (!randint0(10) || creature_ptr->image)
6961 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6965 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6968 /* Open this file */
6970 fff = my_fopen(buf, "rt");
6974 /* Find this time */
6975 int full = hour * 100 + min;
6979 while (!my_fgets(fff, buf, sizeof(buf)))
6981 /* Ignore comments */
6982 if (!buf[0] || (buf[0] == '#')) continue;
6984 /* Ignore invalid lines */
6985 if (buf[1] != ':') continue;
6987 /* Process 'Start' */
6990 /* Extract the starting time */
6991 start = atoi(buf + 2);
6993 /* Assume valid for an hour */
7001 /* Extract the ending time */
7002 end = atoi(buf + 2);
7006 /* Ignore incorrect range */
7007 if ((start > full) || (full > end)) continue;
7009 /* Process 'Description' */
7014 /* Apply the randomizer */
7015 if (!randint0(num)) strcpy(desc, buf + 2);