OSDN Git Service

e4b0ce7b21d9a8ce2e45d7f5550e3bd1624e1e55
[hengband/hengband.git] / src / cmd / cmd-dump.c
1 /*!
2  * @file cmd-dump.c
3  * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
4  * @date 2014/01/02
5  * @author
6  * <pre>
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.
11  * </pre>
12  * @details
13  * <pre>
14  * A set of functions to maintain automatic dumps of various kinds.
15  * -Mogami-
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
27  * point.
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.
39  * </pre>
40  */
41
42 #include "angband.h"
43 #include "util.h"
44 #include "cmd-dump.h"
45 #include "term.h"
46 #include "inet.h"
47 #include "core.h"
48
49 #include "autopick.h"
50
51 #include "bldg.h"
52 #include "birth.h"
53 #include "cmd-pet.h"
54 #include "cmd-spell.h"
55 #include "dungeon.h"
56 #include "feature.h"
57 #include "world.h"
58 #include "player-effects.h"
59 #include "player-status.h"
60 #include "player-skill.h"
61 #include "player-personality.h"
62 #include "sort.h"
63 #include "mutation.h"
64 #include "quest.h"
65 #include "store.h"
66 #include "artifact.h"
67 #include "avatar.h"
68 #include "object-flavor.h"
69 #include "object-hook.h"
70 #include "monster.h"
71 #include "monster-status.h"
72 #include "floor.h"
73 #include "view-mainwindow.h"
74 #include "dungeon-file.h"
75 #include "files.h"
76 #include "player-class.h"
77 #include "player-move.h"
78 #include "spells.h"
79 #include "objectkind.h"
80 #include "floor-town.h"
81 #include "realm.h"
82 #include "view-mainwindow.h"
83
84 #include "english.h"
85
86 /*
87  *  Mark strings for auto dump
88  */
89 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
90 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
91
92 /*
93  * Variables for auto dump
94  */
95 static FILE *auto_dump_stream;
96 static concptr auto_dump_mark;
97 static int auto_dump_line_num;
98
99 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
100 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
101 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
102
103 // todo *抹殺* したい…
104 bool write_level;
105
106 /*!
107  * @brief prf出力内容を消去する /
108  * Remove old lines automatically generated before.
109  * @param orig_file 消去を行うファイル名
110  */
111 static void remove_auto_dump(concptr orig_file)
112 {
113         FILE *tmp_fff, *orig_fff;
114
115         char tmp_file[1024];
116         char buf[1024];
117         bool between_mark = FALSE;
118         bool changed = FALSE;
119         int line_num = 0;
120         long header_location = 0;
121         char header_mark_str[80];
122         char footer_mark_str[80];
123         size_t mark_len;
124
125         /* Prepare a header/footer mark string */
126         sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
127         sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
128
129         mark_len = strlen(footer_mark_str);
130
131         /* Open an old dump file in read-only mode */
132         orig_fff = my_fopen(orig_file, "r");
133
134         /* If original file does not exist, nothing to do */
135         if (!orig_fff) return;
136
137         /* Open a new (temporary) file */
138         tmp_fff = my_fopen_temp(tmp_file, 1024);
139
140         if (!tmp_fff)
141         {
142             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
143             msg_print(NULL);
144             return;
145         }
146
147         /* Loop for every line */
148         while (TRUE)
149         {
150                 /* Read a line */
151                 if (my_fgets(orig_fff, buf, sizeof(buf)))
152                 {
153                         /* Read error: Assume End of File */
154
155                         /*
156                          * Was looking for the footer, but not found.
157                          *
158                          * Since automatic dump might be edited by hand,
159                          * it's dangerous to kill these lines.
160                          * Seek back to the next line of the (pseudo) header,
161                          * and read again.
162                          */
163                         if (between_mark)
164                         {
165                                 fseek(orig_fff, header_location, SEEK_SET);
166                                 between_mark = FALSE;
167                                 continue;
168                         }
169
170                         /* Success -- End the loop */
171                         else
172                         {
173                                 break;
174                         }
175                 }
176
177                 /* We are looking for the header mark of automatic dump */
178                 if (!between_mark)
179                 {
180                         /* Is this line a header? */
181                         if (!strcmp(buf, header_mark_str))
182                         {
183                                 /* Memorise seek point of this line */
184                                 header_location = ftell(orig_fff);
185
186                                 /* Initialize counter for number of lines */
187                                 line_num = 0;
188
189                                 /* Look for the footer from now */
190                                 between_mark = TRUE;
191
192                                 /* There are some changes */
193                                 changed = TRUE;
194                         }
195
196                         /* Not a header */
197                         else
198                         {
199                                 /* Copy orginally lines */
200                                 fprintf(tmp_fff, "%s\n", buf);
201                         }
202
203                         continue;
204                 }
205
206                 /* todo 処理よりもコメントが邪魔でif文を反転できない*/
207                 /* We are looking for the footer mark of automatic dump */
208                 /* Is this line a footer? */
209                 if (!strncmp(buf, footer_mark_str, mark_len))
210                 {
211                         int tmp;
212
213                         /*
214                          * Compare the number of lines
215                          *
216                          * If there is an inconsistency between
217                          * actual number of lines and the
218                          * number here, the automatic dump
219                          * might be edited by hand.  So it's
220                          * dangerous to kill these lines.
221                          * Seek back to the next line of the
222                          * (pseudo) header, and read again.
223                          */
224                         if (!sscanf(buf + mark_len, " (%d)", &tmp)
225                                 || tmp != line_num)
226                         {
227                                 fseek(orig_fff, header_location, SEEK_SET);
228                         }
229
230                         /* Look for another header */
231                         between_mark = FALSE;
232                         continue;
233                 }
234
235                 /* Not a footer */
236                 /* Ignore old line, and count number of lines */
237                 line_num++;
238         }
239
240         /* Close files */
241         my_fclose(orig_fff);
242         my_fclose(tmp_fff);
243
244         /* If there are some changes, overwrite the original file with new one */
245         if (changed)
246         {
247                 /* Copy contents of temporary file */
248
249                 tmp_fff = my_fopen(tmp_file, "r");
250                 orig_fff = my_fopen(orig_file, "w");
251
252                 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
253                         fprintf(orig_fff, "%s\n", buf);
254
255                 my_fclose(orig_fff);
256                 my_fclose(tmp_fff);
257         }
258
259         /* Kill the temporary file */
260         fd_kill(tmp_file);
261 }
262
263
264 /*!
265  * @brief prfファイルのフォーマットに従った内容を出力する /
266  * Dump a formatted line, using "vstrnfmt()".
267  * @param fmt 出力内容
268  */
269 static void auto_dump_printf(concptr fmt, ...)
270 {
271         concptr p;
272         va_list vp;
273
274         char buf[1024];
275
276         /* Begin the Varargs Stuff */
277         va_start(vp, fmt);
278
279         /* Format the args, save the length */
280         (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
281
282         /* End the Varargs Stuff */
283         va_end(vp);
284
285         /* Count number of lines */
286         for (p = buf; *p; p++)
287         {
288                 if (*p == '\n') auto_dump_line_num++;
289         }
290
291         /* Dump it */
292         fprintf(auto_dump_stream, "%s", buf);
293 }
294
295
296 /*!
297  * @brief prfファイルをファイルオープンする /
298  * Open file to append auto dump.
299  * @param buf ファイル名
300  * @param mark 出力するヘッダマーク
301  * @return ファイルポインタを取得できたらTRUEを返す
302  */
303 static bool open_auto_dump(concptr buf, concptr mark)
304 {
305         char header_mark_str[80];
306
307         /* Save the mark string */
308         auto_dump_mark = mark;
309
310         /* Prepare a header mark string */
311         sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
312
313         /* Remove old macro dumps */
314         remove_auto_dump(buf);
315
316         /* Append to the file */
317         auto_dump_stream = my_fopen(buf, "a");
318
319         /* Failure */
320         if (!auto_dump_stream)
321         {
322                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
323                 msg_print(NULL);
324
325                 /* Failed */
326                 return FALSE;
327         }
328
329         /* Start dumping */
330         fprintf(auto_dump_stream, "%s\n", header_mark_str);
331
332         /* Initialize counter */
333         auto_dump_line_num = 0;
334
335         auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
336                                            "# *Warning!*  The lines below are an automatic dump.\n"));
337         auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n", 
338                                            "# Don't edit them; changes will be deleted and replaced automatically.\n"));
339         return TRUE;
340 }
341
342 /*!
343  * @brief prfファイルをファイルクローズする /
344  * Append foot part and close auto dump.
345  * @return なし
346  */
347 static void close_auto_dump(void)
348 {
349         char footer_mark_str[80];
350
351         /* Prepare a footer mark string */
352         sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
353
354         auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
355                                            "# *Warning!*  The lines below are an automatic dump.\n"));
356         auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n", 
357                                            "# Don't edit them; changes will be deleted and replaced automatically.\n"));
358         /* End of dump */
359         fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
360
361         /* Close */
362         my_fclose(auto_dump_stream);
363
364         return;
365 }
366
367
368 #ifndef JP
369
370 /*!
371  * @brief Return suffix of ordinal number
372  * @param num number
373  * @return pointer of suffix string.
374  */
375 concptr get_ordinal_number_suffix(int num)
376 {
377         num = ABS(num) % 100;
378         switch (num % 10)
379         {
380         case 1:
381                 return (num == 11) ? "th" : "st";
382         case 2:
383                 return (num == 12) ? "th" : "nd";
384         case 3:
385                 return (num == 13) ? "th" : "rd";
386         default:
387                 return "th";
388         }
389 }
390 #endif
391
392
393 /*!
394  * @brief 日記にメッセージを追加する /
395  * Take note to the diary.
396  * @param type 日記内容のID
397  * @param num 日記内容のIDに応じた数値
398  * @param note 日記内容のIDに応じた文字列参照ポインタ
399  * @return エラーID
400  */
401 errr exe_write_diary(player_type *creature_ptr, int type, int num, concptr note)
402 {
403         int day, hour, min;
404         FILE *fff = NULL;
405         GAME_TEXT file_name[MAX_NLEN];
406         char buf[1024];
407         concptr note_level = "";
408         bool do_level = TRUE;
409         char note_level_buf[40];
410         QUEST_IDX q_idx;
411
412         static bool disable_nikki = FALSE;
413
414         extract_day_hour_min(&day, &hour, &min);
415
416         if (disable_nikki) return(-1);
417
418         if (type == NIKKI_FIX_QUEST_C ||
419             type == NIKKI_FIX_QUEST_F ||
420             type == NIKKI_RAND_QUEST_C ||
421             type == NIKKI_RAND_QUEST_F ||
422             type == NIKKI_TO_QUEST)
423         {
424                 QUEST_IDX old_quest;
425
426                 old_quest = creature_ptr->current_floor_ptr->inside_quest;
427                 creature_ptr->current_floor_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
428
429                 /* Get the quest text */
430                 init_flags = INIT_NAME_ONLY;
431
432                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
433
434                 /* Reset the old quest number */
435                 creature_ptr->current_floor_ptr->inside_quest = old_quest;
436         }
437
438         /* different filne name to avoid mixing */
439         sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
440         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
441
442         /* File type is "TEXT" */
443         FILE_TYPE(FILE_TYPE_TEXT);
444
445         fff = my_fopen(buf, "a");
446
447         /* Failure */
448         if (!fff)
449         {
450                 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
451                 msg_format(NULL);
452                 disable_nikki=TRUE;
453                 return (-1);
454         }
455
456         q_idx = quest_number(creature_ptr->current_floor_ptr->dun_level);
457
458         if (write_level)
459         {
460                 if (creature_ptr->current_floor_ptr->inside_arena)
461                         note_level = _("アリーナ:", "Arane:");
462                 else if (!creature_ptr->current_floor_ptr->dun_level)
463                         note_level = _("地上:", "Surface:");
464                 else if (q_idx && (is_fixed_quest_idx(q_idx)
465                         && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
466                         note_level = _("クエスト:", "Quest:");
467                 else
468                 {
469 #ifdef JP
470                         sprintf(note_level_buf, "%d階(%s):", (int)creature_ptr->current_floor_ptr->dun_level, d_name+d_info[creature_ptr->dungeon_idx].name);
471 #else
472                         sprintf(note_level_buf, "%s L%d:", d_name+d_info[creature_ptr->dungeon_idx].name, (int)creature_ptr->current_floor_ptr->dun_level);
473 #endif
474                         note_level = note_level_buf;
475                 }
476         }
477
478         switch(type)
479         {
480                 case NIKKI_HIGAWARI:
481                 {
482                         if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
483                         else fputs(_("*****日目\n", "Day *****\n"), fff);
484                         do_level = FALSE;
485                         break;
486                 }
487                 case NIKKI_BUNSHOU:
488                 {
489                         if (num)
490                         {
491                                 fprintf(fff, "%s\n",note);
492                                 do_level = FALSE;
493                         }
494                         else
495                                 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
496                         break;
497                 }
498                 case NIKKI_ART:
499                 {
500                         fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
501                         break;
502                 }
503                 case NIKKI_ART_SCROLL:
504                 {
505                         fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
506                         break;
507                 }
508                 case NIKKI_UNIQUE:
509                 {
510                         fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
511                         break;
512                 }
513                 case NIKKI_FIX_QUEST_C:
514                 {
515                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
516                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
517                                                    " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
518                         break;
519                 }
520                 case NIKKI_FIX_QUEST_F:
521                 {
522                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
523                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
524                                                    " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
525                         break;
526                 }
527                 case NIKKI_RAND_QUEST_C:
528                 {
529                         GAME_TEXT name[MAX_NLEN];
530                         strcpy(name, r_name+r_info[quest[num].r_idx].name);
531                         fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
532                                                    " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
533                         break;
534                 }
535                 case NIKKI_RAND_QUEST_F:
536                 {
537                         GAME_TEXT name[MAX_NLEN];
538                         strcpy(name, r_name+r_info[quest[num].r_idx].name);
539                         fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
540                                                    " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
541                         break;
542                 }
543                 case NIKKI_MAXDEAPTH:
544                 {
545                         fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
546                                                    " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
547                                                    _(d_name+d_info[creature_ptr->dungeon_idx].name, num),
548                                                    _(num, d_name+d_info[creature_ptr->dungeon_idx].name));
549                         break;
550                 }
551                 case NIKKI_TRUMP:
552                 {
553                         fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
554                                                    " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
555                                                    _(d_name + d_info[num].name, (int)max_dlv[num]),
556                                                    _((int)max_dlv[num], d_name + d_info[num].name));
557                         break;
558                 }
559                 case NIKKI_STAIR:
560                 {
561                         concptr to;
562                         if (q_idx && (is_fixed_quest_idx(q_idx)
563                              && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
564                         {
565                                 to = _("地上", "the surface");
566                         }
567                         else
568                         {
569                                 if (!(creature_ptr->current_floor_ptr->dun_level+num)) to = _("地上", "the surface");
570                                 else to = format(_("%d階", "level %d"), creature_ptr->current_floor_ptr->dun_level+num);
571                         }
572                         fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
573                         break;
574                 }
575                 case NIKKI_RECALL:
576                 {
577                         if (!num)
578                         fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"), 
579                                                 hour, min, note_level, _(d_name+d_info[creature_ptr->dungeon_idx].name, (int)max_dlv[creature_ptr->dungeon_idx]), 
580                                                                                            _((int)max_dlv[creature_ptr->dungeon_idx], d_name+d_info[creature_ptr->dungeon_idx].name));
581                         else
582                                 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
583                         break;
584                 }
585                 case NIKKI_TO_QUEST:
586                 {
587                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
588                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
589                                                 hour, min, note_level, quest[num].name);
590                         break;
591                 }
592                 case NIKKI_TELE_LEV:
593                 {
594                         fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
595                                                 hour, min, note_level);
596                         break;
597                 }
598                 case NIKKI_BUY:
599                 {
600                         fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
601                         break;
602                 }
603                 case NIKKI_SELL:
604                 {
605                         fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
606                         break;
607                 }
608                 case NIKKI_ARENA:
609                 {
610                         if (num < 0)
611                         {
612                                 int n = -num;
613                                 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
614                                                         hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
615                                 break;
616                         }
617                         fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
618                                                 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
619                         
620                         if (num == MAX_ARENA_MONS)
621                         {
622                                 fprintf(fff, _("                 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
623                                                            "                 won all fight to become a Chanpion.\n"));
624                                 do_level = FALSE;
625                         }
626                         break;
627                 }
628                 case NIKKI_HANMEI:
629                 {
630                         fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
631                         break;
632                 }
633                 case NIKKI_WIZ_TELE:
634                 {
635                         concptr to;
636                         if (!creature_ptr->current_floor_ptr->dun_level)
637                                 to = _("地上", "the surface");
638                         else
639                                 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name+d_info[creature_ptr->dungeon_idx].name);
640
641                         fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
642                                                    " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
643                         break;
644                 }
645                 case NIKKI_PAT_TELE:
646                 {
647                         concptr to;
648                         if (!creature_ptr->current_floor_ptr->dun_level)
649                                 to = _("地上", "the surface");
650                         else
651                                 to = format(_("%d階(%s)", "level %d of %s"), creature_ptr->current_floor_ptr->dun_level, d_name+d_info[creature_ptr->dungeon_idx].name);
652
653                         fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
654                                                    " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
655                         break;
656                 }
657                 case NIKKI_LEVELUP:
658                 {
659                         fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
660                         break;
661                 }
662                 case NIKKI_GAMESTART:
663                 {
664                         time_t ct = time((time_t*)0);
665                         do_level = FALSE;
666                         if (num)
667                         {
668                                 fprintf(fff, "%s %s",note, ctime(&ct));
669                         }
670                         else
671                                 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
672                         break;
673                 }
674                 case NIKKI_NAMED_PET:
675                 {
676                         fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
677                         switch (num)
678                         {
679                                 case RECORD_NAMED_PET_NAME:
680                                         fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
681                                         break;
682                                 case RECORD_NAMED_PET_UNNAME:
683                                         fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
684                                         break;
685                                 case RECORD_NAMED_PET_DISMISS:
686                                         fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
687                                         break;
688                                 case RECORD_NAMED_PET_DEATH:
689                                         fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
690                                         break;
691                                 case RECORD_NAMED_PET_MOVED:
692                                         fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
693                                         break;
694                                 case RECORD_NAMED_PET_LOST_SIGHT:
695                                         fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
696                                         break;
697                                 case RECORD_NAMED_PET_DESTROY:
698                                         fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
699                                         break;
700                                 case RECORD_NAMED_PET_EARTHQUAKE:
701                                         fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
702                                         break;
703                                 case RECORD_NAMED_PET_GENOCIDE:
704                                         fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
705                                         break;
706                                 case RECORD_NAMED_PET_WIZ_ZAP:
707                                         fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
708                                         break;
709                                 case RECORD_NAMED_PET_TELE_LEVEL:
710                                         fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
711                                         break;
712                                 case RECORD_NAMED_PET_BLAST:
713                                         fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
714                                         break;
715                                 case RECORD_NAMED_PET_HEAL_LEPER:
716                                         fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
717                                         break;
718                                 case RECORD_NAMED_PET_COMPACT:
719                                         fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
720                                         break;
721                                 case RECORD_NAMED_PET_LOSE_PARENT:
722                                         fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
723                                         break;
724
725
726                                 default:
727                                         fprintf(fff, "\n");
728                                         break;
729                         }
730                         break;
731                 }
732
733                 case NIKKI_WIZARD_LOG:
734                         fprintf(fff, "%s\n", note);
735                         break;
736
737                 default:
738                         break;
739         }
740
741         my_fclose(fff);
742
743         if (do_level) write_level = FALSE;
744
745         return (0);
746 }
747
748
749 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
750
751 /*!
752  * @brief 日記のタイトル表記と内容出力 /
753  * @return なし
754  * @details
755  * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
756  */
757 static void display_diary(player_type *creature_ptr)
758 {
759         char nikki_title[256];
760         GAME_TEXT file_name[MAX_NLEN];
761         char buf[1024];
762         char tmp[80];
763 #ifdef JP
764         /*! */
765         static const char subtitle[][30] = {"最強の肉体を求めて",
766                                            "人生それははかない",
767                                            "明日に向かって",
768                                            "棚からぼたもち",
769                                            "あとの祭り",
770                                            "それはいい考えだ",
771                                            "何とでも言え",
772                                            "兎にも角にも",
773                                            "ウソだけど",
774                                            "もはやこれまで",
775                                            "なんでこうなるの",
776                                            "それは無理だ",
777                                            "倒すべき敵はゲ○ツ",
778                                            "ん~?聞こえんなぁ",
779                                            "オレの名を言ってみろ",
780                                            "頭が変になっちゃった",
781                                            "互換しません",
782                                            "せっかくだから",
783                                            "まだまだ甘いね",
784                                            "むごいむごすぎる",
785                                            "こんなもんじゃない",
786                                            "だめだこりゃ",
787                                            "次いってみよう",
788                                            "ちょっとだけよ",
789                                            "哀しき冒険者",
790                                            "野望の果て",
791                                            "無限地獄",
792                                            "神に喧嘩を売る者",
793                                            "未知の世界へ",
794                                            "最高の頭脳を求めて"};
795 #else
796         static const char subtitle[][51] ={"Quest of The World's Toughest Body",
797                                            "Attack is the best form of defence.",
798                                            "Might is right.",
799                                            "An unexpected windfall",
800                                            "A drowning man will catch at a straw",
801                                            "Don't count your chickens before they are hatched.",
802                                            "It is no use crying over spilt milk.",
803                                            "Seeing is believing.",
804                                            "Strike the iron while it is hot.",
805                                            "I don't care what follows.",
806                                            "To dig a well to put out a house on fire.",
807                                            "Tomorrow is another day.",
808                                            "Easy come, easy go.",
809                                            "The more haste, the less speed.",
810                                            "Where there is life, there is hope.",
811                                            "There is no royal road to *WINNER*.",
812                                            "Danger past, God forgotten.",
813                                            "The best thing to do now is to run away.",
814                                            "Life is but an empty dream.",
815                                            "Dead men tell no tales.",
816                                            "A book that remains shut is but a block.",
817                                            "Misfortunes never come singly.",
818                                            "A little knowledge is a dangerous thing.",
819                                            "History repeats itself.",
820                                            "*WINNER* was not built in a day.",
821                                            "Ignorance is bliss.",
822                                            "To lose is to win?",
823                                            "No medicine can cure folly.",
824                                            "All good things come to an end.",
825                                            "M$ Empire strikes back.",
826                                            "To see is to believe",
827                                            "Time is money.",
828                                            "Quest of The World's Greatest Brain"};
829 #endif
830         sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
831         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
832
833         if (creature_ptr->pclass == CLASS_WARRIOR || creature_ptr->pclass == CLASS_MONK || creature_ptr->pclass == CLASS_SAMURAI || creature_ptr->pclass == CLASS_BERSERKER)
834                 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
835         else if (IS_WIZARD_CLASS(creature_ptr))
836                 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
837         else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
838
839 #ifdef JP
840         sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", creature_ptr->name, tmp);
841 #else
842         sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, creature_ptr->name, tmp);
843 #endif
844
845         /* Display the file contents */
846         show_file(FALSE, buf, nikki_title, -1, 0);
847 }
848
849 /*!
850  * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
851  * @return なし
852  */
853 static void add_diary_note(player_type *creature_ptr)
854 {
855         char tmp[80] = "\0";
856         char bunshou[80] = "\0";
857
858         if (get_string(_("内容: ", "diary note: "), tmp, 79))
859         {
860                 strcpy(bunshou, tmp);
861                 exe_write_diary(creature_ptr, NIKKI_BUNSHOU, 0, bunshou);
862         }
863 }
864
865 /*!
866  * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
867  * @return なし
868  */
869 static void do_cmd_last_get(player_type *creaute_ptr)
870 {
871         char buf[256];
872         GAME_TURN turn_tmp;
873
874         if (record_o_name[0] == '\0') return;
875
876         sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
877         if (!get_check(buf)) return;
878
879         turn_tmp = current_world_ptr->game_turn;
880         current_world_ptr->game_turn = record_turn;
881         sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
882         exe_write_diary(creaute_ptr, NIKKI_BUNSHOU, 0, buf);
883         current_world_ptr->game_turn = turn_tmp;
884 }
885
886 /*!
887  * @brief ファイル中の全日記記録を消去する /
888  * @return なし
889  */
890 static void do_cmd_erase_nikki(void)
891 {
892         GAME_TEXT file_name[MAX_NLEN];
893         char buf[256];
894         FILE *fff = NULL;
895
896         if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
897                 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
898         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
899         fd_kill(buf);
900
901         fff = my_fopen(buf, "w");
902         if(fff)
903         {
904                 my_fclose(fff);
905                 msg_format(_("記録を消去しました。", "deleted record."));
906         }else
907         {
908                 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
909         }
910
911         msg_print(NULL);
912 }
913
914 /*!
915  * @brief 日記コマンド
916  * @param crerature_ptr プレーヤーへの参照ポインタ
917  * @return なし
918  */
919 void do_cmd_nikki(player_type *creature_ptr)
920 {
921         int i;
922
923         /* File type is "TEXT" */
924         FILE_TYPE(FILE_TYPE_TEXT);
925         screen_save();
926
927         /* Interact until done */
928         while (TRUE)
929         {
930                 Term_clear();
931
932                 /* Ask for a choice */
933                 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
934
935                 /* Give some choices */
936                 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
937                 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
938                 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
939                 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
940
941                 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
942
943                 /* Prompt */
944                 prt(_("コマンド:", "Command: "), 18, 0);
945
946                 /* Prompt */
947                 i = inkey();
948
949                 if (i == ESCAPE) break;
950
951                 switch (i)
952                 {
953                 case '1':
954                         display_diary(creature_ptr);
955                         break;
956                 case '2':
957                         add_diary_note(creature_ptr);
958                         break;
959                 case '3':
960                         do_cmd_last_get(creature_ptr);
961                         break;
962                 case '4':
963                         do_cmd_erase_nikki();
964                         break;
965                 case 'r': case 'R':
966                         screen_load();
967                         prepare_movie_hooks();
968                         return;
969                 default: /* Unknown option */
970                         bell();
971                 }
972
973                 msg_erase();
974         }
975
976         screen_load();
977 }
978
979
980 /*!
981  * @brief 画面を再描画するコマンドのメインルーチン
982  * Hack -- redraw the screen
983  * @return なし
984  * @details
985  * <pre>
986  * This command performs various low level updates, clears all the "extra"
987  * windows, does a total redraw of the main window, and requests all of the
988  * interesting updates and redraws that I can think of.
989  *
990  * This command is also used to "instantiate" the results of the user
991  * selecting various things, such as graphics mode, so it must call
992  * the "TERM_XTRA_REACT" hook before redrawing the windows.
993  * </pre>
994  */
995 void do_cmd_redraw(player_type *creature_ptr)
996 {
997         term *old = Term;
998
999         /* Hack -- react to changes */
1000         Term_xtra(TERM_XTRA_REACT, 0);
1001
1002         /* Combine and Reorder the pack (later) */
1003         creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1004         creature_ptr->update |= (PU_TORCH);
1005         creature_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1006         creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
1007         creature_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1008         creature_ptr->update |= (PU_MONSTERS);
1009
1010         creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1011
1012         creature_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
1013         creature_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
1014
1015         update_playtime();
1016
1017         handle_stuff();
1018
1019         if (creature_ptr->prace == RACE_ANDROID) calc_android_exp(creature_ptr);
1020
1021         /* Redraw every window */
1022         for (int j = 0; j < 8; j++)
1023         {
1024                 /* Dead window */
1025                 if (!angband_term[j]) continue;
1026
1027                 /* Activate */
1028                 Term_activate(angband_term[j]);
1029                 Term_redraw();
1030                 Term_fresh();
1031                 Term_activate(old);
1032         }
1033 }
1034
1035
1036 /*!
1037  * @brief プレイヤーのステータス表示
1038  * @return なし
1039  */
1040 void do_cmd_player_status(player_type *creature_ptr)
1041 {
1042         char c;
1043         int mode = 0;
1044         char tmp[160];
1045         screen_save();
1046
1047         /* Forever */
1048         while (TRUE)
1049         {
1050                 update_playtime();
1051                 display_player(creature_ptr, mode);
1052
1053                 if (mode == 4)
1054                 {
1055                         mode = 0;
1056                         display_player(creature_ptr, mode);
1057                 }
1058
1059                 /* Prompt */
1060                 Term_putstr(2, 23, -1, TERM_WHITE,
1061                             _("['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]", "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"));
1062
1063                 /* Query */
1064                 c = inkey();
1065                 if (c == ESCAPE) break;
1066
1067                 /* Change name */
1068                 if (c == 'c')
1069                 {
1070                         get_name(creature_ptr);
1071
1072                         /* Process the player name */
1073                         process_player_name(FALSE);
1074                 }
1075
1076                 /* File dump */
1077                 else if (c == 'f')
1078                 {
1079                         sprintf(tmp, "%s.txt", creature_ptr->base_name);
1080                         if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1081                         {
1082                                 if (tmp[0] && (tmp[0] != ' '))
1083                                 {
1084                                         file_character(creature_ptr, tmp);
1085                                 }
1086                         }
1087                 }
1088
1089                 else if (c == 'h')
1090                 {
1091                         mode++;
1092                 }
1093                 else
1094                 {
1095                         bell();
1096                 }
1097
1098                 msg_erase();
1099         }
1100
1101         screen_load();
1102         creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1103
1104         handle_stuff();
1105 }
1106
1107
1108 /*!
1109  * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1110  * Recall the most recent message
1111  * @return なし
1112  */
1113 void do_cmd_message_one(void)
1114 {
1115         /* Recall one message */
1116         prt(format("> %s", message_str(0)), 0, 0);
1117 }
1118
1119
1120 /*!
1121  * @brief メッセージのログを表示するコマンドのメインルーチン
1122  * Recall the most recent message
1123  * @return なし
1124  * @details
1125  * <pre>
1126  * Show previous messages to the user   -BEN-
1127  *
1128  * The screen format uses line 0 and 23 for headers and prompts,
1129  * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1130  *
1131  * This command shows you which commands you are viewing, and allows
1132  * you to "search" for strings in the recall.
1133  *
1134  * Note that messages may be longer than 80 characters, but they are
1135  * displayed using "infinite" length, with a special sub-command to
1136  * "slide" the virtual display to the left or right.
1137  *
1138  * Attempt to only hilite the matching portions of the string.
1139  * </pre>
1140  */
1141 void do_cmd_messages(int num_now)
1142 {
1143         char shower_str[81];
1144         char finder_str[81];
1145         char back_str[81];
1146         concptr shower = NULL;
1147         int wid, hgt;
1148         int num_lines;
1149
1150         Term_get_size(&wid, &hgt);
1151
1152         /* Number of message lines in a screen */
1153         num_lines = hgt - 4;
1154
1155         /* Wipe finder */
1156         strcpy(finder_str, "");
1157
1158         /* Wipe shower */
1159         strcpy(shower_str, "");
1160
1161         /* Total messages */
1162         int n = message_num();
1163
1164         /* Start on first message */
1165         int i = 0;
1166         screen_save();
1167         Term_clear();
1168
1169         /* Process requests until done */
1170         while (TRUE)
1171         {
1172                 int j;
1173                 int skey;
1174
1175                 /* Dump up to 20 lines of messages */
1176                 for (j = 0; (j < num_lines) && (i + j < n); j++)
1177                 {
1178                         concptr msg = message_str(i+j);
1179
1180                         /* Dump the messages, bottom to top */
1181                         c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1182
1183                         if (!shower || !shower[0]) continue;
1184
1185                         /* Hilite "shower" */
1186                         concptr str = msg;
1187
1188                         /* Display matches */
1189                         while ((str = my_strstr(str, shower)) != NULL)
1190                         {
1191                                 int len = strlen(shower);
1192
1193                                 /* Display the match */
1194                                 Term_putstr(str - msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1195
1196                                 /* Advance */
1197                                 str += len;
1198                         }
1199                 }
1200
1201                 /* Erase remaining lines */
1202                 for (; j < num_lines; j++) Term_erase(0, num_lines + 1 - j, 255);
1203
1204                 /* Display header */
1205                 /* translation */
1206                 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1207                            i, i + j - 1, n), 0, 0);
1208
1209                 /* Display prompt (not very informative) */
1210                 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1211                           "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1212
1213                 skey = inkey_special(TRUE);
1214
1215                 /* Exit on Escape */
1216                 if (skey == ESCAPE) break;
1217
1218                 /* Hack -- Save the old index */
1219                 j = i;
1220
1221                 switch (skey)
1222                 {
1223                 /* Hack -- handle show */
1224                 case '=':
1225                         /* Prompt */
1226                         prt(_("強調: ", "Show: "), hgt - 1, 0);
1227
1228                         /* Get a "shower" string, or continue */
1229                         strcpy(back_str, shower_str);
1230                         if (askfor(shower_str, 80))
1231                         {
1232                                 /* Show it */
1233                                 shower = shower_str[0] ? shower_str : NULL;
1234                         }
1235                         else strcpy(shower_str, back_str);
1236
1237                         continue;
1238
1239                 /* Hack -- handle find */
1240                 case '/':
1241                 case KTRL('s'):
1242                         {
1243                                 int z;
1244
1245                                 /* Prompt */
1246                                 prt(_("検索: ", "Find: "), hgt - 1, 0);
1247
1248                                 /* Get a "finder" string, or continue */
1249                                 strcpy(back_str, finder_str);
1250                                 if (!askfor(finder_str, 80))
1251                                 {
1252                                         strcpy(finder_str, back_str);
1253                                         continue;
1254                                 }
1255                                 else if (!finder_str[0])
1256                                 {
1257                                         shower = NULL; /* Stop showing */
1258                                         continue;
1259                                 }
1260
1261                                 /* Show it */
1262                                 shower = finder_str;
1263
1264                                 /* Scan messages */
1265                                 for (z = i + 1; z < n; z++)
1266                                 {
1267                                         concptr msg = message_str(z);
1268
1269                                         /* Search for it */
1270                                         if (my_strstr(msg, finder_str))
1271                                         {
1272                                                 /* New location */
1273                                                 i = z;
1274
1275                                                 break;
1276                                         }
1277                                 }
1278                         }
1279                         break;
1280
1281                 /* Recall 1 older message */
1282                 case SKEY_TOP:
1283                         /* Go to the oldest line */
1284                         i = n - num_lines;
1285                         break;
1286
1287                 /* Recall 1 newer message */
1288                 case SKEY_BOTTOM:
1289                         /* Go to the newest line */
1290                         i = 0;
1291                         break;
1292
1293                 /* Recall 1 older message */
1294                 case '8':
1295                 case SKEY_UP:
1296                 case '\n':
1297                 case '\r':
1298                         /* Go older if legal */
1299                         i = MIN(i + 1, n - num_lines);
1300                         break;
1301
1302                 /* Recall 10 older messages */
1303                 case '+':
1304                         /* Go older if legal */
1305                         i = MIN(i + 10, n - num_lines);
1306                         break;
1307
1308                 /* Recall 20 older messages */
1309                 case 'p':
1310                 case KTRL('P'):
1311                 case ' ':
1312                 case SKEY_PGUP:
1313                         /* Go older if legal */
1314                         i = MIN(i + num_lines, n - num_lines);
1315                         break;
1316
1317                 /* Recall 20 newer messages */
1318                 case 'n':
1319                 case KTRL('N'):
1320                 case SKEY_PGDOWN:
1321                         /* Go newer (if able) */
1322                         i = MAX(0, i - num_lines);
1323                         break;
1324
1325                 /* Recall 10 newer messages */
1326                 case '-':
1327                         /* Go newer (if able) */
1328                         i = MAX(0, i - 10);
1329                         break;
1330
1331                 /* Recall 1 newer messages */
1332                 case '2':
1333                 case SKEY_DOWN:
1334                         /* Go newer (if able) */
1335                         i = MAX(0, i - 1);
1336                         break;
1337                 }
1338
1339                 /* Hack -- Error of some kind */
1340                 if (i == j) bell();
1341         }
1342
1343         screen_load();
1344 }
1345
1346
1347 /*!
1348  * @brief prefファイルを選択して処理する /
1349  * Ask for a "user pref line" and process it
1350  * @return なし
1351  * @details
1352  * Allow absolute file names?
1353  */
1354 void do_cmd_pref(void)
1355 {
1356         char buf[80];
1357
1358         /* Default */
1359         strcpy(buf, "");
1360
1361         /* Ask for a "user pref command" */
1362         if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
1363
1364         /* Process that pref command */
1365         (void)process_pref_file_command(buf);
1366 }
1367
1368 /*!
1369  * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
1370  * @return なし
1371  */
1372 void do_cmd_reload_autopick(void)
1373 {
1374         if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
1375         /* Load the file with messages */
1376         autopick_load_pref(TRUE);
1377 }
1378
1379 #ifdef ALLOW_MACROS
1380
1381 /*!
1382  * @brief マクロ情報をprefファイルに保存する /
1383  * @param fname ファイル名
1384  * @return なし
1385  */
1386 static errr macro_dump(concptr fname)
1387 {
1388         static concptr mark = "Macro Dump";
1389         char buf[1024];
1390         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1391
1392         /* File type is "TEXT" */
1393         FILE_TYPE(FILE_TYPE_TEXT);
1394
1395         /* Append to the file */
1396         if (!open_auto_dump(buf, mark)) return (-1);
1397
1398         /* Start dumping */
1399         auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
1400         
1401         /* Dump them */
1402         for (int i = 0; i < macro__num; i++)
1403         {
1404                 /* Extract the action */
1405                 ascii_to_text(buf, macro__act[i]);
1406
1407                 /* Dump the macro */
1408                 auto_dump_printf("A:%s\n", buf);
1409
1410                 /* Extract the action */
1411                 ascii_to_text(buf, macro__pat[i]);
1412
1413                 /* Dump normal macros */
1414                 auto_dump_printf("P:%s\n", buf);
1415
1416                 /* End the macro */
1417                 auto_dump_printf("\n");
1418         }
1419
1420         close_auto_dump();
1421         return (0);
1422 }
1423
1424
1425 /*!
1426  * @brief マクロのトリガーキーを取得する /
1427  * Hack -- ask for a "trigger" (see below)
1428  * @param buf キー表記を保管するバッファ
1429  * @return なし
1430  * @details
1431  * <pre>
1432  * Note the complex use of the "inkey()" function from "util.c".
1433  *
1434  * Note that both "flush()" calls are extremely important.
1435  * </pre>
1436  */
1437 static void do_cmd_macro_aux(char *buf)
1438 {
1439         char i;
1440         int n = 0;
1441         char tmp[1024];
1442
1443         flush();
1444
1445         /* Do not process macros */
1446         inkey_base = TRUE;
1447
1448         /* First key */
1449         i = inkey();
1450
1451         /* Read the pattern */
1452         while (i)
1453         {
1454                 /* Save the key */
1455                 buf[n++] = i;
1456
1457                 /* Do not process macros */
1458                 inkey_base = TRUE;
1459
1460                 /* Do not wait for keys */
1461                 inkey_scan = TRUE;
1462
1463                 /* Attempt to read a key */
1464                 i = inkey();
1465         }
1466
1467         /* Terminate */
1468         buf[n] = '\0';
1469
1470         flush();
1471
1472         /* Convert the trigger */
1473         ascii_to_text(tmp, buf);
1474
1475         /* Hack -- display the trigger */
1476         Term_addstr(-1, TERM_WHITE, tmp);
1477 }
1478
1479 #endif
1480
1481 /*!
1482  * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
1483  * Hack -- ask for a keymap "trigger" (see below)
1484  * @param buf キー表記を取得するバッファ
1485  * @return なし
1486  * @details
1487  * <pre>
1488  * Note that both "flush()" calls are extremely important.  This may
1489  * no longer be true, since "util.c" is much simpler now.  
1490  * </pre>
1491  */
1492 static void do_cmd_macro_aux_keymap(char *buf)
1493 {
1494         char tmp[1024];
1495
1496         flush();
1497
1498         /* Get a key */
1499         buf[0] = inkey();
1500         buf[1] = '\0';
1501
1502         /* Convert to ascii */
1503         ascii_to_text(tmp, buf);
1504
1505         /* Hack -- display the trigger */
1506         Term_addstr(-1, TERM_WHITE, tmp);
1507
1508         flush();
1509 }
1510
1511
1512 /*!
1513  * @brief キーマップをprefファイルにダンプする /
1514  * Hack -- append all keymaps to the given file
1515  * @param fname ファイルネーム
1516  * @return エラーコード
1517  * @details
1518  */
1519 static errr keymap_dump(concptr fname)
1520 {
1521         static concptr mark = "Keymap Dump";
1522         char key[1024];
1523         char buf[1024];
1524
1525         BIT_FLAGS mode;
1526
1527         /* Roguelike */
1528         if (rogue_like_commands)
1529         {
1530                 mode = KEYMAP_MODE_ROGUE;
1531         }
1532
1533         /* Original */
1534         else
1535         {
1536                 mode = KEYMAP_MODE_ORIG;
1537         }
1538
1539         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
1540
1541         /* File type is "TEXT" */
1542         FILE_TYPE(FILE_TYPE_TEXT);
1543
1544         /* Append to the file */
1545         if (!open_auto_dump(buf, mark)) return -1;
1546
1547         /* Start dumping */
1548         auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
1549         
1550         /* Dump them */
1551         for (int i = 0; i < 256; i++)
1552         {
1553                 concptr act;
1554
1555                 /* Loop up the keymap */
1556                 act = keymap_act[mode][i];
1557
1558                 /* Skip empty keymaps */
1559                 if (!act) continue;
1560
1561                 /* Encode the key */
1562                 buf[0] = (char)i;
1563                 buf[1] = '\0';
1564                 ascii_to_text(key, buf);
1565
1566                 /* Encode the action */
1567                 ascii_to_text(buf, act);
1568
1569                 /* Dump the macro */
1570                 auto_dump_printf("A:%s\n", buf);
1571                 auto_dump_printf("C:%d:%s\n", mode, key);
1572         }
1573
1574         close_auto_dump();
1575         return (0);
1576 }
1577
1578
1579 /*!
1580  * @brief マクロを設定するコマンドのメインルーチン /
1581  * Interact with "macros"
1582  * @return なし
1583  * @details
1584  * <pre>
1585  * Note that the macro "action" must be defined before the trigger.
1586  *
1587  * Could use some helpful instructions on this page.  
1588  * </pre>
1589  */
1590 void do_cmd_macros(player_type *creature_ptr)
1591 {
1592         int i;
1593         char tmp[1024];
1594         char buf[1024];
1595         BIT_FLAGS mode;
1596
1597         /* Roguelike */
1598         if (rogue_like_commands)
1599         {
1600                 mode = KEYMAP_MODE_ROGUE;
1601         }
1602
1603         /* Original */
1604         else
1605         {
1606                 mode = KEYMAP_MODE_ORIG;
1607         }
1608
1609         /* File type is "TEXT" */
1610         FILE_TYPE(FILE_TYPE_TEXT);
1611
1612         screen_save();
1613
1614         /* Process requests until done */
1615         while (TRUE)
1616         {
1617                 Term_clear();
1618                 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
1619
1620                 /* Describe that action */
1621                 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
1622
1623                 /* Analyze the current action */
1624                 ascii_to_text(buf, macro__buf);
1625
1626                 /* Display the current action */
1627                 prt(buf, 22, 0);
1628
1629
1630                 /* Selections */
1631                 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
1632 #ifdef ALLOW_MACROS
1633                 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
1634                 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
1635                 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
1636                 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
1637                 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
1638                 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
1639                 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
1640                 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
1641                 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
1642 #endif /* ALLOW_MACROS */
1643
1644                 /* Prompt */
1645                 prt(_("コマンド: ", "Command: "), 16, 0);
1646
1647                 i = inkey();
1648
1649                 /* Leave */
1650                 if (i == ESCAPE) break;
1651
1652                 /* Load a 'macro' file */
1653                 else if (i == '1')
1654                 {
1655                         errr err;
1656
1657                         /* Prompt */
1658                         prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
1659
1660                         /* Prompt */
1661                         prt(_("ファイル: ", "File: "), 18, 0);
1662
1663                         /* Default filename */
1664                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
1665
1666                         /* Ask for a file */
1667                         if (!askfor(tmp, 80)) continue;
1668
1669                         /* Process the given filename */
1670                         err = process_pref_file(tmp);
1671                         if (-2 == err)
1672                         {
1673                                 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
1674                         }
1675                         else if (err)
1676                         {
1677                                 /* Prompt */
1678                                 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
1679                         }
1680                         else
1681                         {
1682                                 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
1683                         }
1684                 }
1685
1686 #ifdef ALLOW_MACROS
1687                 /* Save macros */
1688                 else if (i == '2')
1689                 {
1690                         /* Prompt */
1691                         prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
1692
1693                         /* Prompt */
1694                         prt(_("ファイル: ", "File: "), 18, 0);
1695
1696                         /* Default filename */
1697                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
1698
1699                         /* Ask for a file */
1700                         if (!askfor(tmp, 80)) continue;
1701
1702                         /* Dump the macros */
1703                         (void)macro_dump(tmp);
1704
1705                         /* Prompt */
1706                         msg_print(_("マクロを追加しました。", "Appended macros."));
1707                 }
1708
1709                 /* Query a macro */
1710                 else if (i == '3')
1711                 {
1712                         int k;
1713
1714                         /* Prompt */
1715                         prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
1716
1717
1718                         /* Prompt */
1719                         prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1720
1721                         /* Get a macro trigger */
1722                         do_cmd_macro_aux(buf);
1723
1724                         /* Acquire action */
1725                         k = macro_find_exact(buf);
1726
1727                         /* Nothing found */
1728                         if (k < 0)
1729                         {
1730                                 /* Prompt */
1731                                 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
1732                         }
1733
1734                         /* Found one */
1735                         else
1736                         {
1737                                 /* Obtain the action */
1738                                 strcpy(macro__buf, macro__act[k]);
1739
1740                                 /* Analyze the current action */
1741                                 ascii_to_text(buf, macro__buf);
1742
1743                                 /* Display the current action */
1744                                 prt(buf, 22, 0);
1745
1746                                 /* Prompt */
1747                                 msg_print(_("マクロを確認しました。", "Found a macro."));
1748                         }
1749                 }
1750
1751                 /* Create a macro */
1752                 else if (i == '4')
1753                 {
1754                         /* Prompt */
1755                         prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
1756
1757                         /* Prompt */
1758                         prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1759
1760                         /* Get a macro trigger */
1761                         do_cmd_macro_aux(buf);
1762                         clear_from(20);
1763
1764                         /* Help message */
1765                         c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1766                                                                 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1767
1768                         /* Prompt */
1769                         prt(_("マクロ行動: ", "Action: "), 20, 0);
1770
1771                         /* Convert to text */
1772                         ascii_to_text(tmp, macro__buf);
1773
1774                         /* Get an encoded action */
1775                         if (askfor(tmp, 80))
1776                         {
1777                                 /* Convert to ascii */
1778                                 text_to_ascii(macro__buf, tmp);
1779
1780                                 /* Link the macro */
1781                                 macro_add(buf, macro__buf);
1782
1783                                 /* Prompt */
1784                                 msg_print(_("マクロを追加しました。", "Added a macro."));
1785                         }
1786                 }
1787
1788                 /* Remove a macro */
1789                 else if (i == '5')
1790                 {
1791                         /* Prompt */
1792                         prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
1793
1794                         /* Prompt */
1795                         prt(_("トリガーキー: ", "Trigger: "), 18, 0);
1796
1797                         /* Get a macro trigger */
1798                         do_cmd_macro_aux(buf);
1799
1800                         /* Link the macro */
1801                         macro_add(buf, buf);
1802
1803                         /* Prompt */
1804                         msg_print(_("マクロを削除しました。", "Removed a macro."));
1805                 }
1806
1807                 /* Save keymaps */
1808                 else if (i == '6')
1809                 {
1810                         /* Prompt */
1811                         prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
1812
1813                         /* Prompt */
1814                         prt(_("ファイル: ", "File: "), 18, 0);
1815
1816                         /* Default filename */
1817                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
1818
1819                         /* Ask for a file */
1820                         if (!askfor(tmp, 80)) continue;
1821
1822                         /* Dump the macros */
1823                         (void)keymap_dump(tmp);
1824
1825                         /* Prompt */
1826                         msg_print(_("キー配置を追加しました。", "Appended keymaps."));
1827                 }
1828
1829                 /* Query a keymap */
1830                 else if (i == '7')
1831                 {
1832                         concptr act;
1833
1834                         /* Prompt */
1835                         prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
1836
1837                         /* Prompt */
1838                         prt(_("押すキー: ", "Keypress: "), 18, 0);
1839
1840                         /* Get a keymap trigger */
1841                         do_cmd_macro_aux_keymap(buf);
1842
1843                         /* Look up the keymap */
1844                         act = keymap_act[mode][(byte)(buf[0])];
1845
1846                         /* Nothing found */
1847                         if (!act)
1848                         {
1849                                 /* Prompt */
1850                                 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
1851                         }
1852
1853                         /* Found one */
1854                         else
1855                         {
1856                                 /* Obtain the action */
1857                                 strcpy(macro__buf, act);
1858
1859                                 /* Analyze the current action */
1860                                 ascii_to_text(buf, macro__buf);
1861
1862                                 /* Display the current action */
1863                                 prt(buf, 22, 0);
1864
1865                                 /* Prompt */
1866                                 msg_print(_("キー配置を確認しました。", "Found a keymap."));
1867                         }
1868                 }
1869
1870                 /* Create a keymap */
1871                 else if (i == '8')
1872                 {
1873                         /* Prompt */
1874                         prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
1875
1876                         /* Prompt */
1877                         prt(_("押すキー: ", "Keypress: "), 18, 0);
1878
1879                         /* Get a keymap trigger */
1880                         do_cmd_macro_aux_keymap(buf);
1881                         clear_from(20);
1882
1883                         /* Help message */
1884                         c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1885                                                             "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1886
1887                         /* Prompt */
1888                         prt(_("行動: ", "Action: "), 20, 0);
1889
1890                         /* Convert to text */
1891                         ascii_to_text(tmp, macro__buf);
1892
1893                         /* Get an encoded action */
1894                         if (askfor(tmp, 80))
1895                         {
1896                                 /* Convert to ascii */
1897                                 text_to_ascii(macro__buf, tmp);
1898
1899                                 /* Free old keymap */
1900                                 string_free(keymap_act[mode][(byte)(buf[0])]);
1901
1902                                 /* Make new keymap */
1903                                 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
1904
1905                                 /* Prompt */
1906                                 msg_print(_("キー配置を追加しました。", "Added a keymap."));
1907                         }
1908                 }
1909
1910                 /* Remove a keymap */
1911                 else if (i == '9')
1912                 {
1913                         /* Prompt */
1914                         prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
1915
1916                         /* Prompt */
1917                         prt(_("押すキー: ", "Keypress: "), 18, 0);
1918
1919                         /* Get a keymap trigger */
1920                         do_cmd_macro_aux_keymap(buf);
1921
1922                         /* Free old keymap */
1923                         string_free(keymap_act[mode][(byte)(buf[0])]);
1924
1925                         /* Make new keymap */
1926                         keymap_act[mode][(byte)(buf[0])] = NULL;
1927
1928                         /* Prompt */
1929                         msg_print(_("キー配置を削除しました。", "Removed a keymap."));
1930                 }
1931
1932                 /* Enter a new action */
1933                 else if (i == '0')
1934                 {
1935                         /* Prompt */
1936                         prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
1937                         clear_from(20);
1938
1939                         /* Help message */
1940                         c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
1941                                                                 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
1942
1943                         /* Prompt */
1944                         prt(_("マクロ行動: ", "Action: "), 20, 0);
1945
1946                         /* Hack -- limit the value */
1947                         tmp[80] = '\0';
1948
1949                         /* Get an encoded action */
1950                         if (!askfor(buf, 80)) continue;
1951
1952                         /* Extract an action */
1953                         text_to_ascii(macro__buf, buf);
1954                 }
1955 #endif /* ALLOW_MACROS */
1956
1957                 else
1958                 {
1959                         bell();
1960                 }
1961
1962                 msg_erase();
1963         }
1964
1965         screen_load();
1966 }
1967
1968
1969 /*!
1970  * @brief キャラクタ色の明暗表現
1971  */
1972 static concptr lighting_level_str[F_LIT_MAX] =
1973 {
1974 #ifdef JP
1975         "標準色",
1976         "明色",
1977         "暗色",
1978 #else
1979         "standard",
1980         "brightly lit",
1981         "darkened",
1982 #endif
1983 };
1984
1985
1986 /*!
1987  * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
1988  * @param i 指定対象となるキャラクタコード
1989  * @param num 指定されたビジュアルIDを返す参照ポインタ
1990  * @param max ビジュアルIDの最大数
1991  * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
1992  */
1993 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
1994 {
1995         if (iscntrl(i))
1996         {
1997                 char str[10] = "";
1998                 IDX tmp;
1999
2000                 sprintf(str, "%d", *num);
2001
2002                 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2003                         return FALSE;
2004
2005                 tmp = (IDX)strtol(str, NULL, 0);
2006                 if (tmp >= 0 && tmp < max)
2007                         *num = tmp;
2008         }
2009         else if (isupper(i))
2010                 *num = (*num + max - 1) % max;
2011         else
2012                 *num = (*num + 1) % max;
2013
2014         return TRUE;
2015 }
2016
2017 /*!
2018  * @brief キャラクタの変更メニュー表示
2019  * @param choice_msg 選択メッセージ
2020  * @return なし
2021  */
2022 static void print_visuals_menu(concptr choice_msg)
2023 {
2024         prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2025         
2026         /* Give some choices */
2027         prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2028         
2029 #ifdef ALLOW_VISUALS
2030         prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2031         prt(_("(2) アイテムの   色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2032         prt(_("(3) 地形の       色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2033         prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2034         prt(_("(5) アイテムの   色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2035         prt(_("(6) 地形の       色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2036         prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2037         prt(_("(8) アイテムの   色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2038         prt(_("(9) 地形の       色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2039 #endif /* ALLOW_VISUALS */
2040
2041         prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2042
2043         /* Prompt */
2044         prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2045 }
2046
2047
2048 /*
2049  * Interact with "visuals"
2050  */
2051 void do_cmd_visuals(player_type *creature_ptr)
2052 {
2053         int i;
2054         char tmp[160];
2055         char buf[1024];
2056         bool need_redraw = FALSE;
2057         concptr empty_symbol = "<< ? >>";
2058
2059         if (use_bigtile) empty_symbol = "<< ?? >>";
2060
2061         /* File type is "TEXT" */
2062         FILE_TYPE(FILE_TYPE_TEXT);
2063         screen_save();
2064
2065         /* Interact until done */
2066         while (TRUE)
2067         {
2068                 Term_clear();
2069
2070                 /* Ask for a choice */
2071                 print_visuals_menu(NULL);
2072
2073                 /* Prompt */
2074                 i = inkey();
2075
2076                 if (i == ESCAPE) break;
2077
2078                 switch (i)
2079                 {
2080                 /* Load a 'pref' file */
2081                 case '0':
2082                         /* Prompt */
2083                         prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
2084
2085                         /* Prompt */
2086                         prt(_("ファイル: ", "File: "), 17, 0);
2087
2088                         /* Default filename */
2089                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2090
2091                         /* Query */
2092                         if (!askfor(tmp, 70)) continue;
2093
2094                         /* Process the given filename */
2095                         (void)process_pref_file(tmp);
2096
2097                         need_redraw = TRUE;
2098                         break;
2099
2100 #ifdef ALLOW_VISUALS
2101
2102                 /* Dump monster attr/chars */
2103                 case '1':
2104                 {
2105                         static concptr mark = "Monster attr/chars";
2106
2107                         /* Prompt */
2108                         prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
2109
2110                         /* Prompt */
2111                         prt(_("ファイル: ", "File: "), 17, 0);
2112
2113                         /* Default filename */
2114                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2115
2116                         /* Get a filename */
2117                         if (!askfor(tmp, 70)) continue;
2118                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2119
2120                         /* Append to the file */
2121                         if (!open_auto_dump(buf, mark)) continue;
2122
2123                         /* Start dumping */
2124                         auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
2125
2126                         /* Dump monsters */
2127                         for (i = 0; i < max_r_idx; i++)
2128                         {
2129                                 monster_race *r_ptr = &r_info[i];
2130
2131                                 /* Skip non-entries */
2132                                 if (!r_ptr->name) continue;
2133
2134                                 /* Dump a comment */
2135                                 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
2136
2137                                 /* Dump the monster attr/char info */
2138                                 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
2139                                         (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
2140                         }
2141
2142                         /* Close */
2143                         close_auto_dump();
2144
2145                         msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
2146
2147                         break;
2148                 }
2149
2150                 /* Dump object attr/chars */
2151                 case '2':
2152                 {
2153                         static concptr mark = "Object attr/chars";
2154                         KIND_OBJECT_IDX k_idx;
2155
2156                         /* Prompt */
2157                         prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
2158
2159                         /* Prompt */
2160                         prt(_("ファイル: ", "File: "), 17, 0);
2161
2162                         /* Default filename */
2163                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2164
2165                         /* Get a filename */
2166                         if (!askfor(tmp, 70)) continue;
2167                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2168
2169                         /* Append to the file */
2170                         if (!open_auto_dump(buf, mark)) continue;
2171
2172                         /* Start dumping */
2173                         auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
2174
2175                         /* Dump objects */
2176                         for (k_idx = 0; k_idx < max_k_idx; k_idx++)
2177                         {
2178                                 GAME_TEXT o_name[MAX_NLEN];
2179                                 object_kind *k_ptr = &k_info[k_idx];
2180
2181                                 /* Skip non-entries */
2182                                 if (!k_ptr->name) continue;
2183
2184                                 if (!k_ptr->flavor)
2185                                 {
2186                                         /* Tidy name */
2187                                         strip_name(o_name, k_idx);
2188                                 }
2189                                 else
2190                                 {
2191                                         object_type forge;
2192
2193                                         /* Prepare dummy object */
2194                                         object_prep(&forge, k_idx);
2195
2196                                         /* Get un-shuffled flavor name */
2197                                         object_desc(o_name, &forge, OD_FORCE_FLAVOR);
2198                                 }
2199
2200                                 /* Dump a comment */
2201                                 auto_dump_printf("# %s\n", o_name);
2202
2203                                 /* Dump the object attr/char info */
2204                                 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
2205                                         (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
2206                         }
2207
2208                         /* Close */
2209                         close_auto_dump();
2210
2211                         msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
2212
2213                         break;
2214                 }
2215
2216                 /* Dump feature attr/chars */
2217                 case '3':
2218                 {
2219                         static concptr mark = "Feature attr/chars";
2220
2221                         /* Prompt */
2222                         prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
2223
2224                         /* Prompt */
2225                         prt(_("ファイル: ", "File: "), 17, 0);
2226
2227                         /* Default filename */
2228                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2229
2230                         /* Get a filename */
2231                         if (!askfor(tmp, 70)) continue;
2232                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2233
2234                         /* Append to the file */
2235                         if (!open_auto_dump(buf, mark)) continue;
2236
2237                         /* Start dumping */
2238                         auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
2239
2240                         /* Dump features */
2241                         for (i = 0; i < max_f_idx; i++)
2242                         {
2243                                 feature_type *f_ptr = &f_info[i];
2244
2245                                 /* Skip non-entries */
2246                                 if (!f_ptr->name) continue;
2247
2248                                 /* Skip mimiccing features */
2249                                 if (f_ptr->mimic != i) continue;
2250
2251                                 /* Dump a comment */
2252                                 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
2253
2254                                 /* Dump the feature attr/char info */
2255                                 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
2256                                         (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
2257                                         (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
2258                                         (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
2259                         }
2260
2261                         /* Close */
2262                         close_auto_dump();
2263
2264                         msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
2265
2266                         break;
2267                 }
2268
2269                 /* Modify monster attr/chars (numeric operation) */
2270                 case '4':
2271                 {
2272                         static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
2273                         static MONRACE_IDX r = 0;
2274
2275                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2276
2277                         /* Hack -- query until done */
2278                         while (1)
2279                         {
2280                                 monster_race *r_ptr = &r_info[r];
2281                                 int c;
2282                                 IDX t;
2283
2284                                 TERM_COLOR da = r_ptr->d_attr;
2285                                 byte dc = r_ptr->d_char;
2286                                 TERM_COLOR ca = r_ptr->x_attr;
2287                                 byte cc = r_ptr->x_char;
2288
2289                                 /* Label the object */
2290                                 Term_putstr(5, 17, -1, TERM_WHITE,
2291                                          format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
2292
2293                                 /* Label the Default values */
2294                                 Term_putstr(10, 19, -1, TERM_WHITE,
2295                                         format(_("初期値  色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
2296
2297                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2298                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2299
2300                                 /* Label the Current values */
2301                                 Term_putstr(10, 20, -1, TERM_WHITE,
2302                                         format(_("現在値  色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
2303
2304                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2305                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2306
2307                                 /* Prompt */
2308                                 Term_putstr(0, 22, -1, TERM_WHITE, 
2309                                         _("コマンド (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): "));
2310
2311                                 i = inkey();
2312
2313                                 /* All done */
2314                                 if (i == ESCAPE) break;
2315
2316                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2317                                 else if (isupper(i)) c = 'a' + i - 'A';
2318                                 else c = i;
2319
2320                                 switch (c)
2321                                 {
2322                                 case 'n':
2323                                         {
2324                                                 IDX prev_r = r;
2325                                                 do
2326                                                 {
2327                                                         if (!cmd_visuals_aux(i, &r, max_r_idx))
2328                                                         {
2329                                                                 r = prev_r;
2330                                                                 break;
2331                                                         }
2332                                                 }
2333                                                 while (!r_info[r].name);
2334                                         }
2335                                         break;
2336                                 case 'a':
2337                                         t = (int)r_ptr->x_attr;
2338                                         (void)cmd_visuals_aux(i, &t, 256);
2339                                         r_ptr->x_attr = (byte)t;
2340                                         need_redraw = TRUE;
2341                                         break;
2342                                 case 'c':
2343                                         t = (int)r_ptr->x_char;
2344                                         (void)cmd_visuals_aux(i, &t, 256);
2345                                         r_ptr->x_char = (byte)t;
2346                                         need_redraw = TRUE;
2347                                         break;
2348                                 case 'v':
2349                                         do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
2350                                         Term_clear();
2351                                         print_visuals_menu(choice_msg);
2352                                         break;
2353                                 }
2354                         }
2355
2356                         break;
2357                 }
2358
2359                 /* Modify object attr/chars (numeric operation) */
2360                 case '5':
2361                 {
2362                         static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
2363                         static IDX k = 0;
2364                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2365
2366                         /* Hack -- query until done */
2367                         while (1)
2368                         {
2369                                 object_kind *k_ptr = &k_info[k];
2370                                 int c;
2371                                 IDX t;
2372
2373                                 TERM_COLOR da = k_ptr->d_attr;
2374                                 SYMBOL_CODE dc = k_ptr->d_char;
2375                                 TERM_COLOR ca = k_ptr->x_attr;
2376                                 SYMBOL_CODE cc = k_ptr->x_char;
2377
2378                                 /* Label the object */
2379                                 Term_putstr(5, 17, -1, TERM_WHITE,
2380                                             format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
2381                                                    k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
2382
2383                                 /* Label the Default values */
2384                                 Term_putstr(10, 19, -1, TERM_WHITE,
2385                                             format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2386
2387                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2388                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2389
2390                                 /* Label the Current values */
2391                                 Term_putstr(10, 20, -1, TERM_WHITE,
2392                                             format(_("現在値  色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
2393
2394                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2395                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2396
2397                                 /* Prompt */
2398                                 Term_putstr(0, 22, -1, TERM_WHITE,
2399                                             _("コマンド (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): "));
2400
2401                                 i = inkey();
2402
2403                                 /* All done */
2404                                 if (i == ESCAPE) break;
2405
2406                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2407                                 else if (isupper(i)) c = 'a' + i - 'A';
2408                                 else c = i;
2409
2410                                 switch (c)
2411                                 {
2412                                 case 'n':
2413                                         {
2414                                                 IDX prev_k = k;
2415                                                 do
2416                                                 {
2417                                                         if (!cmd_visuals_aux(i, &k, max_k_idx))
2418                                                         {
2419                                                                 k = prev_k;
2420                                                                 break;
2421                                                         }
2422                                                 }
2423                                                 while (!k_info[k].name);
2424                                         }
2425                                         break;
2426                                 case 'a':
2427                                         t = (int)k_ptr->x_attr;
2428                                         (void)cmd_visuals_aux(i, &t, 256);
2429                                         k_ptr->x_attr = (byte)t;
2430                                         need_redraw = TRUE;
2431                                         break;
2432                                 case 'c':
2433                                         t = (int)k_ptr->x_char;
2434                                         (void)cmd_visuals_aux(i, &t, 256);
2435                                         k_ptr->x_char = (byte)t;
2436                                         need_redraw = TRUE;
2437                                         break;
2438                                 case 'v':
2439                                         do_cmd_knowledge_objects(&need_redraw, TRUE, k);
2440                                         Term_clear();
2441                                         print_visuals_menu(choice_msg);
2442                                         break;
2443                                 }
2444                         }
2445
2446                         break;
2447                 }
2448
2449                 /* Modify feature attr/chars (numeric operation) */
2450                 case '6':
2451                 {
2452                         static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
2453                         static IDX f = 0;
2454                         static IDX lighting_level = F_LIT_STANDARD;
2455                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
2456
2457                         /* Hack -- query until done */
2458                         while (1)
2459                         {
2460                                 feature_type *f_ptr = &f_info[f];
2461                                 int c;
2462                                 IDX t;
2463
2464                                 TERM_COLOR da = f_ptr->d_attr[lighting_level];
2465                                 byte dc = f_ptr->d_char[lighting_level];
2466                                 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
2467                                 byte cc = f_ptr->x_char[lighting_level];
2468
2469                                 /* Label the object */
2470                                 prt("", 17, 5);
2471                                 Term_putstr(5, 17, -1, TERM_WHITE,
2472                                             format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
2473                                                    f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
2474
2475                                 /* Label the Default values */
2476                                 Term_putstr(10, 19, -1, TERM_WHITE,
2477                                             format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
2478
2479                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
2480                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
2481
2482                                 /* Label the Current values */
2483 #ifdef JP
2484                                 Term_putstr(10, 20, -1, TERM_WHITE,
2485                                             format("現在値  色 / 文字 = %3d / %3d", ca, cc));
2486 #else
2487                                 Term_putstr(10, 20, -1, TERM_WHITE,
2488                                             format("Current attr/char = %3d / %3d", ca, cc));
2489 #endif
2490
2491                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
2492                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
2493
2494                                 /* Prompt */
2495 #ifdef JP
2496                                 Term_putstr(0, 22, -1, TERM_WHITE,
2497                                             "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2498 #else
2499                                 Term_putstr(0, 22, -1, TERM_WHITE,
2500                                             "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
2501 #endif
2502
2503                                 i = inkey();
2504
2505                                 /* All done */
2506                                 if (i == ESCAPE) break;
2507
2508                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
2509                                 else if (isupper(i)) c = 'a' + i - 'A';
2510                                 else c = i;
2511
2512                                 switch (c)
2513                                 {
2514                                 case 'n':
2515                                         {
2516                                                 IDX prev_f = f;
2517                                                 do
2518                                                 {
2519                                                         if (!cmd_visuals_aux(i, &f, max_f_idx))
2520                                                         {
2521                                                                 f = prev_f;
2522                                                                 break;
2523                                                         }
2524                                                 }
2525                                                 while (!f_info[f].name || (f_info[f].mimic != f));
2526                                         }
2527                                         break;
2528                                 case 'a':
2529                                         t = (int)f_ptr->x_attr[lighting_level];
2530                                         (void)cmd_visuals_aux(i, &t, 256);
2531                                         f_ptr->x_attr[lighting_level] = (byte)t;
2532                                         need_redraw = TRUE;
2533                                         break;
2534                                 case 'c':
2535                                         t = (int)f_ptr->x_char[lighting_level];
2536                                         (void)cmd_visuals_aux(i, &t, 256);
2537                                         f_ptr->x_char[lighting_level] = (byte)t;
2538                                         need_redraw = TRUE;
2539                                         break;
2540                                 case 'l':
2541                                         (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
2542                                         break;
2543                                 case 'd':
2544                                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
2545                                         need_redraw = TRUE;
2546                                         break;
2547                                 case 'v':
2548                                         do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
2549                                         Term_clear();
2550                                         print_visuals_menu(choice_msg);
2551                                         break;
2552                                 }
2553                         }
2554
2555                         break;
2556                 }
2557
2558                 /* Modify monster attr/chars (visual mode) */
2559                 case '7':
2560                         do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
2561                         break;
2562
2563                 /* Modify object attr/chars (visual mode) */
2564                 case '8':
2565                         do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
2566                         break;
2567
2568                 /* Modify feature attr/chars (visual mode) */
2569                 case '9':
2570                 {
2571                         IDX lighting_level = F_LIT_STANDARD;
2572                         do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
2573                         break;
2574                 }
2575
2576 #endif /* ALLOW_VISUALS */
2577
2578                 /* Reset visuals */
2579                 case 'R':
2580                 case 'r':
2581                         /* Reset */
2582                         reset_visuals();
2583
2584                         msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
2585                         need_redraw = TRUE;
2586                         break;
2587
2588                 /* Unknown option */
2589                 default:
2590                         bell();
2591                         break;
2592                 }
2593
2594                 msg_erase();
2595         }
2596
2597         screen_load();
2598
2599         if (need_redraw) do_cmd_redraw(creature_ptr);
2600 }
2601
2602
2603 /*
2604  * Interact with "colors"
2605  */
2606 void do_cmd_colors(player_type *creature_ptr)
2607 {
2608         int i;
2609         char tmp[160];
2610         char buf[1024];
2611
2612         /* File type is "TEXT" */
2613         FILE_TYPE(FILE_TYPE_TEXT);
2614
2615         screen_save();
2616
2617         /* Interact until done */
2618         while (TRUE)
2619         {
2620                 Term_clear();
2621
2622                 /* Ask for a choice */
2623                 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
2624
2625                 /* Give some choices */
2626                 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2627
2628 #ifdef ALLOW_COLORS
2629                 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
2630                 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
2631 #endif
2632
2633                 /* Prompt */
2634                 prt(_("コマンド: ", "Command: "), 8, 0);
2635                 /* Prompt */
2636                 i = inkey();
2637
2638                 if (i == ESCAPE) break;
2639
2640                 /* Load a 'pref' file */
2641                 if (i == '1')
2642                 {
2643                         /* Prompt */
2644                         prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
2645
2646                         /* Prompt */
2647                         prt(_("ファイル: ", "File: "), 10, 0);
2648
2649                         /* Default file */
2650                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2651
2652                         /* Query */
2653                         if (!askfor(tmp, 70)) continue;
2654
2655                         /* Process the given filename */
2656                         (void)process_pref_file(tmp);
2657
2658                         /* Mega-Hack -- react to changes */
2659                         Term_xtra(TERM_XTRA_REACT, 0);
2660
2661                         /* Mega-Hack -- redraw */
2662                         Term_redraw();
2663                 }
2664
2665 #ifdef ALLOW_COLORS
2666
2667                 /* Dump colors */
2668                 else if (i == '2')
2669                 {
2670                         static concptr mark = "Colors";
2671
2672                         /* Prompt */
2673                         prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
2674
2675                         /* Prompt */
2676                         prt(_("ファイル: ", "File: "), 10, 0);
2677
2678                         /* Default filename */
2679                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
2680
2681                         /* Get a filename */
2682                         if (!askfor(tmp, 70)) continue;
2683                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
2684
2685                         /* Append to the file */
2686                         if (!open_auto_dump(buf, mark)) continue;
2687
2688                         /* Start dumping */
2689                         auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
2690                         
2691                         /* Dump colors */
2692                         for (i = 0; i < 256; i++)
2693                         {
2694                                 int kv = angband_color_table[i][0];
2695                                 int rv = angband_color_table[i][1];
2696                                 int gv = angband_color_table[i][2];
2697                                 int bv = angband_color_table[i][3];
2698
2699                                 concptr name = _("未知", "unknown");
2700
2701                                 /* Skip non-entries */
2702                                 if (!kv && !rv && !gv && !bv) continue;
2703
2704                                 /* Extract the color name */
2705                                 if (i < 16) name = color_names[i];
2706
2707                                 /* Dump a comment */
2708                                 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
2709                                 
2710                                 /* Dump the monster attr/char info */
2711                                 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
2712                                         i, kv, rv, gv, bv);
2713                         }
2714
2715                         /* Close */
2716                         close_auto_dump();
2717
2718                         msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
2719                 }
2720
2721                 /* Edit colors */
2722                 else if (i == '3')
2723                 {
2724                         static byte a = 0;
2725
2726                         /* Prompt */
2727                         prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
2728
2729                         /* Hack -- query until done */
2730                         while (1)
2731                         {
2732                                 concptr name;
2733                                 byte j;
2734                                 clear_from(10);
2735
2736                                 /* Exhibit the normal colors */
2737                                 for (j = 0; j < 16; j++)
2738                                 {
2739                                         /* Exhibit this color */
2740                                         Term_putstr(j*4, 20, -1, a, "###");
2741
2742                                         /* Exhibit all colors */
2743                                         Term_putstr(j*4, 22, -1, j, format("%3d", j));
2744                                 }
2745
2746                                 /* Describe the color */
2747                                 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
2748
2749                                 /* Describe the color */
2750                                 Term_putstr(5, 10, -1, TERM_WHITE,
2751                                             format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
2752
2753                                 /* Label the Current values */
2754                                 Term_putstr(5, 12, -1, TERM_WHITE,
2755                                             format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
2756                                                    angband_color_table[a][0],
2757                                                    angband_color_table[a][1],
2758                                                    angband_color_table[a][2],
2759                                                    angband_color_table[a][3]));
2760
2761                                 /* Prompt */
2762                                 Term_putstr(0, 14, -1, TERM_WHITE,
2763                                         _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
2764
2765                                 i = inkey();
2766
2767                                 /* All done */
2768                                 if (i == ESCAPE) break;
2769
2770                                 /* Analyze */
2771                                 if (i == 'n') a = (byte)(a + 1);
2772                                 if (i == 'N') a = (byte)(a - 1);
2773                                 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
2774                                 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
2775                                 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
2776                                 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
2777                                 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
2778                                 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
2779                                 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
2780                                 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
2781
2782                                 /* Hack -- react to changes */
2783                                 Term_xtra(TERM_XTRA_REACT, 0);
2784
2785                                 /* Hack -- redraw */
2786                                 Term_redraw();
2787                         }
2788                 }
2789
2790 #endif
2791
2792                 /* Unknown option */
2793                 else
2794                 {
2795                         bell();
2796                 }
2797
2798                 msg_erase();
2799         }
2800
2801         screen_load();
2802 }
2803
2804
2805 /*
2806  * Note something in the message recall
2807  */
2808 void do_cmd_note(void)
2809 {
2810         char buf[80];
2811
2812         /* Default */
2813         strcpy(buf, "");
2814
2815         /* Input */
2816         if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
2817
2818         /* Ignore empty notes */
2819         if (!buf[0] || (buf[0] == ' ')) return;
2820
2821         /* Add the note to the message recall */
2822         msg_format(_("メモ: %s", "Note: %s"), buf);
2823 }
2824
2825
2826 /*
2827  * Mention the current version
2828  */
2829 void do_cmd_version(void)
2830 {
2831 #if FAKE_VER_EXTRA > 0
2832         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
2833                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
2834 #else
2835         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
2836                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
2837 #endif
2838 }
2839
2840
2841 /*
2842  * Array of feeling strings
2843  */
2844 static concptr do_cmd_feeling_text[11] =
2845 {
2846         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2847         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2848         _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
2849         _("この階はとても危険なようだ。", "This level looks very dangerous."),
2850         _("とても悪い予感がする...", "You have a very bad feeling..."),
2851         _("悪い予感がする...", "You have a bad feeling..."),
2852         _("何か緊張する。", "You feel nervous."),
2853         _("少し不運な気がする...", "You feel your luck is turning..."),
2854         _("この場所は好きになれない。", "You don't like the look of this place."),
2855         _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2856         _("なんて退屈なところだ...", "What a boring place...")
2857 };
2858
2859 static concptr do_cmd_feeling_text_combat[11] =
2860 {
2861         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2862         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2863         _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
2864         _("この階はとても危険なようだ。", "This level looks very dangerous."),
2865         _("とても悪い予感がする...", "You have a very bad feeling..."),
2866         _("悪い予感がする...", "You have a bad feeling..."),
2867         _("何か緊張する。", "You feel nervous."),
2868         _("少し不運な気がする...", "You feel your luck is turning..."),
2869         _("この場所は好きになれない。", "You don't like the look of this place."),
2870         _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
2871         _("なんて退屈なところだ...", "What a boring place...")
2872 };
2873
2874 static concptr do_cmd_feeling_text_lucky[11] =
2875 {
2876         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
2877         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
2878         _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
2879         _("素晴らしい感じがする...", "You have an excellent feeling..."),
2880         _("とても良い感じがする...", "You have a very good feeling..."),
2881         _("良い感じがする...", "You have a good feeling..."),
2882         _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
2883         _("多少は運が向いてきたか...", "You feel your luck is turning..."),
2884         _("見た感じ悪くはない...", "You like the look of this place..."),
2885         _("全然駄目ということはないが...", "This level can't be all bad..."),
2886         _("なんて退屈なところだ...", "What a boring place...")
2887 };
2888
2889
2890 /*
2891  * Note that "feeling" is set to zero unless some time has passed.
2892  * Note that this is done when the level is GENERATED, not entered.
2893  */
2894 void do_cmd_feeling(player_type *creature_ptr)
2895 {
2896         if (creature_ptr->wild_mode) return;
2897
2898         /* No useful feeling in quests */
2899         if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr->current_floor_ptr->dun_level))
2900         {
2901                 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
2902                 return;
2903         }
2904
2905         /* No useful feeling in town */
2906         if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
2907         {
2908                 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
2909                 {
2910                         msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
2911                         return;
2912                 }
2913                 
2914                 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
2915                 return;
2916         }
2917
2918         /* No useful feeling in the wilderness */
2919         if (!creature_ptr->current_floor_ptr->dun_level)
2920         {
2921                 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
2922                 return;
2923         }
2924
2925         /* Display the feeling */
2926         if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
2927                 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
2928         else if (creature_ptr->pseikaku == SEIKAKU_COMBAT ||
2929                  creature_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON)
2930                 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
2931         else
2932                 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
2933 }
2934
2935
2936 /*
2937  * Description of each monster group.
2938  */
2939 static concptr monster_group_text[] = 
2940 {
2941 #ifdef JP
2942         "ユニーク", /* "Uniques" */
2943         "乗馬可能なモンスター",       /* "Riding" */
2944         "賞金首", /* "Wanted */
2945         "アンバーの王族", /* "Ambertite" */
2946         "アリ",
2947         "コウモリ",
2948         "ムカデ",
2949         "ドラゴン",
2950         "目玉",
2951         "ネコ",
2952         "ゴーレム",
2953         "標準人間型生物",
2954         "ベトベト",
2955         "ゼリー",
2956         "コボルド",
2957         "水棲生物",
2958         "モルド",
2959         "ナーガ",
2960         "オーク",
2961         "人間",
2962         "四足獣",
2963         "ネズミ",
2964         "スケルトン",
2965         "デーモン",
2966         "ボルテックス",
2967         "イモムシ/大群",
2968         /* "unused", */
2969         "イーク",
2970         "ゾンビ/ミイラ",
2971         "天使",
2972         "鳥",
2973         "犬",
2974         /* "古代ドラゴン/ワイアーム", */
2975         "エレメンタル",
2976         "トンボ",
2977         "ゴースト",
2978         "雑種",
2979         "昆虫",
2980         "ヘビ",
2981         "キラー・ビートル",
2982         "リッチ",
2983         "多首の爬虫類",
2984         "謎の生物",
2985         "オーガ",
2986         "巨大人間型生物",
2987         "クイルスルグ",
2988         "爬虫類/両生類",
2989         "蜘蛛/サソリ/ダニ",
2990         "トロル",
2991         /* "上級デーモン", */
2992         "バンパイア",
2993         "ワイト/レイス/等",
2994         "ゾーン/ザレン/等",
2995         "イエティ",
2996         "ハウンド",
2997         "ミミック",
2998         "壁/植物/気体",
2999         "おばけキノコ",
3000         "球体",
3001         "プレイヤー",
3002 #else
3003         "Uniques",
3004         "Ridable monsters",
3005         "Wanted monsters",
3006         "Ambertite",
3007         "Ant",
3008         "Bat",
3009         "Centipede",
3010         "Dragon",
3011         "Floating Eye",
3012         "Feline",
3013         "Golem",
3014         "Hobbit/Elf/Dwarf",
3015         "Icky Thing",
3016         "Jelly",
3017         "Kobold",
3018         "Aquatic monster",
3019         "Mold",
3020         "Naga",
3021         "Orc",
3022         "Person/Human",
3023         "Quadruped",
3024         "Rodent",
3025         "Skeleton",
3026         "Demon",
3027         "Vortex",
3028         "Worm/Worm-Mass",
3029         /* "unused", */
3030         "Yeek",
3031         "Zombie/Mummy",
3032         "Angel",
3033         "Bird",
3034         "Canine",
3035         /* "Ancient Dragon/Wyrm", */
3036         "Elemental",
3037         "Dragon Fly",
3038         "Ghost",
3039         "Hybrid",
3040         "Insect",
3041         "Snake",
3042         "Killer Beetle",
3043         "Lich",
3044         "Multi-Headed Reptile",
3045         "Mystery Living",
3046         "Ogre",
3047         "Giant Humanoid",
3048         "Quylthulg",
3049         "Reptile/Amphibian",
3050         "Spider/Scorpion/Tick",
3051         "Troll",
3052         /* "Major Demon", */
3053         "Vampire",
3054         "Wight/Wraith/etc",
3055         "Xorn/Xaren/etc",
3056         "Yeti",
3057         "Zephyr Hound",
3058         "Mimic",
3059         "Wall/Plant/Gas",
3060         "Mushroom patch",
3061         "Ball",
3062         "Player",
3063 #endif
3064         NULL
3065 };
3066
3067
3068 /*
3069  * Symbols of monsters in each group. Note the "Uniques" group
3070  * is handled differently.
3071  */
3072 static concptr monster_group_char[] =
3073 {
3074         (char *) -1L,
3075         (char *) -2L,
3076         (char *) -3L,
3077         (char *) -4L,
3078         "a",
3079         "b",
3080         "c",
3081         "dD",
3082         "e",
3083         "f",
3084         "g",
3085         "h",
3086         "i",
3087         "j",
3088         "k",
3089         "l",
3090         "m",
3091         "n",
3092         "o",
3093         "pt",
3094         "q",
3095         "r",
3096         "s",
3097         "uU",
3098         "v",
3099         "w",
3100         /* "x", */
3101         "y",
3102         "z",
3103         "A",
3104         "B",
3105         "C",
3106         /* "D", */
3107         "E",
3108         "F",
3109         "G",
3110         "H",
3111         "I",
3112         "J",
3113         "K",
3114         "L",
3115         "M",
3116         "N",
3117         "O",
3118         "P",
3119         "Q",
3120         "R",
3121         "S",
3122         "T",
3123         /* "U", */
3124         "V",
3125         "W",
3126         "X",
3127         "Y",
3128         "Z",
3129         "!$&()+./=>?[\\]`{|~",
3130         "#%",
3131         ",",
3132         "*",
3133         "@",
3134         NULL
3135 };
3136
3137
3138 /*
3139  * todo 引数と戻り値について追記求む
3140  * Build a list of monster indexes in the given group.
3141  *
3142  * mode & 0x01 : check for non-empty group
3143  * mode & 0x02 : visual operation only
3144
3145  * @param creature_ptr プレーヤーへの参照ポインタ
3146  * @param grp_cur ???
3147  * @param mon_idx[] ???
3148  * @param mode ???
3149  * @return The number of monsters in the group
3150  */
3151 static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
3152 {
3153         IDX mon_cnt = 0;
3154         int dummy_why;
3155
3156         /* Get a list of x_char in this group */
3157         concptr group_char = monster_group_char[grp_cur];
3158
3159         /* XXX Hack -- Check if this is the "Uniques" group */
3160         bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
3161
3162         /* XXX Hack -- Check if this is the "Riding" group */
3163         bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
3164
3165         /* XXX Hack -- Check if this is the "Wanted" group */
3166         bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
3167
3168         /* XXX Hack -- Check if this is the "Amberite" group */
3169         bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
3170
3171
3172         /* Check every race */
3173         for (IDX i = 0; i < max_r_idx; i++)
3174         {
3175                 /* Access the race */
3176                 monster_race *r_ptr = &r_info[i];
3177
3178                 /* Skip empty race */
3179                 if (!r_ptr->name) continue ;
3180
3181                 /* Require known monsters */
3182                 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
3183
3184                 if (grp_unique)
3185                 {
3186                         if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
3187                 }
3188
3189                 else if (grp_riding)
3190                 {
3191                         if (!(r_ptr->flags7 & RF7_RIDING)) continue;
3192                 }
3193
3194                 else if (grp_wanted)
3195                 {
3196                         bool wanted = FALSE;
3197                         int j;
3198                         for (j = 0; j < MAX_KUBI; j++)
3199                         {
3200                                 if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
3201                                         (creature_ptr->today_mon && creature_ptr->today_mon == i))
3202                                 {
3203                                         wanted = TRUE;
3204                                         break;
3205                                 }
3206                         }
3207                         if (!wanted) continue;
3208                 }
3209
3210                 else if (grp_amberite)
3211                 {
3212                         if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
3213                 }
3214
3215                 else
3216                 {
3217                         /* Check for race in the group */
3218                         if (!my_strchr(group_char, r_ptr->d_char)) continue;
3219                 }
3220
3221                 /* Add the race */
3222                 mon_idx[mon_cnt++] = i;
3223
3224                 /* XXX Hack -- Just checking for non-empty group */
3225                 if (mode & 0x01) break;
3226         }
3227
3228         /* Terminate the list */
3229         mon_idx[mon_cnt] = -1;
3230
3231         ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
3232
3233         /* Return the number of races */
3234         return mon_cnt;
3235 }
3236
3237
3238 /*
3239  * Description of each monster group.
3240  */
3241 static concptr object_group_text[] = 
3242 {
3243 #ifdef JP
3244         "キノコ",    /* "Mushrooms" */
3245         "薬",          /* "Potions" */
3246         "油つぼ",    /* "Flasks" */
3247         "巻物",               /* "Scrolls" */
3248         "指輪",               /* "Rings" */
3249         "アミュレット",   /* "Amulets" */
3250         "笛",          /* "Whistle" */
3251         "光源",               /* "Lanterns" */
3252         "魔法棒",    /* "Wands" */
3253         "杖",          /* "Staffs" */
3254         "ロッド",    /* "Rods" */
3255         "カード",    /* "Cards" */
3256         "キャプチャー・ボール",
3257         "羊皮紙",    
3258         "くさび",
3259         "箱",
3260         "人形",
3261         "像",
3262         "ゴミ",
3263         "空のビン",
3264         "骨",
3265         "死体",
3266         "刀剣類",    /* "Swords" */
3267         "鈍器",               /* "Blunt Weapons" */
3268         "長柄武器", /* "Polearms" */
3269         "採掘道具", /* "Diggers" */
3270         "飛び道具", /* "Bows" */
3271         "弾",
3272         "矢",
3273         "ボルト",
3274         "軽装鎧",    /* "Soft Armor" */
3275         "重装鎧",    /* "Hard Armor" */
3276         "ドラゴン鎧",      /* "Dragon Armor" */
3277         "盾",  /* "Shields" */
3278         "クローク", /* "Cloaks" */
3279         "籠手",       /* "Gloves" */
3280         "ヘルメット",      /* "Helms" */
3281         "冠",  /* "Crowns" */
3282         "ブーツ",    /* "Boots" */
3283         "魔法書",
3284         "財宝",
3285         "何か",
3286 #else
3287         "Mushrooms",
3288         "Potions",
3289         "Flasks",
3290         "Scrolls",
3291         "Rings",
3292         "Amulets",
3293         "Whistle",
3294         "Lanterns",
3295         "Wands",
3296         "Staves",
3297         "Rods",
3298         "Cards",
3299         "Capture Balls",
3300         "Parchments",
3301         "Spikes",
3302         "Boxs",
3303         "Figurines",
3304         "Statues",
3305         "Junks",
3306         "Bottles",
3307         "Skeletons",
3308         "Corpses",
3309         "Swords",
3310         "Blunt Weapons",
3311         "Polearms",
3312         "Diggers",
3313         "Bows",
3314         "Shots",
3315         "Arrows",
3316         "Bolts",
3317         "Soft Armor",
3318         "Hard Armor",
3319         "Dragon Armor",
3320         "Shields",
3321         "Cloaks",
3322         "Gloves",
3323         "Helms",
3324         "Crowns",
3325         "Boots",
3326         "Spellbooks",
3327         "Treasure",
3328         "Something",
3329 #endif
3330         NULL
3331 };
3332
3333
3334 /*
3335  * TVALs of items in each group
3336  */
3337 static byte object_group_tval[] = 
3338 {
3339         TV_FOOD,
3340         TV_POTION,
3341         TV_FLASK,
3342         TV_SCROLL,
3343         TV_RING,
3344         TV_AMULET,
3345         TV_WHISTLE,
3346         TV_LITE,
3347         TV_WAND,
3348         TV_STAFF,
3349         TV_ROD,
3350         TV_CARD,
3351         TV_CAPTURE,
3352         TV_PARCHMENT,
3353         TV_SPIKE,
3354         TV_CHEST,
3355         TV_FIGURINE,
3356         TV_STATUE,
3357         TV_JUNK,
3358         TV_BOTTLE,
3359         TV_SKELETON,
3360         TV_CORPSE,
3361         TV_SWORD,
3362         TV_HAFTED,
3363         TV_POLEARM,
3364         TV_DIGGING,
3365         TV_BOW,
3366         TV_SHOT,
3367         TV_ARROW,
3368         TV_BOLT,
3369         TV_SOFT_ARMOR,
3370         TV_HARD_ARMOR,
3371         TV_DRAG_ARMOR,
3372         TV_SHIELD,
3373         TV_CLOAK,
3374         TV_GLOVES,
3375         TV_HELM,
3376         TV_CROWN,
3377         TV_BOOTS,
3378         TV_LIFE_BOOK, /* Hack -- all spellbooks */
3379         TV_GOLD,
3380         0,
3381         0,
3382 };
3383
3384
3385 /*
3386  * Build a list of object indexes in the given group. Return the number
3387  * of objects in the group.
3388  *
3389  * mode & 0x01 : check for non-empty group
3390  * mode & 0x02 : visual operation only
3391  */
3392 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
3393 {
3394         KIND_OBJECT_IDX i, object_cnt = 0;
3395         int j, k;
3396
3397         /* Get a list of x_char in this group */
3398         byte group_tval = object_group_tval[grp_cur];
3399
3400         /* Check every object */
3401         for (i = 0; i < max_k_idx; i++)
3402         {
3403                 /* Access the object */
3404                 object_kind *k_ptr = &k_info[i];
3405
3406                 /* Skip empty objects */
3407                 if (!k_ptr->name) continue;
3408
3409                 if (!(mode & 0x02))
3410                 {
3411                         if (!current_world_ptr->wizard)
3412                         {
3413                                 /* Skip non-flavoured objects */
3414                                 if (!k_ptr->flavor) continue;
3415
3416                                 /* Require objects ever seen */
3417                                 if (!k_ptr->aware) continue;
3418                         }
3419
3420                         /* Skip items with no distribution (special artifacts) */
3421                         for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
3422                         if (!k) continue;
3423                 }
3424
3425                 /* Check for objects in the group */
3426                 if (TV_LIFE_BOOK == group_tval)
3427                 {
3428                         /* Hack -- All spell books */
3429                         if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
3430                         {
3431                                 /* Add the object */
3432                                 object_idx[object_cnt++] = i;
3433                         }
3434                         else continue;
3435                 }
3436                 else if (k_ptr->tval == group_tval)
3437                 {
3438                         /* Add the object */
3439                         object_idx[object_cnt++] = i;
3440                 }
3441                 else continue;
3442
3443                 /* XXX Hack -- Just checking for non-empty group */
3444                 if (mode & 0x01) break;
3445         }
3446
3447         /* Terminate the list */
3448         object_idx[object_cnt] = -1;
3449
3450         /* Return the number of objects */
3451         return object_cnt;
3452 }
3453
3454
3455 /*
3456  * Description of each feature group.
3457  */
3458 static concptr feature_group_text[] = 
3459 {
3460         "terrains",
3461         NULL
3462 };
3463
3464
3465 /*
3466  * Build a list of feature indexes in the given group. Return the number
3467  * of features in the group.
3468  *
3469  * mode & 0x01 : check for non-empty group
3470  */
3471 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
3472 {
3473         FEAT_IDX i;
3474         FEAT_IDX feat_cnt = 0;
3475
3476         /* Unused;  There is a single group. */
3477         (void)grp_cur;
3478
3479         /* Check every feature */
3480         for (i = 0; i < max_f_idx; i++)
3481         {
3482                 feature_type *f_ptr = &f_info[i];
3483
3484                 /* Skip empty index */
3485                 if (!f_ptr->name) continue;
3486
3487                 /* Skip mimiccing features */
3488                 if (f_ptr->mimic != i) continue;
3489
3490                 /* Add the index */
3491                 feat_idx[feat_cnt++] = i;
3492
3493                 /* XXX Hack -- Just checking for non-empty group */
3494                 if (mode & 0x01) break;
3495         }
3496
3497         /* Terminate the list */
3498         feat_idx[feat_cnt] = -1;
3499
3500         /* Return the number of races */
3501         return feat_cnt;
3502 }
3503
3504
3505 #if 0
3506 /*
3507  * Build a list of monster indexes in the given group. Return the number
3508  * of monsters in the group.
3509  */
3510 static int collect_artifacts(int grp_cur, int object_idx[])
3511 {
3512         int i, object_cnt = 0;
3513
3514         /* Get a list of x_char in this group */
3515         byte group_tval = object_group_tval[grp_cur];
3516
3517         /* Check every object */
3518         for (i = 0; i < max_a_idx; i++)
3519         {
3520                 /* Access the artifact */
3521                 artifact_type *a_ptr = &a_info[i];
3522
3523                 /* Skip empty artifacts */
3524                 if (!a_ptr->name) continue;
3525
3526                 /* Skip "uncreated" artifacts */
3527                 if (!a_ptr->cur_num) continue;
3528
3529                 /* Check for race in the group */
3530                 if (a_ptr->tval == group_tval)
3531                 {
3532                         /* Add the race */
3533                         object_idx[object_cnt++] = i;
3534                 }
3535         }
3536
3537         /* Terminate the list */
3538         object_idx[object_cnt] = 0;
3539
3540         /* Return the number of races */
3541         return object_cnt;
3542 }
3543 #endif /* 0 */
3544
3545
3546 /*
3547  * Encode the screen colors
3548  */
3549 static char hack[17] = "dwsorgbuDWvyRGBU";
3550
3551
3552 /*
3553  * Hack -- load a screen dump from a file
3554  */
3555 void do_cmd_load_screen(void)
3556 {
3557         TERM_LEN y, x;
3558         TERM_COLOR a = 0;
3559         SYMBOL_CODE c = ' ';
3560         bool okay = TRUE;
3561         FILE *fff;
3562         char buf[1024];
3563         TERM_LEN wid, hgt;
3564
3565         Term_get_size(&wid, &hgt);
3566         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
3567
3568         /* Append to the file */
3569         fff = my_fopen(buf, "r");
3570
3571         if (!fff)
3572         {
3573                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
3574                 msg_print(NULL);
3575                 return;
3576         }
3577
3578         screen_save();
3579         Term_clear();
3580
3581         /* Load the screen */
3582         for (y = 0; okay; y++)
3583         {
3584                 /* Get a line of data including control code */
3585                 if (!fgets(buf, 1024, fff)) okay = FALSE;
3586
3587                 /* Get the blank line */
3588                 if (buf[0] == '\n' || buf[0] == '\0') break;
3589
3590                 /* Ignore too large screen image */
3591                 if (y >= hgt) continue;
3592
3593                 /* Show each row */
3594                 for (x = 0; x < wid - 1; x++)
3595                 {
3596                         /* End of line */
3597                         if (buf[x] == '\n' || buf[x] == '\0') break;
3598
3599                         /* Put the attr/char */
3600                         Term_draw(x, y, TERM_WHITE, buf[x]);
3601                 }
3602         }
3603
3604         /* Dump the screen */
3605         for (y = 0; okay; y++)
3606         {
3607                 /* Get a line of data including control code */
3608                 if (!fgets(buf, 1024, fff)) okay = FALSE;
3609
3610                 /* Get the blank line */
3611                 if (buf[0] == '\n' || buf[0] == '\0') break;
3612
3613                 /* Ignore too large screen image */
3614                 if (y >= hgt) continue;
3615
3616                 /* Dump each row */
3617                 for (x = 0; x < wid - 1; x++)
3618                 {
3619                         /* End of line */
3620                         if (buf[x] == '\n' || buf[x] == '\0') break;
3621
3622                         /* Get the attr/char */
3623                         (void)(Term_what(x, y, &a, &c));
3624
3625                         /* Look up the attr */
3626                         for (int i = 0; i < 16; i++)
3627                         {
3628                                 /* Use attr matches */
3629                                 if (hack[i] == buf[x]) a = (byte_hack)i;
3630                         }
3631
3632                         /* Put the attr/char */
3633                         Term_draw(x, y, a, c);
3634                 }
3635         }
3636
3637         my_fclose(fff);
3638
3639         prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
3640
3641         flush();
3642         inkey();
3643
3644         screen_load();
3645 }
3646
3647 // todo なぜこんな中途半端なところに? defineも…
3648 concptr inven_res_label = _("                               酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
3649                                                  "                               AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
3650
3651 #define IM_FLAG_STR  _("*", "* ")
3652 #define HAS_FLAG_STR _("+", "+ ")
3653 #define NO_FLAG_STR  _("・", ". ")
3654
3655 #define print_im_or_res_flag(IM, RES) \
3656 { \
3657         fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
3658               (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
3659 }
3660
3661 #define print_flag(TR) \
3662 { \
3663         fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
3664 }
3665
3666
3667 /* XTRA HACK RESLIST */
3668 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
3669 {
3670         GAME_TEXT o_name[MAX_NLEN];
3671         BIT_FLAGS flgs[TR_FLAG_SIZE];
3672
3673         if (!o_ptr->k_idx) return;
3674         if (o_ptr->tval != tval) return;
3675
3676         /* Identified items only */
3677         if (!object_is_known(o_ptr)) return;
3678
3679         /*
3680          * HACK:Ring of Lordly protection and Dragon equipment
3681          * have random resistances.
3682          */
3683         bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
3684                 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
3685                 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
3686                 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
3687                 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
3688                 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
3689                 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
3690                 || object_is_artifact(o_ptr);
3691         if (!is_special_item_type)
3692         {
3693                 return;
3694         }
3695
3696         int i = 0;
3697         object_desc(o_name, o_ptr, OD_NAME_ONLY);
3698
3699         while (o_name[i] && (i < 26))
3700         {
3701 #ifdef JP
3702                 if (iskanji(o_name[i])) i++;
3703 #endif
3704                 i++;
3705         }
3706
3707         if (i < 28)
3708         {
3709                 while (i < 28)
3710                 {
3711                         o_name[i] = ' '; i++;
3712                 }
3713         }
3714
3715         o_name[i] = '\0';
3716
3717         fprintf(fff, "%s %s", where, o_name);
3718
3719         if (!(o_ptr->ident & (IDENT_MENTAL)))
3720         {
3721                 fputs(_("-------不明--------------- -------不明---------\n",
3722                         "-------unknown------------ -------unknown------\n"), fff);
3723         }
3724         else
3725         {
3726                 object_flags_known(o_ptr, flgs);
3727
3728                 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
3729                 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
3730                 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
3731                 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
3732                 print_flag(TR_RES_POIS);
3733                 print_flag(TR_RES_LITE);
3734                 print_flag(TR_RES_DARK);
3735                 print_flag(TR_RES_SHARDS);
3736                 print_flag(TR_RES_SOUND);
3737                 print_flag(TR_RES_NETHER);
3738                 print_flag(TR_RES_NEXUS);
3739                 print_flag(TR_RES_CHAOS);
3740                 print_flag(TR_RES_DISEN);
3741
3742                 fputs(" ", fff);
3743
3744                 print_flag(TR_RES_BLIND);
3745                 print_flag(TR_RES_FEAR);
3746                 print_flag(TR_RES_CONF);
3747                 print_flag(TR_FREE_ACT);
3748                 print_flag(TR_SEE_INVIS);
3749                 print_flag(TR_HOLD_EXP);
3750                 print_flag(TR_TELEPATHY);
3751                 print_flag(TR_SLOW_DIGEST);
3752                 print_flag(TR_REGEN);
3753                 print_flag(TR_LEVITATION);
3754
3755                 fputc('\n', fff);
3756         }
3757
3758         (*j)++;
3759         if (*j == 9)
3760         {
3761                 *j = 0;
3762                 fprintf(fff, "%s\n", inven_res_label);
3763         }
3764 }
3765
3766 /*
3767  * Display *ID* ed weapons/armors's resistances
3768  */
3769 static void do_cmd_knowledge_inven(player_type *creature_ptr)
3770 {
3771         FILE *fff;
3772         GAME_TEXT file_name[1024];
3773         store_type  *st_ptr;
3774         OBJECT_TYPE_VALUE tval;
3775         int i = 0;
3776         int j = 0;
3777
3778         char where[32];
3779
3780         /* Open a new file */
3781         fff = my_fopen_temp(file_name, 1024);
3782         if (!fff)
3783         {
3784             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
3785             msg_print(NULL);
3786             return;
3787         }
3788
3789         fprintf(fff, "%s\n", inven_res_label);
3790
3791         for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
3792         {
3793                 if (j != 0)
3794                 {
3795                         for (; j < 9; j++) fputc('\n', fff);
3796                         j = 0;
3797                         fprintf(fff, "%s\n", inven_res_label);
3798                 }
3799
3800                 strcpy(where, _("装", "E "));
3801                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3802                 {
3803                         do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3804                 }
3805
3806                 strcpy(where, _("持", "I "));
3807                 for (i = 0; i < INVEN_PACK; i++)
3808                 {
3809                         do_cmd_knowledge_inven_aux(fff, &creature_ptr->inventory_list[i], &j, tval, where);
3810                 }
3811
3812                 st_ptr = &town_info[1].store[STORE_HOME];
3813                 strcpy(where, _("家", "H "));
3814                 for (i = 0; i < st_ptr->stock_num; i++)
3815                 {
3816                         do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
3817                 }
3818         }
3819
3820         my_fclose(fff);
3821
3822         /* Display the file contents */
3823         show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
3824         fd_kill(file_name);
3825 }
3826
3827
3828 void do_cmd_save_screen_html_aux(char *filename, int message)
3829 {
3830         TERM_LEN y, x;
3831         int i;
3832
3833         TERM_COLOR a = 0, old_a = 0;
3834         char c = ' ';
3835
3836         FILE *fff, *tmpfff;
3837         char buf[2048];
3838
3839         int yomikomu = 0;
3840         concptr tags[4] = {
3841                 "HEADER_START:",
3842                 "HEADER_END:",
3843                 "FOOTER_START:",
3844                 "FOOTER_END:",
3845         };
3846         concptr html_head[] = {
3847                 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
3848                 "<pre>",
3849                 0,
3850         };
3851         concptr html_foot[] = {
3852                 "</pre>\n",
3853                 "</body>\n</html>\n",
3854                 0,
3855         };
3856
3857         TERM_LEN wid, hgt;
3858
3859         Term_get_size(&wid, &hgt);
3860
3861         /* File type is "TEXT" */
3862         FILE_TYPE(FILE_TYPE_TEXT);
3863
3864         /* Append to the file */
3865         fff = my_fopen(filename, "w");
3866
3867         if (!fff)
3868         {
3869                 if (message)
3870                 {
3871                     msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
3872                     msg_print(NULL);
3873                 }
3874                 
3875                 return;
3876         }
3877
3878         if (message) screen_save();
3879         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
3880         tmpfff = my_fopen(buf, "r");
3881         if (!tmpfff)
3882         {
3883                 for (i = 0; html_head[i]; i++)
3884                         fputs(html_head[i], fff);
3885         }
3886         else
3887         {
3888                 yomikomu = 0;
3889                 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3890                 {
3891                         if (!yomikomu)
3892                         {
3893                                 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
3894                                         yomikomu = 1;
3895                         }
3896                         else
3897                         {
3898                                 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
3899                                         break;
3900                                 fprintf(fff, "%s\n", buf);
3901                         }
3902                 }
3903         }
3904
3905         /* Dump the screen */
3906         for (y = 0; y < hgt; y++)
3907         {
3908                 /* Start the row */
3909                 if (y != 0) fprintf(fff, "\n");
3910
3911                 /* Dump each row */
3912                 for (x = 0; x < wid - 1; x++)
3913                 {
3914                         concptr cc = NULL;
3915                         /* Get the attr/char */
3916                         (void)(Term_what(x, y, &a, &c));
3917
3918                         switch (c)
3919                         {
3920                         case '&': cc = "&amp;"; break;
3921                         case '<': cc = "&lt;"; break;
3922                         case '>': cc = "&gt;"; break;
3923 #ifdef WINDOWS
3924                         case 0x1f: c = '.'; break;
3925                         case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
3926 #endif
3927                         }
3928
3929                         a = a & 0x0F;
3930                         if ((y == 0 && x == 0) || a != old_a)
3931                         {
3932                                 int rv = angband_color_table[a][1];
3933                                 int gv = angband_color_table[a][2];
3934                                 int bv = angband_color_table[a][3];
3935                                 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">", 
3936                                         ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
3937                                 old_a = a;
3938                         }
3939
3940                         if (cc)
3941                                 fprintf(fff, "%s", cc);
3942                         else
3943                                 fprintf(fff, "%c", c);
3944                 }
3945         }
3946
3947         fprintf(fff, "</font>");
3948
3949         if (!tmpfff)
3950         {
3951                 for (i = 0; html_foot[i]; i++)
3952                         fputs(html_foot[i], fff);
3953         }
3954         else
3955         {
3956                 rewind(tmpfff);
3957                 yomikomu = 0;
3958                 while (!my_fgets(tmpfff, buf, sizeof(buf)))
3959                 {
3960                         if (!yomikomu)
3961                         {
3962                                 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
3963                                         yomikomu = 1;
3964                         }
3965                         else
3966                         {
3967                                 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
3968                                         break;
3969                                 fprintf(fff, "%s\n", buf);
3970                         }
3971                 }
3972
3973                 my_fclose(tmpfff);
3974         }
3975
3976         /* Skip a line */
3977         fprintf(fff, "\n");
3978         my_fclose(fff);
3979
3980         if (message)
3981         {
3982                 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
3983                 msg_print(NULL);
3984         }
3985
3986         if (message)
3987                 screen_load();
3988 }
3989
3990 /*
3991  * Hack -- save a screen dump to a file
3992  */
3993 static void do_cmd_save_screen_html(void)
3994 {
3995         char buf[1024], tmp[256] = "screen.html";
3996
3997         if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
3998                 return;
3999         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4000
4001         msg_print(NULL);
4002
4003         do_cmd_save_screen_html_aux(buf, 1);
4004 }
4005
4006
4007 /*
4008  * Redefinable "save_screen" action
4009  */
4010 void (*screendump_aux)(void) = NULL;
4011
4012
4013 /*
4014  * Save a screen dump to a file
4015  * @param creature_ptr プレーヤーへの参照ポインタ
4016  * @return なし
4017  */
4018 void do_cmd_save_screen(player_type *creature_ptr)
4019 {
4020         bool old_use_graphics = use_graphics;
4021         bool html_dump = FALSE;
4022
4023         prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
4024         while(TRUE)
4025         {
4026                 char c = inkey();
4027                 if (c == 'Y' || c == 'y')
4028                         break;
4029                 else if (c == 'H' || c == 'h')
4030                 {
4031                         html_dump = TRUE;
4032                         break;
4033                 }
4034                 else
4035                 {
4036                         prt("", 0, 0);
4037                         return;
4038                 }
4039         }
4040
4041         int wid, hgt;
4042         Term_get_size(&wid, &hgt);
4043
4044         if (old_use_graphics)
4045         {
4046                 use_graphics = FALSE;
4047                 reset_visuals();
4048                 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4049                 handle_stuff();
4050         }
4051
4052         if (html_dump)
4053         {
4054                 do_cmd_save_screen_html();
4055                 do_cmd_redraw(creature_ptr);
4056         }
4057
4058         /* Do we use a special screendump function ? */
4059         else if (screendump_aux)
4060         {
4061                 /* Dump the screen to a graphics file */
4062                 (*screendump_aux)();
4063         }
4064         else /* Dump the screen as text */
4065         {
4066                 TERM_LEN y, x;
4067                 TERM_COLOR a = 0;
4068                 SYMBOL_CODE c = ' ';
4069                 FILE *fff;
4070                 char buf[1024];
4071                 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4072
4073                 /* File type is "TEXT" */
4074                 FILE_TYPE(FILE_TYPE_TEXT);
4075
4076                 /* Append to the file */
4077                 fff = my_fopen(buf, "w");
4078
4079                 if (!fff)
4080                 {
4081                         msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
4082                         msg_print(NULL);
4083                         return;
4084                 }
4085
4086                 screen_save();
4087
4088                 /* Dump the screen */
4089                 for (y = 0; y < hgt; y++)
4090                 {
4091                         /* Dump each row */
4092                         for (x = 0; x < wid - 1; x++)
4093                         {
4094                                 /* Get the attr/char */
4095                                 (void)(Term_what(x, y, &a, &c));
4096
4097                                 /* Dump it */
4098                                 buf[x] = c;
4099                         }
4100
4101                         /* Terminate */
4102                         buf[x] = '\0';
4103
4104                         /* End the row */
4105                         fprintf(fff, "%s\n", buf);
4106                 }
4107
4108                 /* Skip a line */
4109                 fprintf(fff, "\n");
4110
4111
4112                 /* Dump the screen */
4113                 for (y = 0; y < hgt; y++)
4114                 {
4115                         /* Dump each row */
4116                         for (x = 0; x < wid - 1; x++)
4117                         {
4118                                 /* Get the attr/char */
4119                                 (void)(Term_what(x, y, &a, &c));
4120
4121                                 /* Dump it */
4122                                 buf[x] = hack[a&0x0F];
4123                         }
4124
4125                         /* Terminate */
4126                         buf[x] = '\0';
4127
4128                         /* End the row */
4129                         fprintf(fff, "%s\n", buf);
4130                 }
4131
4132                 /* Skip a line */
4133                 fprintf(fff, "\n");
4134                 my_fclose(fff);
4135
4136                 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4137                 msg_print(NULL);
4138                 screen_load();
4139         }
4140
4141         if (old_use_graphics)
4142         {
4143                 use_graphics = TRUE;
4144                 reset_visuals();
4145                 creature_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
4146                 handle_stuff();
4147         }
4148 }
4149
4150 /*
4151  * Check the status of "artifacts"
4152  */
4153 static void do_cmd_knowledge_artifacts(player_type *player_ptr)
4154 {
4155         ARTIFACT_IDX i;
4156         ARTIFACT_IDX k;
4157         POSITION x, y;
4158         int n = 0;
4159         ARTIFACT_IDX z;
4160         u16b why = 3;
4161         ARTIFACT_IDX *who;
4162         FILE *fff;
4163         GAME_TEXT file_name[1024];
4164         GAME_TEXT base_name[MAX_NLEN];
4165
4166         bool *okay;
4167
4168         /* Open a new file */
4169         fff = my_fopen_temp(file_name, 1024);
4170
4171         if (!fff)
4172         {
4173             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4174             msg_print(NULL);
4175             return;
4176         }
4177
4178         /* Allocate the "who" array */
4179         C_MAKE(who, max_a_idx, ARTIFACT_IDX);
4180
4181         /* Allocate the "okay" array */
4182         C_MAKE(okay, max_a_idx, bool);
4183
4184         /* Scan the artifacts */
4185         for (k = 0; k < max_a_idx; k++)
4186         {
4187                 artifact_type *a_ptr = &a_info[k];
4188
4189                 /* Default */
4190                 okay[k] = FALSE;
4191
4192                 /* Skip "empty" artifacts */
4193                 if (!a_ptr->name) continue;
4194
4195                 /* Skip "uncreated" artifacts */
4196                 if (!a_ptr->cur_num) continue;
4197
4198                 /* Assume okay */
4199                 okay[k] = TRUE;
4200         }
4201
4202         /* Check the dungeon */
4203         for (y = 0; y < player_ptr->current_floor_ptr->height; y++)
4204         {
4205                 for (x = 0; x < player_ptr->current_floor_ptr->width; x++)
4206                 {
4207                         grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
4208
4209                         OBJECT_IDX this_o_idx, next_o_idx = 0;
4210
4211                         /* Scan all objects in the grid */
4212                         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
4213                         {
4214                                 object_type *o_ptr;
4215                                 o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
4216                                 next_o_idx = o_ptr->next_o_idx;
4217
4218                                 /* Ignore non-artifacts */
4219                                 if (!object_is_fixed_artifact(o_ptr)) continue;
4220
4221                                 /* Ignore known items */
4222                                 if (object_is_known(o_ptr)) continue;
4223
4224                                 /* Note the artifact */
4225                                 okay[o_ptr->name1] = FALSE;
4226                         }
4227                 }
4228         }
4229
4230         /* Check the player_ptr->inventory_list and equipment */
4231         for (i = 0; i < INVEN_TOTAL; i++)
4232         {
4233                 object_type *o_ptr = &player_ptr->inventory_list[i];
4234
4235                 /* Ignore non-objects */
4236                 if (!o_ptr->k_idx) continue;
4237
4238                 /* Ignore non-artifacts */
4239                 if (!object_is_fixed_artifact(o_ptr)) continue;
4240
4241                 /* Ignore known items */
4242                 if (object_is_known(o_ptr)) continue;
4243
4244                 /* Note the artifact */
4245                 okay[o_ptr->name1] = FALSE;
4246         }
4247
4248         for (k = 0; k < max_a_idx; k++)
4249         {
4250                 if (okay[k]) who[n++] = k;
4251         }
4252
4253         ang_sort(who, &why, n, ang_sort_art_comp, ang_sort_art_swap);
4254
4255         /* Scan the artifacts */
4256         for (k = 0; k < n; k++)
4257         {
4258                 artifact_type *a_ptr = &a_info[who[k]];
4259                 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
4260
4261                 /* Obtain the base object type */
4262                 z = lookup_kind(a_ptr->tval, a_ptr->sval);
4263
4264                 /* Real object */
4265                 if (z)
4266                 {
4267                         object_type forge;
4268                         object_type *q_ptr;
4269                         q_ptr = &forge;
4270
4271                         /* Create fake object */
4272                         object_prep(q_ptr, z);
4273
4274                         /* Make it an artifact */
4275                         q_ptr->name1 = (byte)who[k];
4276
4277                         /* Display as if known */
4278                         q_ptr->ident |= IDENT_STORE;
4279
4280                         /* Describe the artifact */
4281                         object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4282                 }
4283
4284                 /* Hack -- Build the artifact name */
4285                 fprintf(fff, _("     %s\n", "     The %s\n"), base_name);
4286         }
4287
4288         /* Free the "who" array */
4289         C_KILL(who, max_a_idx, ARTIFACT_IDX);
4290
4291         /* Free the "okay" array */
4292         C_KILL(okay, max_a_idx, bool);
4293         my_fclose(fff);
4294
4295         /* Display the file contents */
4296         show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
4297         fd_kill(file_name);
4298 }
4299
4300
4301 /*
4302  * Display known uniques
4303  * With "XTRA HACK UNIQHIST" (Originally from XAngband)
4304  */
4305 static void do_cmd_knowledge_uniques(void)
4306 {
4307         u16b why = 2;
4308         IDX *who;
4309
4310         FILE *fff;
4311
4312         GAME_TEXT file_name[1024];
4313
4314         int n_alive[10];
4315         int n_alive_surface = 0;
4316         int n_alive_over100 = 0;
4317         int n_alive_total = 0;
4318         int max_lev = -1;
4319
4320         for (IDX i = 0; i < 10; i++) n_alive[i] = 0;
4321
4322         /* Open a new file */
4323         fff = my_fopen_temp(file_name, 1024);
4324
4325         if (!fff)
4326         {
4327                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4328                 msg_print(NULL);
4329                 return;
4330         }
4331
4332         /* Allocate the "who" array */
4333         C_MAKE(who, max_r_idx, MONRACE_IDX);
4334
4335         /* Scan the monsters */
4336         int n = 0;
4337         for (IDX i = 1; i < max_r_idx; i++)
4338         {
4339                 monster_race *r_ptr = &r_info[i];
4340                 int          lev;
4341
4342                 if (!r_ptr->name) continue;
4343
4344                 /* Require unique monsters */
4345                 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4346
4347                 /* Only display "known" uniques */
4348                 if (!cheat_know && !r_ptr->r_sights) continue;
4349
4350                 /* Only print rarity <= 100 uniques */
4351                 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
4352
4353                 /* Only "alive" uniques */
4354                 if (r_ptr->max_num == 0) continue;
4355
4356                 if (r_ptr->level)
4357                 {
4358                         lev = (r_ptr->level - 1) / 10;
4359                         if (lev < 10)
4360                         {
4361                                 n_alive[lev]++;
4362                                 if (max_lev < lev) max_lev = lev;
4363                         }
4364                         else n_alive_over100++;
4365                 }
4366                 else n_alive_surface++;
4367
4368                 /* Collect "appropriate" monsters */
4369                 who[n++] = i;
4370         }
4371
4372         /* Sort the array by dungeon depth of monsters */
4373         ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4374
4375         if (n_alive_surface)
4376         {
4377                 fprintf(fff, _("     地上  生存: %3d体\n", "      Surface  alive: %3d\n"), n_alive_surface);
4378                 n_alive_total += n_alive_surface;
4379         }
4380
4381         for (IDX i = 0; i <= max_lev; i++)
4382         {
4383                 fprintf(fff, _("%3d-%3d階  生存: %3d体\n", "Level %3d-%3d  alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
4384                 n_alive_total += n_alive[i];
4385         }
4386
4387         if (n_alive_over100)
4388         {
4389                 fprintf(fff, _("101-   階  生存: %3d体\n", "Level 101-     alive: %3d\n"), n_alive_over100);
4390                 n_alive_total += n_alive_over100;
4391         }
4392
4393         if (n_alive_total)
4394         {
4395                 fputs(_("---------  -----------\n", "-------------  ----------\n"), fff);
4396                 fprintf(fff, _("     合計  生存: %3d体\n\n", "        Total  alive: %3d\n\n"), n_alive_total);
4397         }
4398         else
4399         {
4400                 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
4401         }
4402
4403         /* Scan the monster races */
4404         for (int k = 0; k < n; k++)
4405         {
4406                 monster_race *r_ptr = &r_info[who[k]];
4407                 fprintf(fff, _("     %s (レベル%d)\n", "     %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
4408         }
4409
4410         /* Free the "who" array */
4411         C_KILL(who, max_r_idx, s16b);
4412         my_fclose(fff);
4413
4414         /* Display the file contents */
4415         show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
4416         fd_kill(file_name);
4417 }
4418
4419
4420 /*
4421  * Display weapon-exp
4422  */
4423 static void do_cmd_knowledge_weapon_exp(player_type *creature_ptr)
4424 {
4425         SUB_EXP weapon_exp;
4426
4427         GAME_TEXT file_name[1024];
4428         char tmp[30];
4429
4430         /* Open a new file */
4431         FILE *fff;
4432         fff = my_fopen_temp(file_name, 1024);
4433         if (!fff)
4434         {
4435             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4436             msg_print(NULL);
4437             return;
4438         }
4439
4440         for (int i = 0; i < 5; i++)
4441         {
4442                 for (int num = 0; num < 64; num++)
4443                 {
4444                         for (KIND_OBJECT_IDX j = 0; j < max_k_idx; j++)
4445                         {
4446                                 object_kind *k_ptr = &k_info[j];
4447
4448                                 if ((k_ptr->tval != TV_SWORD - i) || (k_ptr->sval != num)) continue;
4449                                 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
4450
4451                                 weapon_exp = creature_ptr->weapon_exp[4 - i][num];
4452                                 strip_name(tmp, j);
4453                                 fprintf(fff, "%-25s ", tmp);
4454                                 if (weapon_exp >= s_info[creature_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
4455                                 else fprintf(fff, " ");
4456                                 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
4457                                 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
4458                                 fprintf(fff, "\n");
4459                                 break;
4460                         }
4461                 }
4462         }
4463
4464         my_fclose(fff);
4465
4466         /* Display the file contents */
4467         show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
4468         fd_kill(file_name);
4469 }
4470
4471
4472 /*!
4473  * @brief 魔法の経験値を表示するコマンドのメインルーチン
4474  * Display spell-exp
4475  * @return なし
4476  */
4477 static void do_cmd_knowledge_spell_exp(player_type *creature_ptr)
4478 {
4479         SUB_EXP spell_exp;
4480         int exp_level;
4481
4482         FILE *fff;
4483         const magic_type *s_ptr;
4484
4485         GAME_TEXT file_name[1024];
4486
4487         /* Open a new file */
4488         fff = my_fopen_temp(file_name, 1024);
4489         if (!fff)
4490         {
4491             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4492             msg_print(NULL);
4493             return;
4494         }
4495
4496         if (creature_ptr->realm1 != REALM_NONE)
4497         {
4498                 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[creature_ptr->realm1]);
4499                 for (SPELL_IDX i = 0; i < 32; i++)
4500                 {
4501                         if (!is_magic(creature_ptr->realm1))
4502                         {
4503                                 s_ptr = &technic_info[creature_ptr->realm1 - MIN_TECHNIC][i];
4504                         }
4505                         else
4506                         {
4507                                 s_ptr = &mp_ptr->info[creature_ptr->realm1 - 1][i];
4508                         }
4509
4510                         if (s_ptr->slevel >= 99) continue;
4511                         spell_exp = creature_ptr->spell_exp[i];
4512                         exp_level = spell_exp_level(spell_exp);
4513                         fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm1, i, SPELL_NAME));
4514                         if (creature_ptr->realm1 == REALM_HISSATSU)
4515                                 fprintf(fff, "[--]");
4516                         else
4517                         {
4518                                 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
4519                                 else fprintf(fff, " ");
4520                                 fprintf(fff, "%s", exp_level_str[exp_level]);
4521                         }
4522
4523                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4524                         fprintf(fff, "\n");
4525                 }
4526         }
4527
4528         if (creature_ptr->realm2 != REALM_NONE)
4529         {
4530                 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[creature_ptr->realm2]);
4531                 for (SPELL_IDX i = 0; i < 32; i++)
4532                 {
4533                         if (!is_magic(creature_ptr->realm1))
4534                         {
4535                                 s_ptr = &technic_info[creature_ptr->realm2 - MIN_TECHNIC][i];
4536                         }
4537                         else
4538                         {
4539                                 s_ptr = &mp_ptr->info[creature_ptr->realm2 - 1][i];
4540                         }
4541
4542                         if (s_ptr->slevel >= 99) continue;
4543
4544                         spell_exp = creature_ptr->spell_exp[i + 32];
4545                         exp_level = spell_exp_level(spell_exp);
4546                         fprintf(fff, "%-25s ", exe_spell(creature_ptr, creature_ptr->realm2, i, SPELL_NAME));
4547                         if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
4548                         else fprintf(fff, " ");
4549                         fprintf(fff, "%s", exp_level_str[exp_level]);
4550                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
4551                         fprintf(fff, "\n");
4552                 }
4553         }
4554
4555         my_fclose(fff);
4556
4557         /* Display the file contents */
4558         show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
4559         fd_kill(file_name);
4560 }
4561
4562
4563 /*!
4564  * @brief スキル情報を表示するコマンドのメインルーチン /
4565  * Display skill-exp
4566  * @return なし
4567  */
4568 static void do_cmd_knowledge_skill_exp(player_type *creature_ptr)
4569 {
4570         char file_name[1024];
4571         char skill_name[GINOU_TEMPMAX][20] =
4572         {
4573                 _("マーシャルアーツ", "Martial Arts    "),
4574                 _("二刀流          ", "Dual Wielding   "), 
4575                 _("乗馬            ", "Riding          "),
4576                 _("盾              ", "Shield          ")
4577         };
4578
4579         /* Open a new file */
4580         FILE *fff;
4581         fff = my_fopen_temp(file_name, 1024);
4582         if (!fff)
4583         {
4584             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4585             msg_print(NULL);
4586             return;
4587         }
4588
4589         int skill_exp;
4590         for (int i = 0; i < GINOU_TEMPMAX; i++)
4591         {
4592                 skill_exp = creature_ptr->skill_exp[i];
4593                 fprintf(fff, "%-20s ", skill_name[i]);
4594                 if (skill_exp >= s_info[creature_ptr->pclass].s_max[i]) fprintf(fff, "!");
4595                 else fprintf(fff, " ");
4596                 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
4597                 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
4598                 fprintf(fff, "\n");
4599         }
4600
4601         my_fclose(fff);
4602
4603         /* Display the file contents */
4604         show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
4605         fd_kill(file_name);
4606 }
4607
4608
4609 /*!
4610  * @brief 現在のペットを表示するコマンドのメインルーチン /
4611  * Display current pets
4612  * @param creature_ptr プレーヤーへの参照ポインタ
4613  * @return なし
4614  */
4615 static void do_cmd_knowledge_pets(player_type *creature_ptr)
4616 {
4617         /* Open a new file */
4618         GAME_TEXT file_name[1024];
4619         FILE *fff;
4620         fff = my_fopen_temp(file_name, 1024);
4621         if (!fff)
4622         {
4623             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4624             msg_print(NULL);
4625             return;
4626         }
4627
4628         /* Process the monsters (backwards) */
4629         monster_type *m_ptr;
4630         GAME_TEXT pet_name[MAX_NLEN];
4631         int t_friends = 0;
4632         for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
4633         {
4634                 m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
4635
4636                 /* Ignore "dead" monsters */
4637                 if (!monster_is_valid(m_ptr)) continue;
4638
4639                 /* Calculate "upkeep" for pets */
4640                 if (!is_pet(m_ptr)) continue;
4641
4642                 t_friends++;
4643                 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
4644                 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
4645         }
4646
4647         int show_upkeep = calculate_upkeep(creature_ptr);
4648
4649         fprintf(fff, "----------------------------------------------\n");
4650 #ifdef JP
4651         fprintf(fff, "    合計: %d 体のペット\n", t_friends);
4652 #else
4653         fprintf(fff, "   Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
4654 #endif
4655         fprintf(fff, _(" 維持コスト: %d%% MP\n", "   Upkeep: %d%% mana.\n"), show_upkeep);
4656
4657         my_fclose(fff);
4658
4659         /* Display the file contents */
4660         show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
4661         fd_kill(file_name);
4662 }
4663
4664
4665 /*!
4666  * @brief 現在のペットを表示するコマンドのメインルーチン /
4667  * Total kill count
4668  * @return なし
4669  * @note the player ghosts are ignored.  
4670  */
4671 static void do_cmd_knowledge_kill_count(void)
4672 {
4673         /* Open a new file */
4674         FILE *fff;
4675         GAME_TEXT file_name[1024];
4676         fff = my_fopen_temp(file_name, 1024);
4677
4678         if (!fff)
4679         {
4680                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4681                 msg_print(NULL);
4682                 return;
4683         }
4684
4685         /* Allocate the "who" array */
4686         MONRACE_IDX *who;
4687         C_MAKE(who, max_r_idx, MONRACE_IDX);
4688
4689         s32b total = 0;
4690         {
4691                 /* Monsters slain */
4692                 for (int kk = 1; kk < max_r_idx; kk++)
4693                 {
4694                         monster_race *r_ptr = &r_info[kk];
4695
4696                         if (r_ptr->flags1 & (RF1_UNIQUE))
4697                         {
4698                                 bool dead = (r_ptr->max_num == 0);
4699
4700                                 if (dead)
4701                                 {
4702                                         total++;
4703                                 }
4704                         }
4705                         else
4706                         {
4707                                 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4708
4709                                 if (this_monster > 0)
4710                                 {
4711                                         total += this_monster;
4712                                 }
4713                         }
4714                 }
4715
4716                 if (total < 1)
4717                         fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
4718                 else
4719 #ifdef JP
4720                         fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)total);
4721 #else
4722                         fprintf(fff,"You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
4723 #endif
4724         }
4725
4726         total = 0;
4727
4728         /* Scan the monsters */
4729         int n = 0;
4730         for (MONRACE_IDX i = 1; i < max_r_idx; i++)
4731         {
4732                 monster_race *r_ptr = &r_info[i];
4733
4734                 /* Use that monster */
4735                 if (r_ptr->name) who[n++] = i;
4736         }
4737
4738         /* Sort the array by dungeon depth of monsters */
4739         u16b why = 2;
4740         ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
4741
4742         /* Scan the monster races */
4743         for (int k = 0; k < n; k++)
4744         {
4745                 monster_race *r_ptr = &r_info[who[k]];
4746
4747                 if (r_ptr->flags1 & (RF1_UNIQUE))
4748                 {
4749                         bool dead = (r_ptr->max_num == 0);
4750
4751                         if (dead)
4752                         {
4753                                 fprintf(fff, "     %s\n", (r_name + r_ptr->name));
4754                                 total++;
4755                         }
4756
4757                         continue;
4758                 }
4759
4760                 MONSTER_NUMBER this_monster = r_ptr->r_pkills;
4761
4762                 if (this_monster <= 0) continue;
4763
4764 #ifdef JP
4765                 /* p,tは人と数える by ita */
4766                 if (my_strchr("pt", r_ptr->d_char))
4767                         fprintf(fff, "     %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
4768                 else
4769                         fprintf(fff, "     %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
4770 #else
4771                 if (This < 2)
4772                 {
4773                         if (my_strstr(r_name + r_ptr->name, "coins"))
4774                         {
4775                                 fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
4776                         }
4777                         else
4778                         {
4779                                 fprintf(fff, "     1 %s\n", (r_name + r_ptr->name));
4780                         }
4781                 }
4782                 else
4783                 {
4784                         char ToPlural[80];
4785                         strcpy(ToPlural, (r_name + r_ptr->name));
4786                         plural_aux(ToPlural);
4787                         fprintf(fff, "     %d %s\n", This, ToPlural);
4788                 }
4789 #endif
4790                 total += this_monster;
4791         }
4792
4793         fprintf(fff,"----------------------------------------------\n");
4794 #ifdef JP
4795         fprintf(fff,"    合計: %lu 体を倒した。\n", (unsigned long int)total);
4796 #else
4797         fprintf(fff,"   Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
4798 #endif
4799
4800         /* Free the "who" array */
4801         C_KILL(who, max_r_idx, s16b);
4802         my_fclose(fff);
4803
4804         /* Display the file contents */
4805         show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
4806         fd_kill(file_name);
4807 }
4808
4809
4810 /*!
4811  * @brief モンスター情報リスト中のグループを表示する /
4812  * Display the object groups.
4813  * @param col 開始行
4814  * @param row 開始列
4815  * @param wid 表示文字数幅
4816  * @param per_page リストの表示行
4817  * @param grp_idx グループのID配列
4818  * @param group_text グループ名の文字列配列
4819  * @param grp_cur 現在の選択ID
4820  * @param grp_top 現在の選択リスト最上部ID
4821  * @return なし
4822  */
4823 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)
4824 {
4825         /* Display lines until done */
4826         for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
4827         {
4828                 /* Get the group index */
4829                 int grp = grp_idx[grp_top + i];
4830
4831                 /* Choose a color */
4832                 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
4833
4834                 /* Erase the entire line */
4835                 Term_erase(col, row + i, wid);
4836
4837                 /* Display the group label */
4838                 c_put_str(attr, group_text[grp], row + i, col);
4839         }
4840 }
4841
4842
4843 /* 
4844  * Move the cursor in a browser window 
4845  */
4846 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt, 
4847                                                    IDX *list_cur, int list_cnt)
4848 {
4849         int d;
4850         int col = *column;
4851         IDX grp = *grp_cur;
4852         IDX list = *list_cur;
4853
4854         /* Extract direction */
4855         if (ch == ' ')
4856         {
4857                 /* Hack -- scroll up full screen */
4858                 d = 3;
4859         }
4860         else if (ch == '-')
4861         {
4862                 /* Hack -- scroll down full screen */
4863                 d = 9;
4864         }
4865         else
4866         {
4867                 d = get_keymap_dir(ch);
4868         }
4869
4870         if (!d) return;
4871
4872         /* Diagonals - hack */
4873         if ((ddx[d] > 0) && ddy[d])
4874         {
4875                 int browser_rows;
4876                 int wid, hgt;
4877
4878                 Term_get_size(&wid, &hgt);
4879
4880                 browser_rows = hgt - 8;
4881
4882                 /* Browse group list */
4883                 if (!col)
4884                 {
4885                         int old_grp = grp;
4886
4887                         /* Move up or down */
4888                         grp += ddy[d] * (browser_rows - 1);
4889
4890                         /* Verify */
4891                         if (grp >= grp_cnt)     grp = grp_cnt - 1;
4892                         if (grp < 0) grp = 0;
4893                         if (grp != old_grp)     list = 0;
4894                 }
4895
4896                 /* Browse sub-list list */
4897                 else
4898                 {
4899                         /* Move up or down */
4900                         list += ddy[d] * browser_rows;
4901
4902                         /* Verify */
4903                         if (list >= list_cnt) list = list_cnt - 1;
4904                         if (list < 0) list = 0;
4905                 }
4906
4907                 (*grp_cur) = grp;
4908                 (*list_cur) = list;
4909
4910                 return;
4911         }
4912
4913         if (ddx[d])
4914         {
4915                 col += ddx[d];
4916                 if (col < 0) col = 0;
4917                 if (col > 1) col = 1;
4918
4919                 (*column) = col;
4920
4921                 return;
4922         }
4923
4924         /* Browse group list */
4925         if (!col)
4926         {
4927                 int old_grp = grp;
4928
4929                 /* Move up or down */
4930                 grp += (IDX)ddy[d];
4931
4932                 /* Verify */
4933                 if (grp >= grp_cnt)     grp = grp_cnt - 1;
4934                 if (grp < 0) grp = 0;
4935                 if (grp != old_grp)     list = 0;
4936         }
4937
4938         /* Browse sub-list list */
4939         else
4940         {
4941                 /* Move up or down */
4942                 list += (IDX)ddy[d];
4943
4944                 /* Verify */
4945                 if (list >= list_cnt) list = list_cnt - 1;
4946                 if (list < 0) list = 0;
4947         }
4948
4949         (*grp_cur) = grp;
4950         (*list_cur) = list;
4951 }
4952
4953
4954 /*
4955  * Display visuals.
4956  */
4957 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
4958 {
4959         int i, j;
4960
4961         /* Clear the display lines */
4962         for (i = 0; i < height; i++)
4963         {
4964                 Term_erase(col, row + i, width);
4965         }
4966
4967         /* Bigtile mode uses double width */
4968         if (use_bigtile) width /= 2;
4969
4970         /* Display lines until done */
4971         for (i = 0; i < height; i++)
4972         {
4973                 /* Display columns until done */
4974                 for (j = 0; j < width; j++)
4975                 {
4976                         TERM_LEN x = col + j;
4977                         TERM_LEN y = row + i;
4978
4979                         /* Bigtile mode uses double width */
4980                         if (use_bigtile) x += j;
4981
4982                         TERM_COLOR ia = attr_top + i;
4983                         SYMBOL_CODE ic = char_left + j;
4984
4985                         /* Ignore illegal characters */
4986                         if (ia > 0x7f || ic > 0xff || ic < ' ' ||
4987                             (!use_graphics && ic > 0x7f))
4988                                 continue;
4989
4990                         TERM_COLOR a = ia;
4991                         SYMBOL_CODE c = ic;
4992
4993                         /* Force correct code for both ASCII character and tile */
4994                         if (c & 0x80) a |= 0x80;
4995
4996                         /* Display symbol */
4997                         Term_queue_bigchar(x, y, a, c, 0, 0);
4998                 }
4999         }
5000 }
5001
5002
5003 /*
5004  * Place the cursor at the collect position for visual mode
5005  */
5006 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
5007 {
5008         int i = (a & 0x7f) - attr_top;
5009         int j = c - char_left;
5010
5011         TERM_LEN x = col + j;
5012         TERM_LEN y = row + i;
5013
5014         /* Bigtile mode uses double width */
5015         if (use_bigtile) x += j;
5016
5017         /* Place the cursor */
5018         Term_gotoxy(x, y);
5019 }
5020
5021
5022 /*
5023  *  Clipboard variables for copy&paste in visual mode
5024  */
5025 static TERM_COLOR attr_idx = 0;
5026 static SYMBOL_CODE char_idx = 0;
5027
5028 /* Hack -- for feature lighting */
5029 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
5030 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
5031
5032 /*
5033  *  Do visual mode command -- Change symbols
5034  */
5035 static bool visual_mode_command(char ch, bool *visual_list_ptr,
5036                                 int height, int width,
5037                                 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
5038                                 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
5039 {
5040         static TERM_COLOR attr_old = 0;
5041         static SYMBOL_CODE char_old = 0;
5042
5043         switch (ch)
5044         {
5045         case ESCAPE:
5046                 if (*visual_list_ptr)
5047                 {
5048                         /* Cancel change */
5049                         *cur_attr_ptr = attr_old;
5050                         *cur_char_ptr = char_old;
5051                         *visual_list_ptr = FALSE;
5052
5053                         return TRUE;
5054                 }
5055                 break;
5056
5057         case '\n':
5058         case '\r':
5059                 if (*visual_list_ptr)
5060                 {
5061                         /* Accept change */
5062                         *visual_list_ptr = FALSE;
5063                         *need_redraw = TRUE;
5064
5065                         return TRUE;
5066                 }
5067                 break;
5068
5069         case 'V':
5070         case 'v':
5071                 if (!*visual_list_ptr)
5072                 {
5073                         *visual_list_ptr = TRUE;
5074
5075                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5076                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5077
5078                         attr_old = *cur_attr_ptr;
5079                         char_old = *cur_char_ptr;
5080
5081                         return TRUE;
5082                 }
5083                 break;
5084
5085         case 'C':
5086         case 'c':
5087                 {
5088                         int i;
5089
5090                         /* Set the visual */
5091                         attr_idx = *cur_attr_ptr;
5092                         char_idx = *cur_char_ptr;
5093
5094                         /* Hack -- for feature lighting */
5095                         for (i = 0; i < F_LIT_MAX; i++)
5096                         {
5097                                 attr_idx_feat[i] = 0;
5098                                 char_idx_feat[i] = 0;
5099                         }
5100                 }
5101                 return TRUE;
5102
5103         case 'P':
5104         case 'p':
5105                 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
5106                 {
5107                         /* Set the char */
5108                         *cur_attr_ptr = attr_idx;
5109                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
5110                         if (!*visual_list_ptr) *need_redraw = TRUE;
5111                 }
5112
5113                 if (char_idx)
5114                 {
5115                         /* Set the char */
5116                         *cur_char_ptr = char_idx;
5117                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
5118                         if (!*visual_list_ptr) *need_redraw = TRUE;
5119                 }
5120
5121                 return TRUE;
5122
5123         default:
5124                 if (*visual_list_ptr)
5125                 {
5126                         int eff_width;
5127                         int d = get_keymap_dir(ch);
5128                         TERM_COLOR a = (*cur_attr_ptr & 0x7f);
5129                         SYMBOL_CODE c = *cur_char_ptr;
5130
5131                         if (use_bigtile) eff_width = width / 2;
5132                         else eff_width = width;
5133
5134                         /* Restrict direction */
5135                         if ((a == 0) && (ddy[d] < 0)) d = 0;
5136                         if ((c == 0) && (ddx[d] < 0)) d = 0;
5137                         if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
5138                         if ((c == 0xff) && (ddx[d] > 0)) d = 0;
5139
5140                         a += (TERM_COLOR)ddy[d];
5141                         c += (SYMBOL_CODE)ddx[d];
5142
5143                         /* Force correct code for both ASCII character and tile */
5144                         if (c & 0x80) a |= 0x80;
5145
5146                         /* Set the visual */
5147                         *cur_attr_ptr = a;
5148                         *cur_char_ptr = c;
5149
5150
5151                         /* Move the frame */
5152                         if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
5153                         if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
5154                         if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
5155                         if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
5156                         return TRUE;
5157                 }
5158                 break;
5159         }
5160
5161         /* Visual mode command is not used */
5162         return FALSE;
5163 }
5164
5165
5166 /*
5167  * Display the monsters in a group.
5168  */
5169 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
5170         int mon_cur, int mon_top, bool visual_only)
5171 {
5172         int i;
5173
5174         /* Display lines until done */
5175         for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
5176         {
5177                 TERM_COLOR attr;
5178
5179                 /* Get the race index */
5180                 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
5181
5182                 /* Access the race */
5183                 monster_race *r_ptr = &r_info[r_idx];
5184
5185                 /* Choose a color */
5186                 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
5187
5188                 /* Display the name */
5189                 c_prt(attr, (r_name + r_ptr->name), row + i, col);
5190
5191                 /* Hack -- visual_list mode */
5192                 if (per_page == 1)
5193                 {
5194                         c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
5195                 }
5196
5197                 if (current_world_ptr->wizard || visual_only)
5198                 {
5199                         c_prt(attr, format("%d", r_idx), row + i, 62);
5200                 }
5201
5202                 /* Erase chars before overwritten by the race letter */
5203                 Term_erase(69, row + i, 255);
5204
5205                 /* Display symbol */
5206                 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
5207
5208                 if (!visual_only)
5209                 {
5210                         /* Display kills */
5211                         if (!(r_ptr->flags1 & RF1_UNIQUE)) 
5212                                 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
5213                         else 
5214                                 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), 
5215                                                   (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
5216                 }
5217         }
5218
5219         /* Clear remaining lines */
5220         for (; i < per_page; i++)
5221         {
5222                 Term_erase(col, row + i, 255);
5223         }
5224 }
5225
5226
5227 /*
5228  * todo 引数の詳細について加筆求む
5229  * Display known monsters.
5230  * @param creature_ptr プレーヤーへの参照ポインタ
5231  * @param need_redraw 画面の再描画が必要な時TRUE
5232  * @param visual_only ???
5233  * @param direct_r_idx モンスターID
5234  * @return なし
5235  */
5236 static void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
5237 {
5238         TERM_LEN wid, hgt;
5239         Term_get_size(&wid, &hgt);
5240
5241         /* Allocate the "mon_idx" array */
5242         IDX *mon_idx;
5243         C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
5244
5245         int max = 0;
5246         IDX grp_cnt = 0;
5247         IDX grp_idx[100];
5248         IDX mon_cnt;
5249         bool visual_list = FALSE;
5250         TERM_COLOR attr_top = 0;
5251         byte char_left = 0;
5252         BIT_FLAGS8 mode;
5253         int browser_rows = hgt - 8;
5254         if (direct_r_idx < 0)
5255         {
5256                 mode = visual_only ? 0x03 : 0x01;
5257
5258                 /* Check every group */
5259                 int len;
5260                 for (IDX i = 0; monster_group_text[i] != NULL; i++)
5261                 {
5262                         /* Measure the label */
5263                         len = strlen(monster_group_text[i]);
5264
5265                         /* Save the maximum length */
5266                         if (len > max) max = len;
5267
5268                         /* See if any monsters are known */
5269                         if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
5270                         {
5271                                 /* Build a list of groups with known monsters */
5272                                 grp_idx[grp_cnt++] = i;
5273                         }
5274                 }
5275
5276                 mon_cnt = 0;
5277         }
5278         else
5279         {
5280                 mon_idx[0] = direct_r_idx;
5281                 mon_cnt = 1;
5282
5283                 /* Terminate the list */
5284                 mon_idx[1] = -1;
5285
5286                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5287                         &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
5288         }
5289
5290         /* Terminate the list */
5291         grp_idx[grp_cnt] = -1;
5292
5293         mode = visual_only ? 0x02 : 0x00;
5294         IDX old_grp_cur = -1;
5295         IDX grp_cur = 0;
5296         IDX grp_top = 0;
5297         IDX mon_cur = 0;
5298         IDX mon_top = 0;
5299         int column = 0;
5300         bool flag = FALSE;
5301         bool redraw = TRUE;
5302         while (!flag)
5303         {
5304                 char ch;
5305                 monster_race *r_ptr;
5306
5307                 if (redraw)
5308                 {
5309                         clear_from(0);
5310                         prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
5311                         if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
5312                         prt(_("名前", "Name"), 4, max + 3);
5313                         if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
5314                         prt(_("文字", "Sym"), 4, 67);
5315                         if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
5316
5317                         for (IDX i = 0; i < 78; i++)
5318                         {
5319                                 Term_putch(i, 5, TERM_WHITE, '=');
5320                         }
5321
5322                         if (direct_r_idx < 0)
5323                         {
5324                                 for (IDX i = 0; i < browser_rows; i++)
5325                                 {
5326                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5327                                 }
5328                         }
5329
5330                         redraw = FALSE;
5331                 }
5332
5333                 if (direct_r_idx < 0)
5334                 {
5335                         /* Scroll group list */
5336                         if (grp_cur < grp_top) grp_top = grp_cur;
5337                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5338
5339                         /* Display a list of monster groups */
5340                         display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
5341
5342                         if (old_grp_cur != grp_cur)
5343                         {
5344                                 old_grp_cur = grp_cur;
5345
5346                                 /* Get a list of monsters in the current group */
5347                                 mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
5348                         }
5349
5350                         /* Scroll monster list */
5351                         while (mon_cur < mon_top)
5352                                 mon_top = MAX(0, mon_top - browser_rows/2);
5353                         while (mon_cur >= mon_top + browser_rows)
5354                                 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
5355                 }
5356
5357                 if (!visual_list)
5358                 {
5359                         /* Display a list of monsters in the current group */
5360                         display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
5361                 }
5362                 else
5363                 {
5364                         mon_top = mon_cur;
5365
5366                         /* Display a monster name */
5367                         display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
5368
5369                         /* Display visual list below first monster */
5370                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
5371                 }
5372
5373                 /* Prompt */
5374                 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
5375                         (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
5376                         visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
5377                         (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
5378                         hgt - 1, 0);
5379
5380                 /* Get the current monster */
5381                 r_ptr = &r_info[mon_idx[mon_cur]];
5382
5383                 if (!visual_only)
5384                 {
5385                         /* Mega Hack -- track this monster race */
5386                         if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
5387                         handle_stuff();
5388                 }
5389
5390                 if (visual_list)
5391                 {
5392                         place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
5393                 }
5394                 else if (!column)
5395                 {
5396                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
5397                 }
5398                 else
5399                 {
5400                         Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
5401                 }
5402
5403                 ch = inkey();
5404
5405                 /* Do visual mode command if needed */
5406                 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))
5407                 {
5408                         if (direct_r_idx >= 0)
5409                         {
5410                                 switch (ch)
5411                                 {
5412                                 case '\n':
5413                                 case '\r':
5414                                 case ESCAPE:
5415                                         flag = TRUE;
5416                                         break;
5417                                 }
5418                         }
5419                         continue;
5420                 }
5421
5422                 switch (ch)
5423                 {
5424                         case ESCAPE:
5425                         {
5426                                 flag = TRUE;
5427                                 break;
5428                         }
5429
5430                         case 'R':
5431                         case 'r':
5432                         {
5433                                 /* Recall on screen */
5434                                 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
5435                                 {
5436                                         screen_roff(mon_idx[mon_cur], 0);
5437
5438                                         (void)inkey();
5439
5440                                         redraw = TRUE;
5441                                 }
5442                                 break;
5443                         }
5444
5445                         default:
5446                         {
5447                                 /* Move the cursor */
5448                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
5449
5450                                 break;
5451                         }
5452                 }
5453         }
5454
5455         /* Free the "mon_idx" array */
5456         C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
5457 }
5458
5459
5460 /*
5461  * Display the objects in a group.
5462  */
5463 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
5464         int object_cur, int object_top, bool visual_only)
5465 {
5466         int i;
5467
5468         /* Display lines until done */
5469         for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
5470         {
5471                 GAME_TEXT o_name[MAX_NLEN];
5472                 TERM_COLOR a;
5473                 SYMBOL_CODE c;
5474                 object_kind *flavor_k_ptr;
5475
5476                 /* Get the object index */
5477                 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
5478
5479                 /* Access the object */
5480                 object_kind *k_ptr = &k_info[k_idx];
5481
5482                 /* Choose a color */
5483                 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
5484                 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
5485
5486
5487                 if (!visual_only && k_ptr->flavor)
5488                 {
5489                         /* Appearance of this object is shuffled */
5490                         flavor_k_ptr = &k_info[k_ptr->flavor];
5491                 }
5492                 else
5493                 {
5494                         /* Appearance of this object is very normal */
5495                         flavor_k_ptr = k_ptr;
5496                 }
5497
5498                 attr = ((i + object_top == object_cur) ? cursor : attr);
5499
5500                 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
5501                 {
5502                         /* Tidy name */
5503                         strip_name(o_name, k_idx);
5504                 }
5505                 else
5506                 {
5507                         /* Flavor name */
5508                         strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
5509                 }
5510
5511                 /* Display the name */
5512                 c_prt(attr, o_name, row + i, col);
5513
5514                 /* Hack -- visual_list mode */
5515                 if (per_page == 1)
5516                 {
5517                         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);
5518                 }
5519
5520                 if (current_world_ptr->wizard || visual_only)
5521                 {
5522                         c_prt(attr, format("%d", k_idx), row + i, 70);
5523                 }
5524
5525                 a = flavor_k_ptr->x_attr;
5526                 c = flavor_k_ptr->x_char;
5527
5528                 /* Display symbol */
5529                 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
5530         }
5531
5532         /* Clear remaining lines */
5533         for (; i < per_page; i++)
5534         {
5535                 Term_erase(col, row + i, 255);
5536         }
5537 }
5538
5539 /*
5540  * Describe fake object
5541  */
5542 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
5543 {
5544         object_type *o_ptr;
5545         object_type object_type_body;
5546         o_ptr = &object_type_body;
5547         object_wipe(o_ptr);
5548         object_prep(o_ptr, k_idx);
5549
5550         /* It's fully know */
5551         o_ptr->ident |= IDENT_KNOWN;
5552
5553         /* Track the object */
5554         /* object_actual_track(o_ptr); */
5555
5556         /* Hack - mark as fake */
5557         /* term_obj_real = FALSE; */
5558         handle_stuff();
5559
5560         if (screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL)) return;
5561
5562         msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
5563         msg_print(NULL);
5564 }
5565
5566
5567 /*
5568  * Display known objects
5569  */
5570 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
5571 {
5572         IDX object_old, object_top;
5573         IDX grp_idx[100];
5574         int object_cnt;
5575         OBJECT_IDX *object_idx;
5576
5577         bool visual_list = FALSE;
5578         TERM_COLOR attr_top = 0;
5579         byte char_left = 0;
5580         byte mode;
5581
5582         TERM_LEN wid, hgt;
5583         Term_get_size(&wid, &hgt);
5584
5585         int browser_rows = hgt - 8;
5586
5587         /* Allocate the "object_idx" array */
5588         C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
5589
5590         int len;
5591         int max = 0;
5592         int grp_cnt = 0;
5593         if (direct_k_idx < 0)
5594         {
5595                 mode = visual_only ? 0x03 : 0x01;
5596
5597                 /* Check every group */
5598                 for (IDX i = 0; object_group_text[i] != NULL; i++)
5599                 {
5600                         /* Measure the label */
5601                         len = strlen(object_group_text[i]);
5602
5603                         /* Save the maximum length */
5604                         if (len > max) max = len;
5605
5606                         /* See if any monsters are known */
5607                         if (collect_objects(i, object_idx, mode))
5608                         {
5609                                 /* Build a list of groups with known monsters */
5610                                 grp_idx[grp_cnt++] = i;
5611                         }
5612                 }
5613
5614                 object_old = -1;
5615                 object_cnt = 0;
5616         }
5617         else
5618         {
5619                 object_kind *k_ptr = &k_info[direct_k_idx];
5620                 object_kind *flavor_k_ptr;
5621
5622                 if (!visual_only && k_ptr->flavor)
5623                 {
5624                         /* Appearance of this object is shuffled */
5625                         flavor_k_ptr = &k_info[k_ptr->flavor];
5626                 }
5627                 else
5628                 {
5629                         /* Appearance of this object is very normal */
5630                         flavor_k_ptr = k_ptr;
5631                 }
5632
5633                 object_idx[0] = direct_k_idx;
5634                 object_old = direct_k_idx;
5635                 object_cnt = 1;
5636
5637                 /* Terminate the list */
5638                 object_idx[1] = -1;
5639
5640                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5641                         &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
5642         }
5643
5644         /* Terminate the list */
5645         grp_idx[grp_cnt] = -1;
5646
5647         mode = visual_only ? 0x02 : 0x00;
5648         IDX old_grp_cur = -1;
5649         IDX grp_cur = 0;
5650         IDX grp_top = 0;
5651         IDX object_cur = object_top = 0;
5652         bool flag = FALSE;
5653         bool redraw = TRUE;
5654         int column = 0;
5655         while (!flag)
5656         {
5657                 object_kind *k_ptr, *flavor_k_ptr;
5658
5659                 if (redraw)
5660                 {
5661                         clear_from(0);
5662
5663 #ifdef JP
5664                         prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
5665                         if (direct_k_idx < 0) prt("グループ", 4, 0);
5666                         prt("名前", 4, max + 3);
5667                         if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5668                         prt("文字", 4, 74);
5669 #else
5670                         prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
5671                         if (direct_k_idx < 0) prt("Group", 4, 0);
5672                         prt("Name", 4, max + 3);
5673                         if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 70);
5674                         prt("Sym", 4, 75);
5675 #endif
5676
5677                         for (IDX i = 0; i < 78; i++)
5678                         {
5679                                 Term_putch(i, 5, TERM_WHITE, '=');
5680                         }
5681
5682                         if (direct_k_idx < 0)
5683                         {
5684                                 for (IDX i = 0; i < browser_rows; i++)
5685                                 {
5686                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
5687                                 }
5688                         }
5689
5690                         redraw = FALSE;
5691                 }
5692
5693                 if (direct_k_idx < 0)
5694                 {
5695                         /* Scroll group list */
5696                         if (grp_cur < grp_top) grp_top = grp_cur;
5697                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
5698
5699                         /* Display a list of object groups */
5700                         display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
5701
5702                         if (old_grp_cur != grp_cur)
5703                         {
5704                                 old_grp_cur = grp_cur;
5705
5706                                 /* Get a list of objects in the current group */
5707                                 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
5708                         }
5709
5710                         /* Scroll object list */
5711                         while (object_cur < object_top)
5712                                 object_top = MAX(0, object_top - browser_rows/2);
5713                         while (object_cur >= object_top + browser_rows)
5714                                 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
5715                 }
5716
5717                 if (!visual_list)
5718                 {
5719                         /* Display a list of objects in the current group */
5720                         display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
5721                 }
5722                 else
5723                 {
5724                         object_top = object_cur;
5725
5726                         /* Display a list of objects in the current group */
5727                         display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
5728
5729                         /* Display visual list below first object */
5730                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
5731                 }
5732
5733                 /* Get the current object */
5734                 k_ptr = &k_info[object_idx[object_cur]];
5735
5736                 if (!visual_only && k_ptr->flavor)
5737                 {
5738                         /* Appearance of this object is shuffled */
5739                         flavor_k_ptr = &k_info[k_ptr->flavor];
5740                 }
5741                 else
5742                 {
5743                         /* Appearance of this object is very normal */
5744                         flavor_k_ptr = k_ptr;
5745                 }
5746
5747                 /* Prompt */
5748 #ifdef JP
5749                 prt(format("<方向>%s%s%s, ESC",
5750                         (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
5751                         visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
5752                         (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
5753                         hgt - 1, 0);
5754 #else
5755                 prt(format("<dir>%s%s%s, ESC",
5756                         (!visual_list && !visual_only) ? ", 'r' to recall" : "",
5757                         visual_list ? ", ENTER to accept" : ", 'v' for visuals",
5758                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
5759                         hgt - 1, 0);
5760 #endif
5761
5762                 if (!visual_only)
5763                 {
5764                         /* Mega Hack -- track this object */
5765                         if (object_cnt) object_kind_track(object_idx[object_cur]);
5766
5767                         /* The "current" object changed */
5768                         if (object_old != object_idx[object_cur])
5769                         {
5770                                 handle_stuff();
5771
5772                                 /* Remember the "current" object */
5773                                 object_old = object_idx[object_cur];
5774                         }
5775                 }
5776
5777                 if (visual_list)
5778                 {
5779                         place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
5780                 }
5781                 else if (!column)
5782                 {
5783                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
5784                 }
5785                 else
5786                 {
5787                         Term_gotoxy(max + 3, 6 + (object_cur - object_top));
5788                 }
5789
5790                 char ch = inkey();
5791
5792                 /* Do visual mode command if needed */
5793                 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))
5794                 {
5795                         if (direct_k_idx >= 0)
5796                         {
5797                                 switch (ch)
5798                                 {
5799                                 case '\n':
5800                                 case '\r':
5801                                 case ESCAPE:
5802                                         flag = TRUE;
5803                                         break;
5804                                 }
5805                         }
5806                         continue;
5807                 }
5808
5809                 switch (ch)
5810                 {
5811                         case ESCAPE:
5812                         {
5813                                 flag = TRUE;
5814                                 break;
5815                         }
5816
5817                         case 'R':
5818                         case 'r':
5819                         {
5820                                 /* Recall on screen */
5821                                 if (!visual_list && !visual_only && (grp_cnt > 0))
5822                                 {
5823                                         desc_obj_fake(object_idx[object_cur]);
5824                                         redraw = TRUE;
5825                                 }
5826                                 break;
5827                         }
5828
5829                         default:
5830                         {
5831                                 /* Move the cursor */
5832                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
5833                                 break;
5834                         }
5835                 }
5836         }
5837
5838         /* Free the "object_idx" array */
5839         C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
5840 }
5841
5842
5843 /*
5844  * Display the features in a group.
5845  */
5846 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
5847         FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
5848 {
5849         int lit_col[F_LIT_MAX], i, j;
5850         int f_idx_col = use_bigtile ? 62 : 64;
5851
5852         /* Correct columns 1 and 4 */
5853         lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
5854         for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
5855                 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
5856
5857         /* Display lines until done */
5858         for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
5859         {
5860                 TERM_COLOR attr;
5861                 FEAT_IDX f_idx = feat_idx[feat_top + i];
5862                 feature_type *f_ptr = &f_info[f_idx];
5863                 int row_i = row + i;
5864
5865                 /* Choose a color */
5866                 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
5867
5868                 /* Display the name */
5869                 c_prt(attr, f_name + f_ptr->name, row_i, col);
5870
5871                 /* Hack -- visual_list mode */
5872                 if (per_page == 1)
5873                 {
5874                         /* Display lighting level */
5875                         c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
5876
5877                         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));
5878                 }
5879                 if (current_world_ptr->wizard || visual_only)
5880                 {
5881                         c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
5882                 }
5883
5884                 /* Display symbol */
5885                 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);
5886
5887                 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
5888                 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
5889                 {
5890                         Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
5891                 }
5892                 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
5893
5894                 /* Mega-hack -- Use non-standard colour */
5895                 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
5896                 {
5897                         Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
5898                 }
5899         }
5900
5901         /* Clear remaining lines */
5902         for (; i < per_page; i++)
5903         {
5904                 Term_erase(col, row + i, 255);
5905         }
5906 }
5907
5908
5909 /*
5910  * Interact with feature visuals.
5911  */
5912 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
5913 {
5914         TERM_COLOR attr_old[F_LIT_MAX];
5915         (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
5916         SYMBOL_CODE char_old[F_LIT_MAX];
5917         (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
5918
5919         TERM_LEN wid, hgt;
5920         Term_get_size(&wid, &hgt);
5921
5922         /* Allocate the "feat_idx" array */
5923         FEAT_IDX *feat_idx;
5924         C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
5925
5926         int len;
5927         int max = 0;
5928         int grp_cnt = 0;
5929         int feat_cnt;
5930         FEAT_IDX grp_idx[100];
5931         TERM_COLOR attr_top = 0;
5932         bool visual_list = FALSE;
5933         byte char_left = 0;
5934         TERM_LEN browser_rows = hgt - 8;
5935         if (direct_f_idx < 0)
5936         {
5937                 /* Check every group */
5938                 for (FEAT_IDX i = 0; feature_group_text[i] != NULL; i++)
5939                 {
5940                         /* Measure the label */
5941                         len = strlen(feature_group_text[i]);
5942
5943                         /* Save the maximum length */
5944                         if (len > max) max = len;
5945
5946                         /* See if any features are known */
5947                         if (collect_features(i, feat_idx, 0x01))
5948                         {
5949                                 /* Build a list of groups with known features */
5950                                 grp_idx[grp_cnt++] = i;
5951                         }
5952                 }
5953
5954                 feat_cnt = 0;
5955         }
5956         else
5957         {
5958                 feature_type *f_ptr = &f_info[direct_f_idx];
5959
5960                 feat_idx[0] = direct_f_idx;
5961                 feat_cnt = 1;
5962
5963                 /* Terminate the list */
5964                 feat_idx[1] = -1;
5965
5966                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
5967                         &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
5968
5969                 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
5970                 {
5971                         attr_old[i] = f_ptr->x_attr[i];
5972                         char_old[i] = f_ptr->x_char[i];
5973                 }
5974         }
5975
5976         /* Terminate the list */
5977         grp_idx[grp_cnt] = -1;
5978
5979         FEAT_IDX old_grp_cur = -1;
5980         FEAT_IDX grp_cur = 0;
5981         FEAT_IDX grp_top = 0;
5982         FEAT_IDX feat_cur = 0;
5983         FEAT_IDX feat_top = 0;
5984         TERM_LEN column = 0;
5985         bool flag = FALSE;
5986         bool redraw = TRUE;
5987         TERM_COLOR *cur_attr_ptr;
5988         SYMBOL_CODE *cur_char_ptr;
5989         while (!flag)
5990         {
5991                 char ch;
5992                 feature_type *f_ptr;
5993
5994                 if (redraw)
5995                 {
5996                         clear_from(0);
5997
5998                         prt(_("表示 - 地形", "Visuals - features"), 2, 0);
5999                         if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
6000                         prt(_("名前", "Name"), 4, max + 3);
6001                         if (use_bigtile)
6002                         {
6003                                 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
6004                                 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
6005                         }
6006                         else
6007                         {
6008                                 if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 64);
6009                                 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
6010                         }
6011
6012                         for (FEAT_IDX i = 0; i < 78; i++)
6013                         {
6014                                 Term_putch(i, 5, TERM_WHITE, '=');
6015                         }
6016
6017                         if (direct_f_idx < 0)
6018                         {
6019                                 for (FEAT_IDX i = 0; i < browser_rows; i++)
6020                                 {
6021                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6022                                 }
6023                         }
6024
6025                         redraw = FALSE;
6026                 }
6027
6028                 if (direct_f_idx < 0)
6029                 {
6030                         /* Scroll group list */
6031                         if (grp_cur < grp_top) grp_top = grp_cur;
6032                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6033
6034                         /* Display a list of feature groups */
6035                         display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
6036
6037                         if (old_grp_cur != grp_cur)
6038                         {
6039                                 old_grp_cur = grp_cur;
6040
6041                                 /* Get a list of features in the current group */
6042                                 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
6043                         }
6044
6045                         /* Scroll feature list */
6046                         while (feat_cur < feat_top)
6047                                 feat_top = MAX(0, feat_top - browser_rows/2);
6048                         while (feat_cur >= feat_top + browser_rows)
6049                                 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
6050                 }
6051
6052                 if (!visual_list)
6053                 {
6054                         /* Display a list of features in the current group */
6055                         display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
6056                 }
6057                 else
6058                 {
6059                         feat_top = feat_cur;
6060
6061                         /* Display a list of features in the current group */
6062                         display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
6063
6064                         /* Display visual list below first object */
6065                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6066                 }
6067
6068                 /* Prompt */
6069                 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
6070                         visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6071                         (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6072                         hgt - 1, 0);
6073
6074                 /* Get the current feature */
6075                 f_ptr = &f_info[feat_idx[feat_cur]];
6076                 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
6077                 cur_char_ptr = &f_ptr->x_char[*lighting_level];
6078
6079                 if (visual_list)
6080                 {
6081                         place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
6082                 }
6083                 else if (!column)
6084                 {
6085                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
6086                 }
6087                 else
6088                 {
6089                         Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
6090                 }
6091
6092                 ch = inkey();
6093
6094                 if (visual_list && ((ch == 'A') || (ch == 'a')))
6095                 {
6096                         int prev_lighting_level = *lighting_level;
6097
6098                         if (ch == 'A')
6099                         {
6100                                 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
6101                                 else (*lighting_level)--;
6102                         }
6103                         else
6104                         {
6105                                 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
6106                                 else (*lighting_level)++;
6107                         }
6108
6109                         if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
6110                                 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6111
6112                         if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
6113                                 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6114
6115                         continue;
6116                 }
6117
6118                 else if ((ch == 'D') || (ch == 'd'))
6119                 {
6120                         TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
6121                         byte prev_x_char = f_ptr->x_char[*lighting_level];
6122
6123                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
6124
6125                         if (visual_list)
6126                         {
6127                                 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
6128                                          attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
6129
6130                                 if (prev_x_char != f_ptr->x_char[*lighting_level])
6131                                         char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
6132                         }
6133                         else *need_redraw = TRUE;
6134
6135                         continue;
6136                 }
6137
6138                 /* Do visual mode command if needed */
6139                 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))
6140                 {
6141                         switch (ch)
6142                         {
6143                         /* Restore previous visual settings */
6144                         case ESCAPE:
6145                                 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6146                                 {
6147                                         f_ptr->x_attr[i] = attr_old[i];
6148                                         f_ptr->x_char[i] = char_old[i];
6149                                 }
6150
6151                                 /* Fall through */
6152
6153                         case '\n':
6154                         case '\r':
6155                                 if (direct_f_idx >= 0) flag = TRUE;
6156                                 else *lighting_level = F_LIT_STANDARD;
6157                                 break;
6158
6159                         /* Preserve current visual settings */
6160                         case 'V':
6161                         case 'v':
6162                                 for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6163                                 {
6164                                         attr_old[i] = f_ptr->x_attr[i];
6165                                         char_old[i] = f_ptr->x_char[i];
6166                                 }
6167                                 *lighting_level = F_LIT_STANDARD;
6168                                 break;
6169
6170                         case 'C':
6171                         case 'c':
6172                                 if (!visual_list)
6173                                 {
6174                                         for (FEAT_IDX i = 0; i < F_LIT_MAX; i++)
6175                                         {
6176                                                 attr_idx_feat[i] = f_ptr->x_attr[i];
6177                                                 char_idx_feat[i] = f_ptr->x_char[i];
6178                                         }
6179                                 }
6180                                 break;
6181
6182                         case 'P':
6183                         case 'p':
6184                                 if (!visual_list)
6185                                 {
6186                                         /* Allow TERM_DARK text */
6187                                         for (FEAT_IDX i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
6188                                         {
6189                                                 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
6190                                                 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
6191                                         }
6192                                 }
6193                                 break;
6194                         }
6195                         continue;
6196                 }
6197
6198                 switch (ch)
6199                 {
6200                         case ESCAPE:
6201                         {
6202                                 flag = TRUE;
6203                                 break;
6204                         }
6205
6206                         default:
6207                         {
6208                                 /* Move the cursor */
6209                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
6210                                 break;
6211                         }
6212                 }
6213         }
6214
6215         /* Free the "feat_idx" array */
6216         C_KILL(feat_idx, max_f_idx, FEAT_IDX);
6217 }
6218
6219
6220 /*
6221  * List wanted monsters
6222  * @param creature_ptr プレーヤーへの参照ポインタ
6223  * @return なし
6224  */
6225 static void do_cmd_knowledge_kubi(player_type *creature_ptr)
6226 {
6227         /* Open a new file */
6228         FILE *fff;
6229         GAME_TEXT file_name[1024];
6230         fff = my_fopen_temp(file_name, 1024);
6231         if (!fff)
6232         {
6233             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6234             msg_print(NULL);
6235             return;
6236         }
6237         
6238         if (fff)
6239         {
6240                 bool listed = FALSE;
6241
6242                 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
6243                         (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
6244                 fprintf(fff, "\n");
6245                 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
6246                 fprintf(fff, "----------------------------------------------\n");
6247
6248                 for (int i = 0; i < MAX_KUBI; i++)
6249                 {
6250                         if (current_world_ptr->bounty_r_idx[i] <= 10000)
6251                         {
6252                                 fprintf(fff,"%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
6253                                 listed = TRUE;
6254                         }
6255                 }
6256
6257                 if (!listed)
6258                 {
6259                         fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
6260                 }
6261         }
6262         
6263         my_fclose(fff);
6264         
6265         /* Display the file contents */
6266         show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
6267         fd_kill(file_name);
6268 }
6269
6270 /*
6271  * List virtues & status
6272  */
6273 static void do_cmd_knowledge_virtues(player_type *creature_ptr)
6274 {
6275         /* Open a new file */
6276         FILE *fff;
6277         GAME_TEXT file_name[1024];
6278         fff = my_fopen_temp(file_name, 1024);
6279         if (!fff)
6280         {
6281             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6282             msg_print(NULL);
6283             return;
6284         }
6285         
6286         if (fff)
6287         {
6288                 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment(creature_ptr));
6289                 dump_virtues(creature_ptr, fff);
6290         }
6291         
6292         my_fclose(fff);
6293         
6294         /* Display the file contents */
6295         show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
6296         fd_kill(file_name);
6297 }
6298
6299 /*
6300  * Dungeon
6301  */
6302 static void do_cmd_knowledge_dungeon(void)
6303 {
6304         /* Open a new file */
6305         FILE *fff;
6306         GAME_TEXT file_name[1024];
6307         fff = my_fopen_temp(file_name, 1024);
6308         if (!fff)
6309         {
6310             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6311             msg_print(NULL);
6312             return;
6313         }
6314         
6315         if (fff)
6316         {
6317                 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
6318                 {
6319                         bool seiha = FALSE;
6320
6321                         if (!d_info[i].maxdepth) continue;
6322                         if (!max_dlv[i]) continue;
6323                         if (d_info[i].final_guardian)
6324                         {
6325                                 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
6326                         }
6327                         else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
6328                         
6329                         fprintf(fff, _("%c%-12s :  %3d 階\n", "%c%-16s :  level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
6330                 }
6331         }
6332         
6333         my_fclose(fff);
6334         
6335         /* Display the file contents */
6336         show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
6337         fd_kill(file_name);
6338 }
6339
6340 /*
6341 * List virtues & status
6342 *
6343 */
6344 static void do_cmd_knowledge_stat(player_type *creature_ptr)
6345 {
6346         /* Open a new file */
6347         FILE *fff;
6348         GAME_TEXT file_name[1024];
6349         fff = my_fopen_temp(file_name, 1024);
6350         if (!fff)
6351         {
6352             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6353             msg_print(NULL);
6354             return;
6355         }
6356         
6357         int percent = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
6358                 (2 * creature_ptr->hitdie +
6359                 ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
6360
6361         if (creature_ptr->knowledge & KNOW_HPRATE)
6362                 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
6363         else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
6364
6365         fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
6366         for (int v_nr = 0; v_nr < A_MAX; v_nr++)
6367         {
6368                 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);
6369                 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
6370         }
6371
6372         dump_yourself(creature_ptr, fff);
6373         my_fclose(fff);
6374         
6375         /* Display the file contents */
6376         show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
6377         fd_kill(file_name);
6378 }
6379
6380
6381 /*
6382  * todo player_typeではなくQUEST_IDXを引数にすべきかもしれない
6383  * Print all active quests
6384  * @param creature_ptr プレーヤーへの参照ポインタ
6385  * @return なし
6386  */
6387 static void do_cmd_knowledge_quests_current(player_type *creature_ptr, FILE *fff)
6388 {
6389         char tmp_str[120];
6390         char rand_tmp_str[120] = "\0";
6391         GAME_TEXT name[MAX_NLEN];
6392         monster_race *r_ptr;
6393         int rand_level = 100;
6394         int total = 0;
6395
6396         fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
6397
6398         for (QUEST_IDX i = 1; i < max_q_idx; i++)
6399         {
6400                 bool is_no_print = quest[i].status != QUEST_STATUS_TAKEN;
6401                 is_no_print &= (quest[i].status != QUEST_STATUS_STAGE_COMPLETED) || (quest[i].type != QUEST_TYPE_TOWER);
6402                 is_no_print &= quest[i].status == QUEST_STATUS_COMPLETED;
6403                 if (is_no_print)
6404                         continue;
6405
6406                 /* Set the quest number temporary */
6407                 QUEST_IDX old_quest = creature_ptr->current_floor_ptr->inside_quest;
6408
6409                 /* Clear the text */
6410                 for (int j = 0; j < 10; j++) quest_text[j][0] = '\0';
6411                 quest_text_line = 0;
6412
6413                 creature_ptr->current_floor_ptr->inside_quest = i;
6414
6415                 /* Get the quest text */
6416                 init_flags = INIT_SHOW_TEXT;
6417
6418                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
6419
6420                 /* Reset the old quest number */
6421                 creature_ptr->current_floor_ptr->inside_quest = old_quest;
6422
6423                 /* No info from "silent" quests */
6424                 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6425
6426                 total++;
6427
6428                 if (quest[i].type != QUEST_TYPE_RANDOM)
6429                 {
6430                         char note[80] = "\0";
6431
6432                         if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
6433                         {
6434                                 switch (quest[i].type)
6435                                 {
6436                                 case QUEST_TYPE_KILL_LEVEL:
6437                                 case QUEST_TYPE_KILL_ANY_LEVEL:
6438                                         r_ptr = &r_info[quest[i].r_idx];
6439                                         strcpy(name, r_name + r_ptr->name);
6440                                         if (quest[i].max_num > 1)
6441                                         {
6442 #ifdef JP
6443                                                 sprintf(note, " - %d 体の%sを倒す。(あと %d 体)",
6444                                                         (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6445 #else
6446                                                 plural_aux(name);
6447                                                 sprintf(note, " - kill %d %s, have killed %d.",
6448                                                         (int)quest[i].max_num, name, (int)quest[i].cur_num);
6449 #endif
6450                                         }
6451                                         else
6452                                                 sprintf(note, _(" - %sを倒す。", " - kill %s."), name);
6453                                         break;
6454
6455                                 case QUEST_TYPE_FIND_ARTIFACT:
6456                                         if (quest[i].k_idx)
6457                                         {
6458                                                 artifact_type *a_ptr = &a_info[quest[i].k_idx];
6459                                                 object_type forge;
6460                                                 object_type *q_ptr = &forge;
6461                                                 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
6462                                                 object_prep(q_ptr, k_idx);
6463                                                 q_ptr->name1 = quest[i].k_idx;
6464                                                 q_ptr->ident = IDENT_STORE;
6465                                                 object_desc(name, q_ptr, OD_NAME_ONLY);
6466                                         }
6467                                         sprintf(note, _("\n   - %sを見つけ出す。", "\n   - Find out %s."), name);
6468                                         break;
6469                                 case QUEST_TYPE_FIND_EXIT:
6470                                         sprintf(note, _(" - 出口に到達する。", " - Reach to Exit."));
6471                                         break;
6472
6473                                 case QUEST_TYPE_KILL_NUMBER:
6474 #ifdef JP
6475                                         sprintf(note, " - %d 体のモンスターを倒す。(あと %d 体)",
6476                                                 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
6477 #else
6478                                         sprintf(note, " - Kill %d monsters, have killed %d.",
6479                                                 (int)quest[i].max_num, (int)quest[i].cur_num);
6480 #endif
6481                                         break;
6482
6483                                 case QUEST_TYPE_KILL_ALL:
6484                                 case QUEST_TYPE_TOWER:
6485                                         sprintf(note, _(" - 全てのモンスターを倒す。", " - Kill all monsters."));
6486                                         break;
6487                                 }
6488                         }
6489
6490                         /* Print the quest info */
6491                         sprintf(tmp_str, _("  %s (危険度:%d階相当)%s\n", "  %s (Danger level: %d)%s\n"),
6492                                 quest[i].name, (int)quest[i].level, note);
6493
6494                         fputs(tmp_str, fff);
6495
6496                         if (quest[i].status == QUEST_STATUS_COMPLETED)
6497                         {
6498                                 sprintf(tmp_str, _("    クエスト達成 - まだ報酬を受けとってない。\n", "    Quest Completed - Unrewarded\n"));
6499                                 fputs(tmp_str, fff);
6500                                 continue;
6501                         }
6502
6503                         int k = 0;
6504                         while (quest_text[k][0] && k < 10)
6505                         {
6506                                 fprintf(fff, "    %s\n", quest_text[k]);
6507                                 k++;
6508                         }
6509
6510                         continue;
6511                 }
6512                 
6513                 /* QUEST_TYPE_RANDOM */
6514                 if (quest[i].level >= rand_level)
6515                         continue;
6516
6517                 /* New random */
6518                 rand_level = quest[i].level;
6519
6520                 if (max_dlv[DUNGEON_ANGBAND] < rand_level) continue;
6521
6522                 /* Print the quest info */
6523                 r_ptr = &r_info[quest[i].r_idx];
6524                 strcpy(name, r_name + r_ptr->name);
6525
6526                 if (quest[i].max_num <= 1)
6527                 {
6528                         sprintf(rand_tmp_str, _("  %s (%d 階) - %sを倒す。\n", "  %s (Dungeon level: %d)\n  Kill %s.\n"),
6529                                 quest[i].name, (int)quest[i].level, name);
6530                         continue;
6531                 }
6532
6533 #ifdef JP
6534                 sprintf(rand_tmp_str, "  %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
6535                         quest[i].name, (int)quest[i].level,
6536                         (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
6537 #else
6538                 plural_aux(name);
6539
6540                 sprintf(rand_tmp_str, "  %s (Dungeon level: %d)\n  Kill %d %s, have killed %d.\n",
6541                         quest[i].name, (int)quest[i].level,
6542                         (int)quest[i].max_num, name, (int)quest[i].cur_num);
6543 #endif
6544         }
6545
6546         /* Print the current random quest  */
6547         if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
6548
6549         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
6550 }
6551
6552
6553 static bool do_cmd_knowledge_quests_aux(FILE *fff, floor_type *floor_ptr, IDX q_idx)
6554 {
6555         char tmp_str[120];
6556         char playtime_str[16];
6557         quest_type* const q_ptr = &quest[q_idx];
6558
6559         if (is_fixed_quest_idx(q_idx))
6560         {
6561                 /* Set the quest number temporary */
6562                 IDX old_quest = floor_ptr->inside_quest;
6563
6564                 floor_ptr->inside_quest = q_idx;
6565
6566                 /* Get the quest */
6567                 init_flags = INIT_NAME_ONLY;
6568
6569                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
6570
6571                 /* Reset the old quest number */
6572                 floor_ptr->inside_quest = old_quest;
6573
6574                 /* No info from "silent" quests */
6575                 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
6576         }
6577
6578         strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
6579                 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
6580
6581         if (is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
6582         {
6583                 /* Print the quest info */
6584                 sprintf(tmp_str,
6585                         _("  %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
6586                                 "  %-35s (Danger  level: %3d) - level %2d - %s\n"),
6587                         q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
6588                 fputs(tmp_str, fff);
6589                 return TRUE;
6590         }
6591
6592         /* Print the quest info */
6593         if (q_ptr->complev == 0)
6594         {
6595                 sprintf(tmp_str,
6596                         _("  %-35s (%3d階)            -   不戦勝 - %s\n",
6597                                 "  %-35s (Dungeon level: %3d) - Unearned - %s\n"),
6598                         r_name + r_info[q_ptr->r_idx].name,
6599                         (int)q_ptr->level, playtime_str);
6600         }
6601         else
6602         {
6603                 sprintf(tmp_str,
6604                         _("  %-35s (%3d階)            - レベル%2d - %s\n",
6605                                 "  %-35s (Dungeon level: %3d) - level %2d - %s\n"),
6606                         r_name + r_info[q_ptr->r_idx].name,
6607                         (int)q_ptr->level,
6608                         q_ptr->complev,
6609                         playtime_str);
6610         }
6611
6612         fputs(tmp_str, fff);
6613         return TRUE;
6614 }
6615
6616
6617 /*
6618  * Print all finished quests
6619  * @param creature_ptr プレーヤーへの参照ポインタ
6620  * @param fff セーブファイル (展開済?)
6621  * @param quest_num[] 受注したことのあるクエスト群
6622  * @return なし
6623  */
6624 void do_cmd_knowledge_quests_completed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6625 {
6626         fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
6627         QUEST_IDX total = 0;
6628         for (QUEST_IDX i = 1; i < max_q_idx; i++)
6629         {
6630                 QUEST_IDX q_idx = quest_num[i];
6631                 quest_type* const q_ptr = &quest[q_idx];
6632
6633                 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, creature_ptr->current_floor_ptr, q_idx))
6634                 {
6635                         ++total;
6636                 }
6637         }
6638
6639         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
6640 }
6641
6642
6643 /*
6644  * Print all failed quests
6645  * @param creature_ptr プレーヤーへの参照ポインタ
6646  * @param fff セーブファイル (展開済?)
6647  * @param quest_num[] 受注したことのあるクエスト群
6648  * @return なし
6649 */
6650 void do_cmd_knowledge_quests_failed(player_type *creature_ptr, FILE *fff, QUEST_IDX quest_num[])
6651 {
6652         fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
6653         QUEST_IDX total = 0;
6654         for (QUEST_IDX i = 1; i < max_q_idx; i++)
6655         {
6656                 QUEST_IDX q_idx = quest_num[i];
6657                 quest_type* const q_ptr = &quest[q_idx];
6658
6659                 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
6660                     do_cmd_knowledge_quests_aux(fff, creature_ptr->current_floor_ptr, q_idx))
6661                 {
6662                         ++total;
6663                 }
6664         }
6665
6666         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
6667 }
6668
6669
6670 /*
6671  * Print all random quests
6672  */
6673 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
6674 {
6675         fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
6676         GAME_TEXT tmp_str[120];
6677         QUEST_IDX total = 0;
6678         for (QUEST_IDX i = 1; i < max_q_idx; i++)
6679         {
6680                 /* No info from "silent" quests */
6681                 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
6682
6683                 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
6684                 {
6685                         total++;
6686
6687                         /* Print the quest info */
6688                         sprintf(tmp_str, _("  %s (%d階, %s)\n", "  %s (%d, %s)\n"),
6689                                 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
6690                         fputs(tmp_str, fff);
6691                 }
6692         }
6693
6694         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
6695 }
6696
6697 /*
6698  * Print quest status of all active quests
6699  * @param creature_ptr プレーヤーへの参照ポインタ
6700  * @return なし
6701  */
6702 static void do_cmd_knowledge_quests(player_type *creature_ptr)
6703 {
6704         /* Open a new file */
6705         FILE *fff;
6706         GAME_TEXT file_name[1024];
6707         fff = my_fopen_temp(file_name, 1024);
6708         if (!fff)
6709         {
6710             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6711             msg_print(NULL);
6712             return;
6713         }
6714
6715         /* Allocate Memory */
6716         IDX *quest_num;
6717         C_MAKE(quest_num, max_q_idx, QUEST_IDX);
6718
6719         /* Sort by compete level */
6720         for (IDX i = 1; i < max_q_idx; i++) quest_num[i] = i;
6721         int dummy;
6722         ang_sort(quest_num, &dummy, max_q_idx, ang_sort_comp_quest_num, ang_sort_swap_quest_num);
6723
6724         /* Dump Quest Information */
6725         do_cmd_knowledge_quests_current(creature_ptr, fff);
6726         fputc('\n', fff);
6727         do_cmd_knowledge_quests_completed(creature_ptr, fff, quest_num);
6728         fputc('\n', fff);
6729         do_cmd_knowledge_quests_failed(creature_ptr, fff, quest_num);
6730         if (current_world_ptr->wizard)
6731         {
6732                 fputc('\n', fff);
6733                 do_cmd_knowledge_quests_wiz_random(fff);
6734         }
6735
6736         my_fclose(fff);
6737
6738         /* Display the file contents */
6739         show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
6740         fd_kill(file_name);
6741
6742         /* Free Memory */
6743         C_KILL(quest_num, max_q_idx, QUEST_IDX);
6744 }
6745
6746
6747 /*
6748  * List my home
6749  */
6750 static void do_cmd_knowledge_home(void)
6751 {
6752         process_dungeon_file("w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
6753
6754         /* Open a new file */
6755         FILE *fff;
6756         GAME_TEXT file_name[1024];
6757         fff = my_fopen_temp(file_name, 1024);
6758         if (!fff)
6759         {
6760                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6761                 msg_print(NULL);
6762                 return;
6763         }
6764
6765         /* Print all homes in the different towns */
6766         store_type *st_ptr;
6767         st_ptr = &town_info[1].store[STORE_HOME];
6768
6769         /* Home -- if anything there */
6770         if (st_ptr->stock_num)
6771         {
6772 #ifdef JP
6773                 TERM_LEN x = 1;
6774 #endif
6775                 /* Header with name of the town */
6776                 fprintf(fff, _("  [ 我が家のアイテム ]\n", "  [Home Inventory]\n"));
6777
6778                 /* Dump all available items */
6779                 concptr paren = ")";
6780                 GAME_TEXT o_name[MAX_NLEN];
6781                 for (int i = 0; i < st_ptr->stock_num; i++)
6782                 {
6783 #ifdef JP
6784                         if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
6785                         object_desc(o_name, &st_ptr->stock[i], 0);
6786                         if (strlen(o_name) <= 80 - 3)
6787                         {
6788                                 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6789                         }
6790                         else
6791                         {
6792                                 int n;
6793                                 char *t;
6794                                 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
6795                                         if (iskanji(*t)) { t++; n++; }
6796                                 if (n == 81 - 3) n = 79 - 3; /* 最後が漢字半分 */
6797
6798                                 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
6799                                 fprintf(fff, "   %.77s\n", o_name + n);
6800                         }
6801 #else
6802                         object_desc(o_name, &st_ptr->stock[i], 0);
6803                         fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
6804 #endif
6805                 }
6806
6807                 /* Add an empty line */
6808                 fprintf(fff, "\n\n");
6809         }
6810
6811         my_fclose(fff);
6812
6813         /* Display the file contents */
6814         show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
6815         fd_kill(file_name);
6816 }
6817
6818
6819 /*
6820  * Check the status of "autopick"
6821  */
6822 static void do_cmd_knowledge_autopick(void)
6823 {
6824         /* Open a new file */
6825         FILE *fff;
6826         GAME_TEXT file_name[1024];
6827         fff = my_fopen_temp(file_name, 1024);
6828         if (!fff)
6829         {
6830             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6831             msg_print(NULL);
6832             return;
6833         }
6834
6835         if (!max_autopick)
6836         {
6837             fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
6838         }
6839         else
6840         {
6841                 fprintf(fff, _("   自動拾い/破壊には現在 %d行登録されています。\n\n",
6842                                            "   There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
6843         }
6844
6845         for (int k = 0; k < max_autopick; k++)
6846         {
6847                 concptr tmp;
6848                 byte act = autopick_list[k].action;
6849                 if (act & DONT_AUTOPICK)
6850                 {
6851                         tmp = _("放置", "Leave");
6852                 }
6853                 else if (act & DO_AUTODESTROY)
6854                 {
6855                         tmp = _("破壊", "Destroy");
6856                 }
6857                 else if (act & DO_AUTOPICK)
6858                 {
6859                         tmp = _("拾う", "Pickup");
6860                 }
6861                 else
6862                 {
6863                         tmp = _("確認", "Query");
6864                 }
6865
6866                 if (act & DO_DISPLAY)
6867                         fprintf(fff, "%11s", format("[%s]", tmp));
6868                 else
6869                         fprintf(fff, "%11s", format("(%s)", tmp));
6870
6871                 tmp = autopick_line_from_entry(&autopick_list[k]);
6872                 fprintf(fff, " %s", tmp);
6873                 string_free(tmp);
6874                 fprintf(fff, "\n");
6875         }
6876
6877         my_fclose(fff);
6878
6879         /* Display the file contents */
6880         show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
6881         fd_kill(file_name);
6882 }
6883
6884
6885 /*
6886  * Interact with "knowledge"
6887  */
6888 void do_cmd_knowledge(player_type *creature_ptr)
6889 {
6890         int i, p = 0;
6891         bool need_redraw = FALSE;
6892
6893         /* File type is "TEXT" */
6894         FILE_TYPE(FILE_TYPE_TEXT);
6895         screen_save();
6896
6897         /* Interact until done */
6898         while (TRUE)
6899         {
6900                 Term_clear();
6901
6902                 /* Ask for a choice */
6903                 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
6904                 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
6905
6906                 /* Give some choices */
6907 #ifdef JP
6908                 if (p == 0)
6909                 {
6910                         prt("(1) 既知の伝説のアイテム                 の一覧", 6, 5);
6911                         prt("(2) 既知のアイテム                       の一覧", 7, 5);
6912                         prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
6913                         prt("(4) 既知のモンスター                     の一覧", 9, 5);
6914                         prt("(5) 倒した敵の数                         の一覧", 10, 5);
6915                         if (!vanilla_town) prt("(6) 賞金首                               の一覧", 11, 5);
6916                         prt("(7) 現在のペット                         の一覧", 12, 5);
6917                         prt("(8) 我が家のアイテム                     の一覧", 13, 5);
6918                         prt("(9) *鑑定*済み装備の耐性                 の一覧", 14, 5);
6919                         prt("(0) 地形の表示文字/タイル                の一覧", 15, 5);
6920                 }
6921                 else
6922                 {
6923                         prt("(a) 自分に関する情報                     の一覧", 6, 5);
6924                         prt("(b) 突然変異                             の一覧", 7, 5);
6925                         prt("(c) 武器の経験値                         の一覧", 8, 5);
6926                         prt("(d) 魔法の経験値                         の一覧", 9, 5);
6927                         prt("(e) 技能の経験値                         の一覧", 10, 5);
6928                         prt("(f) プレイヤーの徳                       の一覧", 11, 5);
6929                         prt("(g) 入ったダンジョン                     の一覧", 12, 5);
6930                         prt("(h) 実行中のクエスト                     の一覧", 13, 5);
6931                         prt("(i) 現在の自動拾い/破壊設定              の一覧", 14, 5);
6932                 }
6933 #else
6934                 if (p == 0)
6935                 {
6936                         prt("(1) Display known artifacts", 6, 5);
6937                         prt("(2) Display known objects", 7, 5);
6938                         prt("(3) Display remaining uniques", 8, 5);
6939                         prt("(4) Display known monster", 9, 5);
6940                         prt("(5) Display kill count", 10, 5);
6941                         if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
6942                         prt("(7) Display current pets", 12, 5);
6943                         prt("(8) Display home inventory", 13, 5);
6944                         prt("(9) Display *identified* equip.", 14, 5);
6945                         prt("(0) Display terrain symbols.", 15, 5);
6946                 }
6947                 else
6948                 {
6949                         prt("(a) Display about yourself", 6, 5);
6950                         prt("(b) Display mutations", 7, 5);
6951                         prt("(c) Display weapon proficiency", 8, 5);
6952                         prt("(d) Display spell proficiency", 9, 5);
6953                         prt("(e) Display misc. proficiency", 10, 5);
6954                         prt("(f) Display virtues", 11, 5);
6955                         prt("(g) Display dungeons", 12, 5);
6956                         prt("(h) Display current quests", 13, 5);
6957                         prt("(i) Display auto pick/destroy", 14, 5);
6958                 }
6959 #endif
6960                 /* Prompt */
6961                 prt(_("-続く-", "-more-"), 17, 8);
6962                 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
6963                 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
6964                 /*prt("-) 前ページ", 21, 60);*/
6965                 prt(_("コマンド:", "Command: "), 20, 0);
6966                 i = inkey();
6967
6968                 if (i == ESCAPE) break;
6969                 switch (i)
6970                 {
6971                 case ' ': /* Page change */
6972                 case '-':
6973                         p = 1 - p;
6974                         break;
6975                 case '1': /* Artifacts */
6976                         do_cmd_knowledge_artifacts(creature_ptr);
6977                         break;
6978                 case '2': /* Objects */
6979                         do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
6980                         break;
6981                 case '3': /* Uniques */
6982                         do_cmd_knowledge_uniques();
6983                         break;
6984                 case '4': /* Monsters */
6985                         do_cmd_knowledge_monsters(creature_ptr, &need_redraw, FALSE, -1);
6986                         break;
6987                 case '5': /* Kill count  */
6988                         do_cmd_knowledge_kill_count();
6989                         break;
6990                 case '6': /* wanted */
6991                         if (!vanilla_town) do_cmd_knowledge_kubi(creature_ptr);
6992                         break;
6993                 case '7': /* Pets */
6994                         do_cmd_knowledge_pets(creature_ptr);
6995                         break;
6996                 case '8': /* Home */
6997                         do_cmd_knowledge_home();
6998                         break;
6999                 case '9': /* Resist list */
7000                         do_cmd_knowledge_inven(creature_ptr);
7001                         break;
7002                 case '0': /* Feature list */
7003                         {
7004                                 IDX lighting_level = F_LIT_STANDARD;
7005                                 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
7006                         }
7007                         break;
7008                 /* Next page */
7009                 case 'a': /* Max stat */
7010                         do_cmd_knowledge_stat(creature_ptr);
7011                         break;
7012                 case 'b': /* Mutations */
7013                         do_cmd_knowledge_mutations(creature_ptr);
7014                         break;
7015                 case 'c': /* weapon-exp */
7016                         do_cmd_knowledge_weapon_exp(creature_ptr);
7017                         break;
7018                 case 'd': /* spell-exp */
7019                         do_cmd_knowledge_spell_exp(creature_ptr);
7020                         break;
7021                 case 'e': /* skill-exp */
7022                         do_cmd_knowledge_skill_exp(creature_ptr);
7023                         break;
7024                 case 'f': /* Virtues */
7025                         do_cmd_knowledge_virtues(creature_ptr);
7026                         break;
7027                 case 'g': /* Dungeon */
7028                         do_cmd_knowledge_dungeon();
7029                         break;
7030                 case 'h': /* Quests */
7031                         do_cmd_knowledge_quests(creature_ptr);
7032                         break;
7033                 case 'i': /* Autopick */
7034                         do_cmd_knowledge_autopick();
7035                         break;
7036                 default: /* Unknown option */
7037                         bell();
7038                 }
7039
7040                 msg_erase();
7041         }
7042
7043         screen_load();
7044         if (need_redraw) do_cmd_redraw(creature_ptr);
7045 }
7046
7047
7048 /*
7049  * Check on the status of an active quest
7050  * @param creature_ptr プレーヤーへの参照ポインタ
7051  * @return なし
7052  */
7053 void do_cmd_checkquest(player_type *creature_ptr)
7054 {
7055         /* File type is "TEXT" */
7056         FILE_TYPE(FILE_TYPE_TEXT);
7057         screen_save();
7058
7059         /* Quest info */
7060         do_cmd_knowledge_quests(creature_ptr);
7061         screen_load();
7062 }
7063
7064
7065 /*
7066  * Display the time and date
7067  * @param creature_ptr プレーヤーへの参照ポインタ
7068  * @return なし
7069  */
7070 void do_cmd_time(player_type *creature_ptr)
7071 {
7072         int day, hour, min;
7073         extract_day_hour_min(&day, &hour, &min);
7074
7075         int full = hour * 100 + min;
7076         int start = 9999;
7077         int end = -9999;
7078         int num = 0;
7079
7080         char desc[1024];
7081         strcpy(desc, _("変な時刻だ。", "It is a strange time."));
7082
7083         char day_buf[10];
7084         if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
7085         else strcpy(day_buf, "*****");
7086
7087         msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
7088                    day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
7089
7090         /* Find the path */
7091         char buf[1024];
7092         if (!randint0(10) || creature_ptr->image)
7093         {
7094                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
7095         }
7096         else
7097         {
7098                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
7099         }
7100
7101         /* Open this file */
7102         FILE *fff;
7103         fff = my_fopen(buf, "rt");
7104
7105         if (!fff) return;
7106
7107         /* Find this time */
7108         while (!my_fgets(fff, buf, sizeof(buf)))
7109         {
7110                 /* Ignore comments */
7111                 if (!buf[0] || (buf[0] == '#')) continue;
7112
7113                 /* Ignore invalid lines */
7114                 if (buf[1] != ':') continue;
7115
7116                 /* Process 'Start' */
7117                 if (buf[0] == 'S')
7118                 {
7119                         /* Extract the starting time */
7120                         start = atoi(buf + 2);
7121
7122                         /* Assume valid for an hour */
7123                         end = start + 59;
7124                         continue;
7125                 }
7126
7127                 /* Process 'End' */
7128                 if (buf[0] == 'E')
7129                 {
7130                         /* Extract the ending time */
7131                         end = atoi(buf + 2);
7132                         continue;
7133                 }
7134
7135                 /* Ignore incorrect range */
7136                 if ((start > full) || (full > end)) continue;
7137
7138                 /* Process 'Description' */
7139                 if (buf[0] == 'D')
7140                 {
7141                         num++;
7142
7143                         /* Apply the randomizer */
7144                         if (!randint0(num)) strcpy(desc, buf + 2);
7145                         continue;
7146                 }
7147         }
7148
7149         msg_print(desc);
7150         my_fclose(fff);
7151 }