OSDN Git Service

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