OSDN Git Service

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