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 == NIKKI_FIX_QUEST_C ||
421 type == NIKKI_FIX_QUEST_F ||
422 type == NIKKI_RAND_QUEST_C ||
423 type == NIKKI_RAND_QUEST_F ||
424 type == NIKKI_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);
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 NIKKI_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 NIKKI_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 NIKKI_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 NIKKI_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 NIKKI_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 NIKKI_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);
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 NIKKI_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 NIKKI_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 made disappeared 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 made disappeared by 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 made disappeared by teleport 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 made disappeared by compacting monsters.\n"), note);
723 case RECORD_NAMED_PET_LOSE_PARENT:
724 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
735 case NIKKI_WIZARD_LOG:
736 fprintf(fff, "%s\n", note);
745 if (do_level) write_level = FALSE;
751 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
754 * @brief 日記のタイトル表記と内容出力 /
757 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
759 static void display_diary(player_type *creature_ptr)
761 char diary_title[256];
762 GAME_TEXT file_name[MAX_NLEN];
766 static const char subtitle[][30] = {
799 static const char subtitle[][51] = {
800 "Quest of The World's Toughest Body",
801 "Attack is the best form of defence.",
803 "An unexpected windfall",
804 "A drowning man will catch at a straw",
805 "Don't count your chickens before they are hatched.",
806 "It is no use crying over spilt milk.",
807 "Seeing is believing.",
808 "Strike the iron while it is hot.",
809 "I don't care what follows.",
810 "To dig a well to put out a house on fire.",
811 "Tomorrow is another day.",
812 "Easy come, easy go.",
813 "The more haste, the less speed.",
814 "Where there is life, there is hope.",
815 "There is no royal road to *WINNER*.",
816 "Danger past, God forgotten.",
817 "The best thing to do now is to run away.",
818 "Life is but an empty dream.",
819 "Dead men tell no tales.",
820 "A book that remains shut is but a block.",
821 "Misfortunes never come singly.",
822 "A little knowledge is a dangerous thing.",
823 "History repeats itself.",
824 "*WINNER* was not built in a day.",
825 "Ignorance is bliss.",
826 "To lose is to win?",
827 "No medicine can cure folly.",
828 "All good things come to an end.",
829 "M$ Empire strikes back.",
830 "To see is to believe",
832 "Quest of The World's Greatest Brain"
835 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
836 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
838 if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
839 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1)]);
840 else if (IS_WIZARD_CLASS(creature_ptr))
841 strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 1) + 1]);
842 else strcpy(tmp, subtitle[randint0(MAX_SUBTITLE - 2) + 1]);
845 sprintf(diary_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
847 sprintf(diary_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
850 /* Display the file contents */
851 show_file(creature_ptr, FALSE, buf, diary_title, -1, 0);
856 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
859 static void add_diary_note(player_type *creature_ptr)
862 char bunshou[80] = "\0";
864 if (get_string(_("内容: ", "diary note: "), tmp, 79))
866 strcpy(bunshou, tmp);
867 exe_write_diary(creature_ptr, NIKKI_BUNSHOU, 0, bunshou);
872 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
875 static void do_cmd_last_get(player_type *creaute_ptr)
877 if (record_o_name[0] == '\0') return;
880 sprintf(buf, _("%sの入手を記録します。", "Do you really want to record getting %s? "), record_o_name);
881 if (!get_check(buf)) return;
883 GAME_TURN turn_tmp = current_world_ptr->game_turn;
884 current_world_ptr->game_turn = record_turn;
885 sprintf(buf, _("%sを手に入れた。", "descover %s."), record_o_name);
886 exe_write_diary(creaute_ptr, NIKKI_BUNSHOU, 0, buf);
887 current_world_ptr->game_turn = turn_tmp;
892 * @brief ファイル中の全日記記録を消去する /
895 static void do_cmd_erase_diary(void)
897 GAME_TEXT file_name[MAX_NLEN];
901 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
902 sprintf(file_name, _("playrecord-%s.txt", "playrec-%s.txt"), savefile_base);
903 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
906 fff = my_fopen(buf, "w");
910 msg_format(_("記録を消去しました。", "deleted record."));
914 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
923 * @param crerature_ptr プレーヤーへの参照ポインタ
926 void do_cmd_diary(player_type *creature_ptr)
928 /* File type is "TEXT" */
929 FILE_TYPE(FILE_TYPE_TEXT);
932 /* Interact until done */
938 /* Ask for a choice */
939 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
941 /* Give some choices */
942 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
943 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
944 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
945 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
947 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
950 prt(_("コマンド:", "Command: "), 18, 0);
955 if (i == ESCAPE) break;
960 display_diary(creature_ptr);
963 add_diary_note(creature_ptr);
966 do_cmd_last_get(creature_ptr);
969 do_cmd_erase_diary();
973 prepare_movie_hooks();
975 default: /* Unknown option */
987 * @brief 画面を再描画するコマンドのメインルーチン
988 * Hack -- redraw the screen
989 * @param creature_ptr プレーヤーへの参照ポインタ
993 * This command performs various low level updates, clears all the "extra"
994 * windows, does a total redraw of the main window, and requests all of the
995 * interesting updates and redraws that I can think of.
997 * This command is also used to "instantiate" the results of the user
998 * selecting various things, such as graphics mode, so it must call
999 * the "TERM_XTRA_REACT" hook before redrawing the windows.
1002 void do_cmd_redraw(player_type *creature_ptr)
1004 Term_xtra(TERM_XTRA_REACT, 0);
1006 /* Combine and Reorder the pack (later) */
1007 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1008 creature_ptr->update |= (PU_TORCH);
1009 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1010 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1011 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1012 creature_ptr->update |= (PU_MONSTERS);
1014 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1016 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1017 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1020 handle_stuff(creature_ptr);
1022 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1024 /* Redraw every window */
1026 for (int j = 0; j < 8; j++)
1029 if (!angband_term[j]) continue;
1032 Term_activate(angband_term[j]);
1041 * @brief プレイヤーのステータス表示
1044 void do_cmd_player_status(player_type *creature_ptr)
1055 display_player(creature_ptr, mode);
1060 display_player(creature_ptr, mode);
1064 Term_putstr(2, 23, -1, TERM_WHITE,
1065 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1069 if (c == ESCAPE) break;
1074 get_name(creature_ptr);
1076 /* Process the player name */
1077 process_player_name(creature_ptr, FALSE);
1083 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1084 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1086 if (tmp[0] && (tmp[0] != ' '))
1088 file_character(creature_ptr, tmp);
1106 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1108 handle_stuff(creature_ptr);
1113 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1114 * Recall the most recent message
1117 void do_cmd_message_one(void)
1119 /* Recall one message */
1120 prt(format("> %s", message_str(0)), 0, 0);
1125 * @brief メッセージのログを表示するコマンドのメインルーチン
1126 * Recall the most recent message
1130 * Show previous messages to the user -BEN-
1132 * The screen format uses line 0 and 23 for headers and prompts,
1133 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1135 * This command shows you which commands you are viewing, and allows
1136 * you to "search" for strings in the recall.
1138 * Note that messages may be longer than 80 characters, but they are
1139 * displayed using "infinite" length, with a special sub-command to
1140 * "slide" the virtual display to the left or right.
1142 * Attempt to only hilite the matching portions of the string.
1145 void do_cmd_messages(int num_now)
1147 char shower_str[81];
1148 char finder_str[81];
1150 concptr shower = NULL;
1154 Term_get_size(&wid, &hgt);
1156 /* Number of message lines in a screen */
1157 num_lines = hgt - 4;
1160 strcpy(finder_str, "");
1163 strcpy(shower_str, "");
1165 /* Total messages */
1166 int n = message_num();
1168 /* Start on first message */
1173 /* Process requests until done */
1179 /* Dump up to 20 lines of messages */
1180 for (j = 0; (j < num_lines) && (i + j < n); j++)
1182 concptr msg = message_str(i + j);
1184 /* Dump the messages, bottom to top */
1185 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1187 if (!shower || !shower[0]) continue;
1189 /* Hilite "shower" */
1192 /* Display matches */
1193 while ((str = my_strstr(str, shower)) != NULL)
1195 int len = strlen(shower);
1197 /* Display the match */
1198 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1205 /* Erase remaining lines */
1206 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1208 /* Display header */
1210 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1211 i, i + j - 1, n), 0, 0);
1213 /* Display prompt (not very informative) */
1214 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1215 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1217 skey = inkey_special(TRUE);
1219 /* Exit on Escape */
1220 if (skey == ESCAPE) break;
1222 /* Hack -- Save the old index */
1227 /* Hack -- handle show */
1230 prt(_("強調: ", "Show: "), hgt - 1, 0);
1232 /* Get a "shower" string, or continue */
1233 strcpy(back_str, shower_str);
1234 if (askfor(shower_str, 80))
1237 shower = shower_str[0] ? shower_str : NULL;
1239 else strcpy(shower_str, back_str);
1243 /* Hack -- handle find */
1250 prt(_("検索: ", "Find: "), hgt - 1, 0);
1252 /* Get a "finder" string, or continue */
1253 strcpy(back_str, finder_str);
1254 if (!askfor(finder_str, 80))
1256 strcpy(finder_str, back_str);
1259 else if (!finder_str[0])
1261 shower = NULL; /* Stop showing */
1266 shower = finder_str;
1269 for (z = i + 1; z < n; z++)
1271 concptr msg = message_str(z);
1274 if (my_strstr(msg, finder_str))
1285 /* Recall 1 older message */
1287 /* Go to the oldest line */
1291 /* Recall 1 newer message */
1293 /* Go to the newest line */
1297 /* Recall 1 older message */
1302 /* Go older if legal */
1303 i = MIN(i + 1, n - num_lines);
1306 /* Recall 10 older messages */
1308 /* Go older if legal */
1309 i = MIN(i + 10, n - num_lines);
1312 /* Recall 20 older messages */
1317 /* Go older if legal */
1318 i = MIN(i + num_lines, n - num_lines);
1321 /* Recall 20 newer messages */
1325 /* Go newer (if able) */
1326 i = MAX(0, i - num_lines);
1329 /* Recall 10 newer messages */
1331 /* Go newer (if able) */
1335 /* Recall 1 newer messages */
1338 /* Go newer (if able) */
1343 /* Hack -- Error of some kind */
1352 * @brief prefファイルを選択して処理する /
1353 * Ask for a "user pref line" and process it
1354 * @param creature_ptr プレーヤーへの参照ポインタ
1357 * Allow absolute file names?
1359 void do_cmd_pref(player_type *creature_ptr)
1364 /* Ask for a "user pref command" */
1365 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1367 /* Process that pref command */
1368 (void)process_pref_file_command(creature_ptr, buf);
1373 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1374 * @param creature_ptr プレーヤーへの参照ポインタ
1377 void do_cmd_reload_autopick(player_type *creature_ptr)
1379 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1380 /* Load the file with messages */
1381 autopick_load_pref(creature_ptr, TRUE);
1388 * @brief マクロ情報をprefファイルに保存する /
1389 * @param fname ファイル名
1392 static errr macro_dump(concptr fname)
1394 static concptr mark = "Macro Dump";
1396 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1398 /* File type is "TEXT" */
1399 FILE_TYPE(FILE_TYPE_TEXT);
1401 /* Append to the file */
1402 if (!open_auto_dump(buf, mark)) return -1;
1405 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1408 for (int i = 0; i < macro__num; i++)
1410 /* Extract the action */
1411 ascii_to_text(buf, macro__act[i]);
1413 /* Dump the macro */
1414 auto_dump_printf("A:%s\n", buf);
1416 /* Extract the action */
1417 ascii_to_text(buf, macro__pat[i]);
1419 /* Dump normal macros */
1420 auto_dump_printf("P:%s\n", buf);
1423 auto_dump_printf("\n");
1432 * @brief マクロのトリガーキーを取得する /
1433 * Hack -- ask for a "trigger" (see below)
1434 * @param buf キー表記を保管するバッファ
1438 * Note the complex use of the "inkey()" function from "util.c".
1440 * Note that both "flush()" calls are extremely important.
1443 static void do_cmd_macro_aux(char *buf)
1447 /* Do not process macros */
1453 /* Read the pattern */
1460 /* Do not process macros */
1463 /* Do not wait for keys */
1466 /* Attempt to read a key */
1475 /* Convert the trigger */
1477 ascii_to_text(tmp, buf);
1479 /* Hack -- display the trigger */
1480 Term_addstr(-1, TERM_WHITE, tmp);
1486 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1487 * Hack -- ask for a keymap "trigger" (see below)
1488 * @param buf キー表記を取得するバッファ
1492 * Note that both "flush()" calls are extremely important. This may
1493 * no longer be true, since "util.c" is much simpler now.
1496 static void do_cmd_macro_aux_keymap(char *buf)
1506 /* Convert to ascii */
1507 ascii_to_text(tmp, buf);
1509 /* Hack -- display the trigger */
1510 Term_addstr(-1, TERM_WHITE, tmp);
1517 * @brief キーマップをprefファイルにダンプする /
1518 * Hack -- append all keymaps to the given file
1519 * @param fname ファイルネーム
1523 static errr keymap_dump(concptr fname)
1525 static concptr mark = "Keymap Dump";
1532 if (rogue_like_commands)
1534 mode = KEYMAP_MODE_ROGUE;
1540 mode = KEYMAP_MODE_ORIG;
1543 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1545 /* File type is "TEXT" */
1546 FILE_TYPE(FILE_TYPE_TEXT);
1548 /* Append to the file */
1549 if (!open_auto_dump(buf, mark)) return -1;
1552 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1555 for (int i = 0; i < 256; i++)
1559 /* Loop up the keymap */
1560 act = keymap_act[mode][i];
1562 /* Skip empty keymaps */
1565 /* Encode the key */
1568 ascii_to_text(key, buf);
1570 /* Encode the action */
1571 ascii_to_text(buf, act);
1573 /* Dump the macro */
1574 auto_dump_printf("A:%s\n", buf);
1575 auto_dump_printf("C:%d:%s\n", mode, key);
1584 * @brief マクロを設定するコマンドのメインルーチン /
1585 * Interact with "macros"
1589 * Note that the macro "action" must be defined before the trigger.
1591 * Could use some helpful instructions on this page.
1594 void do_cmd_macros(player_type *creature_ptr)
1602 if (rogue_like_commands)
1604 mode = KEYMAP_MODE_ROGUE;
1610 mode = KEYMAP_MODE_ORIG;
1613 /* File type is "TEXT" */
1614 FILE_TYPE(FILE_TYPE_TEXT);
1618 /* Process requests until done */
1622 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1624 /* Describe that action */
1625 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1627 /* Analyze the current action */
1628 ascii_to_text(buf, macro__buf);
1630 /* Display the current action */
1635 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1637 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1638 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1639 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1640 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1641 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1642 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1643 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1644 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1645 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1646 #endif /* ALLOW_MACROS */
1649 prt(_("コマンド: ", "Command: "), 16, 0);
1654 if (i == ESCAPE) break;
1656 /* Load a 'macro' file */
1662 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1665 prt(_("ファイル: ", "File: "), 18, 0);
1667 /* Default filename */
1668 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1670 /* Ask for a file */
1671 if (!askfor(tmp, 80)) continue;
1673 /* Process the given filename */
1674 err = process_pref_file(creature_ptr, tmp);
1677 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1682 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1686 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1695 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1698 prt(_("ファイル: ", "File: "), 18, 0);
1700 /* Default filename */
1701 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1703 /* Ask for a file */
1704 if (!askfor(tmp, 80)) continue;
1706 /* Dump the macros */
1707 (void)macro_dump(tmp);
1710 msg_print(_("マクロを追加しました。", "Appended macros."));
1719 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1723 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1725 /* Get a macro trigger */
1726 do_cmd_macro_aux(buf);
1728 /* Acquire action */
1729 k = macro_find_exact(buf);
1735 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1741 /* Obtain the action */
1742 strcpy(macro__buf, macro__act[k]);
1744 /* Analyze the current action */
1745 ascii_to_text(buf, macro__buf);
1747 /* Display the current action */
1751 msg_print(_("マクロを確認しました。", "Found a macro."));
1755 /* Create a macro */
1759 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1762 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1764 /* Get a macro trigger */
1765 do_cmd_macro_aux(buf);
1769 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1770 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1773 prt(_("マクロ行動: ", "Action: "), 20, 0);
1775 /* Convert to text */
1776 ascii_to_text(tmp, macro__buf);
1778 /* Get an encoded action */
1779 if (askfor(tmp, 80))
1781 /* Convert to ascii */
1782 text_to_ascii(macro__buf, tmp);
1784 /* Link the macro */
1785 macro_add(buf, macro__buf);
1788 msg_print(_("マクロを追加しました。", "Added a macro."));
1792 /* Remove a macro */
1796 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1799 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1801 /* Get a macro trigger */
1802 do_cmd_macro_aux(buf);
1804 /* Link the macro */
1805 macro_add(buf, buf);
1808 msg_print(_("マクロを削除しました。", "Removed a macro."));
1815 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1818 prt(_("ファイル: ", "File: "), 18, 0);
1820 /* Default filename */
1821 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1823 /* Ask for a file */
1824 if (!askfor(tmp, 80)) continue;
1826 /* Dump the macros */
1827 (void)keymap_dump(tmp);
1830 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1833 /* Query a keymap */
1839 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1842 prt(_("押すキー: ", "Keypress: "), 18, 0);
1844 /* Get a keymap trigger */
1845 do_cmd_macro_aux_keymap(buf);
1847 /* Look up the keymap */
1848 act = keymap_act[mode][(byte)(buf[0])];
1854 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1860 /* Obtain the action */
1861 strcpy(macro__buf, act);
1863 /* Analyze the current action */
1864 ascii_to_text(buf, macro__buf);
1866 /* Display the current action */
1870 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1874 /* Create a keymap */
1878 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1881 prt(_("押すキー: ", "Keypress: "), 18, 0);
1883 /* Get a keymap trigger */
1884 do_cmd_macro_aux_keymap(buf);
1888 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1889 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1892 prt(_("行動: ", "Action: "), 20, 0);
1894 /* Convert to text */
1895 ascii_to_text(tmp, macro__buf);
1897 /* Get an encoded action */
1898 if (askfor(tmp, 80))
1900 /* Convert to ascii */
1901 text_to_ascii(macro__buf, tmp);
1903 /* Free old keymap */
1904 string_free(keymap_act[mode][(byte)(buf[0])]);
1906 /* Make new keymap */
1907 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1910 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1914 /* Remove a keymap */
1918 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1921 prt(_("押すキー: ", "Keypress: "), 18, 0);
1923 /* Get a keymap trigger */
1924 do_cmd_macro_aux_keymap(buf);
1926 /* Free old keymap */
1927 string_free(keymap_act[mode][(byte)(buf[0])]);
1929 /* Make new keymap */
1930 keymap_act[mode][(byte)(buf[0])] = NULL;
1933 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1936 /* Enter a new action */
1940 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1944 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1945 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1948 prt(_("マクロ行動: ", "Action: "), 20, 0);
1950 /* Hack -- limit the value */
1953 /* Get an encoded action */
1954 if (!askfor(buf, 80)) continue;
1956 /* Extract an action */
1957 text_to_ascii(macro__buf, buf);
1959 #endif /* ALLOW_MACROS */
1974 * @brief キャラクタ色の明暗表現
1976 static concptr lighting_level_str[F_LIT_MAX] =
1991 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1992 * @param i 指定対象となるキャラクタコード
1993 * @param num 指定されたビジュアルIDを返す参照ポインタ
1994 * @param max ビジュアルIDの最大数
1995 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1997 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2004 sprintf(str, "%d", *num);
2006 if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
2009 tmp = (IDX)strtol(str, NULL, 0);
2010 if (tmp >= 0 && tmp < max)
2013 else if (isupper(i))
2014 *num = (*num + max - 1) % max;
2016 *num = (*num + 1) % max;
2022 * @brief キャラクタの変更メニュー表示
2023 * @param choice_msg 選択メッセージ
2026 static void print_visuals_menu(concptr choice_msg)
2028 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2030 /* Give some choices */
2031 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2033 #ifdef ALLOW_VISUALS
2034 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2035 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2036 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2037 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2038 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2039 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2040 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2041 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2042 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2043 #endif /* ALLOW_VISUALS */
2045 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2048 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2053 * Interact with "visuals"
2055 void do_cmd_visuals(player_type *creature_ptr)
2060 bool need_redraw = FALSE;
2061 concptr empty_symbol = "<< ? >>";
2063 if (use_bigtile) empty_symbol = "<< ?? >>";
2065 /* File type is "TEXT" */
2066 FILE_TYPE(FILE_TYPE_TEXT);
2069 /* Interact until done */
2074 /* Ask for a choice */
2075 print_visuals_menu(NULL);
2080 if (i == ESCAPE) break;
2084 /* Load a 'pref' file */
2087 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2090 prt(_("ファイル: ", "File: "), 17, 0);
2092 /* Default filename */
2093 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2096 if (!askfor(tmp, 70)) continue;
2098 /* Process the given filename */
2099 (void)process_pref_file(creature_ptr, tmp);
2104 #ifdef ALLOW_VISUALS
2106 /* Dump monster attr/chars */
2109 static concptr mark = "Monster attr/chars";
2112 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2115 prt(_("ファイル: ", "File: "), 17, 0);
2117 /* Default filename */
2118 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2120 /* Get a filename */
2121 if (!askfor(tmp, 70)) continue;
2122 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2124 /* Append to the file */
2125 if (!open_auto_dump(buf, mark)) continue;
2128 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2131 for (i = 0; i < max_r_idx; i++)
2133 monster_race *r_ptr = &r_info[i];
2135 /* Skip non-entries */
2136 if (!r_ptr->name) continue;
2138 /* Dump a comment */
2139 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2141 /* Dump the monster attr/char info */
2142 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2143 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2149 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2154 /* Dump object attr/chars */
2157 static concptr mark = "Object attr/chars";
2158 KIND_OBJECT_IDX k_idx;
2161 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2164 prt(_("ファイル: ", "File: "), 17, 0);
2166 /* Default filename */
2167 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2169 /* Get a filename */
2170 if (!askfor(tmp, 70)) continue;
2171 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2173 /* Append to the file */
2174 if (!open_auto_dump(buf, mark)) continue;
2177 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2180 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2182 GAME_TEXT o_name[MAX_NLEN];
2183 object_kind *k_ptr = &k_info[k_idx];
2185 /* Skip non-entries */
2186 if (!k_ptr->name) continue;
2191 strip_name(o_name, k_idx);
2197 /* Prepare dummy object */
2198 object_prep(&forge, k_idx);
2200 /* Get un-shuffled flavor name */
2201 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
2204 /* Dump a comment */
2205 auto_dump_printf("# %s\n", o_name);
2207 /* Dump the object attr/char info */
2208 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2209 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2215 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2220 /* Dump feature attr/chars */
2223 static concptr mark = "Feature attr/chars";
2226 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2229 prt(_("ファイル: ", "File: "), 17, 0);
2231 /* Default filename */
2232 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2234 /* Get a filename */
2235 if (!askfor(tmp, 70)) continue;
2236 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2238 /* Append to the file */
2239 if (!open_auto_dump(buf, mark)) continue;
2242 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2245 for (i = 0; i < max_f_idx; i++)
2247 feature_type *f_ptr = &f_info[i];
2249 /* Skip non-entries */
2250 if (!f_ptr->name) continue;
2252 /* Skip mimiccing features */
2253 if (f_ptr->mimic != i) continue;
2255 /* Dump a comment */
2256 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2258 /* Dump the feature attr/char info */
2259 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2260 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2261 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2262 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2268 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2273 /* Modify monster attr/chars (numeric operation) */
2276 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2277 static MONRACE_IDX r = 0;
2279 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2281 /* Hack -- query until done */
2284 monster_race *r_ptr = &r_info[r];
2288 TERM_COLOR da = r_ptr->d_attr;
2289 byte dc = r_ptr->d_char;
2290 TERM_COLOR ca = r_ptr->x_attr;
2291 byte cc = r_ptr->x_char;
2293 /* Label the object */
2294 Term_putstr(5, 17, -1, TERM_WHITE,
2295 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2297 /* Label the Default values */
2298 Term_putstr(10, 19, -1, TERM_WHITE,
2299 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2301 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2302 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2304 /* Label the Current values */
2305 Term_putstr(10, 20, -1, TERM_WHITE,
2306 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2308 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2309 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2312 Term_putstr(0, 22, -1, TERM_WHITE,
2313 _("コマンド (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): "));
2318 if (i == ESCAPE) break;
2320 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2321 else if (isupper(i)) c = 'a' + i - 'A';
2331 if (!cmd_visuals_aux(i, &r, max_r_idx))
2336 } while (!r_info[r].name);
2340 t = (int)r_ptr->x_attr;
2341 (void)cmd_visuals_aux(i, &t, 256);
2342 r_ptr->x_attr = (byte)t;
2346 t = (int)r_ptr->x_char;
2347 (void)cmd_visuals_aux(i, &t, 256);
2348 r_ptr->x_char = (byte)t;
2352 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2354 print_visuals_menu(choice_msg);
2362 /* Modify object attr/chars (numeric operation) */
2365 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2367 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2369 /* Hack -- query until done */
2372 object_kind *k_ptr = &k_info[k];
2376 TERM_COLOR da = k_ptr->d_attr;
2377 SYMBOL_CODE dc = k_ptr->d_char;
2378 TERM_COLOR ca = k_ptr->x_attr;
2379 SYMBOL_CODE cc = k_ptr->x_char;
2381 /* Label the object */
2382 Term_putstr(5, 17, -1, TERM_WHITE,
2383 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2384 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2386 /* Label the Default values */
2387 Term_putstr(10, 19, -1, TERM_WHITE,
2388 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2390 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2391 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2393 /* Label the Current values */
2394 Term_putstr(10, 20, -1, TERM_WHITE,
2395 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2397 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2398 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2401 Term_putstr(0, 22, -1, TERM_WHITE,
2402 _("コマンド (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): "));
2407 if (i == ESCAPE) break;
2409 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2410 else if (isupper(i)) c = 'a' + i - 'A';
2420 if (!cmd_visuals_aux(i, &k, max_k_idx))
2425 } while (!k_info[k].name);
2429 t = (int)k_ptr->x_attr;
2430 (void)cmd_visuals_aux(i, &t, 256);
2431 k_ptr->x_attr = (byte)t;
2435 t = (int)k_ptr->x_char;
2436 (void)cmd_visuals_aux(i, &t, 256);
2437 k_ptr->x_char = (byte)t;
2441 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
2443 print_visuals_menu(choice_msg);
2451 /* Modify feature attr/chars (numeric operation) */
2454 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2456 static IDX lighting_level = F_LIT_STANDARD;
2457 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2459 /* Hack -- query until done */
2462 feature_type *f_ptr = &f_info[f];
2466 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2467 byte dc = f_ptr->d_char[lighting_level];
2468 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2469 byte cc = f_ptr->x_char[lighting_level];
2471 /* Label the object */
2473 Term_putstr(5, 17, -1, TERM_WHITE,
2474 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2475 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2477 /* Label the Default values */
2478 Term_putstr(10, 19, -1, TERM_WHITE,
2479 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2481 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2482 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2484 /* Label the Current values */
2486 Term_putstr(10, 20, -1, TERM_WHITE,
2487 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
2489 Term_putstr(10, 20, -1, TERM_WHITE,
2490 format("Current attr/char = %3d / %3d", ca, cc));
2493 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2494 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2498 Term_putstr(0, 22, -1, TERM_WHITE,
2499 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2501 Term_putstr(0, 22, -1, TERM_WHITE,
2502 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2508 if (i == ESCAPE) break;
2510 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2511 else if (isupper(i)) c = 'a' + i - 'A';
2521 if (!cmd_visuals_aux(i, &f, max_f_idx))
2526 } while (!f_info[f].name || (f_info[f].mimic != f));
2530 t = (int)f_ptr->x_attr[lighting_level];
2531 (void)cmd_visuals_aux(i, &t, 256);
2532 f_ptr->x_attr[lighting_level] = (byte)t;
2536 t = (int)f_ptr->x_char[lighting_level];
2537 (void)cmd_visuals_aux(i, &t, 256);
2538 f_ptr->x_char[lighting_level] = (byte)t;
2542 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2545 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2549 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2551 print_visuals_menu(choice_msg);
2559 /* Modify monster attr/chars (visual mode) */
2561 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2564 /* Modify object attr/chars (visual mode) */
2566 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2569 /* Modify feature attr/chars (visual mode) */
2572 IDX lighting_level = F_LIT_STANDARD;
2573 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2577 #endif /* ALLOW_VISUALS */
2585 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2589 /* Unknown option */
2600 if (need_redraw) do_cmd_redraw(creature_ptr);
2605 * Interact with "colors"
2607 void do_cmd_colors(player_type *creature_ptr)
2613 /* File type is "TEXT" */
2614 FILE_TYPE(FILE_TYPE_TEXT);
2618 /* Interact until done */
2623 /* Ask for a choice */
2624 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2626 /* Give some choices */
2627 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2630 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2631 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2635 prt(_("コマンド: ", "Command: "), 8, 0);
2639 if (i == ESCAPE) break;
2641 /* Load a 'pref' file */
2645 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2648 prt(_("ファイル: ", "File: "), 10, 0);
2651 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2654 if (!askfor(tmp, 70)) continue;
2656 /* Process the given filename */
2657 (void)process_pref_file(creature_ptr, tmp);
2659 /* Mega-Hack -- react to changes */
2660 Term_xtra(TERM_XTRA_REACT, 0);
2662 /* Mega-Hack -- redraw */
2671 static concptr mark = "Colors";
2674 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2677 prt(_("ファイル: ", "File: "), 10, 0);
2679 /* Default filename */
2680 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2682 /* Get a filename */
2683 if (!askfor(tmp, 70)) continue;
2684 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2686 /* Append to the file */
2687 if (!open_auto_dump(buf, mark)) continue;
2690 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2693 for (i = 0; i < 256; i++)
2695 int kv = angband_color_table[i][0];
2696 int rv = angband_color_table[i][1];
2697 int gv = angband_color_table[i][2];
2698 int bv = angband_color_table[i][3];
2700 concptr name = _("未知", "unknown");
2702 /* Skip non-entries */
2703 if (!kv && !rv && !gv && !bv) continue;
2705 /* Extract the color name */
2706 if (i < 16) name = color_names[i];
2708 /* Dump a comment */
2709 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2711 /* Dump the monster attr/char info */
2712 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2719 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2728 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2730 /* Hack -- query until done */
2737 /* Exhibit the normal colors */
2738 for (j = 0; j < 16; j++)
2740 /* Exhibit this color */
2741 Term_putstr(j * 4, 20, -1, a, "###");
2743 /* Exhibit all colors */
2744 Term_putstr(j * 4, 22, -1, j, format("%3d", j));
2747 /* Describe the color */
2748 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2750 /* Describe the color */
2751 Term_putstr(5, 10, -1, TERM_WHITE,
2752 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2754 /* Label the Current values */
2755 Term_putstr(5, 12, -1, TERM_WHITE,
2756 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2757 angband_color_table[a][0],
2758 angband_color_table[a][1],
2759 angband_color_table[a][2],
2760 angband_color_table[a][3]));
2763 Term_putstr(0, 14, -1, TERM_WHITE,
2764 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2769 if (i == ESCAPE) break;
2772 if (i == 'n') a = (byte)(a + 1);
2773 if (i == 'N') a = (byte)(a - 1);
2774 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2775 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2776 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2777 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2778 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2779 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2780 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2781 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2783 /* Hack -- react to changes */
2784 Term_xtra(TERM_XTRA_REACT, 0);
2786 /* Hack -- redraw */
2793 /* Unknown option */
2807 * Note something in the message recall
2809 void do_cmd_note(void)
2817 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2819 /* Ignore empty notes */
2820 if (!buf[0] || (buf[0] == ' ')) return;
2822 /* Add the note to the message recall */
2823 msg_format(_("メモ: %s", "Note: %s"), buf);
2828 * Mention the current version
2830 void do_cmd_version(void)
2832 #if FAKE_VER_EXTRA > 0
2833 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2834 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2836 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2837 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2843 * Array of feeling strings
2845 static concptr do_cmd_feeling_text[11] =
2847 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2848 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2849 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2850 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2851 _("とても悪い予感がする...", "You have a very bad feeling..."),
2852 _("悪い予感がする...", "You have a bad feeling..."),
2853 _("何か緊張する。", "You feel nervous."),
2854 _("少し不運な気がする...", "You feel your luck is turning..."),
2855 _("この場所は好きになれない。", "You don't like the look of this place."),
2856 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2857 _("なんて退屈なところだ...", "What a boring place...")
2860 static concptr do_cmd_feeling_text_combat[11] =
2862 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2863 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2864 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2865 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2866 _("とても悪い予感がする...", "You have a very bad feeling..."),
2867 _("悪い予感がする...", "You have a bad feeling..."),
2868 _("何か緊張する。", "You feel nervous."),
2869 _("少し不運な気がする...", "You feel your luck is turning..."),
2870 _("この場所は好きになれない。", "You don't like the look of this place."),
2871 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2872 _("なんて退屈なところだ...", "What a boring place...")
2875 static concptr do_cmd_feeling_text_lucky[11] =
2877 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2878 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2879 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2880 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2881 _("とても良い感じがする...", "You have a very good feeling..."),
2882 _("良い感じがする...", "You have a good feeling..."),
2883 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2884 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2885 _("見た感じ悪くはない...", "You like the look of this place..."),
2886 _("全然駄目ということはないが...", "This level can't be all bad..."),
2887 _("なんて退屈なところだ...", "What a boring place...")
2892 * Note that "feeling" is set to zero unless some time has passed.
2893 * Note that this is done when the level is GENERATED, not entered.
2895 void do_cmd_feeling(player_type *creature_ptr)
2897 if (creature_ptr->wild_mode) return;
2899 /* No useful feeling in quests */
2900 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2902 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2906 /* No useful feeling in town */
2907 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2909 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2911 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2915 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2919 /* No useful feeling in the wilderness */
2920 if (!creature_ptr->current_floor_ptr->dun_level)
2922 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2926 /* Display the feeling */
2927 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2928 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2929 else if (creature_ptr->pseikaku == SEIKAKU_COMBAT ||
2930 creature_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
2931 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2933 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2938 * Description of each monster group.
2940 static concptr monster_group_text[] =
2943 "ユニーク", /* "Uniques" */
2944 "乗馬可能なモンスター", /* "Riding" */
2945 "賞金首", /* "Wanted */
2946 "アンバーの王族", /* "Ambertite" */
2975 /* "古代ドラゴン/ワイアーム", */
3036 /* "Ancient Dragon/Wyrm", */
3045 "Multi-Headed Reptile",
3050 "Reptile/Amphibian",
3051 "Spider/Scorpion/Tick",
3053 /* "Major Demon", */
3070 * Symbols of monsters in each group. Note the "Uniques" group
3071 * is handled differently.
3073 static concptr monster_group_char[] =
3130 "!$&()+./=>?[\\]`{|~",
3140 * todo 引数と戻り値について追記求む
3141 * Build a list of monster indexes in the given group.
3143 * mode & 0x01 : check for non-empty group
3144 * mode & 0x02 : visual operation only
3146 * @param creature_ptr プレーヤーへの参照ポインタ
3147 * @param grp_cur ???
3148 * @param mon_idx[] ???
3150 * @return The number of monsters in the group
3152 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3154 /* Get a list of x_char in this group */
3155 concptr group_char = monster_group_char[grp_cur];
3157 bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
3158 bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
3159 bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
3160 bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
3162 /* Check every race */
3164 for (IDX i = 0; i < max_r_idx; i++)
3166 /* Access the race */
3167 monster_race *r_ptr = &r_info[i];
3169 /* Skip empty race */
3170 if (!r_ptr->name) continue;
3172 /* Require known monsters */
3173 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3177 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3180 else if (grp_riding)
3182 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3185 else if (grp_wanted)
3187 bool wanted = FALSE;
3189 for (j = 0; j < MAX_BOUNTY; j++)
3191 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3192 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3198 if (!wanted) continue;
3201 else if (grp_amberite)
3203 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3208 /* Check for race in the group */
3209 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3213 mon_idx[mon_cnt++] = i;
3215 /* XXX Hack -- Just checking for non-empty group */
3216 if (mode & 0x01) break;
3219 /* Terminate the list */
3220 mon_idx[mon_cnt] = -1;
3223 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3225 /* Return the number of races */
3231 * Description of each monster group.
3233 static concptr object_group_text[] =
3236 "キノコ", /* "Mushrooms" */
3237 "薬", /* "Potions" */
3238 "油つぼ", /* "Flasks" */
3239 "巻物", /* "Scrolls" */
3241 "アミュレット", /* "Amulets" */
3242 "笛", /* "Whistle" */
3243 "光源", /* "Lanterns" */
3244 "魔法棒", /* "Wands" */
3247 "カード", /* "Cards" */
3258 "刀剣類", /* "Swords" */
3259 "鈍器", /* "Blunt Weapons" */
3260 "長柄武器", /* "Polearms" */
3261 "採掘道具", /* "Diggers" */
3262 "飛び道具", /* "Bows" */
3266 "軽装鎧", /* "Soft Armor" */
3267 "重装鎧", /* "Hard Armor" */
3268 "ドラゴン鎧", /* "Dragon Armor" */
3269 "盾", /* "Shields" */
3270 "クローク", /* "Cloaks" */
3271 "籠手", /* "Gloves" */
3272 "ヘルメット", /* "Helms" */
3274 "ブーツ", /* "Boots" */
3327 * TVALs of items in each group
3329 static byte object_group_tval[] =
3370 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3378 * Build a list of object indexes in the given group. Return the number
3379 * of objects in the group.
3381 * mode & 0x01 : check for non-empty group
3382 * mode & 0x02 : visual operation only
3384 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3386 KIND_OBJECT_IDX i, object_cnt = 0;
3389 /* Get a list of x_char in this group */
3390 byte group_tval = object_group_tval[grp_cur];
3392 /* Check every object */
3393 for (i = 0; i < max_k_idx; i++)
3395 /* Access the object */
3396 object_kind *k_ptr = &k_info[i];
3398 /* Skip empty objects */
3399 if (!k_ptr->name) continue;
3403 if (!current_world_ptr->wizard)
3405 /* Skip non-flavoured objects */
3406 if (!k_ptr->flavor) continue;
3408 /* Require objects ever seen */
3409 if (!k_ptr->aware) continue;
3412 /* Skip items with no distribution (special artifacts) */
3413 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3417 /* Check for objects in the group */
3418 if (TV_LIFE_BOOK == group_tval)
3420 /* Hack -- All spell books */
3421 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3423 /* Add the object */
3424 object_idx[object_cnt++] = i;
3428 else if (k_ptr->tval == group_tval)
3430 /* Add the object */
3431 object_idx[object_cnt++] = i;
3435 /* XXX Hack -- Just checking for non-empty group */
3436 if (mode & 0x01) break;
3439 /* Terminate the list */
3440 object_idx[object_cnt] = -1;
3442 /* Return the number of objects */
3448 * Description of each feature group.
3450 static concptr feature_group_text[] =
3458 * Build a list of feature indexes in the given group. Return the number
3459 * of features in the group.
3461 * mode & 0x01 : check for non-empty group
3463 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3465 /* Check every feature */
3466 FEAT_IDX feat_cnt = 0;
3467 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3469 feature_type *f_ptr = &f_info[i];
3471 /* Skip empty index */
3472 if (!f_ptr->name) continue;
3474 /* Skip mimiccing features */
3475 if (f_ptr->mimic != i) continue;
3478 feat_idx[feat_cnt++] = i;
3480 /* XXX Hack -- Just checking for non-empty group */
3481 if (mode & 0x01) break;
3484 /* Terminate the list */
3485 feat_idx[feat_cnt] = -1;
3487 /* Return the number of races */
3493 * Hack -- load a screen dump from a file
3495 void do_cmd_load_screen(void)
3499 SYMBOL_CODE c = ' ';
3505 Term_get_size(&wid, &hgt);
3506 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3508 /* Append to the file */
3509 fff = my_fopen(buf, "r");
3513 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3521 /* Load 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 /* Put the attr/char */
3540 Term_draw(x, y, TERM_WHITE, buf[x]);
3544 /* Dump the screen */
3545 for (y = 0; okay; y++)
3547 /* Get a line of data including control code */
3548 if (!fgets(buf, 1024, fff)) okay = FALSE;
3550 /* Get the blank line */
3551 if (buf[0] == '\n' || buf[0] == '\0') break;
3553 /* Ignore too large screen image */
3554 if (y >= hgt) continue;
3557 for (x = 0; x < wid - 1; x++)
3560 if (buf[x] == '\n' || buf[x] == '\0') break;
3562 /* Get the attr/char */
3563 (void)(Term_what(x, y, &a, &c));
3565 /* Look up the attr */
3566 for (int i = 0; i < 16; i++)
3568 /* Use attr matches */
3569 if (hack[i] == buf[x]) a = (byte_hack)i;
3572 /* Put the attr/char */
3573 Term_draw(x, y, a, c);
3579 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3587 // todo なぜこんな中途半端なところに? defineも…
3588 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3589 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3591 #define IM_FLAG_STR _("*", "* ")
3592 #define HAS_FLAG_STR _("+", "+ ")
3593 #define NO_FLAG_STR _("・", ". ")
3595 #define print_im_or_res_flag(IM, RES) \
3597 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3598 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3601 #define print_flag(TR) \
3603 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3607 /* XTRA HACK RESLIST */
3608 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
3610 GAME_TEXT o_name[MAX_NLEN];
3611 BIT_FLAGS flgs[TR_FLAG_SIZE];
3613 if (!o_ptr->k_idx) return;
3614 if (o_ptr->tval != tval) return;
3616 /* Identified items only */
3617 if (!object_is_known(o_ptr)) return;
3620 * HACK:Ring of Lordly protection and Dragon equipment
3621 * have random resistances.
3623 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3624 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3625 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3626 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3627 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3628 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3629 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3630 || object_is_artifact(o_ptr);
3631 if (!is_special_item_type)
3637 object_desc(o_name, o_ptr, OD_NAME_ONLY);
3639 while (o_name[i] && (i < 26))
3642 if (iskanji(o_name[i])) i++;
3651 o_name[i] = ' '; i++;
3657 fprintf(fff, "%s %s", where, o_name);
3659 if (!(o_ptr->ident & (IDENT_MENTAL)))
3661 fputs(_("-------不明--------------- -------不明---------\n",
3662 "-------unknown------------ -------unknown------\n"), fff);
3666 object_flags_known(o_ptr, flgs);
3668 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3669 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3670 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3671 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3672 print_flag(TR_RES_POIS);
3673 print_flag(TR_RES_LITE);
3674 print_flag(TR_RES_DARK);
3675 print_flag(TR_RES_SHARDS);
3676 print_flag(TR_RES_SOUND);
3677 print_flag(TR_RES_NETHER);
3678 print_flag(TR_RES_NEXUS);
3679 print_flag(TR_RES_CHAOS);
3680 print_flag(TR_RES_DISEN);
3684 print_flag(TR_RES_BLIND);
3685 print_flag(TR_RES_FEAR);
3686 print_flag(TR_RES_CONF);
3687 print_flag(TR_FREE_ACT);
3688 print_flag(TR_SEE_INVIS);
3689 print_flag(TR_HOLD_EXP);
3690 print_flag(TR_TELEPATHY);
3691 print_flag(TR_SLOW_DIGEST);
3692 print_flag(TR_REGEN);
3693 print_flag(TR_LEVITATION);
3702 fprintf(fff, "%s\n", inven_res_label);
3707 * Display *ID* ed weapons/armors's resistances
3709 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3712 GAME_TEXT file_name[1024];
3714 OBJECT_TYPE_VALUE tval;
3720 /* Open a new file */
3721 fff = my_fopen_temp(file_name, 1024);
3724 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3729 fprintf(fff, "%s\n", inven_res_label);
3731 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3735 for (; j < 9; j++) fputc('\n', fff);
3737 fprintf(fff, "%s\n", inven_res_label);
3740 strcpy(where, _("装", "E "));
3741 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3743 do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3746 strcpy(where, _("持", "I "));
3747 for (i = 0; i < INVEN_PACK; i++)
3749 do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3752 st_ptr = &town_info[1].store[STORE_HOME];
3753 strcpy(where, _("家", "H "));
3754 for (i = 0; i < st_ptr->stock_num; i++)
3756 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
3762 /* Display the file contents */
3763 show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3768 void do_cmd_save_screen_html_aux(char *filename, int message)
3776 concptr html_head[] = {
3777 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3781 concptr html_foot[] = {
3783 "</body>\n</html>\n",
3788 Term_get_size(&wid, &hgt);
3790 /* File type is "TEXT" */
3791 FILE_TYPE(FILE_TYPE_TEXT);
3793 /* Append to the file */
3795 fff = my_fopen(filename, "w");
3801 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3808 if (message) screen_save();
3810 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3812 tmpfff = my_fopen(buf, "r");
3815 for (int i = 0; html_head[i]; i++)
3816 fputs(html_head[i], fff);
3820 bool is_first_line = TRUE;
3821 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3825 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3826 is_first_line = FALSE;
3830 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3832 fprintf(fff, "%s\n", buf);
3837 /* Dump the screen */
3838 for (TERM_LEN y = 0; y < hgt; y++)
3841 if (y != 0) fprintf(fff, "\n");
3844 TERM_COLOR a = 0, old_a = 0;
3846 for (TERM_LEN x = 0; x < wid - 1; x++)
3849 /* Get the attr/char */
3850 (void)(Term_what(x, y, &a, &c));
3854 case '&': cc = "&"; break;
3855 case '<': cc = "<"; break;
3856 case '>': cc = ">"; break;
3858 case 0x1f: c = '.'; break;
3859 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3864 if ((y == 0 && x == 0) || a != old_a)
3866 int rv = angband_color_table[a][1];
3867 int gv = angband_color_table[a][2];
3868 int bv = angband_color_table[a][3];
3869 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3870 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3875 fprintf(fff, "%s", cc);
3877 fprintf(fff, "%c", c);
3881 fprintf(fff, "</font>");
3885 for (int i = 0; html_foot[i]; i++)
3886 fputs(html_foot[i], fff);
3891 bool is_first_line = TRUE;
3892 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3896 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3897 is_first_line = FALSE;
3901 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3903 fprintf(fff, "%s\n", buf);
3916 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3925 * Hack -- save a screen dump to a file
3927 static void do_cmd_save_screen_html(void)
3929 char buf[1024], tmp[256] = "screen.html";
3931 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3933 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3937 do_cmd_save_screen_html_aux(buf, 1);
3942 * Redefinable "save_screen" action
3944 void(*screendump_aux)(void) = NULL;
3948 * Save a screen dump to a file
3949 * @param creature_ptr プレーヤーへの参照ポインタ
3952 void do_cmd_save_screen(player_type *creature_ptr)
3954 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3955 bool html_dump = FALSE;
3959 if (c == 'Y' || c == 'y')
3961 else if (c == 'H' || c == 'h')
3974 Term_get_size(&wid, &hgt);
3976 bool old_use_graphics = use_graphics;
3977 if (old_use_graphics)
3979 use_graphics = FALSE;
3981 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
3982 handle_stuff(creature_ptr);
3987 do_cmd_save_screen_html();
3988 do_cmd_redraw(creature_ptr);
3991 /* Do we use a special screendump function ? */
3992 else if (screendump_aux)
3994 /* Dump the screen to a graphics file */
3995 (*screendump_aux)();
3997 else /* Dump the screen as text */
4001 SYMBOL_CODE c = ' ';
4004 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4006 /* File type is "TEXT" */
4007 FILE_TYPE(FILE_TYPE_TEXT);
4009 /* Append to the file */
4010 fff = my_fopen(buf, "w");
4014 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
4021 /* Dump the screen */
4022 for (y = 0; y < hgt; y++)
4025 for (x = 0; x < wid - 1; x++)
4027 /* Get the attr/char */
4028 (void)(Term_what(x, y, &a, &c));
4038 fprintf(fff, "%s\n", buf);
4045 /* Dump the screen */
4046 for (y = 0; y < hgt; y++)
4049 for (x = 0; x < wid - 1; x++)
4051 /* Get the attr/char */
4052 (void)(Term_what(x, y, &a, &c));
4055 buf[x] = hack[a & 0x0F];
4062 fprintf(fff, "%s\n", buf);
4069 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4074 if (!old_use_graphics) return;
4076 use_graphics = TRUE;
4078 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4079 handle_stuff(creature_ptr);
4084 * todo okay = 既知のアーティファクト? と思われるが確証がない
4085 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4086 * Check the status of "artifacts"
4087 * @param player_ptr プレーヤーへの参照ポインタ
4090 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4092 /* Open a new file */
4094 GAME_TEXT file_name[1024];
4095 fff = my_fopen_temp(file_name, 1024);
4098 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4103 /* Allocate the "who" array */
4105 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4107 /* Allocate the "okay" array */
4109 C_MAKE(okay, max_a_idx, bool);
4111 /* Scan the artifacts */
4112 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4114 artifact_type *a_ptr = &a_info[k];
4119 /* Skip "empty" artifacts */
4120 if (!a_ptr->name) continue;
4122 /* Skip "uncreated" artifacts */
4123 if (!a_ptr->cur_num) continue;
4129 /* Check the dungeon */
4130 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4132 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4134 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4136 OBJECT_IDX this_o_idx, next_o_idx = 0;
4138 /* Scan all objects in the grid */
4139 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4142 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4143 next_o_idx = o_ptr->next_o_idx;
4145 /* Ignore non-artifacts */
4146 if (!object_is_fixed_artifact(o_ptr)) continue;
4148 /* Ignore known items */
4149 if (object_is_known(o_ptr)) continue;
4151 /* Note the artifact */
4152 okay[o_ptr->name1] = FALSE;
4157 /* Check the player_ptr->inventory_list and equipment */
4158 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4160 object_type *o_ptr = &player_ptr->inventory_list[i];
4162 /* Ignore non-objects */
4163 if (!o_ptr->k_idx) continue;
4165 /* Ignore non-artifacts */
4166 if (!object_is_fixed_artifact(o_ptr)) continue;
4168 /* Ignore known items */
4169 if (object_is_known(o_ptr)) continue;
4171 /* Note the artifact */
4172 okay[o_ptr->name1] = FALSE;
4176 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4178 if (okay[k]) who[n++] = k;
4182 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4184 /* Scan the artifacts */
4185 for (ARTIFACT_IDX k = 0; k < n; k++)
4187 artifact_type *a_ptr = &a_info[who[k]];
4188 GAME_TEXT base_name[MAX_NLEN];
4189 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4191 /* Obtain the base object type */
4192 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4201 /* Create fake object */
4202 object_prep(q_ptr, z);
4204 /* Make it an artifact */
4205 q_ptr->name1 = (byte)who[k];
4207 /* Display as if known */
4208 q_ptr->ident |= IDENT_STORE;
4210 /* Describe the artifact */
4211 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4214 /* Hack -- Build the artifact name */
4215 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4218 /* Free the "who" array */
4219 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4221 /* Free the "okay" array */
4222 C_KILL(okay, max_a_idx, bool);
4225 /* Display the file contents */
4226 show_file(player_ptr, TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4232 * Display known uniques
4233 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4235 static void do_cmd_knowledge_uniques(player_type *creature_ptr)
4242 GAME_TEXT file_name[1024];
4245 int n_alive_surface = 0;
4246 int n_alive_over100 = 0;
4247 int n_alive_total = 0;
4250 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4252 /* Open a new file */
4253 fff = my_fopen_temp(file_name, 1024);
4257 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4262 /* Allocate the "who" array */
4263 C_MAKE(who, max_r_idx, MONRACE_IDX);
4265 /* Scan the monsters */
4267 for (IDX i = 1; i < max_r_idx; i++)
4269 monster_race *r_ptr = &r_info[i];
4272 if (!r_ptr->name) continue;
4274 /* Require unique monsters */
4275 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4277 /* Only display "known" uniques */
4278 if (!cheat_know && !r_ptr->r_sights) continue;
4280 /* Only print rarity <= 100 uniques */
4281 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4283 /* Only "alive" uniques */
4284 if (r_ptr->max_num == 0) continue;
4288 lev = (r_ptr->level - 1) / 10;
4292 if (max_lev < lev) max_lev = lev;
4294 else n_alive_over100++;
4296 else n_alive_surface++;
4298 /* Collect "appropriate" monsters */
4302 /* Sort the array by dungeon depth of monsters */
4303 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4305 if (n_alive_surface)
4307 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4308 n_alive_total += n_alive_surface;
4311 for (IDX i = 0; i <= max_lev; i++)
4313 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4314 n_alive_total += n_alive[i];
4317 if (n_alive_over100)
4319 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4320 n_alive_total += n_alive_over100;
4325 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4326 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4330 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4333 /* Scan the monster races */
4334 for (int k = 0; k < n; k++)
4336 monster_race *r_ptr = &r_info[who[k]];
4337 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4340 /* Free the "who" array */
4341 C_KILL(who, max_r_idx, s16b);
4344 /* Display the file contents */
4345 show_file(creature_ptr, TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4351 * Display weapon-exp
4353 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4355 /* Open a new file */
4357 GAME_TEXT file_name[1024];
4358 fff = my_fopen_temp(file_name, 1024);
4361 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4366 for (int i = 0; i < 5; i++)
4368 for (int num = 0; num < 64; num++)
4372 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4374 object_kind *k_ptr = &k_info[j];
4376 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4377 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4379 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4381 fprintf(fff, "%-25s ", tmp);
4382 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4383 else fprintf(fff, " ");
4384 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4385 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4394 /* Display the file contents */
4395 show_file(creature_ptr, TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4401 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4405 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4407 /* Open a new file */
4409 GAME_TEXT file_name[1024];
4410 fff = my_fopen_temp(file_name, 1024);
4413 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4418 if (creature_ptr->realm1 != REALM_NONE)
4420 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4421 for (SPELL_IDX i = 0; i < 32; i++)
4423 const magic_type *s_ptr;
4424 if (!is_magic(creature_ptr->realm1))
4426 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4430 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4433 if (s_ptr->slevel >= 99) continue;
4434 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4435 int exp_level = spell_exp_level(spell_exp);
4436 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4437 if (creature_ptr->realm1 == REALM_HISSATSU)
4438 fprintf(fff, "[--]");
4441 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4442 else fprintf(fff, " ");
4443 fprintf(fff, "%s", exp_level_str[exp_level]);
4446 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4451 if (creature_ptr->realm2 != REALM_NONE)
4453 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4454 for (SPELL_IDX i = 0; i < 32; i++)
4456 const magic_type *s_ptr;
4457 if (!is_magic(creature_ptr->realm1))
4459 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4463 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4466 if (s_ptr->slevel >= 99) continue;
4468 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4469 int exp_level = spell_exp_level(spell_exp);
4470 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4471 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4472 else fprintf(fff, " ");
4473 fprintf(fff, "%s", exp_level_str[exp_level]);
4474 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4481 /* Display the file contents */
4482 show_file(creature_ptr, TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4488 * @brief スキル情報を表示するコマンドのメインルーチン /
4492 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4494 char skill_name[GINOU_TEMPMAX][20] =
4496 _("マーシャルアーツ", "Martial Arts "),
4497 _("二刀流 ", "Dual Wielding "),
4498 _("乗馬 ", "Riding "),
4502 /* Open a new file */
4504 char file_name[1024];
4505 fff = my_fopen_temp(file_name, 1024);
4508 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4513 for (int i = 0; i < GINOU_TEMPMAX; i++)
4515 int skill_exp = creature_ptr->skill_exp[i];
4516 fprintf(fff, "%-20s ", skill_name[i]);
4517 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4518 else fprintf(fff, " ");
4519 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4520 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4526 /* Display the file contents */
4527 show_file(creature_ptr, TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4533 * @brief 現在のペットを表示するコマンドのメインルーチン /
4534 * Display current pets
4535 * @param creature_ptr プレーヤーへの参照ポインタ
4538 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4540 /* Open a new file */
4541 GAME_TEXT file_name[1024];
4543 fff = my_fopen_temp(file_name, 1024);
4546 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4551 /* Process the monsters (backwards) */
4552 monster_type *m_ptr;
4553 GAME_TEXT pet_name[MAX_NLEN];
4555 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4557 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4559 /* Ignore "dead" monsters */
4560 if (!monster_is_valid(m_ptr)) continue;
4562 /* Calculate "upkeep" for pets */
4563 if (!is_pet(m_ptr)) continue;
4566 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4567 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4570 int show_upkeep = calculate_upkeep(creature_ptr);
4572 fprintf(fff, "----------------------------------------------\n");
4574 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4576 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4578 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4582 /* Display the file contents */
4583 show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4589 * @brief 現在のペットを表示するコマンドのメインルーチン /
4590 * @param creature_ptr プレーヤーへの参照ポインタ
4593 * @note the player ghosts are ignored.
4595 static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
4597 /* Open a new file */
4599 GAME_TEXT file_name[1024];
4600 fff = my_fopen_temp(file_name, 1024);
4603 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4608 /* Allocate the "who" array */
4610 C_MAKE(who, max_r_idx, MONRACE_IDX);
4614 /* Monsters slain */
4615 for (int kk = 1; kk < max_r_idx; kk++)
4617 monster_race *r_ptr = &r_info[kk];
4619 if (r_ptr->flags1 & (RF1_UNIQUE))
4621 bool dead = (r_ptr->max_num == 0);
4630 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4632 if (this_monster > 0)
4634 total += this_monster;
4640 fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4643 fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
4645 fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4651 /* Scan the monsters */
4653 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4655 monster_race *r_ptr = &r_info[i];
4657 /* Use that monster */
4658 if (r_ptr->name) who[n++] = i;
4661 /* Sort the array by dungeon depth of monsters */
4663 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4665 /* Scan the monster races */
4666 for (int k = 0; k < n; k++)
4668 monster_race *r_ptr = &r_info[who[k]];
4670 if (r_ptr->flags1 & (RF1_UNIQUE))
4672 bool dead = (r_ptr->max_num == 0);
4676 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4683 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4685 if (this_monster <= 0) continue;
4688 /* p,tは人と数える by ita */
4689 if (my_strchr("pt", r_ptr->d_char))
4690 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4692 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4694 if (this_monster < 2)
4696 if (my_strstr(r_name + r_ptr->name, "coins"))
4698 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4702 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4708 strcpy(ToPlural, (r_name + r_ptr->name));
4709 plural_aux(ToPlural);
4710 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4713 total += this_monster;
4716 fprintf(fff, "----------------------------------------------\n");
4718 fprintf(fff, " 合計: %lu 体を倒した。\n", (unsigned long int)total);
4720 fprintf(fff, " Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4723 /* Free the "who" array */
4724 C_KILL(who, max_r_idx, s16b);
4727 /* Display the file contents */
4728 show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4734 * @brief モンスター情報リスト中のグループを表示する /
4735 * Display the object groups.
4739 * @param per_page リストの表示行
4740 * @param grp_idx グループのID配列
4741 * @param group_text グループ名の文字列配列
4742 * @param grp_cur 現在の選択ID
4743 * @param grp_top 現在の選択リスト最上部ID
4746 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)
4748 /* Display lines until done */
4749 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4751 /* Get the group index */
4752 int grp = grp_idx[grp_top + i];
4754 /* Choose a color */
4755 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4757 /* Erase the entire line */
4758 Term_erase(col, row + i, wid);
4760 /* Display the group label */
4761 c_put_str(attr, group_text[grp], row + i, col);
4767 * Move the cursor in a browser window
4769 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4770 IDX *list_cur, int list_cnt)
4775 IDX list = *list_cur;
4777 /* Extract direction */
4780 /* Hack -- scroll up full screen */
4785 /* Hack -- scroll down full screen */
4790 d = get_keymap_dir(ch);
4795 /* Diagonals - hack */
4796 if ((ddx[d] > 0) && ddy[d])
4801 Term_get_size(&wid, &hgt);
4803 browser_rows = hgt - 8;
4805 /* Browse group list */
4810 /* Move up or down */
4811 grp += ddy[d] * (browser_rows - 1);
4814 if (grp >= grp_cnt) grp = grp_cnt - 1;
4815 if (grp < 0) grp = 0;
4816 if (grp != old_grp) list = 0;
4819 /* Browse sub-list list */
4822 /* Move up or down */
4823 list += ddy[d] * browser_rows;
4826 if (list >= list_cnt) list = list_cnt - 1;
4827 if (list < 0) list = 0;
4839 if (col < 0) col = 0;
4840 if (col > 1) col = 1;
4847 /* Browse group list */
4852 /* Move up or down */
4856 if (grp >= grp_cnt) grp = grp_cnt - 1;
4857 if (grp < 0) grp = 0;
4858 if (grp != old_grp) list = 0;
4861 /* Browse sub-list list */
4864 /* Move up or down */
4865 list += (IDX)ddy[d];
4868 if (list >= list_cnt) list = list_cnt - 1;
4869 if (list < 0) list = 0;
4880 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4882 /* Clear the display lines */
4883 for (int i = 0; i < height; i++)
4885 Term_erase(col, row + i, width);
4888 /* Bigtile mode uses double width */
4889 if (use_bigtile) width /= 2;
4891 /* Display lines until done */
4892 for (int i = 0; i < height; i++)
4894 /* Display columns until done */
4895 for (int j = 0; j < width; j++)
4897 TERM_LEN x = col + j;
4898 TERM_LEN y = row + i;
4900 /* Bigtile mode uses double width */
4901 if (use_bigtile) x += j;
4903 TERM_COLOR ia = attr_top + i;
4904 SYMBOL_CODE ic = char_left + j;
4906 /* Ignore illegal characters */
4907 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4908 (!use_graphics && ic > 0x7f))
4914 /* Force correct code for both ASCII character and tile */
4915 if (c & 0x80) a |= 0x80;
4917 /* Display symbol */
4918 Term_queue_bigchar(x, y, a, c, 0, 0);
4925 * Place the cursor at the collect position for visual mode
4927 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4929 int i = (a & 0x7f) - attr_top;
4930 int j = c - char_left;
4932 TERM_LEN x = col + j;
4933 TERM_LEN y = row + i;
4935 /* Bigtile mode uses double width */
4936 if (use_bigtile) x += j;
4938 /* Place the cursor */
4944 * Do visual mode command -- Change symbols
4946 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4947 int height, int width,
4948 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4949 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4951 static TERM_COLOR attr_old = 0;
4952 static SYMBOL_CODE char_old = 0;
4957 if (*visual_list_ptr)
4960 *cur_attr_ptr = attr_old;
4961 *cur_char_ptr = char_old;
4962 *visual_list_ptr = FALSE;
4970 if (*visual_list_ptr)
4973 *visual_list_ptr = FALSE;
4974 *need_redraw = TRUE;
4982 if (!*visual_list_ptr)
4984 *visual_list_ptr = TRUE;
4986 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
4987 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
4989 attr_old = *cur_attr_ptr;
4990 char_old = *cur_char_ptr;
5001 /* Set the visual */
5002 attr_idx = *cur_attr_ptr;
5003 char_idx = *cur_char_ptr;
5005 /* Hack -- for feature lighting */
5006 for (i = 0; i < F_LIT_MAX; i++)
5008 attr_idx_feat[i] = 0;
5009 char_idx_feat[i] = 0;
5016 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
5019 *cur_attr_ptr = attr_idx;
5020 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5021 if (!*visual_list_ptr) *need_redraw = TRUE;
5027 *cur_char_ptr = char_idx;
5028 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5029 if (!*visual_list_ptr) *need_redraw = TRUE;
5035 if (*visual_list_ptr)
5038 int d = get_keymap_dir(ch);
5039 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5040 SYMBOL_CODE c = *cur_char_ptr;
5042 if (use_bigtile) eff_width = width / 2;
5043 else eff_width = width;
5045 /* Restrict direction */
5046 if ((a == 0) && (ddy[d] < 0)) d = 0;
5047 if ((c == 0) && (ddx[d] < 0)) d = 0;
5048 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5049 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5051 a += (TERM_COLOR)ddy[d];
5052 c += (SYMBOL_CODE)ddx[d];
5054 /* Force correct code for both ASCII character and tile */
5055 if (c & 0x80) a |= 0x80;
5057 /* Set the visual */
5062 /* Move the frame */
5063 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5064 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5065 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5066 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5072 /* Visual mode command is not used */
5078 * Display the monsters in a group.
5080 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5081 int mon_cur, int mon_top, bool visual_only)
5083 /* Display lines until done */
5085 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5089 /* Get the race index */
5090 MONRACE_IDX r_idx = mon_idx[mon_top + i];
5092 /* Access the race */
5093 monster_race *r_ptr = &r_info[r_idx];
5095 /* Choose a color */
5096 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5098 /* Display the name */
5099 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5101 /* Hack -- visual_list mode */
5104 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5107 if (current_world_ptr->wizard || visual_only)
5109 c_prt(attr, format("%d", r_idx), row + i, 62);
5112 /* Erase chars before overwritten by the race letter */
5113 Term_erase(69, row + i, 255);
5115 /* Display symbol */
5116 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5121 if (!(r_ptr->flags1 & RF1_UNIQUE))
5122 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5124 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5125 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5129 /* Clear remaining lines */
5130 for (; i < per_page; i++)
5132 Term_erase(col, row + i, 255);
5138 * todo 引数の詳細について加筆求む
5139 * Display known monsters.
5140 * @param creature_ptr プレーヤーへの参照ポインタ
5141 * @param need_redraw 画面の再描画が必要な時TRUE
5142 * @param visual_only ???
5143 * @param direct_r_idx モンスターID
5146 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5149 Term_get_size(&wid, &hgt);
5151 /* Allocate the "mon_idx" array */
5153 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5159 bool visual_list = FALSE;
5160 TERM_COLOR attr_top = 0;
5163 int browser_rows = hgt - 8;
5164 if (direct_r_idx < 0)
5166 mode = visual_only ? 0x03 : 0x01;
5168 /* Check every group */
5170 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5172 /* Measure the label */
5173 len = strlen(monster_group_text[i]);
5175 /* Save the maximum length */
5176 if (len > max) max = len;
5178 /* See if any monsters are known */
5179 if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5181 /* Build a list of groups with known monsters */
5182 grp_idx[grp_cnt++] = i;
5190 mon_idx[0] = direct_r_idx;
5193 /* Terminate the list */
5196 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5197 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5200 /* Terminate the list */
5201 grp_idx[grp_cnt] = -1;
5203 mode = visual_only ? 0x02 : 0x00;
5204 IDX old_grp_cur = -1;
5217 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5218 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5219 prt(_("名前", "Name"), 4, max + 3);
5220 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5221 prt(_("文字", "Sym"), 4, 67);
5222 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5224 for (IDX i = 0; i < 78; i++)
5226 Term_putch(i, 5, TERM_WHITE, '=');
5229 if (direct_r_idx < 0)
5231 for (IDX i = 0; i < browser_rows; i++)
5233 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5240 if (direct_r_idx < 0)
5242 /* Scroll group list */
5243 if (grp_cur < grp_top) grp_top = grp_cur;
5244 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5246 /* Display a list of monster groups */
5247 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5249 if (old_grp_cur != grp_cur)
5251 old_grp_cur = grp_cur;
5253 /* Get a list of monsters in the current group */
5254 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5257 /* Scroll monster list */
5258 while (mon_cur < mon_top)
5259 mon_top = MAX(0, mon_top - browser_rows / 2);
5260 while (mon_cur >= mon_top + browser_rows)
5261 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
5266 /* Display a list of monsters in the current group */
5267 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5273 /* Display a monster name */
5274 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5276 /* Display visual list below first monster */
5277 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5281 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5282 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5283 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5284 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5287 /* Get the current monster */
5288 monster_race *r_ptr;
5289 r_ptr = &r_info[mon_idx[mon_cur]];
5293 /* Mega Hack -- track this monster race */
5294 if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
5295 handle_stuff(creature_ptr);
5300 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5304 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5308 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5313 /* Do visual mode command if needed */
5314 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))
5316 if (direct_r_idx >= 0)
5342 /* Recall on screen */
5343 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5345 screen_roff(mon_idx[mon_cur], 0);
5357 /* Move the cursor */
5358 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5365 /* Free the "mon_idx" array */
5366 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5371 * Display the objects in a group.
5373 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5374 int object_cur, int object_top, bool visual_only)
5376 /* Display lines until done */
5378 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5380 GAME_TEXT o_name[MAX_NLEN];
5383 object_kind *flavor_k_ptr;
5385 /* Get the object index */
5386 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5388 /* Access the object */
5389 object_kind *k_ptr = &k_info[k_idx];
5391 /* Choose a color */
5392 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5393 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5395 if (!visual_only && k_ptr->flavor)
5397 /* Appearance of this object is shuffled */
5398 flavor_k_ptr = &k_info[k_ptr->flavor];
5402 /* Appearance of this object is very normal */
5403 flavor_k_ptr = k_ptr;
5406 attr = ((i + object_top == object_cur) ? cursor : attr);
5408 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5411 strip_name(o_name, k_idx);
5416 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5419 /* Display the name */
5420 c_prt(attr, o_name, row + i, col);
5422 /* Hack -- visual_list mode */
5425 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);
5428 if (current_world_ptr->wizard || visual_only)
5430 c_prt(attr, format("%d", k_idx), row + i, 70);
5433 a = flavor_k_ptr->x_attr;
5434 c = flavor_k_ptr->x_char;
5436 /* Display symbol */
5437 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5440 /* Clear remaining lines */
5441 for (; i < per_page; i++)
5443 Term_erase(col, row + i, 255);
5449 * Describe fake object
5451 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5454 object_type object_type_body;
5455 o_ptr = &object_type_body;
5457 object_prep(o_ptr, k_idx);
5459 /* It's fully know */
5460 o_ptr->ident |= IDENT_KNOWN;
5461 handle_stuff(creature_ptr);
5463 if (screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5465 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5471 * Display known objects
5473 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5475 IDX object_old, object_top;
5478 OBJECT_IDX *object_idx;
5480 bool visual_list = FALSE;
5481 TERM_COLOR attr_top = 0;
5486 Term_get_size(&wid, &hgt);
5488 int browser_rows = hgt - 8;
5490 /* Allocate the "object_idx" array */
5491 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5496 if (direct_k_idx < 0)
5498 mode = visual_only ? 0x03 : 0x01;
5500 /* Check every group */
5501 for (IDX i = 0; object_group_text[i] != NULL; i++)
5503 /* Measure the label */
5504 len = strlen(object_group_text[i]);
5506 /* Save the maximum length */
5507 if (len > max) max = len;
5509 /* See if any monsters are known */
5510 if (collect_objects(i, object_idx, mode))
5512 /* Build a list of groups with known monsters */
5513 grp_idx[grp_cnt++] = i;
5522 object_kind *k_ptr = &k_info[direct_k_idx];
5523 object_kind *flavor_k_ptr;
5525 if (!visual_only && k_ptr->flavor)
5527 /* Appearance of this object is shuffled */
5528 flavor_k_ptr = &k_info[k_ptr->flavor];
5532 /* Appearance of this object is very normal */
5533 flavor_k_ptr = k_ptr;
5536 object_idx[0] = direct_k_idx;
5537 object_old = direct_k_idx;
5540 /* Terminate the list */
5543 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5544 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5547 /* Terminate the list */
5548 grp_idx[grp_cnt] = -1;
5550 mode = visual_only ? 0x02 : 0x00;
5551 IDX old_grp_cur = -1;
5554 IDX object_cur = object_top = 0;
5560 object_kind *k_ptr, *flavor_k_ptr;
5567 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5568 if (direct_k_idx < 0) prt("グループ", 4, 0);
5569 prt("名前", 4, max + 3);
5570 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5573 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5574 if (direct_k_idx < 0) prt("Group", 4, 0);
5575 prt("Name", 4, max + 3);
5576 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5580 for (IDX i = 0; i < 78; i++)
5582 Term_putch(i, 5, TERM_WHITE, '=');
5585 if (direct_k_idx < 0)
5587 for (IDX i = 0; i < browser_rows; i++)
5589 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5596 if (direct_k_idx < 0)
5598 /* Scroll group list */
5599 if (grp_cur < grp_top) grp_top = grp_cur;
5600 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5602 /* Display a list of object groups */
5603 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5605 if (old_grp_cur != grp_cur)
5607 old_grp_cur = grp_cur;
5609 /* Get a list of objects in the current group */
5610 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5613 /* Scroll object list */
5614 while (object_cur < object_top)
5615 object_top = MAX(0, object_top - browser_rows / 2);
5616 while (object_cur >= object_top + browser_rows)
5617 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows / 2);
5622 /* Display a list of objects in the current group */
5623 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5627 object_top = object_cur;
5629 /* Display a list of objects in the current group */
5630 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5632 /* Display visual list below first object */
5633 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5636 /* Get the current object */
5637 k_ptr = &k_info[object_idx[object_cur]];
5639 if (!visual_only && k_ptr->flavor)
5641 /* Appearance of this object is shuffled */
5642 flavor_k_ptr = &k_info[k_ptr->flavor];
5646 /* Appearance of this object is very normal */
5647 flavor_k_ptr = k_ptr;
5652 prt(format("<方向>%s%s%s, ESC",
5653 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5654 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5655 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5658 prt(format("<dir>%s%s%s, ESC",
5659 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5660 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5661 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5667 /* Mega Hack -- track this object */
5668 if (object_cnt) object_kind_track(creature_ptr, object_idx[object_cur]);
5670 /* The "current" object changed */
5671 if (object_old != object_idx[object_cur])
5673 handle_stuff(creature_ptr);
5675 /* Remember the "current" object */
5676 object_old = object_idx[object_cur];
5682 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5686 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5690 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5695 /* Do visual mode command if needed */
5696 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))
5698 if (direct_k_idx >= 0)
5723 /* Recall on screen */
5724 if (!visual_list && !visual_only && (grp_cnt > 0))
5726 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5734 /* Move the cursor */
5735 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5741 /* Free the "object_idx" array */
5742 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5747 * Display the features in a group.
5749 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5750 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5752 int lit_col[F_LIT_MAX], i;
5753 int f_idx_col = use_bigtile ? 62 : 64;
5755 /* Correct columns 1 and 4 */
5756 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5757 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5758 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5760 /* Display lines until done */
5761 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5764 FEAT_IDX f_idx = feat_idx[feat_top + i];
5765 feature_type *f_ptr = &f_info[f_idx];
5766 int row_i = row + i;
5768 /* Choose a color */
5769 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5771 /* Display the name */
5772 c_prt(attr, f_name + f_ptr->name, row_i, col);
5774 /* Hack -- visual_list mode */
5777 /* Display lighting level */
5778 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5780 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));
5782 if (current_world_ptr->wizard || visual_only)
5784 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5787 /* Display symbol */
5788 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);
5790 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5791 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5793 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5795 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5797 /* Mega-hack -- Use non-standard colour */
5798 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5800 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5804 /* Clear remaining lines */
5805 for (; i < per_page; i++)
5807 Term_erase(col, row + i, 255);
5813 * Interact with feature visuals.
5815 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5817 TERM_COLOR attr_old[F_LIT_MAX];
5818 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5819 SYMBOL_CODE char_old[F_LIT_MAX];
5820 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5823 Term_get_size(&wid, &hgt);
5825 /* Allocate the "feat_idx" array */
5827 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5833 FEAT_IDX grp_idx[100];
5834 TERM_COLOR attr_top = 0;
5835 bool visual_list = FALSE;
5837 TERM_LEN browser_rows = hgt - 8;
5838 if (direct_f_idx < 0)
5840 /* Check every group */
5841 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5843 /* Measure the label */
5844 len = strlen(feature_group_text[i]);
5846 /* Save the maximum length */
5847 if (len > max) max = len;
5849 /* See if any features are known */
5850 if (collect_features(feat_idx, 0x01))
5852 /* Build a list of groups with known features */
5853 grp_idx[grp_cnt++] = i;
5861 feature_type *f_ptr = &f_info[direct_f_idx];
5863 feat_idx[0] = direct_f_idx;
5866 /* Terminate the list */
5869 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5870 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5872 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5874 attr_old[i] = f_ptr->x_attr[i];
5875 char_old[i] = f_ptr->x_char[i];
5879 /* Terminate the list */
5880 grp_idx[grp_cnt] = -1;
5882 FEAT_IDX old_grp_cur = -1;
5883 FEAT_IDX grp_cur = 0;
5884 FEAT_IDX grp_top = 0;
5885 FEAT_IDX feat_cur = 0;
5886 FEAT_IDX feat_top = 0;
5887 TERM_LEN column = 0;
5890 TERM_COLOR *cur_attr_ptr;
5891 SYMBOL_CODE *cur_char_ptr;
5895 feature_type *f_ptr;
5901 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5902 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5903 prt(_("名前", "Name"), 4, max + 3);
5906 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5907 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5911 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5912 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5915 for (FEAT_IDX i = 0; i < 78; i++)
5917 Term_putch(i, 5, TERM_WHITE, '=');
5920 if (direct_f_idx < 0)
5922 for (FEAT_IDX i = 0; i < browser_rows; i++)
5924 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5931 if (direct_f_idx < 0)
5933 /* Scroll group list */
5934 if (grp_cur < grp_top) grp_top = grp_cur;
5935 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5937 /* Display a list of feature groups */
5938 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5940 if (old_grp_cur != grp_cur)
5942 old_grp_cur = grp_cur;
5944 /* Get a list of features in the current group */
5945 feat_cnt = collect_features(feat_idx, 0x00);
5948 /* Scroll feature list */
5949 while (feat_cur < feat_top)
5950 feat_top = MAX(0, feat_top - browser_rows / 2);
5951 while (feat_cur >= feat_top + browser_rows)
5952 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows / 2);
5957 /* Display a list of features in the current group */
5958 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
5962 feat_top = feat_cur;
5964 /* Display a list of features in the current group */
5965 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
5967 /* Display visual list below first object */
5968 display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
5972 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
5973 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5974 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5977 /* Get the current feature */
5978 f_ptr = &f_info[feat_idx[feat_cur]];
5979 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
5980 cur_char_ptr = &f_ptr->x_char[*lighting_level];
5984 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
5988 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5992 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
5997 if (visual_list && ((ch == 'A') || (ch == 'a')))
5999 int prev_lighting_level = *lighting_level;
6003 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
6004 else (*lighting_level)--;
6008 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
6009 else (*lighting_level)++;
6012 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
6013 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6015 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
6016 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6021 else if ((ch == 'D') || (ch == 'd'))
6023 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
6024 byte prev_x_char = f_ptr->x_char[*lighting_level];
6026 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6030 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6031 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6033 if (prev_x_char != f_ptr->x_char[*lighting_level])
6034 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6036 else *need_redraw = TRUE;
6041 /* Do visual mode command if needed */
6042 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))
6046 /* Restore previous visual settings */
6048 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6050 f_ptr->x_attr[i] = attr_old[i];
6051 f_ptr->x_char[i] = char_old[i];
6058 if (direct_f_idx >= 0) flag = TRUE;
6059 else *lighting_level = F_LIT_STANDARD;
6062 /* Preserve current visual settings */
6065 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6067 attr_old[i] = f_ptr->x_attr[i];
6068 char_old[i] = f_ptr->x_char[i];
6070 *lighting_level = F_LIT_STANDARD;
6077 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6079 attr_idx_feat[i] = f_ptr->x_attr[i];
6080 char_idx_feat[i] = f_ptr->x_char[i];
6089 /* Allow TERM_DARK text */
6090 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6092 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6093 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6111 /* Move the cursor */
6112 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6118 /* Free the "feat_idx" array */
6119 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6124 * List wanted monsters
6125 * @param creature_ptr プレーヤーへの参照ポインタ
6128 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6130 /* Open a new file */
6132 GAME_TEXT file_name[1024];
6133 fff = my_fopen_temp(file_name, 1024);
6136 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6141 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
6142 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6144 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6145 fprintf(fff, "----------------------------------------------\n");
6147 bool listed = FALSE;
6148 for (int i = 0; i < MAX_BOUNTY; i++)
6150 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6152 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6159 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
6164 /* Display the file contents */
6165 show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6170 * List virtues & status
6172 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6174 /* Open a new file */
6176 GAME_TEXT file_name[1024];
6177 fff = my_fopen_temp(file_name, 1024);
6180 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6185 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment(creature_ptr));
6186 dump_virtues(creature_ptr, fff);
6189 /* Display the file contents */
6190 show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6197 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
6199 /* Open a new file */
6201 GAME_TEXT file_name[1024];
6202 fff = my_fopen_temp(file_name, 1024);
6205 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6210 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6214 if (!d_info[i].maxdepth) continue;
6215 if (!max_dlv[i]) continue;
6216 if (d_info[i].final_guardian)
6218 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6220 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6222 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6227 /* Display the file contents */
6228 show_file(creature_ptr, TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6234 * List virtues & status
6237 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6239 /* Open a new file */
6241 GAME_TEXT file_name[1024];
6242 fff = my_fopen_temp(file_name, 1024);
6245 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6250 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6251 (2 * creature_ptr->hitdie +
6252 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6254 if (creature_ptr->knowledge & KNOW_HPRATE)
6255 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6256 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6258 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6259 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6261 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);
6262 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6265 dump_yourself(creature_ptr, fff);
6268 /* Display the file contents */
6269 show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6275 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6276 * Print all active quests
6277 * @param creature_ptr プレーヤーへの参照ポインタ
6280 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6283 char rand_tmp_str[120] = "\0";
6284 GAME_TEXT name[MAX_NLEN];
6285 monster_race *r_ptr;
6286 int rand_level = 100;
6289 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6291 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6293 bool is_no_print = quest[i].status != QUEST_STATUS_TAKEN;
6294 is_no_print &= (quest[i].status != QUEST_STATUS_STAGE_COMPLETED) || (quest[i].type != QUEST_TYPE_TOWER);
6295 is_no_print &= quest[i].status == QUEST_STATUS_COMPLETED;
6299 /* Set the quest number temporary */
6300 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6302 /* Clear the text */
6303 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6304 quest_text_line = 0;
6306 creature_ptr->current_floor_ptr->inside_quest = i;
6308 /* Get the quest text */
6309 init_flags = INIT_SHOW_TEXT;
6311 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6313 /* Reset the old quest number */
6314 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6316 /* No info from "silent" quests */
6317 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6321 if (quest[i].type != QUEST_TYPE_RANDOM)
6323 char note[80] = "\0";
6325 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6327 switch (quest[i].type)
6329 case QUEST_TYPE_KILL_LEVEL:
6330 case QUEST_TYPE_KILL_ANY_LEVEL:
6331 r_ptr = &r_info[quest[i].r_idx];
6332 strcpy(name, r_name + r_ptr->name);
6333 if (quest[i].max_num > 1)
6336 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6337 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6340 sprintf(note, " - kill %d %s, have killed %d.",
6341 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6345 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6348 case QUEST_TYPE_FIND_ARTIFACT:
6351 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6353 object_type *q_ptr = &forge;
6354 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6355 object_prep(q_ptr, k_idx);
6356 q_ptr->name1 = quest[i].k_idx;
6357 q_ptr->ident = IDENT_STORE;
6358 object_desc(name, q_ptr, OD_NAME_ONLY);
6360 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find out %s."), name);
6362 case QUEST_TYPE_FIND_EXIT:
6363 sprintf(note, _(" - 出口に到達する。", " - Reach to Exit."));
6366 case QUEST_TYPE_KILL_NUMBER:
6368 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6369 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6371 sprintf(note, " - Kill %d monsters, have killed %d.",
6372 (int)quest[i].max_num, (int)quest[i].cur_num);
6376 case QUEST_TYPE_KILL_ALL:
6377 case QUEST_TYPE_TOWER:
6378 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6383 /* Print the quest info */
6384 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6385 quest[i].name, (int)quest[i].level, note);
6387 fputs(tmp_str, fff);
6389 if (quest[i].status == QUEST_STATUS_COMPLETED)
6391 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6392 fputs(tmp_str, fff);
6397 while (quest_text[k][0] && k < 10)
6399 fprintf(fff, " %s\n", quest_text[k]);
6406 /* QUEST_TYPE_RANDOM */
6407 if (quest[i].level >= rand_level)
6411 rand_level = quest[i].level;
6413 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6415 /* Print the quest info */
6416 r_ptr = &r_info[quest[i].r_idx];
6417 strcpy(name, r_name + r_ptr->name);
6419 if (quest[i].max_num <= 1)
6421 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6422 quest[i].name, (int)quest[i].level, name);
6427 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6428 quest[i].name, (int)quest[i].level,
6429 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6433 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6434 quest[i].name, (int)quest[i].level,
6435 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6439 /* Print the current random quest */
6440 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6442 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6446 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6449 char playtime_str[16];
6450 quest_type* const q_ptr = &quest[q_idx];
6452 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6453 if (is_fixed_quest_idx(q_idx))
6455 /* Set the quest number temporary */
6456 IDX old_quest = floor_ptr->inside_quest;
6458 floor_ptr->inside_quest = q_idx;
6461 init_flags = INIT_NAME_ONLY;
6463 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6465 /* Reset the old quest number */
6466 floor_ptr->inside_quest = old_quest;
6468 /* No info from "silent" quests */
6469 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6472 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6473 q_ptr->comptime / (60 * 60), (q_ptr->comptime / 60) % 60, q_ptr->comptime % 60);
6475 if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6477 /* Print the quest info */
6479 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6480 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6481 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6482 fputs(tmp_str, fff);
6486 /* Print the quest info */
6487 if (q_ptr->complev == 0)
6490 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6491 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6492 r_name + r_info[q_ptr->r_idx].name,
6493 (int)q_ptr->level, playtime_str);
6494 fputs(tmp_str, fff);
6499 _(" %-35s (%3d階) - レベル%2d - %s\n",
6500 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6501 r_name + r_info[q_ptr->r_idx].name,
6505 fputs(tmp_str, fff);
6511 * Print all finished quests
6512 * @param creature_ptr プレーヤーへの参照ポインタ
6513 * @param fff セーブファイル (展開済?)
6514 * @param quest_num[] 受注したことのあるクエスト群
6517 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6519 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6520 QUEST_IDX total = 0;
6521 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6523 QUEST_IDX q_idx = quest_num[i];
6524 quest_type* const q_ptr = &quest[q_idx];
6526 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6532 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6537 * Print all failed quests
6538 * @param creature_ptr プレーヤーへの参照ポインタ
6539 * @param fff セーブファイル (展開済?)
6540 * @param quest_num[] 受注したことのあるクエスト群
6543 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6545 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6546 QUEST_IDX total = 0;
6547 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6549 QUEST_IDX q_idx = quest_num[i];
6550 quest_type* const q_ptr = &quest[q_idx];
6552 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6553 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6559 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6564 * Print all random quests
6566 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6568 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6569 GAME_TEXT tmp_str[120];
6570 QUEST_IDX total = 0;
6571 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6573 /* No info from "silent" quests */
6574 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6576 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6580 /* Print the quest info */
6581 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6582 quest[i].name, (int)quest[i].level, r_name + r_info[quest[i].r_idx].name);
6583 fputs(tmp_str, fff);
6587 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6591 * Print quest status of all active quests
6592 * @param creature_ptr プレーヤーへの参照ポインタ
6595 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6597 /* Open a new file */
6599 GAME_TEXT file_name[1024];
6600 fff = my_fopen_temp(file_name, 1024);
6603 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6608 /* Allocate Memory */
6610 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6612 /* Sort by compete level */
6613 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6615 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6617 /* Dump Quest Information */
6618 do_cmd_knowledge_quests_current(creature_ptr, fff);
6620 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6622 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6623 if (current_world_ptr->wizard)
6626 do_cmd_knowledge_quests_wiz_random(fff);
6631 /* Display the file contents */
6632 show_file(creature_ptr, TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6636 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6642 * @param player_ptr プレーヤーへの参照ポインタ
6645 static void do_cmd_knowledge_home(player_type *player_ptr)
6647 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6649 /* Open a new file */
6651 GAME_TEXT file_name[1024];
6652 fff = my_fopen_temp(file_name, 1024);
6655 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6660 /* Print all homes in the different towns */
6662 st_ptr = &town_info[1].store[STORE_HOME];
6664 /* Home -- if anything there */
6665 if (st_ptr->stock_num)
6670 /* Header with name of the town */
6671 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6673 /* Dump all available items */
6674 concptr paren = ")";
6675 GAME_TEXT o_name[MAX_NLEN];
6676 for (int i = 0; i < st_ptr->stock_num; i++)
6679 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6680 object_desc(o_name, &st_ptr->stock[i], 0);
6681 if (strlen(o_name) <= 80 - 3)
6683 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6689 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6690 if (iskanji(*t)) { t++; n++; }
6691 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6693 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6694 fprintf(fff, " %.77s\n", o_name + n);
6697 object_desc(o_name, &st_ptr->stock[i], 0);
6698 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6702 /* Add an empty line */
6703 fprintf(fff, "\n\n");
6708 /* Display the file contents */
6709 show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6715 * Check the status of "autopick"
6717 static void do_cmd_knowledge_autopick(player_type *creature_ptr)
6719 /* Open a new file */
6721 GAME_TEXT file_name[1024];
6722 fff = my_fopen_temp(file_name, 1024);
6725 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6732 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6736 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6737 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6740 for (int k = 0; k < max_autopick; k++)
6743 byte act = autopick_list[k].action;
6744 if (act & DONT_AUTOPICK)
6746 tmp = _("放置", "Leave");
6748 else if (act & DO_AUTODESTROY)
6750 tmp = _("破壊", "Destroy");
6752 else if (act & DO_AUTOPICK)
6754 tmp = _("拾う", "Pickup");
6758 tmp = _("確認", "Query");
6761 if (act & DO_DISPLAY)
6762 fprintf(fff, "%11s", format("[%s]", tmp));
6764 fprintf(fff, "%11s", format("(%s)", tmp));
6766 tmp = autopick_line_from_entry(&autopick_list[k]);
6767 fprintf(fff, " %s", tmp);
6774 /* Display the file contents */
6775 show_file(creature_ptr, TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6781 * Interact with "knowledge"
6783 void do_cmd_knowledge(player_type *creature_ptr)
6786 bool need_redraw = FALSE;
6788 /* File type is "TEXT" */
6789 FILE_TYPE(FILE_TYPE_TEXT);
6792 /* Interact until done */
6797 /* Ask for a choice */
6798 prt(format(_("%d/2 ページ", "page %d/2"), (p + 1)), 2, 65);
6799 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6801 /* Give some choices */
6805 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6806 prt("(2) 既知のアイテム の一覧", 7, 5);
6807 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6808 prt("(4) 既知のモンスター の一覧", 9, 5);
6809 prt("(5) 倒した敵の数 の一覧", 10, 5);
6810 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6811 prt("(7) 現在のペット の一覧", 12, 5);
6812 prt("(8) 我が家のアイテム の一覧", 13, 5);
6813 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6814 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6818 prt("(a) 自分に関する情報 の一覧", 6, 5);
6819 prt("(b) 突然変異 の一覧", 7, 5);
6820 prt("(c) 武器の経験値 の一覧", 8, 5);
6821 prt("(d) 魔法の経験値 の一覧", 9, 5);
6822 prt("(e) 技能の経験値 の一覧", 10, 5);
6823 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6824 prt("(g) 入ったダンジョン の一覧", 12, 5);
6825 prt("(h) 実行中のクエスト の一覧", 13, 5);
6826 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6831 prt("(1) Display known artifacts", 6, 5);
6832 prt("(2) Display known objects", 7, 5);
6833 prt("(3) Display remaining uniques", 8, 5);
6834 prt("(4) Display known monster", 9, 5);
6835 prt("(5) Display kill count", 10, 5);
6836 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6837 prt("(7) Display current pets", 12, 5);
6838 prt("(8) Display home inventory", 13, 5);
6839 prt("(9) Display *identified* equip.", 14, 5);
6840 prt("(0) Display terrain symbols.", 15, 5);
6844 prt("(a) Display about yourself", 6, 5);
6845 prt("(b) Display mutations", 7, 5);
6846 prt("(c) Display weapon proficiency", 8, 5);
6847 prt("(d) Display spell proficiency", 9, 5);
6848 prt("(e) Display misc. proficiency", 10, 5);
6849 prt("(f) Display virtues", 11, 5);
6850 prt("(g) Display dungeons", 12, 5);
6851 prt("(h) Display current quests", 13, 5);
6852 prt("(i) Display auto pick/destroy", 14, 5);
6856 prt(_("-続く-", "-more-"), 17, 8);
6857 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6858 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6859 /*prt("-) 前ページ", 21, 60);*/
6860 prt(_("コマンド:", "Command: "), 20, 0);
6863 if (i == ESCAPE) break;
6866 case ' ': /* Page change */
6870 case '1': /* Artifacts */
6871 do_cmd_knowledge_artifacts(creature_ptr);
6873 case '2': /* Objects */
6874 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6876 case '3': /* Uniques */
6877 do_cmd_knowledge_uniques(creature_ptr);
6879 case '4': /* Monsters */
6880 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6882 case '5': /* Kill count */
6883 do_cmd_knowledge_kill_count(creature_ptr);
6885 case '6': /* wanted */
6886 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6888 case '7': /* Pets */
6889 do_cmd_knowledge_pets(creature_ptr);
6891 case '8': /* Home */
6892 do_cmd_knowledge_home(creature_ptr);
6894 case '9': /* Resist list */
6895 do_cmd_knowledge_inven(creature_ptr);
6897 case '0': /* Feature list */
6899 IDX lighting_level = F_LIT_STANDARD;
6900 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6904 case 'a': /* Max stat */
6905 do_cmd_knowledge_stat(creature_ptr);
6907 case 'b': /* Mutations */
6908 do_cmd_knowledge_mutations(creature_ptr);
6910 case 'c': /* weapon-exp */
6911 do_cmd_knowledge_weapon_exp(creature_ptr);
6913 case 'd': /* spell-exp */
6914 do_cmd_knowledge_spell_exp(creature_ptr);
6916 case 'e': /* skill-exp */
6917 do_cmd_knowledge_skill_exp(creature_ptr);
6919 case 'f': /* Virtues */
6920 do_cmd_knowledge_virtues(creature_ptr);
6922 case 'g': /* Dungeon */
6923 do_cmd_knowledge_dungeon(creature_ptr);
6925 case 'h': /* Quests */
6926 do_cmd_knowledge_quests(creature_ptr);
6928 case 'i': /* Autopick */
6929 do_cmd_knowledge_autopick(creature_ptr);
6931 default: /* Unknown option */
6939 if (need_redraw) do_cmd_redraw(creature_ptr);
6944 * Check on the status of an active quest
6945 * @param creature_ptr プレーヤーへの参照ポインタ
6948 void do_cmd_checkquest(player_type *creature_ptr)
6950 /* File type is "TEXT" */
6951 FILE_TYPE(FILE_TYPE_TEXT);
6955 do_cmd_knowledge_quests(creature_ptr);
6961 * Display the time and date
6962 * @param creature_ptr プレーヤーへの参照ポインタ
6965 void do_cmd_time(player_type *creature_ptr)
6968 extract_day_hour_min(creature_ptr, &day, &hour, &min);
6971 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
6974 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
6975 else strcpy(day_buf, "*****");
6977 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
6978 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
6982 if (!randint0(10) || creature_ptr->image)
6984 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
6988 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
6991 /* Open this file */
6993 fff = my_fopen(buf, "rt");
6997 /* Find this time */
6998 int full = hour * 100 + min;
7002 while (!my_fgets(fff, buf, sizeof(buf)))
7004 /* Ignore comments */
7005 if (!buf[0] || (buf[0] == '#')) continue;
7007 /* Ignore invalid lines */
7008 if (buf[1] != ':') continue;
7010 /* Process 'Start' */
7013 /* Extract the starting time */
7014 start = atoi(buf + 2);
7016 /* Assume valid for an hour */
7024 /* Extract the ending time */
7025 end = atoi(buf + 2);
7029 /* Ignore incorrect range */
7030 if ((start > full) || (full > end)) continue;
7032 /* Process 'Description' */
7037 /* Apply the randomizer */
7038 if (!randint0(num)) strcpy(desc, buf + 2);