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(&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);
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(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."));
913 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
922 * @param crerature_ptr プレーヤーへの参照ポインタ
925 void do_cmd_diary(player_type *creature_ptr)
927 /* File type is "TEXT" */
928 FILE_TYPE(FILE_TYPE_TEXT);
931 /* Interact until done */
937 /* Ask for a choice */
938 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
940 /* Give some choices */
941 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
942 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
943 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
944 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
946 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
949 prt(_("コマンド:", "Command: "), 18, 0);
954 if (i == ESCAPE) break;
959 display_diary(creature_ptr);
962 add_diary_note(creature_ptr);
965 do_cmd_last_get(creature_ptr);
968 do_cmd_erase_diary();
972 prepare_movie_hooks();
974 default: /* Unknown option */
986 * @brief 画面を再描画するコマンドのメインルーチン
987 * Hack -- redraw the screen
988 * @param creature_ptr プレーヤーへの参照ポインタ
992 * This command performs various low level updates, clears all the "extra"
993 * windows, does a total redraw of the main window, and requests all of the
994 * interesting updates and redraws that I can think of.
996 * This command is also used to "instantiate" the results of the user
997 * selecting various things, such as graphics mode, so it must call
998 * the "TERM_XTRA_REACT" hook before redrawing the windows.
1001 void do_cmd_redraw(player_type *creature_ptr)
1003 Term_xtra(TERM_XTRA_REACT, 0);
1005 /* Combine and Reorder the pack (later) */
1006 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1007 creature_ptr->update |= (PU_TORCH);
1008 creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1009 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1010 creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1011 creature_ptr->update |= (PU_MONSTERS);
1013 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1015 creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1016 creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1019 handle_stuff(creature_ptr);
1021 if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1023 /* Redraw every window */
1025 for (int j = 0; j < 8; j++)
1028 if (!angband_term[j]) continue;
1031 Term_activate(angband_term[j]);
1040 * @brief プレイヤーのステータス表示
1043 void do_cmd_player_status(player_type *creature_ptr)
1054 display_player(creature_ptr, mode);
1059 display_player(creature_ptr, mode);
1063 Term_putstr(2, 23, -1, TERM_WHITE,
1064 _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1068 if (c == ESCAPE) break;
1073 get_name(creature_ptr);
1075 /* Process the player name */
1076 process_player_name(creature_ptr, FALSE);
1082 sprintf(tmp, "%s.txt", creature_ptr->base_name);
1083 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1085 if (tmp[0] && (tmp[0] != ' '))
1087 file_character(creature_ptr, tmp);
1105 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1107 handle_stuff(creature_ptr);
1112 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1113 * Recall the most recent message
1116 void do_cmd_message_one(void)
1118 /* Recall one message */
1119 prt(format("> %s", message_str(0)), 0, 0);
1124 * @brief メッセージのログを表示するコマンドのメインルーチン
1125 * Recall the most recent message
1129 * Show previous messages to the user -BEN-
1131 * The screen format uses line 0 and 23 for headers and prompts,
1132 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1134 * This command shows you which commands you are viewing, and allows
1135 * you to "search" for strings in the recall.
1137 * Note that messages may be longer than 80 characters, but they are
1138 * displayed using "infinite" length, with a special sub-command to
1139 * "slide" the virtual display to the left or right.
1141 * Attempt to only hilite the matching portions of the string.
1144 void do_cmd_messages(int num_now)
1146 char shower_str[81];
1147 char finder_str[81];
1149 concptr shower = NULL;
1153 Term_get_size(&wid, &hgt);
1155 /* Number of message lines in a screen */
1156 num_lines = hgt - 4;
1159 strcpy(finder_str, "");
1162 strcpy(shower_str, "");
1164 /* Total messages */
1165 int n = message_num();
1167 /* Start on first message */
1172 /* Process requests until done */
1178 /* Dump up to 20 lines of messages */
1179 for (j = 0; (j < num_lines) && (i + j < n); j++)
1181 concptr msg = message_str(i+j);
1183 /* Dump the messages, bottom to top */
1184 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1186 if (!shower || !shower[0]) continue;
1188 /* Hilite "shower" */
1191 /* Display matches */
1192 while ((str = my_strstr(str, shower)) != NULL)
1194 int len = strlen(shower);
1196 /* Display the match */
1197 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1204 /* Erase remaining lines */
1205 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1207 /* Display header */
1209 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1210 i, i + j - 1, n), 0, 0);
1212 /* Display prompt (not very informative) */
1213 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1214 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1216 skey = inkey_special(TRUE);
1218 /* Exit on Escape */
1219 if (skey == ESCAPE) break;
1221 /* Hack -- Save the old index */
1226 /* Hack -- handle show */
1229 prt(_("強調: ", "Show: "), hgt - 1, 0);
1231 /* Get a "shower" string, or continue */
1232 strcpy(back_str, shower_str);
1233 if (askfor(shower_str, 80))
1236 shower = shower_str[0] ? shower_str : NULL;
1238 else strcpy(shower_str, back_str);
1242 /* Hack -- handle find */
1249 prt(_("検索: ", "Find: "), hgt - 1, 0);
1251 /* Get a "finder" string, or continue */
1252 strcpy(back_str, finder_str);
1253 if (!askfor(finder_str, 80))
1255 strcpy(finder_str, back_str);
1258 else if (!finder_str[0])
1260 shower = NULL; /* Stop showing */
1265 shower = finder_str;
1268 for (z = i + 1; z < n; z++)
1270 concptr msg = message_str(z);
1273 if (my_strstr(msg, finder_str))
1284 /* Recall 1 older message */
1286 /* Go to the oldest line */
1290 /* Recall 1 newer message */
1292 /* Go to the newest line */
1296 /* Recall 1 older message */
1301 /* Go older if legal */
1302 i = MIN(i + 1, n - num_lines);
1305 /* Recall 10 older messages */
1307 /* Go older if legal */
1308 i = MIN(i + 10, n - num_lines);
1311 /* Recall 20 older messages */
1316 /* Go older if legal */
1317 i = MIN(i + num_lines, n - num_lines);
1320 /* Recall 20 newer messages */
1324 /* Go newer (if able) */
1325 i = MAX(0, i - num_lines);
1328 /* Recall 10 newer messages */
1330 /* Go newer (if able) */
1334 /* Recall 1 newer messages */
1337 /* Go newer (if able) */
1342 /* Hack -- Error of some kind */
1351 * @brief prefファイルを選択して処理する /
1352 * Ask for a "user pref line" and process it
1355 * Allow absolute file names?
1357 void do_cmd_pref(void)
1362 /* Ask for a "user pref command" */
1363 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1365 /* Process that pref command */
1366 (void)process_pref_file_command(buf);
1371 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1372 * @param creature_ptr プレーヤーへの参照ポインタ
1375 void do_cmd_reload_autopick(player_type *creature_ptr)
1377 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1378 /* Load the file with messages */
1379 autopick_load_pref(creature_ptr, TRUE);
1386 * @brief マクロ情報をprefファイルに保存する /
1387 * @param fname ファイル名
1390 static errr macro_dump(concptr fname)
1392 static concptr mark = "Macro Dump";
1394 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1396 /* File type is "TEXT" */
1397 FILE_TYPE(FILE_TYPE_TEXT);
1399 /* Append to the file */
1400 if (!open_auto_dump(buf, mark)) return (-1);
1403 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1406 for (int i = 0; i < macro__num; i++)
1408 /* Extract the action */
1409 ascii_to_text(buf, macro__act[i]);
1411 /* Dump the macro */
1412 auto_dump_printf("A:%s\n", buf);
1414 /* Extract the action */
1415 ascii_to_text(buf, macro__pat[i]);
1417 /* Dump normal macros */
1418 auto_dump_printf("P:%s\n", buf);
1421 auto_dump_printf("\n");
1430 * @brief マクロのトリガーキーを取得する /
1431 * Hack -- ask for a "trigger" (see below)
1432 * @param buf キー表記を保管するバッファ
1436 * Note the complex use of the "inkey()" function from "util.c".
1438 * Note that both "flush()" calls are extremely important.
1441 static void do_cmd_macro_aux(char *buf)
1445 /* Do not process macros */
1451 /* Read the pattern */
1458 /* Do not process macros */
1461 /* Do not wait for keys */
1464 /* Attempt to read a key */
1473 /* Convert the trigger */
1475 ascii_to_text(tmp, buf);
1477 /* Hack -- display the trigger */
1478 Term_addstr(-1, TERM_WHITE, tmp);
1484 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1485 * Hack -- ask for a keymap "trigger" (see below)
1486 * @param buf キー表記を取得するバッファ
1490 * Note that both "flush()" calls are extremely important. This may
1491 * no longer be true, since "util.c" is much simpler now.
1494 static void do_cmd_macro_aux_keymap(char *buf)
1504 /* Convert to ascii */
1505 ascii_to_text(tmp, buf);
1507 /* Hack -- display the trigger */
1508 Term_addstr(-1, TERM_WHITE, tmp);
1515 * @brief キーマップをprefファイルにダンプする /
1516 * Hack -- append all keymaps to the given file
1517 * @param fname ファイルネーム
1521 static errr keymap_dump(concptr fname)
1523 static concptr mark = "Keymap Dump";
1530 if (rogue_like_commands)
1532 mode = KEYMAP_MODE_ROGUE;
1538 mode = KEYMAP_MODE_ORIG;
1541 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1543 /* File type is "TEXT" */
1544 FILE_TYPE(FILE_TYPE_TEXT);
1546 /* Append to the file */
1547 if (!open_auto_dump(buf, mark)) return -1;
1550 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1553 for (int i = 0; i < 256; i++)
1557 /* Loop up the keymap */
1558 act = keymap_act[mode][i];
1560 /* Skip empty keymaps */
1563 /* Encode the key */
1566 ascii_to_text(key, buf);
1568 /* Encode the action */
1569 ascii_to_text(buf, act);
1571 /* Dump the macro */
1572 auto_dump_printf("A:%s\n", buf);
1573 auto_dump_printf("C:%d:%s\n", mode, key);
1582 * @brief マクロを設定するコマンドのメインルーチン /
1583 * Interact with "macros"
1587 * Note that the macro "action" must be defined before the trigger.
1589 * Could use some helpful instructions on this page.
1592 void do_cmd_macros(player_type *creature_ptr)
1600 if (rogue_like_commands)
1602 mode = KEYMAP_MODE_ROGUE;
1608 mode = KEYMAP_MODE_ORIG;
1611 /* File type is "TEXT" */
1612 FILE_TYPE(FILE_TYPE_TEXT);
1616 /* Process requests until done */
1620 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1622 /* Describe that action */
1623 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1625 /* Analyze the current action */
1626 ascii_to_text(buf, macro__buf);
1628 /* Display the current action */
1633 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1635 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1636 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1637 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1638 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1639 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1640 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1641 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1642 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1643 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1644 #endif /* ALLOW_MACROS */
1647 prt(_("コマンド: ", "Command: "), 16, 0);
1652 if (i == ESCAPE) break;
1654 /* Load a 'macro' file */
1660 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1663 prt(_("ファイル: ", "File: "), 18, 0);
1665 /* Default filename */
1666 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1668 /* Ask for a file */
1669 if (!askfor(tmp, 80)) continue;
1671 /* Process the given filename */
1672 err = process_pref_file(tmp);
1675 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1680 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1684 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1693 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1696 prt(_("ファイル: ", "File: "), 18, 0);
1698 /* Default filename */
1699 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1701 /* Ask for a file */
1702 if (!askfor(tmp, 80)) continue;
1704 /* Dump the macros */
1705 (void)macro_dump(tmp);
1708 msg_print(_("マクロを追加しました。", "Appended macros."));
1717 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1721 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1723 /* Get a macro trigger */
1724 do_cmd_macro_aux(buf);
1726 /* Acquire action */
1727 k = macro_find_exact(buf);
1733 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1739 /* Obtain the action */
1740 strcpy(macro__buf, macro__act[k]);
1742 /* Analyze the current action */
1743 ascii_to_text(buf, macro__buf);
1745 /* Display the current action */
1749 msg_print(_("マクロを確認しました。", "Found a macro."));
1753 /* Create a macro */
1757 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1760 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1762 /* Get a macro trigger */
1763 do_cmd_macro_aux(buf);
1767 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1768 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1771 prt(_("マクロ行動: ", "Action: "), 20, 0);
1773 /* Convert to text */
1774 ascii_to_text(tmp, macro__buf);
1776 /* Get an encoded action */
1777 if (askfor(tmp, 80))
1779 /* Convert to ascii */
1780 text_to_ascii(macro__buf, tmp);
1782 /* Link the macro */
1783 macro_add(buf, macro__buf);
1786 msg_print(_("マクロを追加しました。", "Added a macro."));
1790 /* Remove a macro */
1794 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1797 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1799 /* Get a macro trigger */
1800 do_cmd_macro_aux(buf);
1802 /* Link the macro */
1803 macro_add(buf, buf);
1806 msg_print(_("マクロを削除しました。", "Removed a macro."));
1813 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1816 prt(_("ファイル: ", "File: "), 18, 0);
1818 /* Default filename */
1819 sprintf(tmp, "%s.prf", creature_ptr->base_name);
1821 /* Ask for a file */
1822 if (!askfor(tmp, 80)) continue;
1824 /* Dump the macros */
1825 (void)keymap_dump(tmp);
1828 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1831 /* Query a keymap */
1837 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1840 prt(_("押すキー: ", "Keypress: "), 18, 0);
1842 /* Get a keymap trigger */
1843 do_cmd_macro_aux_keymap(buf);
1845 /* Look up the keymap */
1846 act = keymap_act[mode][(byte)(buf[0])];
1852 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1858 /* Obtain the action */
1859 strcpy(macro__buf, act);
1861 /* Analyze the current action */
1862 ascii_to_text(buf, macro__buf);
1864 /* Display the current action */
1868 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1872 /* Create a keymap */
1876 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1879 prt(_("押すキー: ", "Keypress: "), 18, 0);
1881 /* Get a keymap trigger */
1882 do_cmd_macro_aux_keymap(buf);
1886 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1887 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1890 prt(_("行動: ", "Action: "), 20, 0);
1892 /* Convert to text */
1893 ascii_to_text(tmp, macro__buf);
1895 /* Get an encoded action */
1896 if (askfor(tmp, 80))
1898 /* Convert to ascii */
1899 text_to_ascii(macro__buf, tmp);
1901 /* Free old keymap */
1902 string_free(keymap_act[mode][(byte)(buf[0])]);
1904 /* Make new keymap */
1905 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1908 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1912 /* Remove a keymap */
1916 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1919 prt(_("押すキー: ", "Keypress: "), 18, 0);
1921 /* Get a keymap trigger */
1922 do_cmd_macro_aux_keymap(buf);
1924 /* Free old keymap */
1925 string_free(keymap_act[mode][(byte)(buf[0])]);
1927 /* Make new keymap */
1928 keymap_act[mode][(byte)(buf[0])] = NULL;
1931 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1934 /* Enter a new action */
1938 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1942 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1943 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1946 prt(_("マクロ行動: ", "Action: "), 20, 0);
1948 /* Hack -- limit the value */
1951 /* Get an encoded action */
1952 if (!askfor(buf, 80)) continue;
1954 /* Extract an action */
1955 text_to_ascii(macro__buf, buf);
1957 #endif /* ALLOW_MACROS */
1972 * @brief キャラクタ色の明暗表現
1974 static concptr lighting_level_str[F_LIT_MAX] =
1989 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1990 * @param i 指定対象となるキャラクタコード
1991 * @param num 指定されたビジュアルIDを返す参照ポインタ
1992 * @param max ビジュアルIDの最大数
1993 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1995 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2002 sprintf(str, "%d", *num);
2004 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2007 tmp = (IDX)strtol(str, NULL, 0);
2008 if (tmp >= 0 && tmp < max)
2011 else if (isupper(i))
2012 *num = (*num + max - 1) % max;
2014 *num = (*num + 1) % max;
2020 * @brief キャラクタの変更メニュー表示
2021 * @param choice_msg 選択メッセージ
2024 static void print_visuals_menu(concptr choice_msg)
2026 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2028 /* Give some choices */
2029 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2031 #ifdef ALLOW_VISUALS
2032 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2033 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2034 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2035 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2036 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2037 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2038 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2039 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2040 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2041 #endif /* ALLOW_VISUALS */
2043 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2046 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2051 * Interact with "visuals"
2053 void do_cmd_visuals(player_type *creature_ptr)
2058 bool need_redraw = FALSE;
2059 concptr empty_symbol = "<< ? >>";
2061 if (use_bigtile) empty_symbol = "<< ?? >>";
2063 /* File type is "TEXT" */
2064 FILE_TYPE(FILE_TYPE_TEXT);
2067 /* Interact until done */
2072 /* Ask for a choice */
2073 print_visuals_menu(NULL);
2078 if (i == ESCAPE) break;
2082 /* Load a 'pref' file */
2085 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2088 prt(_("ファイル: ", "File: "), 17, 0);
2090 /* Default filename */
2091 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2094 if (!askfor(tmp, 70)) continue;
2096 /* Process the given filename */
2097 (void)process_pref_file(tmp);
2102 #ifdef ALLOW_VISUALS
2104 /* Dump monster attr/chars */
2107 static concptr mark = "Monster attr/chars";
2110 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2113 prt(_("ファイル: ", "File: "), 17, 0);
2115 /* Default filename */
2116 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2118 /* Get a filename */
2119 if (!askfor(tmp, 70)) continue;
2120 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2122 /* Append to the file */
2123 if (!open_auto_dump(buf, mark)) continue;
2126 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2129 for (i = 0; i < max_r_idx; i++)
2131 monster_race *r_ptr = &r_info[i];
2133 /* Skip non-entries */
2134 if (!r_ptr->name) continue;
2136 /* Dump a comment */
2137 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2139 /* Dump the monster attr/char info */
2140 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2141 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2147 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2152 /* Dump object attr/chars */
2155 static concptr mark = "Object attr/chars";
2156 KIND_OBJECT_IDX k_idx;
2159 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2162 prt(_("ファイル: ", "File: "), 17, 0);
2164 /* Default filename */
2165 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2167 /* Get a filename */
2168 if (!askfor(tmp, 70)) continue;
2169 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2171 /* Append to the file */
2172 if (!open_auto_dump(buf, mark)) continue;
2175 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2178 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2180 GAME_TEXT o_name[MAX_NLEN];
2181 object_kind *k_ptr = &k_info[k_idx];
2183 /* Skip non-entries */
2184 if (!k_ptr->name) continue;
2189 strip_name(o_name, k_idx);
2195 /* Prepare dummy object */
2196 object_prep(&forge, k_idx);
2198 /* Get un-shuffled flavor name */
2199 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
2202 /* Dump a comment */
2203 auto_dump_printf("# %s\n", o_name);
2205 /* Dump the object attr/char info */
2206 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2207 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2213 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2218 /* Dump feature attr/chars */
2221 static concptr mark = "Feature attr/chars";
2224 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2227 prt(_("ファイル: ", "File: "), 17, 0);
2229 /* Default filename */
2230 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2232 /* Get a filename */
2233 if (!askfor(tmp, 70)) continue;
2234 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2236 /* Append to the file */
2237 if (!open_auto_dump(buf, mark)) continue;
2240 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2243 for (i = 0; i < max_f_idx; i++)
2245 feature_type *f_ptr = &f_info[i];
2247 /* Skip non-entries */
2248 if (!f_ptr->name) continue;
2250 /* Skip mimiccing features */
2251 if (f_ptr->mimic != i) continue;
2253 /* Dump a comment */
2254 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2256 /* Dump the feature attr/char info */
2257 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2258 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2259 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2260 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2266 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2271 /* Modify monster attr/chars (numeric operation) */
2274 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2275 static MONRACE_IDX r = 0;
2277 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2279 /* Hack -- query until done */
2282 monster_race *r_ptr = &r_info[r];
2286 TERM_COLOR da = r_ptr->d_attr;
2287 byte dc = r_ptr->d_char;
2288 TERM_COLOR ca = r_ptr->x_attr;
2289 byte cc = r_ptr->x_char;
2291 /* Label the object */
2292 Term_putstr(5, 17, -1, TERM_WHITE,
2293 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2295 /* Label the Default values */
2296 Term_putstr(10, 19, -1, TERM_WHITE,
2297 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2299 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2300 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2302 /* Label the Current values */
2303 Term_putstr(10, 20, -1, TERM_WHITE,
2304 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2306 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2307 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2310 Term_putstr(0, 22, -1, TERM_WHITE,
2311 _("コマンド (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): "));
2316 if (i == ESCAPE) break;
2318 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2319 else if (isupper(i)) c = 'a' + i - 'A';
2329 if (!cmd_visuals_aux(i, &r, max_r_idx))
2335 while (!r_info[r].name);
2339 t = (int)r_ptr->x_attr;
2340 (void)cmd_visuals_aux(i, &t, 256);
2341 r_ptr->x_attr = (byte)t;
2345 t = (int)r_ptr->x_char;
2346 (void)cmd_visuals_aux(i, &t, 256);
2347 r_ptr->x_char = (byte)t;
2351 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2353 print_visuals_menu(choice_msg);
2361 /* Modify object attr/chars (numeric operation) */
2364 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2366 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2368 /* Hack -- query until done */
2371 object_kind *k_ptr = &k_info[k];
2375 TERM_COLOR da = k_ptr->d_attr;
2376 SYMBOL_CODE dc = k_ptr->d_char;
2377 TERM_COLOR ca = k_ptr->x_attr;
2378 SYMBOL_CODE cc = k_ptr->x_char;
2380 /* Label the object */
2381 Term_putstr(5, 17, -1, TERM_WHITE,
2382 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2383 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2385 /* Label the Default values */
2386 Term_putstr(10, 19, -1, TERM_WHITE,
2387 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2389 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2390 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2392 /* Label the Current values */
2393 Term_putstr(10, 20, -1, TERM_WHITE,
2394 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2396 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2397 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2400 Term_putstr(0, 22, -1, TERM_WHITE,
2401 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
2406 if (i == ESCAPE) break;
2408 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2409 else if (isupper(i)) c = 'a' + i - 'A';
2419 if (!cmd_visuals_aux(i, &k, max_k_idx))
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))
2527 while (!f_info[f].name || (f_info[f].mimic != f));
2531 t = (int)f_ptr->x_attr[lighting_level];
2532 (void)cmd_visuals_aux(i, &t, 256);
2533 f_ptr->x_attr[lighting_level] = (byte)t;
2537 t = (int)f_ptr->x_char[lighting_level];
2538 (void)cmd_visuals_aux(i, &t, 256);
2539 f_ptr->x_char[lighting_level] = (byte)t;
2543 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2546 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2550 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2552 print_visuals_menu(choice_msg);
2560 /* Modify monster attr/chars (visual mode) */
2562 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2565 /* Modify object attr/chars (visual mode) */
2567 do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
2570 /* Modify feature attr/chars (visual mode) */
2573 IDX lighting_level = F_LIT_STANDARD;
2574 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2578 #endif /* ALLOW_VISUALS */
2586 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2590 /* Unknown option */
2601 if (need_redraw) do_cmd_redraw(creature_ptr);
2606 * Interact with "colors"
2608 void do_cmd_colors(player_type *creature_ptr)
2614 /* File type is "TEXT" */
2615 FILE_TYPE(FILE_TYPE_TEXT);
2619 /* Interact until done */
2624 /* Ask for a choice */
2625 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2627 /* Give some choices */
2628 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2631 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2632 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2636 prt(_("コマンド: ", "Command: "), 8, 0);
2640 if (i == ESCAPE) break;
2642 /* Load a 'pref' file */
2646 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2649 prt(_("ファイル: ", "File: "), 10, 0);
2652 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2655 if (!askfor(tmp, 70)) continue;
2657 /* Process the given filename */
2658 (void)process_pref_file(tmp);
2660 /* Mega-Hack -- react to changes */
2661 Term_xtra(TERM_XTRA_REACT, 0);
2663 /* Mega-Hack -- redraw */
2672 static concptr mark = "Colors";
2675 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2678 prt(_("ファイル: ", "File: "), 10, 0);
2680 /* Default filename */
2681 sprintf(tmp, "%s.prf", creature_ptr->base_name);
2683 /* Get a filename */
2684 if (!askfor(tmp, 70)) continue;
2685 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2687 /* Append to the file */
2688 if (!open_auto_dump(buf, mark)) continue;
2691 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2694 for (i = 0; i < 256; i++)
2696 int kv = angband_color_table[i][0];
2697 int rv = angband_color_table[i][1];
2698 int gv = angband_color_table[i][2];
2699 int bv = angband_color_table[i][3];
2701 concptr name = _("未知", "unknown");
2703 /* Skip non-entries */
2704 if (!kv && !rv && !gv && !bv) continue;
2706 /* Extract the color name */
2707 if (i < 16) name = color_names[i];
2709 /* Dump a comment */
2710 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2712 /* Dump the monster attr/char info */
2713 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2720 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2729 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2731 /* Hack -- query until done */
2738 /* Exhibit the normal colors */
2739 for (j = 0; j < 16; j++)
2741 /* Exhibit this color */
2742 Term_putstr(j*4, 20, -1, a, "###");
2744 /* Exhibit all colors */
2745 Term_putstr(j*4, 22, -1, j, format("%3d", j));
2748 /* Describe the color */
2749 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2751 /* Describe the color */
2752 Term_putstr(5, 10, -1, TERM_WHITE,
2753 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2755 /* Label the Current values */
2756 Term_putstr(5, 12, -1, TERM_WHITE,
2757 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2758 angband_color_table[a][0],
2759 angband_color_table[a][1],
2760 angband_color_table[a][2],
2761 angband_color_table[a][3]));
2764 Term_putstr(0, 14, -1, TERM_WHITE,
2765 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2770 if (i == ESCAPE) break;
2773 if (i == 'n') a = (byte)(a + 1);
2774 if (i == 'N') a = (byte)(a - 1);
2775 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2776 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2777 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2778 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2779 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2780 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2781 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2782 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2784 /* Hack -- react to changes */
2785 Term_xtra(TERM_XTRA_REACT, 0);
2787 /* Hack -- redraw */
2794 /* Unknown option */
2808 * Note something in the message recall
2810 void do_cmd_note(void)
2818 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2820 /* Ignore empty notes */
2821 if (!buf[0] || (buf[0] == ' ')) return;
2823 /* Add the note to the message recall */
2824 msg_format(_("メモ: %s", "Note: %s"), buf);
2829 * Mention the current version
2831 void do_cmd_version(void)
2833 #if FAKE_VER_EXTRA > 0
2834 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2835 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2837 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2838 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2844 * Array of feeling strings
2846 static concptr do_cmd_feeling_text[11] =
2848 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2849 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2850 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2851 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2852 _("とても悪い予感がする...", "You have a very bad feeling..."),
2853 _("悪い予感がする...", "You have a bad feeling..."),
2854 _("何か緊張する。", "You feel nervous."),
2855 _("少し不運な気がする...", "You feel your luck is turning..."),
2856 _("この場所は好きになれない。", "You don't like the look of this place."),
2857 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2858 _("なんて退屈なところだ...", "What a boring place...")
2861 static concptr do_cmd_feeling_text_combat[11] =
2863 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2864 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2865 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2866 _("この階はとても危険なようだ。", "This level looks very dangerous."),
2867 _("とても悪い予感がする...", "You have a very bad feeling..."),
2868 _("悪い予感がする...", "You have a bad feeling..."),
2869 _("何か緊張する。", "You feel nervous."),
2870 _("少し不運な気がする...", "You feel your luck is turning..."),
2871 _("この場所は好きになれない。", "You don't like the look of this place."),
2872 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2873 _("なんて退屈なところだ...", "What a boring place...")
2876 static concptr do_cmd_feeling_text_lucky[11] =
2878 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2879 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2880 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2881 _("素晴らしい感じがする...", "You have an excellent feeling..."),
2882 _("とても良い感じがする...", "You have a very good feeling..."),
2883 _("良い感じがする...", "You have a good feeling..."),
2884 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2885 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2886 _("見た感じ悪くはない...", "You like the look of this place..."),
2887 _("全然駄目ということはないが...", "This level can't be all bad..."),
2888 _("なんて退屈なところだ...", "What a boring place...")
2893 * Note that "feeling" is set to zero unless some time has passed.
2894 * Note that this is done when the level is GENERATED, not entered.
2896 void do_cmd_feeling(player_type *creature_ptr)
2898 if (creature_ptr->wild_mode) return;
2900 /* No useful feeling in quests */
2901 if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
2903 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2907 /* No useful feeling in town */
2908 if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2910 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2912 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2916 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2920 /* No useful feeling in the wilderness */
2921 if (!creature_ptr->current_floor_ptr->dun_level)
2923 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2927 /* Display the feeling */
2928 if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2929 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2930 else if (creature_ptr->pseikaku == SEIKAKU_COMBAT ||
2931 creature_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
2932 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2934 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2939 * Description of each monster group.
2941 static concptr monster_group_text[] =
2944 "ユニーク", /* "Uniques" */
2945 "乗馬可能なモンスター", /* "Riding" */
2946 "賞金首", /* "Wanted */
2947 "アンバーの王族", /* "Ambertite" */
2976 /* "古代ドラゴン/ワイアーム", */
3037 /* "Ancient Dragon/Wyrm", */
3046 "Multi-Headed Reptile",
3051 "Reptile/Amphibian",
3052 "Spider/Scorpion/Tick",
3054 /* "Major Demon", */
3071 * Symbols of monsters in each group. Note the "Uniques" group
3072 * is handled differently.
3074 static concptr monster_group_char[] =
3131 "!$&()+./=>?[\\]`{|~",
3141 * todo 引数と戻り値について追記求む
3142 * Build a list of monster indexes in the given group.
3144 * mode & 0x01 : check for non-empty group
3145 * mode & 0x02 : visual operation only
3147 * @param creature_ptr プレーヤーへの参照ポインタ
3148 * @param grp_cur ???
3149 * @param mon_idx[] ???
3151 * @return The number of monsters in the group
3153 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3155 /* Get a list of x_char in this group */
3156 concptr group_char = monster_group_char[grp_cur];
3158 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
3159 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
3160 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
3161 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
3163 /* Check every race */
3165 for (IDX i = 0; i < max_r_idx; i++)
3167 /* Access the race */
3168 monster_race *r_ptr = &r_info[i];
3170 /* Skip empty race */
3171 if (!r_ptr->name) continue ;
3173 /* Require known monsters */
3174 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3178 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3181 else if (grp_riding)
3183 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3186 else if (grp_wanted)
3188 bool wanted = FALSE;
3190 for (j = 0; j < MAX_BOUNTY; j++)
3192 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3193 (creature_ptr->today_mon && creature_ptr->today_mon == i))
3199 if (!wanted) continue;
3202 else if (grp_amberite)
3204 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3209 /* Check for race in the group */
3210 if (!my_strchr(group_char, r_ptr->d_char)) continue;
3214 mon_idx[mon_cnt++] = i;
3216 /* XXX Hack -- Just checking for non-empty group */
3217 if (mode & 0x01) break;
3220 /* Terminate the list */
3221 mon_idx[mon_cnt] = -1;
3224 ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3226 /* Return the number of races */
3232 * Description of each monster group.
3234 static concptr object_group_text[] =
3237 "キノコ", /* "Mushrooms" */
3238 "薬", /* "Potions" */
3239 "油つぼ", /* "Flasks" */
3240 "巻物", /* "Scrolls" */
3242 "アミュレット", /* "Amulets" */
3243 "笛", /* "Whistle" */
3244 "光源", /* "Lanterns" */
3245 "魔法棒", /* "Wands" */
3248 "カード", /* "Cards" */
3259 "刀剣類", /* "Swords" */
3260 "鈍器", /* "Blunt Weapons" */
3261 "長柄武器", /* "Polearms" */
3262 "採掘道具", /* "Diggers" */
3263 "飛び道具", /* "Bows" */
3267 "軽装鎧", /* "Soft Armor" */
3268 "重装鎧", /* "Hard Armor" */
3269 "ドラゴン鎧", /* "Dragon Armor" */
3270 "盾", /* "Shields" */
3271 "クローク", /* "Cloaks" */
3272 "籠手", /* "Gloves" */
3273 "ヘルメット", /* "Helms" */
3275 "ブーツ", /* "Boots" */
3328 * TVALs of items in each group
3330 static byte object_group_tval[] =
3371 TV_LIFE_BOOK, /* Hack -- all spellbooks */
3379 * Build a list of object indexes in the given group. Return the number
3380 * of objects in the group.
3382 * mode & 0x01 : check for non-empty group
3383 * mode & 0x02 : visual operation only
3385 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3387 KIND_OBJECT_IDX i, object_cnt = 0;
3390 /* Get a list of x_char in this group */
3391 byte group_tval = object_group_tval[grp_cur];
3393 /* Check every object */
3394 for (i = 0; i < max_k_idx; i++)
3396 /* Access the object */
3397 object_kind *k_ptr = &k_info[i];
3399 /* Skip empty objects */
3400 if (!k_ptr->name) continue;
3404 if (!current_world_ptr->wizard)
3406 /* Skip non-flavoured objects */
3407 if (!k_ptr->flavor) continue;
3409 /* Require objects ever seen */
3410 if (!k_ptr->aware) continue;
3413 /* Skip items with no distribution (special artifacts) */
3414 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3418 /* Check for objects in the group */
3419 if (TV_LIFE_BOOK == group_tval)
3421 /* Hack -- All spell books */
3422 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3424 /* Add the object */
3425 object_idx[object_cnt++] = i;
3429 else if (k_ptr->tval == group_tval)
3431 /* Add the object */
3432 object_idx[object_cnt++] = i;
3436 /* XXX Hack -- Just checking for non-empty group */
3437 if (mode & 0x01) break;
3440 /* Terminate the list */
3441 object_idx[object_cnt] = -1;
3443 /* Return the number of objects */
3449 * Description of each feature group.
3451 static concptr feature_group_text[] =
3459 * Build a list of feature indexes in the given group. Return the number
3460 * of features in the group.
3462 * mode & 0x01 : check for non-empty group
3464 static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3466 /* Check every feature */
3467 FEAT_IDX feat_cnt = 0;
3468 for (FEAT_IDX i = 0; i < max_f_idx; i++)
3470 feature_type *f_ptr = &f_info[i];
3472 /* Skip empty index */
3473 if (!f_ptr->name) continue;
3475 /* Skip mimiccing features */
3476 if (f_ptr->mimic != i) continue;
3479 feat_idx[feat_cnt++] = i;
3481 /* XXX Hack -- Just checking for non-empty group */
3482 if (mode & 0x01) break;
3485 /* Terminate the list */
3486 feat_idx[feat_cnt] = -1;
3488 /* Return the number of races */
3495 * Build a list of monster indexes in the given group. Return the number
3496 * of monsters in the group.
3498 static int collect_artifacts(int grp_cur, int object_idx[])
3500 int i, object_cnt = 0;
3502 /* Get a list of x_char in this group */
3503 byte group_tval = object_group_tval[grp_cur];
3505 /* Check every object */
3506 for (i = 0; i < max_a_idx; i++)
3508 /* Access the artifact */
3509 artifact_type *a_ptr = &a_info[i];
3511 /* Skip empty artifacts */
3512 if (!a_ptr->name) continue;
3514 /* Skip "uncreated" artifacts */
3515 if (!a_ptr->cur_num) continue;
3517 /* Check for race in the group */
3518 if (a_ptr->tval == group_tval)
3521 object_idx[object_cnt++] = i;
3525 /* Terminate the list */
3526 object_idx[object_cnt] = 0;
3528 /* Return the number of races */
3535 * Hack -- load a screen dump from a file
3537 void do_cmd_load_screen(void)
3541 SYMBOL_CODE c = ' ';
3547 Term_get_size(&wid, &hgt);
3548 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3550 /* Append to the file */
3551 fff = my_fopen(buf, "r");
3555 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3563 /* Load the screen */
3564 for (y = 0; okay; y++)
3566 /* Get a line of data including control code */
3567 if (!fgets(buf, 1024, fff)) okay = FALSE;
3569 /* Get the blank line */
3570 if (buf[0] == '\n' || buf[0] == '\0') break;
3572 /* Ignore too large screen image */
3573 if (y >= hgt) continue;
3576 for (x = 0; x < wid - 1; x++)
3579 if (buf[x] == '\n' || buf[x] == '\0') break;
3581 /* Put the attr/char */
3582 Term_draw(x, y, TERM_WHITE, buf[x]);
3586 /* Dump the screen */
3587 for (y = 0; okay; y++)
3589 /* Get a line of data including control code */
3590 if (!fgets(buf, 1024, fff)) okay = FALSE;
3592 /* Get the blank line */
3593 if (buf[0] == '\n' || buf[0] == '\0') break;
3595 /* Ignore too large screen image */
3596 if (y >= hgt) continue;
3599 for (x = 0; x < wid - 1; x++)
3602 if (buf[x] == '\n' || buf[x] == '\0') break;
3604 /* Get the attr/char */
3605 (void)(Term_what(x, y, &a, &c));
3607 /* Look up the attr */
3608 for (int i = 0; i < 16; i++)
3610 /* Use attr matches */
3611 if (hack[i] == buf[x]) a = (byte_hack)i;
3614 /* Put the attr/char */
3615 Term_draw(x, y, a, c);
3621 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3629 // todo なぜこんな中途半端なところに? defineも…
3630 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3631 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3633 #define IM_FLAG_STR _("*", "* ")
3634 #define HAS_FLAG_STR _("+", "+ ")
3635 #define NO_FLAG_STR _("・", ". ")
3637 #define print_im_or_res_flag(IM, RES) \
3639 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3640 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3643 #define print_flag(TR) \
3645 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3649 /* XTRA HACK RESLIST */
3650 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
3652 GAME_TEXT o_name[MAX_NLEN];
3653 BIT_FLAGS flgs[TR_FLAG_SIZE];
3655 if (!o_ptr->k_idx) return;
3656 if (o_ptr->tval != tval) return;
3658 /* Identified items only */
3659 if (!object_is_known(o_ptr)) return;
3662 * HACK:Ring of Lordly protection and Dragon equipment
3663 * have random resistances.
3665 bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3666 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3667 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3668 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3669 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3670 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3671 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3672 || object_is_artifact(o_ptr);
3673 if (!is_special_item_type)
3679 object_desc(o_name, o_ptr, OD_NAME_ONLY);
3681 while (o_name[i] && (i < 26))
3684 if (iskanji(o_name[i])) i++;
3693 o_name[i] = ' '; i++;
3699 fprintf(fff, "%s %s", where, o_name);
3701 if (!(o_ptr->ident & (IDENT_MENTAL)))
3703 fputs(_("-------不明--------------- -------不明---------\n",
3704 "-------unknown------------ -------unknown------\n"), fff);
3708 object_flags_known(o_ptr, flgs);
3710 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3711 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3712 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3713 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3714 print_flag(TR_RES_POIS);
3715 print_flag(TR_RES_LITE);
3716 print_flag(TR_RES_DARK);
3717 print_flag(TR_RES_SHARDS);
3718 print_flag(TR_RES_SOUND);
3719 print_flag(TR_RES_NETHER);
3720 print_flag(TR_RES_NEXUS);
3721 print_flag(TR_RES_CHAOS);
3722 print_flag(TR_RES_DISEN);
3726 print_flag(TR_RES_BLIND);
3727 print_flag(TR_RES_FEAR);
3728 print_flag(TR_RES_CONF);
3729 print_flag(TR_FREE_ACT);
3730 print_flag(TR_SEE_INVIS);
3731 print_flag(TR_HOLD_EXP);
3732 print_flag(TR_TELEPATHY);
3733 print_flag(TR_SLOW_DIGEST);
3734 print_flag(TR_REGEN);
3735 print_flag(TR_LEVITATION);
3744 fprintf(fff, "%s\n", inven_res_label);
3749 * Display *ID* ed weapons/armors's resistances
3751 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3754 GAME_TEXT file_name[1024];
3756 OBJECT_TYPE_VALUE tval;
3762 /* Open a new file */
3763 fff = my_fopen_temp(file_name, 1024);
3766 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3771 fprintf(fff, "%s\n", inven_res_label);
3773 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3777 for (; j < 9; j++) fputc('\n', fff);
3779 fprintf(fff, "%s\n", inven_res_label);
3782 strcpy(where, _("装", "E "));
3783 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3785 do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3788 strcpy(where, _("持", "I "));
3789 for (i = 0; i < INVEN_PACK; i++)
3791 do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3794 st_ptr = &town_info[1].store[STORE_HOME];
3795 strcpy(where, _("家", "H "));
3796 for (i = 0; i < st_ptr->stock_num; i++)
3798 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
3804 /* Display the file contents */
3805 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3810 void do_cmd_save_screen_html_aux(char *filename, int message)
3818 concptr html_head[] = {
3819 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3823 concptr html_foot[] = {
3825 "</body>\n</html>\n",
3830 Term_get_size(&wid, &hgt);
3832 /* File type is "TEXT" */
3833 FILE_TYPE(FILE_TYPE_TEXT);
3835 /* Append to the file */
3837 fff = my_fopen(filename, "w");
3843 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3850 if (message) screen_save();
3852 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3854 tmpfff = my_fopen(buf, "r");
3857 for (int i = 0; html_head[i]; i++)
3858 fputs(html_head[i], fff);
3862 bool is_first_line = TRUE;
3863 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3867 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3868 is_first_line = FALSE;
3872 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3874 fprintf(fff, "%s\n", buf);
3879 /* Dump the screen */
3880 for (TERM_LEN y = 0; y < hgt; y++)
3883 if (y != 0) fprintf(fff, "\n");
3886 TERM_COLOR a = 0, old_a = 0;
3888 for (TERM_LEN x = 0; x < wid - 1; x++)
3891 /* Get the attr/char */
3892 (void)(Term_what(x, y, &a, &c));
3896 case '&': cc = "&"; break;
3897 case '<': cc = "<"; break;
3898 case '>': cc = ">"; break;
3900 case 0x1f: c = '.'; break;
3901 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3906 if ((y == 0 && x == 0) || a != old_a)
3908 int rv = angband_color_table[a][1];
3909 int gv = angband_color_table[a][2];
3910 int bv = angband_color_table[a][3];
3911 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
3912 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3917 fprintf(fff, "%s", cc);
3919 fprintf(fff, "%c", c);
3923 fprintf(fff, "</font>");
3927 for (int i = 0; html_foot[i]; i++)
3928 fputs(html_foot[i], fff);
3933 bool is_first_line = TRUE;
3934 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3938 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3939 is_first_line = FALSE;
3943 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3945 fprintf(fff, "%s\n", buf);
3958 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3967 * Hack -- save a screen dump to a file
3969 static void do_cmd_save_screen_html(void)
3971 char buf[1024], tmp[256] = "screen.html";
3973 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3975 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3979 do_cmd_save_screen_html_aux(buf, 1);
3984 * Redefinable "save_screen" action
3986 void (*screendump_aux)(void) = NULL;
3990 * Save a screen dump to a file
3991 * @param creature_ptr プレーヤーへの参照ポインタ
3994 void do_cmd_save_screen(player_type *creature_ptr)
3996 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
3997 bool html_dump = FALSE;
4001 if (c == 'Y' || c == 'y')
4003 else if (c == 'H' || c == 'h')
4016 Term_get_size(&wid, &hgt);
4018 bool old_use_graphics = use_graphics;
4019 if (old_use_graphics)
4021 use_graphics = FALSE;
4023 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4024 handle_stuff(creature_ptr);
4029 do_cmd_save_screen_html();
4030 do_cmd_redraw(creature_ptr);
4033 /* Do we use a special screendump function ? */
4034 else if (screendump_aux)
4036 /* Dump the screen to a graphics file */
4037 (*screendump_aux)();
4039 else /* Dump the screen as text */
4043 SYMBOL_CODE c = ' ';
4046 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4048 /* File type is "TEXT" */
4049 FILE_TYPE(FILE_TYPE_TEXT);
4051 /* Append to the file */
4052 fff = my_fopen(buf, "w");
4056 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
4063 /* Dump the screen */
4064 for (y = 0; y < hgt; y++)
4067 for (x = 0; x < wid - 1; x++)
4069 /* Get the attr/char */
4070 (void)(Term_what(x, y, &a, &c));
4080 fprintf(fff, "%s\n", buf);
4087 /* Dump the screen */
4088 for (y = 0; y < hgt; y++)
4091 for (x = 0; x < wid - 1; x++)
4093 /* Get the attr/char */
4094 (void)(Term_what(x, y, &a, &c));
4097 buf[x] = hack[a&0x0F];
4104 fprintf(fff, "%s\n", buf);
4111 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4116 if (!old_use_graphics) return;
4118 use_graphics = TRUE;
4120 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4121 handle_stuff(creature_ptr);
4126 * todo okay = 既知のアーティファクト? と思われるが確証がない
4127 * 分かりやすい変数名へ変更求む&万が一未知である旨の配列なら負論理なのでゴソッと差し替えるべき
4128 * Check the status of "artifacts"
4129 * @param player_ptr プレーヤーへの参照ポインタ
4132 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4134 /* Open a new file */
4136 GAME_TEXT file_name[1024];
4137 fff = my_fopen_temp(file_name, 1024);
4140 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4145 /* Allocate the "who" array */
4147 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4149 /* Allocate the "okay" array */
4151 C_MAKE(okay, max_a_idx, bool);
4153 /* Scan the artifacts */
4154 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4156 artifact_type *a_ptr = &a_info[k];
4161 /* Skip "empty" artifacts */
4162 if (!a_ptr->name) continue;
4164 /* Skip "uncreated" artifacts */
4165 if (!a_ptr->cur_num) continue;
4171 /* Check the dungeon */
4172 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++)
4174 for (POSITION x = 0; x < player_ptr->current_floor_ptr->width; x++)
4176 grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4178 OBJECT_IDX this_o_idx, next_o_idx = 0;
4180 /* Scan all objects in the grid */
4181 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4184 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4185 next_o_idx = o_ptr->next_o_idx;
4187 /* Ignore non-artifacts */
4188 if (!object_is_fixed_artifact(o_ptr)) continue;
4190 /* Ignore known items */
4191 if (object_is_known(o_ptr)) continue;
4193 /* Note the artifact */
4194 okay[o_ptr->name1] = FALSE;
4199 /* Check the player_ptr->inventory_list and equipment */
4200 for (ARTIFACT_IDX i = 0; i < INVEN_TOTAL; i++)
4202 object_type *o_ptr = &player_ptr->inventory_list[i];
4204 /* Ignore non-objects */
4205 if (!o_ptr->k_idx) continue;
4207 /* Ignore non-artifacts */
4208 if (!object_is_fixed_artifact(o_ptr)) continue;
4210 /* Ignore known items */
4211 if (object_is_known(o_ptr)) continue;
4213 /* Note the artifact */
4214 okay[o_ptr->name1] = FALSE;
4218 for (ARTIFACT_IDX k = 0; k < max_a_idx; k++)
4220 if (okay[k]) who[n++] = k;
4224 ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4226 /* Scan the artifacts */
4227 for (ARTIFACT_IDX k = 0; k < n; k++)
4229 artifact_type *a_ptr = &a_info[who[k]];
4230 GAME_TEXT base_name[MAX_NLEN];
4231 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4233 /* Obtain the base object type */
4234 ARTIFACT_IDX z = lookup_kind(a_ptr->tval, a_ptr->sval);
4243 /* Create fake object */
4244 object_prep(q_ptr, z);
4246 /* Make it an artifact */
4247 q_ptr->name1 = (byte)who[k];
4249 /* Display as if known */
4250 q_ptr->ident |= IDENT_STORE;
4252 /* Describe the artifact */
4253 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4256 /* Hack -- Build the artifact name */
4257 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
4260 /* Free the "who" array */
4261 C_KILL(who, max_a_idx, ARTIFACT_IDX);
4263 /* Free the "okay" array */
4264 C_KILL(okay, max_a_idx, bool);
4267 /* Display the file contents */
4268 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4274 * Display known uniques
4275 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4277 static void do_cmd_knowledge_uniques(void)
4284 GAME_TEXT file_name[1024];
4287 int n_alive_surface = 0;
4288 int n_alive_over100 = 0;
4289 int n_alive_total = 0;
4292 for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4294 /* Open a new file */
4295 fff = my_fopen_temp(file_name, 1024);
4299 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4304 /* Allocate the "who" array */
4305 C_MAKE(who, max_r_idx, MONRACE_IDX);
4307 /* Scan the monsters */
4309 for (IDX i = 1; i < max_r_idx; i++)
4311 monster_race *r_ptr = &r_info[i];
4314 if (!r_ptr->name) continue;
4316 /* Require unique monsters */
4317 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4319 /* Only display "known" uniques */
4320 if (!cheat_know && !r_ptr->r_sights) continue;
4322 /* Only print rarity <= 100 uniques */
4323 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4325 /* Only "alive" uniques */
4326 if (r_ptr->max_num == 0) continue;
4330 lev = (r_ptr->level - 1) / 10;
4334 if (max_lev < lev) max_lev = lev;
4336 else n_alive_over100++;
4338 else n_alive_surface++;
4340 /* Collect "appropriate" monsters */
4344 /* Sort the array by dungeon depth of monsters */
4345 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4347 if (n_alive_surface)
4349 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
4350 n_alive_total += n_alive_surface;
4353 for (IDX i = 0; i <= max_lev; i++)
4355 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4356 n_alive_total += n_alive[i];
4359 if (n_alive_over100)
4361 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
4362 n_alive_total += n_alive_over100;
4367 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
4368 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
4372 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4375 /* Scan the monster races */
4376 for (int k = 0; k < n; k++)
4378 monster_race *r_ptr = &r_info[who[k]];
4379 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4382 /* Free the "who" array */
4383 C_KILL(who, max_r_idx, s16b);
4386 /* Display the file contents */
4387 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4393 * Display weapon-exp
4395 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4397 /* Open a new file */
4399 GAME_TEXT file_name[1024];
4400 fff = my_fopen_temp(file_name, 1024);
4403 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4408 for (int i = 0; i < 5; i++)
4410 for (int num = 0; num < 64; num++)
4414 for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4416 object_kind *k_ptr = &k_info[j];
4418 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4419 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4421 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4423 fprintf(fff, "%-25s ", tmp);
4424 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4425 else fprintf(fff, " ");
4426 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4427 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4436 /* Display the file contents */
4437 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4443 * @brief 魔法の経験値を表示するコマンドのメインルーチン
4447 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4449 /* Open a new file */
4451 GAME_TEXT file_name[1024];
4452 fff = my_fopen_temp(file_name, 1024);
4455 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4460 if (creature_ptr->realm1 != REALM_NONE)
4462 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4463 for (SPELL_IDX i = 0; i < 32; i++)
4465 const magic_type *s_ptr;
4466 if (!is_magic(creature_ptr->realm1))
4468 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4472 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4475 if (s_ptr->slevel >= 99) continue;
4476 SUB_EXP spell_exp = creature_ptr->spell_exp[i];
4477 int exp_level = spell_exp_level(spell_exp);
4478 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4479 if (creature_ptr->realm1 == REALM_HISSATSU)
4480 fprintf(fff, "[--]");
4483 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4484 else fprintf(fff, " ");
4485 fprintf(fff, "%s", exp_level_str[exp_level]);
4488 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4493 if (creature_ptr->realm2 != REALM_NONE)
4495 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4496 for (SPELL_IDX i = 0; i < 32; i++)
4498 const magic_type *s_ptr;
4499 if (!is_magic(creature_ptr->realm1))
4501 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4505 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4508 if (s_ptr->slevel >= 99) continue;
4510 SUB_EXP spell_exp = creature_ptr->spell_exp[i + 32];
4511 int exp_level = spell_exp_level(spell_exp);
4512 fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4513 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4514 else fprintf(fff, " ");
4515 fprintf(fff, "%s", exp_level_str[exp_level]);
4516 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4523 /* Display the file contents */
4524 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4530 * @brief スキル情報を表示するコマンドのメインルーチン /
4534 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4536 char skill_name[GINOU_TEMPMAX][20] =
4538 _("マーシャルアーツ", "Martial Arts "),
4539 _("二刀流 ", "Dual Wielding "),
4540 _("乗馬 ", "Riding "),
4544 /* Open a new file */
4546 char file_name[1024];
4547 fff = my_fopen_temp(file_name, 1024);
4550 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4555 for (int i = 0; i < GINOU_TEMPMAX; i++)
4557 int skill_exp = creature_ptr->skill_exp[i];
4558 fprintf(fff, "%-20s ", skill_name[i]);
4559 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4560 else fprintf(fff, " ");
4561 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4562 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4568 /* Display the file contents */
4569 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4575 * @brief 現在のペットを表示するコマンドのメインルーチン /
4576 * Display current pets
4577 * @param creature_ptr プレーヤーへの参照ポインタ
4580 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4582 /* Open a new file */
4583 GAME_TEXT file_name[1024];
4585 fff = my_fopen_temp(file_name, 1024);
4588 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4593 /* Process the monsters (backwards) */
4594 monster_type *m_ptr;
4595 GAME_TEXT pet_name[MAX_NLEN];
4597 for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4599 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4601 /* Ignore "dead" monsters */
4602 if (!monster_is_valid(m_ptr)) continue;
4604 /* Calculate "upkeep" for pets */
4605 if (!is_pet(m_ptr)) continue;
4608 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4609 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4612 int show_upkeep = calculate_upkeep(creature_ptr);
4614 fprintf(fff, "----------------------------------------------\n");
4616 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
4618 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4620 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
4624 /* Display the file contents */
4625 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4631 * @brief 現在のペットを表示するコマンドのメインルーチン /
4634 * @note the player ghosts are ignored.
4636 static void do_cmd_knowledge_kill_count(void)
4638 /* Open a new file */
4640 GAME_TEXT file_name[1024];
4641 fff = my_fopen_temp(file_name, 1024);
4644 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4649 /* Allocate the "who" array */
4651 C_MAKE(who, max_r_idx, MONRACE_IDX);
4655 /* Monsters slain */
4656 for (int kk = 1; kk < max_r_idx; kk++)
4658 monster_race *r_ptr = &r_info[kk];
4660 if (r_ptr->flags1 & (RF1_UNIQUE))
4662 bool dead = (r_ptr->max_num == 0);
4671 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4673 if (this_monster > 0)
4675 total += this_monster;
4681 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4684 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)total);
4686 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4692 /* Scan the monsters */
4694 for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4696 monster_race *r_ptr = &r_info[i];
4698 /* Use that monster */
4699 if (r_ptr->name) who[n++] = i;
4702 /* Sort the array by dungeon depth of monsters */
4704 ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4706 /* Scan the monster races */
4707 for (int k = 0; k < n; k++)
4709 monster_race *r_ptr = &r_info[who[k]];
4711 if (r_ptr->flags1 & (RF1_UNIQUE))
4713 bool dead = (r_ptr->max_num == 0);
4717 fprintf(fff, " %s\n", (r_name + r_ptr->name));
4724 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4726 if (this_monster <= 0) continue;
4729 /* p,tは人と数える by ita */
4730 if (my_strchr("pt", r_ptr->d_char))
4731 fprintf(fff, " %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4733 fprintf(fff, " %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4735 if (this_monster < 2)
4737 if (my_strstr(r_name + r_ptr->name, "coins"))
4739 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
4743 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
4749 strcpy(ToPlural, (r_name + r_ptr->name));
4750 plural_aux(ToPlural);
4751 fprintf(fff, " %d %s\n", this_monster, ToPlural);
4754 total += this_monster;
4757 fprintf(fff,"----------------------------------------------\n");
4759 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)total);
4761 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4764 /* Free the "who" array */
4765 C_KILL(who, max_r_idx, s16b);
4768 /* Display the file contents */
4769 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4775 * @brief モンスター情報リスト中のグループを表示する /
4776 * Display the object groups.
4780 * @param per_page リストの表示行
4781 * @param grp_idx グループのID配列
4782 * @param group_text グループ名の文字列配列
4783 * @param grp_cur 現在の選択ID
4784 * @param grp_top 現在の選択リスト最上部ID
4787 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)
4789 /* Display lines until done */
4790 for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4792 /* Get the group index */
4793 int grp = grp_idx[grp_top + i];
4795 /* Choose a color */
4796 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4798 /* Erase the entire line */
4799 Term_erase(col, row + i, wid);
4801 /* Display the group label */
4802 c_put_str(attr, group_text[grp], row + i, col);
4808 * Move the cursor in a browser window
4810 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
4811 IDX *list_cur, int list_cnt)
4816 IDX list = *list_cur;
4818 /* Extract direction */
4821 /* Hack -- scroll up full screen */
4826 /* Hack -- scroll down full screen */
4831 d = get_keymap_dir(ch);
4836 /* Diagonals - hack */
4837 if ((ddx[d] > 0) && ddy[d])
4842 Term_get_size(&wid, &hgt);
4844 browser_rows = hgt - 8;
4846 /* Browse group list */
4851 /* Move up or down */
4852 grp += ddy[d] * (browser_rows - 1);
4855 if (grp >= grp_cnt) grp = grp_cnt - 1;
4856 if (grp < 0) grp = 0;
4857 if (grp != old_grp) list = 0;
4860 /* Browse sub-list list */
4863 /* Move up or down */
4864 list += ddy[d] * browser_rows;
4867 if (list >= list_cnt) list = list_cnt - 1;
4868 if (list < 0) list = 0;
4880 if (col < 0) col = 0;
4881 if (col > 1) col = 1;
4888 /* Browse group list */
4893 /* Move up or down */
4897 if (grp >= grp_cnt) grp = grp_cnt - 1;
4898 if (grp < 0) grp = 0;
4899 if (grp != old_grp) list = 0;
4902 /* Browse sub-list list */
4905 /* Move up or down */
4906 list += (IDX)ddy[d];
4909 if (list >= list_cnt) list = list_cnt - 1;
4910 if (list < 0) list = 0;
4921 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4923 /* Clear the display lines */
4924 for (int i = 0; i < height; i++)
4926 Term_erase(col, row + i, width);
4929 /* Bigtile mode uses double width */
4930 if (use_bigtile) width /= 2;
4932 /* Display lines until done */
4933 for (int i = 0; i < height; i++)
4935 /* Display columns until done */
4936 for (int j = 0; j < width; j++)
4938 TERM_LEN x = col + j;
4939 TERM_LEN y = row + i;
4941 /* Bigtile mode uses double width */
4942 if (use_bigtile) x += j;
4944 TERM_COLOR ia = attr_top + i;
4945 SYMBOL_CODE ic = char_left + j;
4947 /* Ignore illegal characters */
4948 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4949 (!use_graphics && ic > 0x7f))
4955 /* Force correct code for both ASCII character and tile */
4956 if (c & 0x80) a |= 0x80;
4958 /* Display symbol */
4959 Term_queue_bigchar(x, y, a, c, 0, 0);
4966 * Place the cursor at the collect position for visual mode
4968 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
4970 int i = (a & 0x7f) - attr_top;
4971 int j = c - char_left;
4973 TERM_LEN x = col + j;
4974 TERM_LEN y = row + i;
4976 /* Bigtile mode uses double width */
4977 if (use_bigtile) x += j;
4979 /* Place the cursor */
4985 * Do visual mode command -- Change symbols
4987 static bool visual_mode_command(char ch, bool *visual_list_ptr,
4988 int height, int width,
4989 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
4990 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
4992 static TERM_COLOR attr_old = 0;
4993 static SYMBOL_CODE char_old = 0;
4998 if (*visual_list_ptr)
5001 *cur_attr_ptr = attr_old;
5002 *cur_char_ptr = char_old;
5003 *visual_list_ptr = FALSE;
5011 if (*visual_list_ptr)
5014 *visual_list_ptr = FALSE;
5015 *need_redraw = TRUE;
5023 if (!*visual_list_ptr)
5025 *visual_list_ptr = TRUE;
5027 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5028 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5030 attr_old = *cur_attr_ptr;
5031 char_old = *cur_char_ptr;
5042 /* Set the visual */
5043 attr_idx = *cur_attr_ptr;
5044 char_idx = *cur_char_ptr;
5046 /* Hack -- for feature lighting */
5047 for (i = 0; i < F_LIT_MAX; i++)
5049 attr_idx_feat[i] = 0;
5050 char_idx_feat[i] = 0;
5057 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
5060 *cur_attr_ptr = attr_idx;
5061 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5062 if (!*visual_list_ptr) *need_redraw = TRUE;
5068 *cur_char_ptr = char_idx;
5069 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5070 if (!*visual_list_ptr) *need_redraw = TRUE;
5076 if (*visual_list_ptr)
5079 int d = get_keymap_dir(ch);
5080 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5081 SYMBOL_CODE c = *cur_char_ptr;
5083 if (use_bigtile) eff_width = width / 2;
5084 else eff_width = width;
5086 /* Restrict direction */
5087 if ((a == 0) && (ddy[d] < 0)) d = 0;
5088 if ((c == 0) && (ddx[d] < 0)) d = 0;
5089 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5090 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5092 a += (TERM_COLOR)ddy[d];
5093 c += (SYMBOL_CODE)ddx[d];
5095 /* Force correct code for both ASCII character and tile */
5096 if (c & 0x80) a |= 0x80;
5098 /* Set the visual */
5103 /* Move the frame */
5104 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5105 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5106 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5107 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5113 /* Visual mode command is not used */
5119 * Display the monsters in a group.
5121 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5122 int mon_cur, int mon_top, bool visual_only)
5124 /* Display lines until done */
5126 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5130 /* Get the race index */
5131 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
5133 /* Access the race */
5134 monster_race *r_ptr = &r_info[r_idx];
5136 /* Choose a color */
5137 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5139 /* Display the name */
5140 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5142 /* Hack -- visual_list mode */
5145 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5148 if (current_world_ptr->wizard || visual_only)
5150 c_prt(attr, format("%d", r_idx), row + i, 62);
5153 /* Erase chars before overwritten by the race letter */
5154 Term_erase(69, row + i, 255);
5156 /* Display symbol */
5157 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5162 if (!(r_ptr->flags1 & RF1_UNIQUE))
5163 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5165 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
5166 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5170 /* Clear remaining lines */
5171 for (; i < per_page; i++)
5173 Term_erase(col, row + i, 255);
5179 * todo 引数の詳細について加筆求む
5180 * Display known monsters.
5181 * @param creature_ptr プレーヤーへの参照ポインタ
5182 * @param need_redraw 画面の再描画が必要な時TRUE
5183 * @param visual_only ???
5184 * @param direct_r_idx モンスターID
5187 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5190 Term_get_size(&wid, &hgt);
5192 /* Allocate the "mon_idx" array */
5194 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5200 bool visual_list = FALSE;
5201 TERM_COLOR attr_top = 0;
5204 int browser_rows = hgt - 8;
5205 if (direct_r_idx < 0)
5207 mode = visual_only ? 0x03 : 0x01;
5209 /* Check every group */
5211 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5213 /* Measure the label */
5214 len = strlen(monster_group_text[i]);
5216 /* Save the maximum length */
5217 if (len > max) max = len;
5219 /* See if any monsters are known */
5220 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5222 /* Build a list of groups with known monsters */
5223 grp_idx[grp_cnt++] = i;
5231 mon_idx[0] = direct_r_idx;
5234 /* Terminate the list */
5237 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5238 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5241 /* Terminate the list */
5242 grp_idx[grp_cnt] = -1;
5244 mode = visual_only ? 0x02 : 0x00;
5245 IDX old_grp_cur = -1;
5258 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5259 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5260 prt(_("名前", "Name"), 4, max + 3);
5261 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5262 prt(_("文字", "Sym"), 4, 67);
5263 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5265 for (IDX i = 0; i < 78; i++)
5267 Term_putch(i, 5, TERM_WHITE, '=');
5270 if (direct_r_idx < 0)
5272 for (IDX i = 0; i < browser_rows; i++)
5274 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5281 if (direct_r_idx < 0)
5283 /* Scroll group list */
5284 if (grp_cur < grp_top) grp_top = grp_cur;
5285 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5287 /* Display a list of monster groups */
5288 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5290 if (old_grp_cur != grp_cur)
5292 old_grp_cur = grp_cur;
5294 /* Get a list of monsters in the current group */
5295 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5298 /* Scroll monster list */
5299 while (mon_cur < mon_top)
5300 mon_top = MAX(0, mon_top - browser_rows/2);
5301 while (mon_cur >= mon_top + browser_rows)
5302 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
5307 /* Display a list of monsters in the current group */
5308 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5314 /* Display a monster name */
5315 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5317 /* Display visual list below first monster */
5318 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
5322 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5323 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5324 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5325 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5328 /* Get the current monster */
5329 monster_race *r_ptr;
5330 r_ptr = &r_info[mon_idx[mon_cur]];
5334 /* Mega Hack -- track this monster race */
5335 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
5336 handle_stuff(creature_ptr);
5341 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5345 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5349 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5354 /* Do visual mode command if needed */
5355 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))
5357 if (direct_r_idx >= 0)
5383 /* Recall on screen */
5384 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5386 screen_roff(mon_idx[mon_cur], 0);
5398 /* Move the cursor */
5399 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5406 /* Free the "mon_idx" array */
5407 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5412 * Display the objects in a group.
5414 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5415 int object_cur, int object_top, bool visual_only)
5417 /* Display lines until done */
5419 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5421 GAME_TEXT o_name[MAX_NLEN];
5424 object_kind *flavor_k_ptr;
5426 /* Get the object index */
5427 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5429 /* Access the object */
5430 object_kind *k_ptr = &k_info[k_idx];
5432 /* Choose a color */
5433 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5434 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5436 if (!visual_only && k_ptr->flavor)
5438 /* Appearance of this object is shuffled */
5439 flavor_k_ptr = &k_info[k_ptr->flavor];
5443 /* Appearance of this object is very normal */
5444 flavor_k_ptr = k_ptr;
5447 attr = ((i + object_top == object_cur) ? cursor : attr);
5449 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5452 strip_name(o_name, k_idx);
5457 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5460 /* Display the name */
5461 c_prt(attr, o_name, row + i, col);
5463 /* Hack -- visual_list mode */
5466 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);
5469 if (current_world_ptr->wizard || visual_only)
5471 c_prt(attr, format("%d", k_idx), row + i, 70);
5474 a = flavor_k_ptr->x_attr;
5475 c = flavor_k_ptr->x_char;
5477 /* Display symbol */
5478 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5481 /* Clear remaining lines */
5482 for (; i < per_page; i++)
5484 Term_erase(col, row + i, 255);
5490 * Describe fake object
5492 static void desc_obj_fake(player_type *creature_ptr, KIND_OBJECT_IDX k_idx)
5495 object_type object_type_body;
5496 o_ptr = &object_type_body;
5498 object_prep(o_ptr, k_idx);
5500 /* It's fully know */
5501 o_ptr->ident |= IDENT_KNOWN;
5502 handle_stuff(creature_ptr);
5504 if (screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5506 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5512 * Display known objects
5514 static void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx)
5516 IDX object_old, object_top;
5519 OBJECT_IDX *object_idx;
5521 bool visual_list = FALSE;
5522 TERM_COLOR attr_top = 0;
5527 Term_get_size(&wid, &hgt);
5529 int browser_rows = hgt - 8;
5531 /* Allocate the "object_idx" array */
5532 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5537 if (direct_k_idx < 0)
5539 mode = visual_only ? 0x03 : 0x01;
5541 /* Check every group */
5542 for (IDX i = 0; object_group_text[i] != NULL; i++)
5544 /* Measure the label */
5545 len = strlen(object_group_text[i]);
5547 /* Save the maximum length */
5548 if (len > max) max = len;
5550 /* See if any monsters are known */
5551 if (collect_objects(i, object_idx, mode))
5553 /* Build a list of groups with known monsters */
5554 grp_idx[grp_cnt++] = i;
5563 object_kind *k_ptr = &k_info[direct_k_idx];
5564 object_kind *flavor_k_ptr;
5566 if (!visual_only && k_ptr->flavor)
5568 /* Appearance of this object is shuffled */
5569 flavor_k_ptr = &k_info[k_ptr->flavor];
5573 /* Appearance of this object is very normal */
5574 flavor_k_ptr = k_ptr;
5577 object_idx[0] = direct_k_idx;
5578 object_old = direct_k_idx;
5581 /* Terminate the list */
5584 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5585 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5588 /* Terminate the list */
5589 grp_idx[grp_cnt] = -1;
5591 mode = visual_only ? 0x02 : 0x00;
5592 IDX old_grp_cur = -1;
5595 IDX object_cur = object_top = 0;
5601 object_kind *k_ptr, *flavor_k_ptr;
5608 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5609 if (direct_k_idx < 0) prt("グループ", 4, 0);
5610 prt("名前", 4, max + 3);
5611 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5614 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5615 if (direct_k_idx < 0) prt("Group", 4, 0);
5616 prt("Name", 4, max + 3);
5617 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5621 for (IDX i = 0; i < 78; i++)
5623 Term_putch(i, 5, TERM_WHITE, '=');
5626 if (direct_k_idx < 0)
5628 for (IDX i = 0; i < browser_rows; i++)
5630 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5637 if (direct_k_idx < 0)
5639 /* Scroll group list */
5640 if (grp_cur < grp_top) grp_top = grp_cur;
5641 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5643 /* Display a list of object groups */
5644 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5646 if (old_grp_cur != grp_cur)
5648 old_grp_cur = grp_cur;
5650 /* Get a list of objects in the current group */
5651 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5654 /* Scroll object list */
5655 while (object_cur < object_top)
5656 object_top = MAX(0, object_top - browser_rows/2);
5657 while (object_cur >= object_top + browser_rows)
5658 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
5663 /* Display a list of objects in the current group */
5664 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5668 object_top = object_cur;
5670 /* Display a list of objects in the current group */
5671 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5673 /* Display visual list below first object */
5674 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
5677 /* Get the current object */
5678 k_ptr = &k_info[object_idx[object_cur]];
5680 if (!visual_only && k_ptr->flavor)
5682 /* Appearance of this object is shuffled */
5683 flavor_k_ptr = &k_info[k_ptr->flavor];
5687 /* Appearance of this object is very normal */
5688 flavor_k_ptr = k_ptr;
5693 prt(format("<方向>%s%s%s, ESC",
5694 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5695 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5696 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5699 prt(format("<dir>%s%s%s, ESC",
5700 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5701 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5702 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5708 /* Mega Hack -- track this object */
5709 if (object_cnt) object_kind_track(object_idx[object_cur]);
5711 /* The "current" object changed */
5712 if (object_old != object_idx[object_cur])
5714 handle_stuff(creature_ptr);
5716 /* Remember the "current" object */
5717 object_old = object_idx[object_cur];
5723 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5727 Term_gotoxy(0, 6 + (grp_cur - grp_top));
5731 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5736 /* Do visual mode command if needed */
5737 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))
5739 if (direct_k_idx >= 0)
5764 /* Recall on screen */
5765 if (!visual_list && !visual_only && (grp_cnt > 0))
5767 desc_obj_fake(creature_ptr, object_idx[object_cur]);
5775 /* Move the cursor */
5776 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5782 /* Free the "object_idx" array */
5783 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5788 * Display the features in a group.
5790 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5791 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5793 int lit_col[F_LIT_MAX], i;
5794 int f_idx_col = use_bigtile ? 62 : 64;
5796 /* Correct columns 1 and 4 */
5797 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5798 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5799 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5801 /* Display lines until done */
5802 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5805 FEAT_IDX f_idx = feat_idx[feat_top + i];
5806 feature_type *f_ptr = &f_info[f_idx];
5807 int row_i = row + i;
5809 /* Choose a color */
5810 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5812 /* Display the name */
5813 c_prt(attr, f_name + f_ptr->name, row_i, col);
5815 /* Hack -- visual_list mode */
5818 /* Display lighting level */
5819 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5821 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));
5823 if (current_world_ptr->wizard || visual_only)
5825 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5828 /* Display symbol */
5829 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);
5831 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5832 for (int j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5834 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5836 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5838 /* Mega-hack -- Use non-standard colour */
5839 for (int j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5841 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5845 /* Clear remaining lines */
5846 for (; i < per_page; i++)
5848 Term_erase(col, row + i, 255);
5854 * Interact with feature visuals.
5856 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5858 TERM_COLOR attr_old[F_LIT_MAX];
5859 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5860 SYMBOL_CODE char_old[F_LIT_MAX];
5861 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5864 Term_get_size(&wid, &hgt);
5866 /* Allocate the "feat_idx" array */
5868 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5874 FEAT_IDX grp_idx[100];
5875 TERM_COLOR attr_top = 0;
5876 bool visual_list = FALSE;
5878 TERM_LEN browser_rows = hgt - 8;
5879 if (direct_f_idx < 0)
5881 /* Check every group */
5882 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5884 /* Measure the label */
5885 len = strlen(feature_group_text[i]);
5887 /* Save the maximum length */
5888 if (len > max) max = len;
5890 /* See if any features are known */
5891 if (collect_features(feat_idx, 0x01))
5893 /* Build a list of groups with known features */
5894 grp_idx[grp_cnt++] = i;
5902 feature_type *f_ptr = &f_info[direct_f_idx];
5904 feat_idx[0] = direct_f_idx;
5907 /* Terminate the list */
5910 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5911 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5913 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5915 attr_old[i] = f_ptr->x_attr[i];
5916 char_old[i] = f_ptr->x_char[i];
5920 /* Terminate the list */
5921 grp_idx[grp_cnt] = -1;
5923 FEAT_IDX old_grp_cur = -1;
5924 FEAT_IDX grp_cur = 0;
5925 FEAT_IDX grp_top = 0;
5926 FEAT_IDX feat_cur = 0;
5927 FEAT_IDX feat_top = 0;
5928 TERM_LEN column = 0;
5931 TERM_COLOR *cur_attr_ptr;
5932 SYMBOL_CODE *cur_char_ptr;
5936 feature_type *f_ptr;
5942 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5943 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
5944 prt(_("名前", "Name"), 4, max + 3);
5947 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5948 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
5952 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
5953 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
5956 for (FEAT_IDX i = 0; i < 78; i++)
5958 Term_putch(i, 5, TERM_WHITE, '=');
5961 if (direct_f_idx < 0)
5963 for (FEAT_IDX i = 0; i < browser_rows; i++)
5965 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5972 if (direct_f_idx < 0)
5974 /* Scroll group list */
5975 if (grp_cur < grp_top) grp_top = grp_cur;
5976 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5978 /* Display a list of feature groups */
5979 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
5981 if (old_grp_cur != grp_cur)
5983 old_grp_cur = grp_cur;
5985 /* Get a list of features in the current group */
5986 feat_cnt = collect_features(feat_idx, 0x00);
5989 /* Scroll feature list */
5990 while (feat_cur < feat_top)
5991 feat_top = MAX(0, feat_top - browser_rows/2);
5992 while (feat_cur >= feat_top + browser_rows)
5993 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
5998 /* Display a list of features in the current group */
5999 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
6003 feat_top = feat_cur;
6005 /* Display a list of features in the current group */
6006 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
6008 /* Display visual list below first object */
6009 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6013 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
6014 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6015 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6018 /* Get the current feature */
6019 f_ptr = &f_info[feat_idx[feat_cur]];
6020 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
6021 cur_char_ptr = &f_ptr->x_char[*lighting_level];
6025 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
6029 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6033 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
6038 if (visual_list && ((ch == 'A') || (ch == 'a')))
6040 int prev_lighting_level = *lighting_level;
6044 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
6045 else (*lighting_level)--;
6049 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
6050 else (*lighting_level)++;
6053 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
6054 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6056 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
6057 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6062 else if ((ch == 'D') || (ch == 'd'))
6064 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
6065 byte prev_x_char = f_ptr->x_char[*lighting_level];
6067 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6071 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6072 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6074 if (prev_x_char != f_ptr->x_char[*lighting_level])
6075 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6077 else *need_redraw = TRUE;
6082 /* Do visual mode command if needed */
6083 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))
6087 /* Restore previous visual settings */
6089 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6091 f_ptr->x_attr[i] = attr_old[i];
6092 f_ptr->x_char[i] = char_old[i];
6099 if (direct_f_idx >= 0) flag = TRUE;
6100 else *lighting_level = F_LIT_STANDARD;
6103 /* Preserve current visual settings */
6106 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6108 attr_old[i] = f_ptr->x_attr[i];
6109 char_old[i] = f_ptr->x_char[i];
6111 *lighting_level = F_LIT_STANDARD;
6118 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6120 attr_idx_feat[i] = f_ptr->x_attr[i];
6121 char_idx_feat[i] = f_ptr->x_char[i];
6130 /* Allow TERM_DARK text */
6131 for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6133 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6134 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6152 /* Move the cursor */
6153 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6159 /* Free the "feat_idx" array */
6160 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6165 * List wanted monsters
6166 * @param creature_ptr プレーヤーへの参照ポインタ
6169 static void do_cmd_knowledge_bounty(player_type *creature_ptr)
6171 /* Open a new file */
6173 GAME_TEXT file_name[1024];
6174 fff = my_fopen_temp(file_name, 1024);
6177 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6182 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
6183 (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6185 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6186 fprintf(fff, "----------------------------------------------\n");
6188 bool listed = FALSE;
6189 for (int i = 0; i < MAX_BOUNTY; i++)
6191 if (current_world_ptr->bounty_r_idx[i] <= 10000)
6193 fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6200 fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
6205 /* Display the file contents */
6206 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6211 * List virtues & status
6213 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6215 /* Open a new file */
6217 GAME_TEXT file_name[1024];
6218 fff = my_fopen_temp(file_name, 1024);
6221 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6226 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment(creature_ptr));
6227 dump_virtues(creature_ptr, fff);
6230 /* Display the file contents */
6231 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6238 static void do_cmd_knowledge_dungeon(void)
6240 /* Open a new file */
6242 GAME_TEXT file_name[1024];
6243 fff = my_fopen_temp(file_name, 1024);
6246 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6251 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6255 if (!d_info[i].maxdepth) continue;
6256 if (!max_dlv[i]) continue;
6257 if (d_info[i].final_guardian)
6259 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6261 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6263 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6268 /* Display the file contents */
6269 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6275 * List virtues & status
6278 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6280 /* Open a new file */
6282 GAME_TEXT file_name[1024];
6283 fff = my_fopen_temp(file_name, 1024);
6286 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6291 int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6292 (2 * creature_ptr->hitdie +
6293 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6295 if (creature_ptr->knowledge & KNOW_HPRATE)
6296 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6297 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6299 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6300 for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6302 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);
6303 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6306 dump_yourself(creature_ptr, fff);
6309 /* Display the file contents */
6310 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6316 * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6317 * Print all active quests
6318 * @param creature_ptr プレーヤーへの参照ポインタ
6321 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6324 char rand_tmp_str[120] = "\0";
6325 GAME_TEXT name[MAX_NLEN];
6326 monster_race *r_ptr;
6327 int rand_level = 100;
6330 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6332 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6334 bool is_no_print = quest[i].status != QUEST_STATUS_TAKEN;
6335 is_no_print &= (quest[i].status != QUEST_STATUS_STAGE_COMPLETED) || (quest[i].type != QUEST_TYPE_TOWER);
6336 is_no_print &= quest[i].status == QUEST_STATUS_COMPLETED;
6340 /* Set the quest number temporary */
6341 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6343 /* Clear the text */
6344 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6345 quest_text_line = 0;
6347 creature_ptr->current_floor_ptr->inside_quest = i;
6349 /* Get the quest text */
6350 init_flags = INIT_SHOW_TEXT;
6352 process_dungeon_file(creature_ptr, "q_info.txt", 0, 0, 0, 0);
6354 /* Reset the old quest number */
6355 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6357 /* No info from "silent" quests */
6358 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6362 if (quest[i].type != QUEST_TYPE_RANDOM)
6364 char note[80] = "\0";
6366 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6368 switch (quest[i].type)
6370 case QUEST_TYPE_KILL_LEVEL:
6371 case QUEST_TYPE_KILL_ANY_LEVEL:
6372 r_ptr = &r_info[quest[i].r_idx];
6373 strcpy(name, r_name + r_ptr->name);
6374 if (quest[i].max_num > 1)
6377 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6378 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6381 sprintf(note, " - kill %d %s, have killed %d.",
6382 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6386 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6389 case QUEST_TYPE_FIND_ARTIFACT:
6392 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6394 object_type *q_ptr = &forge;
6395 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6396 object_prep(q_ptr, k_idx);
6397 q_ptr->name1 = quest[i].k_idx;
6398 q_ptr->ident = IDENT_STORE;
6399 object_desc(name, q_ptr, OD_NAME_ONLY);
6401 sprintf(note, _("\n - %sを見つけ出す。", "\n - Find out %s."), name);
6403 case QUEST_TYPE_FIND_EXIT:
6404 sprintf(note, _(" - 出口に到達する。", " - Reach to Exit."));
6407 case QUEST_TYPE_KILL_NUMBER:
6409 sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6410 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6412 sprintf(note, " - Kill %d monsters, have killed %d.",
6413 (int)quest[i].max_num, (int)quest[i].cur_num);
6417 case QUEST_TYPE_KILL_ALL:
6418 case QUEST_TYPE_TOWER:
6419 sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6424 /* Print the quest info */
6425 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
6426 quest[i].name, (int)quest[i].level, note);
6428 fputs(tmp_str, fff);
6430 if (quest[i].status == QUEST_STATUS_COMPLETED)
6432 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
6433 fputs(tmp_str, fff);
6438 while (quest_text[k][0] && k < 10)
6440 fprintf(fff, " %s\n", quest_text[k]);
6447 /* QUEST_TYPE_RANDOM */
6448 if (quest[i].level >= rand_level)
6452 rand_level = quest[i].level;
6454 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6456 /* Print the quest info */
6457 r_ptr = &r_info[quest[i].r_idx];
6458 strcpy(name, r_name + r_ptr->name);
6460 if (quest[i].max_num <= 1)
6462 sprintf(rand_tmp_str, _(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
6463 quest[i].name, (int)quest[i].level, name);
6468 sprintf(rand_tmp_str, " %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6469 quest[i].name, (int)quest[i].level,
6470 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6474 sprintf(rand_tmp_str, " %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
6475 quest[i].name, (int)quest[i].level,
6476 (int)quest[i].max_num, name, (int)quest[i].cur_num);
6480 /* Print the current random quest */
6481 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6483 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6487 static bool do_cmd_knowledge_quests_aux(player_type *player_ptr, FILE *fff, IDX q_idx)
6490 char playtime_str[16];
6491 quest_type* const q_ptr = &quest[q_idx];
6493 floor_type *floor_ptr = player_ptr->current_floor_ptr;
6494 if (is_fixed_quest_idx(q_idx))
6496 /* Set the quest number temporary */
6497 IDX old_quest = floor_ptr->inside_quest;
6499 floor_ptr->inside_quest = q_idx;
6502 init_flags = INIT_NAME_ONLY;
6504 process_dungeon_file(player_ptr, "q_info.txt", 0, 0, 0, 0);
6506 /* Reset the old quest number */
6507 floor_ptr->inside_quest = old_quest;
6509 /* No info from "silent" quests */
6510 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6513 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6514 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
6516 if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6518 /* Print the quest info */
6520 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6521 " %-35s (Danger level: %3d) - level %2d - %s\n"),
6522 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6523 fputs(tmp_str, fff);
6527 /* Print the quest info */
6528 if (q_ptr->complev == 0)
6531 _(" %-35s (%3d階) - 不戦勝 - %s\n",
6532 " %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6533 r_name + r_info[q_ptr->r_idx].name,
6534 (int)q_ptr->level, playtime_str);
6535 fputs(tmp_str, fff);
6540 _(" %-35s (%3d階) - レベル%2d - %s\n",
6541 " %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6542 r_name + r_info[q_ptr->r_idx].name,
6546 fputs(tmp_str, fff);
6552 * Print all finished quests
6553 * @param creature_ptr プレーヤーへの参照ポインタ
6554 * @param fff セーブファイル (展開済?)
6555 * @param quest_num[] 受注したことのあるクエスト群
6558 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6560 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6561 QUEST_IDX total = 0;
6562 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6564 QUEST_IDX q_idx = quest_num[i];
6565 quest_type* const q_ptr = &quest[q_idx];
6567 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6573 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6578 * Print all failed quests
6579 * @param creature_ptr プレーヤーへの参照ポインタ
6580 * @param fff セーブファイル (展開済?)
6581 * @param quest_num[] 受注したことのあるクエスト群
6584 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6586 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6587 QUEST_IDX total = 0;
6588 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6590 QUEST_IDX q_idx = quest_num[i];
6591 quest_type* const q_ptr = &quest[q_idx];
6593 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6594 do_cmd_knowledge_quests_aux(creature_ptr, fff, q_idx))
6600 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6605 * Print all random quests
6607 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6609 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6610 GAME_TEXT tmp_str[120];
6611 QUEST_IDX total = 0;
6612 for (QUEST_IDX i = 1; i < max_q_idx; i++)
6614 /* No info from "silent" quests */
6615 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6617 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6621 /* Print the quest info */
6622 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
6623 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
6624 fputs(tmp_str, fff);
6628 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
6632 * Print quest status of all active quests
6633 * @param creature_ptr プレーヤーへの参照ポインタ
6636 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6638 /* Open a new file */
6640 GAME_TEXT file_name[1024];
6641 fff = my_fopen_temp(file_name, 1024);
6644 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6649 /* Allocate Memory */
6651 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6653 /* Sort by compete level */
6654 for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6656 ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6658 /* Dump Quest Information */
6659 do_cmd_knowledge_quests_current(creature_ptr, fff);
6661 do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6663 do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6664 if (current_world_ptr->wizard)
6667 do_cmd_knowledge_quests_wiz_random(fff);
6672 /* Display the file contents */
6673 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6677 C_KILL(quest_num, max_q_idx, QUEST_IDX);
6683 * @param player_ptr プレーヤーへの参照ポインタ
6686 static void do_cmd_knowledge_home(player_type *player_ptr)
6688 process_dungeon_file(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6690 /* Open a new file */
6692 GAME_TEXT file_name[1024];
6693 fff = my_fopen_temp(file_name, 1024);
6696 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6701 /* Print all homes in the different towns */
6703 st_ptr = &town_info[1].store[STORE_HOME];
6705 /* Home -- if anything there */
6706 if (st_ptr->stock_num)
6711 /* Header with name of the town */
6712 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
6714 /* Dump all available items */
6715 concptr paren = ")";
6716 GAME_TEXT o_name[MAX_NLEN];
6717 for (int i = 0; i < st_ptr->stock_num; i++)
6720 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6721 object_desc(o_name, &st_ptr->stock[i], 0);
6722 if (strlen(o_name) <= 80 - 3)
6724 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6730 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6731 if (iskanji(*t)) { t++; n++; }
6732 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6734 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6735 fprintf(fff, " %.77s\n", o_name + n);
6738 object_desc(o_name, &st_ptr->stock[i], 0);
6739 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6743 /* Add an empty line */
6744 fprintf(fff, "\n\n");
6749 /* Display the file contents */
6750 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6756 * Check the status of "autopick"
6758 static void do_cmd_knowledge_autopick(void)
6760 /* Open a new file */
6762 GAME_TEXT file_name[1024];
6763 fff = my_fopen_temp(file_name, 1024);
6766 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6773 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6777 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
6778 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6781 for (int k = 0; k < max_autopick; k++)
6784 byte act = autopick_list[k].action;
6785 if (act & DONT_AUTOPICK)
6787 tmp = _("放置", "Leave");
6789 else if (act & DO_AUTODESTROY)
6791 tmp = _("破壊", "Destroy");
6793 else if (act & DO_AUTOPICK)
6795 tmp = _("拾う", "Pickup");
6799 tmp = _("確認", "Query");
6802 if (act & DO_DISPLAY)
6803 fprintf(fff, "%11s", format("[%s]", tmp));
6805 fprintf(fff, "%11s", format("(%s)", tmp));
6807 tmp = autopick_line_from_entry(&autopick_list[k]);
6808 fprintf(fff, " %s", tmp);
6815 /* Display the file contents */
6816 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6822 * Interact with "knowledge"
6824 void do_cmd_knowledge(player_type *creature_ptr)
6827 bool need_redraw = FALSE;
6829 /* File type is "TEXT" */
6830 FILE_TYPE(FILE_TYPE_TEXT);
6833 /* Interact until done */
6838 /* Ask for a choice */
6839 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
6840 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6842 /* Give some choices */
6846 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
6847 prt("(2) 既知のアイテム の一覧", 7, 5);
6848 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6849 prt("(4) 既知のモンスター の一覧", 9, 5);
6850 prt("(5) 倒した敵の数 の一覧", 10, 5);
6851 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
6852 prt("(7) 現在のペット の一覧", 12, 5);
6853 prt("(8) 我が家のアイテム の一覧", 13, 5);
6854 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
6855 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
6859 prt("(a) 自分に関する情報 の一覧", 6, 5);
6860 prt("(b) 突然変異 の一覧", 7, 5);
6861 prt("(c) 武器の経験値 の一覧", 8, 5);
6862 prt("(d) 魔法の経験値 の一覧", 9, 5);
6863 prt("(e) 技能の経験値 の一覧", 10, 5);
6864 prt("(f) プレイヤーの徳 の一覧", 11, 5);
6865 prt("(g) 入ったダンジョン の一覧", 12, 5);
6866 prt("(h) 実行中のクエスト の一覧", 13, 5);
6867 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
6872 prt("(1) Display known artifacts", 6, 5);
6873 prt("(2) Display known objects", 7, 5);
6874 prt("(3) Display remaining uniques", 8, 5);
6875 prt("(4) Display known monster", 9, 5);
6876 prt("(5) Display kill count", 10, 5);
6877 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6878 prt("(7) Display current pets", 12, 5);
6879 prt("(8) Display home inventory", 13, 5);
6880 prt("(9) Display *identified* equip.", 14, 5);
6881 prt("(0) Display terrain symbols.", 15, 5);
6885 prt("(a) Display about yourself", 6, 5);
6886 prt("(b) Display mutations", 7, 5);
6887 prt("(c) Display weapon proficiency", 8, 5);
6888 prt("(d) Display spell proficiency", 9, 5);
6889 prt("(e) Display misc. proficiency", 10, 5);
6890 prt("(f) Display virtues", 11, 5);
6891 prt("(g) Display dungeons", 12, 5);
6892 prt("(h) Display current quests", 13, 5);
6893 prt("(i) Display auto pick/destroy", 14, 5);
6897 prt(_("-続く-", "-more-"), 17, 8);
6898 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6899 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6900 /*prt("-) 前ページ", 21, 60);*/
6901 prt(_("コマンド:", "Command: "), 20, 0);
6904 if (i == ESCAPE) break;
6907 case ' ': /* Page change */
6911 case '1': /* Artifacts */
6912 do_cmd_knowledge_artifacts(creature_ptr);
6914 case '2': /* Objects */
6915 do_cmd_knowledge_objects(creature_ptr, &need_redraw, FALSE, -1);
6917 case '3': /* Uniques */
6918 do_cmd_knowledge_uniques();
6920 case '4': /* Monsters */
6921 do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6923 case '5': /* Kill count */
6924 do_cmd_knowledge_kill_count();
6926 case '6': /* wanted */
6927 if (!vanilla_town) do_cmd_knowledge_bounty(creature_ptr);
6929 case '7': /* Pets */
6930 do_cmd_knowledge_pets(creature_ptr);
6932 case '8': /* Home */
6933 do_cmd_knowledge_home(creature_ptr);
6935 case '9': /* Resist list */
6936 do_cmd_knowledge_inven(creature_ptr);
6938 case '0': /* Feature list */
6940 IDX lighting_level = F_LIT_STANDARD;
6941 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
6945 case 'a': /* Max stat */
6946 do_cmd_knowledge_stat(creature_ptr);
6948 case 'b': /* Mutations */
6949 do_cmd_knowledge_mutations(creature_ptr);
6951 case 'c': /* weapon-exp */
6952 do_cmd_knowledge_weapon_exp(creature_ptr);
6954 case 'd': /* spell-exp */
6955 do_cmd_knowledge_spell_exp(creature_ptr);
6957 case 'e': /* skill-exp */
6958 do_cmd_knowledge_skill_exp(creature_ptr);
6960 case 'f': /* Virtues */
6961 do_cmd_knowledge_virtues(creature_ptr);
6963 case 'g': /* Dungeon */
6964 do_cmd_knowledge_dungeon();
6966 case 'h': /* Quests */
6967 do_cmd_knowledge_quests(creature_ptr);
6969 case 'i': /* Autopick */
6970 do_cmd_knowledge_autopick();
6972 default: /* Unknown option */
6980 if (need_redraw) do_cmd_redraw(creature_ptr);
6985 * Check on the status of an active quest
6986 * @param creature_ptr プレーヤーへの参照ポインタ
6989 void do_cmd_checkquest(player_type *creature_ptr)
6991 /* File type is "TEXT" */
6992 FILE_TYPE(FILE_TYPE_TEXT);
6996 do_cmd_knowledge_quests(creature_ptr);
7002 * Display the time and date
7003 * @param creature_ptr プレーヤーへの参照ポインタ
7006 void do_cmd_time(player_type *creature_ptr)
7009 extract_day_hour_min(&day, &hour, &min);
7012 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
7015 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
7016 else strcpy(day_buf, "*****");
7018 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
7019 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
7023 if (!randint0(10) || creature_ptr->image)
7025 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
7029 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
7032 /* Open this file */
7034 fff = my_fopen(buf, "rt");
7038 /* Find this time */
7039 int full = hour * 100 + min;
7043 while (!my_fgets(fff, buf, sizeof(buf)))
7045 /* Ignore comments */
7046 if (!buf[0] || (buf[0] == '#')) continue;
7048 /* Ignore invalid lines */
7049 if (buf[1] != ':') continue;
7051 /* Process 'Start' */
7054 /* Extract the starting time */
7055 start = atoi(buf + 2);
7057 /* Assume valid for an hour */
7065 /* Extract the ending time */
7066 end = atoi(buf + 2);
7070 /* Ignore incorrect range */
7071 if ((start > full) || (full > end)) continue;
7073 /* Process 'Description' */
7078 /* Apply the randomizer */
7079 if (!randint0(num)) strcpy(desc, buf + 2);