OSDN Git Service

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