OSDN Git Service

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