OSDN Git Service

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