OSDN Git Service

#37287 #37353 (2.2.0.89) QUANTITY 型を定義し、型の置換を継続中。 / Define QUANTITY, ongoing type...
[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):", (int)dun_level, d_name+d_info[dungeon_type].name);
435 #else
436                         sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
437 #endif
438                         note_level = note_level_buf;
439                 }
440         }
441
442         switch(type)
443         {
444                 case NIKKI_HIGAWARI:
445                 {
446                         if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
447                         else fputs(_("*****日目\n", "Day *****\n"), fff);
448                         do_level = FALSE;
449                         break;
450                 }
451                 case NIKKI_BUNSHOU:
452                 {
453                         if (num)
454                         {
455                                 fprintf(fff, "%s\n",note);
456                                 do_level = FALSE;
457                         }
458                         else
459                                 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
460                         break;
461                 }
462                 case NIKKI_ART:
463                 {
464                         fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
465                         break;
466                 }
467                 case NIKKI_ART_SCROLL:
468                 {
469                         fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
470                         break;
471                 }
472                 case NIKKI_UNIQUE:
473                 {
474                         fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
475                         break;
476                 }
477                 case NIKKI_FIX_QUEST_C:
478                 {
479                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
480                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
481                                                    " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
482                         break;
483                 }
484                 case NIKKI_FIX_QUEST_F:
485                 {
486                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
487                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
488                                                    " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
489                         break;
490                 }
491                 case NIKKI_RAND_QUEST_C:
492                 {
493                         char name[80];
494                         strcpy(name, r_name+r_info[quest[num].r_idx].name);
495                         fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
496                                                    " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
497                         break;
498                 }
499                 case NIKKI_RAND_QUEST_F:
500                 {
501                         char name[80];
502                         strcpy(name, r_name+r_info[quest[num].r_idx].name);
503                         fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
504                                                    " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
505                         break;
506                 }
507                 case NIKKI_MAXDEAPTH:
508                 {
509                         fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
510                                                    " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
511                                                    _(d_name+d_info[dungeon_type].name, num),
512                                                    _(num, d_name+d_info[dungeon_type].name));
513                         break;
514                 }
515                 case NIKKI_TRUMP:
516                 {
517                         fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
518                                                    " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
519                                                    _(d_name + d_info[num].name, (int)max_dlv[num]),
520                                                    _((int)max_dlv[num], d_name + d_info[num].name));
521                         break;
522                 }
523                 case NIKKI_STAIR:
524                 {
525                         cptr to;
526                         if (q_idx && (is_fixed_quest_idx(q_idx)
527                              && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
528                         {
529                                 to = _("地上", "the surface");
530                         }
531                         else
532                         {
533                                 if (!(dun_level+num)) to = _("地上", "the surface");
534                                 else to = format(_("%d階", "level %d"), dun_level+num);
535                         }
536                         fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
537                         break;
538                 }
539                 case NIKKI_RECALL:
540                 {
541                         if (!num)
542                         fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"), 
543                                                 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]), 
544                                                                                            _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
545                         else
546                                 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
547                         break;
548                 }
549                 case NIKKI_TO_QUEST:
550                 {
551                         if (quest[num].flags & QUEST_FLAG_SILENT) break;
552                         fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
553                                                 hour, min, note_level, quest[num].name);
554                         break;
555                 }
556                 case NIKKI_TELE_LEV:
557                 {
558                         fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
559                                                 hour, min, note_level);
560                         break;
561                 }
562                 case NIKKI_BUY:
563                 {
564                         fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
565                         break;
566                 }
567                 case NIKKI_SELL:
568                 {
569                         fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
570                         break;
571                 }
572                 case NIKKI_ARENA:
573                 {
574                         if (num < 0)
575                         {
576                                 int n = -num;
577                                 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
578                                                         hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
579                                 break;
580                         }
581                         fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
582                                                 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
583                         
584                         if (num == MAX_ARENA_MONS)
585                         {
586                                 fprintf(fff, _("                 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
587                                                            "                 won all fight to become a Chanpion.\n"));
588                                 do_level = FALSE;
589                         }
590                         break;
591                 }
592                 case NIKKI_HANMEI:
593                 {
594                         fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
595                         break;
596                 }
597                 case NIKKI_WIZ_TELE:
598                 {
599                         cptr to;
600                         if (!dun_level)
601                                 to = _("地上", "the surface");
602                         else
603                                 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
604
605                         fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
606                                                    " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
607                         break;
608                 }
609                 case NIKKI_PAT_TELE:
610                 {
611                         cptr to;
612                         if (!dun_level)
613                                 to = _("地上", "the surface");
614                         else
615                                 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
616
617                         fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
618                                                    " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
619                         break;
620                 }
621                 case NIKKI_LEVELUP:
622                 {
623                         fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
624                         break;
625                 }
626                 case NIKKI_GAMESTART:
627                 {
628                         time_t ct = time((time_t*)0);
629                         do_level = FALSE;
630                         if (num)
631                         {
632                                 fprintf(fff, "%s %s",note, ctime(&ct));
633                         }
634                         else
635                                 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
636                         break;
637                 }
638                 case NIKKI_NAMED_PET:
639                 {
640                         fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
641                         switch (num)
642                         {
643                                 case RECORD_NAMED_PET_NAME:
644                                         fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
645                                         break;
646                                 case RECORD_NAMED_PET_UNNAME:
647                                         fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
648                                         break;
649                                 case RECORD_NAMED_PET_DISMISS:
650                                         fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
651                                         break;
652                                 case RECORD_NAMED_PET_DEATH:
653                                         fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
654                                         break;
655                                 case RECORD_NAMED_PET_MOVED:
656                                         fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
657                                         break;
658                                 case RECORD_NAMED_PET_LOST_SIGHT:
659                                         fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
660                                         break;
661                                 case RECORD_NAMED_PET_DESTROY:
662                                         fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
663                                         break;
664                                 case RECORD_NAMED_PET_EARTHQUAKE:
665                                         fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
666                                         break;
667                                 case RECORD_NAMED_PET_GENOCIDE:
668                                         fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
669                                         break;
670                                 case RECORD_NAMED_PET_WIZ_ZAP:
671                                         fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
672                                         break;
673                                 case RECORD_NAMED_PET_TELE_LEVEL:
674                                         fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
675                                         break;
676                                 case RECORD_NAMED_PET_BLAST:
677                                         fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
678                                         break;
679                                 case RECORD_NAMED_PET_HEAL_LEPER:
680                                         fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
681                                         break;
682                                 case RECORD_NAMED_PET_COMPACT:
683                                         fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
684                                         break;
685                                 case RECORD_NAMED_PET_LOSE_PARENT:
686                                         fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
687                                         break;
688
689
690                                 default:
691                                         fprintf(fff, "\n");
692                                         break;
693                         }
694                         break;
695                 }
696
697                 case NIKKI_WIZARD_LOG:
698                         fprintf(fff, "%s\n", note);
699                         break;
700
701                 default:
702                         break;
703         }
704
705         my_fclose(fff);
706
707         if (do_level) write_level = FALSE;
708
709         return (0);
710 }
711
712
713 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
714
715 /*!
716  * @brief 日記のタイトル表記と内容出力 /
717  * @return なし
718  * @details
719  * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
720  */
721 static void do_cmd_disp_nikki(void)
722 {
723         char nikki_title[256];
724         char file_name[80];
725         char buf[1024];
726         char tmp[80];
727 #ifdef JP
728         /*! */
729         static const char subtitle[][30] = {"最強の肉体を求めて",
730                                            "人生それははかない",
731                                            "明日に向かって",
732                                            "棚からぼたもち",
733                                            "あとの祭り",
734                                            "それはいい考えだ",
735                                            "何とでも言え",
736                                            "兎にも角にも",
737                                            "ウソだけど",
738                                            "もはやこれまで",
739                                            "なんでこうなるの",
740                                            "それは無理だ",
741                                            "倒すべき敵はゲ○ツ",
742                                            "ん~?聞こえんなぁ",
743                                            "オレの名を言ってみろ",
744                                            "頭が変になっちゃった",
745                                            "互換しません",
746                                            "せっかくだから",
747                                            "まだまだ甘いね",
748                                            "むごいむごすぎる",
749                                            "こんなもんじゃない",
750                                            "だめだこりゃ",
751                                            "次いってみよう",
752                                            "ちょっとだけよ",
753                                            "哀しき冒険者",
754                                            "野望の果て",
755                                            "無限地獄",
756                                            "神に喧嘩を売る者",
757                                            "未知の世界へ",
758                                            "最高の頭脳を求めて"};
759 #else
760         static const char subtitle[][51] ={"Quest of The World's Toughest Body",
761                                            "Attack is the best form of defence.",
762                                            "Might is right.",
763                                            "An unexpected windfall",
764                                            "A drowning man will catch at a straw",
765                                            "Don't count your chickens before they are hatched.",
766                                            "It is no use crying over spilt milk.",
767                                            "Seeing is believing.",
768                                            "Strike the iron while it is hot.",
769                                            "I don't care what follows.",
770                                            "To dig a well to put out a house on fire.",
771                                            "Tomorrow is another day.",
772                                            "Easy come, easy go.",
773                                            "The more haste, the less speed.",
774                                            "Where there is life, there is hope.",
775                                            "There is no royal road to *WINNER*.",
776                                            "Danger past, God forgotten.",
777                                            "The best thing to do now is to run away.",
778                                            "Life is but an empty dream.",
779                                            "Dead men tell no tales.",
780                                            "A book that remains shut is but a block.",
781                                            "Misfortunes never come singly.",
782                                            "A little knowledge is a dangerous thing.",
783                                            "History repeats itself.",
784                                            "*WINNER* was not built in a day.",
785                                            "Ignorance is bliss.",
786                                            "To lose is to win?",
787                                            "No medicine can cure folly.",
788                                            "All good things come to an end.",
789                                            "M$ Empire strikes back.",
790                                            "To see is to believe",
791                                            "Time is money.",
792                                            "Quest of The World's Greatest Brain"};
793 #endif
794         sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
795
796         /* Build the filename */
797         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
798
799         if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
800                 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
801         else if (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] = (char)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, IDX *num, IDX max)
3092 {
3093         if (iscntrl(i))
3094         {
3095                 char str[10] = "";
3096                 IDX 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 = (IDX)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, IDX direct_r_idx);
3146 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
3147 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
3148
3149 /*
3150  * Interact with "visuals"
3151  */
3152 void do_cmd_visuals(void)
3153 {
3154         char 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                         IDX k_idx;
3263
3264                         /* Prompt */
3265                         prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3266
3267                         /* Prompt */
3268                         prt(_("ファイル: ", "File: "), 17, 0);
3269
3270                         /* Default filename */
3271                         sprintf(tmp, "%s.prf", player_base);
3272
3273                         /* Get a filename */
3274                         if (!askfor(tmp, 70)) continue;
3275
3276                         /* Build the filename */
3277                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3278
3279                         /* Append to the file */
3280                         if (!open_auto_dump(buf, mark)) continue;
3281
3282                         /* Start dumping */
3283                         auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3284
3285                         /* Dump objects */
3286                         for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3287                         {
3288                                 char o_name[80];
3289                                 object_kind *k_ptr = &k_info[k_idx];
3290
3291                                 /* Skip non-entries */
3292                                 if (!k_ptr->name) continue;
3293
3294                                 if (!k_ptr->flavor)
3295                                 {
3296                                         /* Tidy name */
3297                                         strip_name(o_name, k_idx);
3298                                 }
3299                                 else
3300                                 {
3301                                         object_type forge;
3302
3303                                         /* Prepare dummy object */
3304                                         object_prep(&forge, k_idx);
3305
3306                                         /* Get un-shuffled flavor name */
3307                                         object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3308                                 }
3309
3310                                 /* Dump a comment */
3311                                 auto_dump_printf("# %s\n", o_name);
3312
3313                                 /* Dump the object attr/char info */
3314                                 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3315                                         (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3316                         }
3317
3318                         /* Close */
3319                         close_auto_dump();
3320
3321                         /* Message */
3322                         msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3323
3324                         break;
3325                 }
3326
3327                 /* Dump feature attr/chars */
3328                 case '3':
3329                 {
3330                         static cptr mark = "Feature attr/chars";
3331
3332                         /* Prompt */
3333                         prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3334
3335                         /* Prompt */
3336                         prt(_("ファイル: ", "File: "), 17, 0);
3337
3338                         /* Default filename */
3339                         sprintf(tmp, "%s.prf", player_base);
3340
3341                         /* Get a filename */
3342                         if (!askfor(tmp, 70)) continue;
3343
3344                         /* Build the filename */
3345                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3346
3347                         /* Append to the file */
3348                         if (!open_auto_dump(buf, mark)) continue;
3349
3350                         /* Start dumping */
3351                         auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3352
3353                         /* Dump features */
3354                         for (i = 0; i < max_f_idx; i++)
3355                         {
3356                                 feature_type *f_ptr = &f_info[i];
3357
3358                                 /* Skip non-entries */
3359                                 if (!f_ptr->name) continue;
3360
3361                                 /* Skip mimiccing features */
3362                                 if (f_ptr->mimic != i) continue;
3363
3364                                 /* Dump a comment */
3365                                 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3366
3367                                 /* Dump the feature attr/char info */
3368                                 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3369                                         (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3370                                         (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3371                                         (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3372                         }
3373
3374                         /* Close */
3375                         close_auto_dump();
3376
3377                         /* Message */
3378                         msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3379
3380                         break;
3381                 }
3382
3383                 /* Modify monster attr/chars (numeric operation) */
3384                 case '4':
3385                 {
3386                         static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3387                         static IDX r = 0;
3388
3389                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3390
3391                         /* Hack -- query until done */
3392                         while (1)
3393                         {
3394                                 monster_race *r_ptr = &r_info[r];
3395                                 char c;
3396                                 IDX t;
3397
3398                                 byte da = r_ptr->d_attr;
3399                                 byte dc = r_ptr->d_char;
3400                                 byte ca = r_ptr->x_attr;
3401                                 byte cc = r_ptr->x_char;
3402
3403                                 /* Label the object */
3404                                 Term_putstr(5, 17, -1, TERM_WHITE,
3405                                          format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3406
3407                                 /* Label the Default values */
3408                                 Term_putstr(10, 19, -1, TERM_WHITE,
3409                                         format(_("初期値  色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3410
3411                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3412                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3413
3414                                 /* Label the Current values */
3415                                 Term_putstr(10, 20, -1, TERM_WHITE,
3416                                         format(_("現在値  色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3417
3418                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3419                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3420
3421                                 /* Prompt */
3422                                 Term_putstr(0, 22, -1, TERM_WHITE, 
3423                                         _("コマンド (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): "));
3424
3425                                 /* Get a command */
3426                                 i = inkey();
3427
3428                                 /* All done */
3429                                 if (i == ESCAPE) break;
3430
3431                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3432                                 else if (isupper(i)) c = 'a' + i - 'A';
3433                                 else c = i;
3434
3435                                 switch (c)
3436                                 {
3437                                 case 'n':
3438                                         {
3439                                                 IDX prev_r = r;
3440                                                 do
3441                                                 {
3442                                                         if (!cmd_visuals_aux(i, &r, max_r_idx))
3443                                                         {
3444                                                                 r = prev_r;
3445                                                                 break;
3446                                                         }
3447                                                 }
3448                                                 while (!r_info[r].name);
3449                                         }
3450                                         break;
3451                                 case 'a':
3452                                         t = (int)r_ptr->x_attr;
3453                                         (void)cmd_visuals_aux(i, &t, 256);
3454                                         r_ptr->x_attr = (byte)t;
3455                                         need_redraw = TRUE;
3456                                         break;
3457                                 case 'c':
3458                                         t = (int)r_ptr->x_char;
3459                                         (void)cmd_visuals_aux(i, &t, 256);
3460                                         r_ptr->x_char = (byte)t;
3461                                         need_redraw = TRUE;
3462                                         break;
3463                                 case 'v':
3464                                         do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3465
3466                                         /* Clear screen */
3467                                         Term_clear();
3468                                         print_visuals_menu(choice_msg);
3469                                         break;
3470                                 }
3471                         }
3472
3473                         break;
3474                 }
3475
3476                 /* Modify object attr/chars (numeric operation) */
3477                 case '5':
3478                 {
3479                         static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3480                         static IDX k = 0;
3481                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3482
3483                         /* Hack -- query until done */
3484                         while (1)
3485                         {
3486                                 object_kind *k_ptr = &k_info[k];
3487                                 char c;
3488                                 IDX t;
3489
3490                                 SYMBOL_COLOR da = k_ptr->d_attr;
3491                                 SYMBOL_CODE dc = k_ptr->d_char;
3492                                 SYMBOL_COLOR ca = k_ptr->x_attr;
3493                                 SYMBOL_CODE cc = k_ptr->x_char;
3494
3495                                 /* Label the object */
3496                                 Term_putstr(5, 17, -1, TERM_WHITE,
3497                                             format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3498                                                    k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3499
3500                                 /* Label the Default values */
3501                                 Term_putstr(10, 19, -1, TERM_WHITE,
3502                                             format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3503
3504                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3505                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3506
3507                                 /* Label the Current values */
3508                                 Term_putstr(10, 20, -1, TERM_WHITE,
3509                                             format(_("現在値  色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3510
3511                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3512                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3513
3514                                 /* Prompt */
3515                                 Term_putstr(0, 22, -1, TERM_WHITE,
3516                                             _("コマンド (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): "));
3517
3518                                 /* Get a command */
3519                                 i = inkey();
3520
3521                                 /* All done */
3522                                 if (i == ESCAPE) break;
3523
3524                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3525                                 else if (isupper(i)) c = 'a' + i - 'A';
3526                                 else c = i;
3527
3528                                 switch (c)
3529                                 {
3530                                 case 'n':
3531                                         {
3532                                                 IDX prev_k = k;
3533                                                 do
3534                                                 {
3535                                                         if (!cmd_visuals_aux(i, &k, max_k_idx))
3536                                                         {
3537                                                                 k = prev_k;
3538                                                                 break;
3539                                                         }
3540                                                 }
3541                                                 while (!k_info[k].name);
3542                                         }
3543                                         break;
3544                                 case 'a':
3545                                         t = (int)k_ptr->x_attr;
3546                                         (void)cmd_visuals_aux(i, &t, 256);
3547                                         k_ptr->x_attr = (byte)t;
3548                                         need_redraw = TRUE;
3549                                         break;
3550                                 case 'c':
3551                                         t = (int)k_ptr->x_char;
3552                                         (void)cmd_visuals_aux(i, &t, 256);
3553                                         k_ptr->x_char = (byte)t;
3554                                         need_redraw = TRUE;
3555                                         break;
3556                                 case 'v':
3557                                         do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3558
3559                                         /* Clear screen */
3560                                         Term_clear();
3561                                         print_visuals_menu(choice_msg);
3562                                         break;
3563                                 }
3564                         }
3565
3566                         break;
3567                 }
3568
3569                 /* Modify feature attr/chars (numeric operation) */
3570                 case '6':
3571                 {
3572                         static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3573                         static IDX f = 0;
3574                         static IDX lighting_level = F_LIT_STANDARD;
3575                         prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3576
3577                         /* Hack -- query until done */
3578                         while (1)
3579                         {
3580                                 feature_type *f_ptr = &f_info[f];
3581                                 char c;
3582                                 IDX t;
3583
3584                                 byte da = f_ptr->d_attr[lighting_level];
3585                                 byte dc = f_ptr->d_char[lighting_level];
3586                                 byte ca = f_ptr->x_attr[lighting_level];
3587                                 byte cc = f_ptr->x_char[lighting_level];
3588
3589                                 /* Label the object */
3590                                 prt("", 17, 5);
3591                                 Term_putstr(5, 17, -1, TERM_WHITE,
3592                                             format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3593                                                    f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3594
3595                                 /* Label the Default values */
3596                                 Term_putstr(10, 19, -1, TERM_WHITE,
3597                                             format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3598
3599                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3600                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3601
3602                                 /* Label the Current values */
3603 #ifdef JP
3604                                 Term_putstr(10, 20, -1, TERM_WHITE,
3605                                             format("現在値  色 / 文字 = %3d / %3d", ca, cc));
3606 #else
3607                                 Term_putstr(10, 20, -1, TERM_WHITE,
3608                                             format("Current attr/char = %3d / %3d", ca, cc));
3609 #endif
3610
3611                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3612                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3613
3614                                 /* Prompt */
3615 #ifdef JP
3616                                 Term_putstr(0, 22, -1, TERM_WHITE,
3617                                             "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3618 #else
3619                                 Term_putstr(0, 22, -1, TERM_WHITE,
3620                                             "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3621 #endif
3622
3623                                 /* Get a command */
3624                                 i = inkey();
3625
3626                                 /* All done */
3627                                 if (i == ESCAPE) break;
3628
3629                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3630                                 else if (isupper(i)) c = 'a' + i - 'A';
3631                                 else c = i;
3632
3633                                 switch (c)
3634                                 {
3635                                 case 'n':
3636                                         {
3637                                                 IDX prev_f = f;
3638                                                 do
3639                                                 {
3640                                                         if (!cmd_visuals_aux(i, &f, max_f_idx))
3641                                                         {
3642                                                                 f = prev_f;
3643                                                                 break;
3644                                                         }
3645                                                 }
3646                                                 while (!f_info[f].name || (f_info[f].mimic != f));
3647                                         }
3648                                         break;
3649                                 case 'a':
3650                                         t = (int)f_ptr->x_attr[lighting_level];
3651                                         (void)cmd_visuals_aux(i, &t, 256);
3652                                         f_ptr->x_attr[lighting_level] = (byte)t;
3653                                         need_redraw = TRUE;
3654                                         break;
3655                                 case 'c':
3656                                         t = (int)f_ptr->x_char[lighting_level];
3657                                         (void)cmd_visuals_aux(i, &t, 256);
3658                                         f_ptr->x_char[lighting_level] = (byte)t;
3659                                         need_redraw = TRUE;
3660                                         break;
3661                                 case 'l':
3662                                         (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3663                                         break;
3664                                 case 'd':
3665                                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3666                                         need_redraw = TRUE;
3667                                         break;
3668                                 case 'v':
3669                                         do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3670
3671                                         /* Clear screen */
3672                                         Term_clear();
3673                                         print_visuals_menu(choice_msg);
3674                                         break;
3675                                 }
3676                         }
3677
3678                         break;
3679                 }
3680
3681                 /* Modify monster attr/chars (visual mode) */
3682                 case '7':
3683                         do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3684                         break;
3685
3686                 /* Modify object attr/chars (visual mode) */
3687                 case '8':
3688                         do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3689                         break;
3690
3691                 /* Modify feature attr/chars (visual mode) */
3692                 case '9':
3693                 {
3694                         IDX lighting_level = F_LIT_STANDARD;
3695                         do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3696                         break;
3697                 }
3698
3699 #endif /* ALLOW_VISUALS */
3700
3701                 /* Reset visuals */
3702                 case 'R':
3703                 case 'r':
3704                         /* Reset */
3705                         reset_visuals();
3706
3707                         /* Message */
3708                         msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3709                         need_redraw = TRUE;
3710                         break;
3711
3712                 /* Unknown option */
3713                 default:
3714                         bell();
3715                         break;
3716                 }
3717
3718                 /* Flush messages */
3719                 msg_print(NULL);
3720         }
3721
3722         /* Restore the screen */
3723         screen_load();
3724
3725         if (need_redraw) do_cmd_redraw();
3726 }
3727
3728
3729 /*
3730  * Interact with "colors"
3731  */
3732 void do_cmd_colors(void)
3733 {
3734         int i;
3735
3736         char tmp[160];
3737
3738         char buf[1024];
3739
3740
3741         /* File type is "TEXT" */
3742         FILE_TYPE(FILE_TYPE_TEXT);
3743
3744
3745         /* Save the screen */
3746         screen_save();
3747
3748
3749         /* Interact until done */
3750         while (1)
3751         {
3752                 /* Clear screen */
3753                 Term_clear();
3754
3755                 /* Ask for a choice */
3756                 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3757
3758                 /* Give some choices */
3759                 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3760
3761 #ifdef ALLOW_COLORS
3762                 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3763                 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3764 #endif
3765
3766                 /* Prompt */
3767                 prt(_("コマンド: ", "Command: "), 8, 0);
3768                 /* Prompt */
3769                 i = inkey();
3770
3771                 /* Done */
3772                 if (i == ESCAPE) break;
3773
3774                 /* Load a 'pref' file */
3775                 if (i == '1')
3776                 {
3777                         /* Prompt */
3778                         prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3779
3780                         /* Prompt */
3781                         prt(_("ファイル: ", "File: "), 10, 0);
3782
3783                         /* Default file */
3784                         sprintf(tmp, "%s.prf", player_base);
3785
3786                         /* Query */
3787                         if (!askfor(tmp, 70)) continue;
3788
3789                         /* Process the given filename */
3790                         (void)process_pref_file(tmp);
3791
3792                         /* Mega-Hack -- react to changes */
3793                         Term_xtra(TERM_XTRA_REACT, 0);
3794
3795                         /* Mega-Hack -- redraw */
3796                         Term_redraw();
3797                 }
3798
3799 #ifdef ALLOW_COLORS
3800
3801                 /* Dump colors */
3802                 else if (i == '2')
3803                 {
3804                         static cptr mark = "Colors";
3805
3806                         /* Prompt */
3807                         prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3808
3809                         /* Prompt */
3810                         prt(_("ファイル: ", "File: "), 10, 0);
3811
3812                         /* Default filename */
3813                         sprintf(tmp, "%s.prf", player_base);
3814
3815                         /* Get a filename */
3816                         if (!askfor(tmp, 70)) continue;
3817
3818                         /* Build the filename */
3819                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3820
3821                         /* Append to the file */
3822                         if (!open_auto_dump(buf, mark)) continue;
3823
3824                         /* Start dumping */
3825                         auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3826                         
3827                         /* Dump colors */
3828                         for (i = 0; i < 256; i++)
3829                         {
3830                                 int kv = angband_color_table[i][0];
3831                                 int rv = angband_color_table[i][1];
3832                                 int gv = angband_color_table[i][2];
3833                                 int bv = angband_color_table[i][3];
3834
3835                                 cptr name = _("未知", "unknown");
3836
3837                                 /* Skip non-entries */
3838                                 if (!kv && !rv && !gv && !bv) continue;
3839
3840                                 /* Extract the color name */
3841                                 if (i < 16) name = color_names[i];
3842
3843                                 /* Dump a comment */
3844                                 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3845                                 
3846                                 /* Dump the monster attr/char info */
3847                                 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3848                                         i, kv, rv, gv, bv);
3849                         }
3850
3851                         /* Close */
3852                         close_auto_dump();
3853
3854                         /* Message */
3855                         msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3856                 }
3857
3858                 /* Edit colors */
3859                 else if (i == '3')
3860                 {
3861                         static byte a = 0;
3862
3863                         /* Prompt */
3864                         prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3865
3866                         /* Hack -- query until done */
3867                         while (1)
3868                         {
3869                                 cptr name;
3870                                 byte j;
3871
3872                                 /* Clear */
3873                                 clear_from(10);
3874
3875                                 /* Exhibit the normal colors */
3876                                 for (j = 0; j < 16; j++)
3877                                 {
3878                                         /* Exhibit this color */
3879                                         Term_putstr(j*4, 20, -1, a, "###");
3880
3881                                         /* Exhibit all colors */
3882                                         Term_putstr(j*4, 22, -1, j, format("%3d", j));
3883                                 }
3884
3885                                 /* Describe the color */
3886                                 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3887
3888                                 /* Describe the color */
3889                                 Term_putstr(5, 10, -1, TERM_WHITE,
3890                                             format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3891
3892                                 /* Label the Current values */
3893                                 Term_putstr(5, 12, -1, TERM_WHITE,
3894                                             format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3895                                                    angband_color_table[a][0],
3896                                                    angband_color_table[a][1],
3897                                                    angband_color_table[a][2],
3898                                                    angband_color_table[a][3]));
3899
3900                                 /* Prompt */
3901                                 Term_putstr(0, 14, -1, TERM_WHITE,
3902                                         _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3903
3904
3905                                 /* Get a command */
3906                                 i = inkey();
3907
3908                                 /* All done */
3909                                 if (i == ESCAPE) break;
3910
3911                                 /* Analyze */
3912                                 if (i == 'n') a = (byte)(a + 1);
3913                                 if (i == 'N') a = (byte)(a - 1);
3914                                 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3915                                 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3916                                 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3917                                 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3918                                 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3919                                 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3920                                 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3921                                 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3922
3923                                 /* Hack -- react to changes */
3924                                 Term_xtra(TERM_XTRA_REACT, 0);
3925
3926                                 /* Hack -- redraw */
3927                                 Term_redraw();
3928                         }
3929                 }
3930
3931 #endif
3932
3933                 /* Unknown option */
3934                 else
3935                 {
3936                         bell();
3937                 }
3938
3939                 /* Flush messages */
3940                 msg_print(NULL);
3941         }
3942
3943
3944         /* Restore the screen */
3945         screen_load();
3946 }
3947
3948
3949 /*
3950  * Note something in the message recall
3951  */
3952 void do_cmd_note(void)
3953 {
3954         char buf[80];
3955
3956         /* Default */
3957         strcpy(buf, "");
3958
3959         /* Input */
3960         if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3961
3962         /* Ignore empty notes */
3963         if (!buf[0] || (buf[0] == ' ')) return;
3964
3965         /* Add the note to the message recall */
3966         msg_format(_("メモ: %s", "Note: %s"), buf);
3967 }
3968
3969
3970 /*
3971  * Mention the current version
3972  */
3973 void do_cmd_version(void)
3974 {
3975         /* Silly message */
3976
3977 #if FAKE_VER_EXTRA > 0
3978         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3979                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3980 #else
3981         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3982                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3983 #endif
3984 }
3985
3986
3987
3988 /*
3989  * Array of feeling strings
3990  */
3991 static cptr do_cmd_feeling_text[11] =
3992 {
3993         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3994         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3995         _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3996         _("この階はとても危険なようだ。", "This level looks very dangerous."),
3997         _("とても悪い予感がする...", "You have a very bad feeling..."),
3998         _("悪い予感がする...", "You have a bad feeling..."),
3999         _("何か緊張する。", "You feel nervous."),
4000         _("少し不運な気がする...", "You feel your luck is turning..."),
4001         _("この場所は好きになれない。", "You don't like the look of this place."),
4002         _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
4003         _("なんて退屈なところだ...", "What a boring place...")
4004 };
4005
4006 static cptr do_cmd_feeling_text_combat[11] =
4007 {
4008         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
4009         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
4010         _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
4011         _("この階はとても危険なようだ。", "This level looks very dangerous."),
4012         _("とても悪い予感がする...", "You have a very bad feeling..."),
4013         _("悪い予感がする...", "You have a bad feeling..."),
4014         _("何か緊張する。", "You feel nervous."),
4015         _("少し不運な気がする...", "You feel your luck is turning..."),
4016         _("この場所は好きになれない。", "You don't like the look of this place."),
4017         _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
4018         _("なんて退屈なところだ...", "What a boring place...")
4019 };
4020
4021 static cptr do_cmd_feeling_text_lucky[11] =
4022 {
4023         _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
4024         _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
4025         _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
4026         _("素晴らしい感じがする...", "You have an excellent feeling..."),
4027         _("とても良い感じがする...", "You have a very good feeling..."),
4028         _("良い感じがする...", "You have a good feeling..."),
4029         _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
4030         _("多少は運が向いてきたか...", "You feel your luck is turning..."),
4031         _("見た感じ悪くはない...", "You like the look of this place..."),
4032         _("全然駄目ということはないが...", "This level can't be all bad..."),
4033         _("なんて退屈なところだ...", "What a boring place...")
4034 };
4035
4036
4037 /*
4038  * Note that "feeling" is set to zero unless some time has passed.
4039  * Note that this is done when the level is GENERATED, not entered.
4040  */
4041 void do_cmd_feeling(void)
4042 {
4043         /* No useful feeling in quests */
4044         if (p_ptr->inside_quest && !random_quest_number(dun_level))
4045         {
4046                 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
4047                 return;
4048         }
4049
4050         /* No useful feeling in town */
4051         else if (p_ptr->town_num && !dun_level)
4052         {
4053                 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
4054                 {
4055                         msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
4056                         return;
4057                 }
4058                 else
4059                 {
4060                         msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
4061                         return;
4062                 }
4063         }
4064
4065         /* No useful feeling in the wilderness */
4066         else if (!dun_level)
4067         {
4068                 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
4069                 return;
4070         }
4071
4072         /* Display the feeling */
4073         if (p_ptr->muta3 & MUT3_GOOD_LUCK)
4074                 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
4075         else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
4076                  inventory[INVEN_BOW].name1 == ART_CRIMSON)
4077                 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
4078         else
4079                 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
4080 }
4081
4082
4083
4084 /*
4085  * Description of each monster group.
4086  */
4087 static cptr monster_group_text[] = 
4088 {
4089 #ifdef JP
4090         "ユニーク", /* "Uniques" */
4091         "乗馬可能なモンスター",       /* "Riding" */
4092         "賞金首", /* "Wanted */
4093         "アンバーの王族", /* "Ambertite" */
4094         "アリ",
4095         "コウモリ",
4096         "ムカデ",
4097         "ドラゴン",
4098         "目玉",
4099         "ネコ",
4100         "ゴーレム",
4101         "標準人間型生物",
4102         "ベトベト",
4103         "ゼリー",
4104         "コボルド",
4105         "水棲生物",
4106         "モルド",
4107         "ナーガ",
4108         "オーク",
4109         "人間",
4110         "四足獣",
4111         "ネズミ",
4112         "スケルトン",
4113         "デーモン",
4114         "ボルテックス",
4115         "イモムシ/大群",
4116         /* "unused", */
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         "プレイヤー",
4150 #else
4151         "Uniques",
4152         "Ridable monsters",
4153         "Wanted monsters",
4154         "Ambertite",
4155         "Ant",
4156         "Bat",
4157         "Centipede",
4158         "Dragon",
4159         "Floating Eye",
4160         "Feline",
4161         "Golem",
4162         "Hobbit/Elf/Dwarf",
4163         "Icky Thing",
4164         "Jelly",
4165         "Kobold",
4166         "Aquatic monster",
4167         "Mold",
4168         "Naga",
4169         "Orc",
4170         "Person/Human",
4171         "Quadruped",
4172         "Rodent",
4173         "Skeleton",
4174         "Demon",
4175         "Vortex",
4176         "Worm/Worm-Mass",
4177         /* "unused", */
4178         "Yeek",
4179         "Zombie/Mummy",
4180         "Angel",
4181         "Bird",
4182         "Canine",
4183         /* "Ancient Dragon/Wyrm", */
4184         "Elemental",
4185         "Dragon Fly",
4186         "Ghost",
4187         "Hybrid",
4188         "Insect",
4189         "Snake",
4190         "Killer Beetle",
4191         "Lich",
4192         "Multi-Headed Reptile",
4193         "Mystery Living",
4194         "Ogre",
4195         "Giant Humanoid",
4196         "Quylthulg",
4197         "Reptile/Amphibian",
4198         "Spider/Scorpion/Tick",
4199         "Troll",
4200         /* "Major Demon", */
4201         "Vampire",
4202         "Wight/Wraith/etc",
4203         "Xorn/Xaren/etc",
4204         "Yeti",
4205         "Zephyr Hound",
4206         "Mimic",
4207         "Wall/Plant/Gas",
4208         "Mushroom patch",
4209         "Ball",
4210         "Player",
4211 #endif
4212         NULL
4213 };
4214
4215
4216 /*
4217  * Symbols of monsters in each group. Note the "Uniques" group
4218  * is handled differently.
4219  */
4220 static cptr monster_group_char[] =
4221 {
4222         (char *) -1L,
4223         (char *) -2L,
4224         (char *) -3L,
4225         (char *) -4L,
4226         "a",
4227         "b",
4228         "c",
4229         "dD",
4230         "e",
4231         "f",
4232         "g",
4233         "h",
4234         "i",
4235         "j",
4236         "k",
4237         "l",
4238         "m",
4239         "n",
4240         "o",
4241         "pt",
4242         "q",
4243         "r",
4244         "s",
4245         "uU",
4246         "v",
4247         "w",
4248         /* "x", */
4249         "y",
4250         "z",
4251         "A",
4252         "B",
4253         "C",
4254         /* "D", */
4255         "E",
4256         "F",
4257         "G",
4258         "H",
4259         "I",
4260         "J",
4261         "K",
4262         "L",
4263         "M",
4264         "N",
4265         "O",
4266         "P",
4267         "Q",
4268         "R",
4269         "S",
4270         "T",
4271         /* "U", */
4272         "V",
4273         "W",
4274         "X",
4275         "Y",
4276         "Z",
4277         "!$&()+./=>?[\\]`{|~",
4278         "#%",
4279         ",",
4280         "*",
4281         "@",
4282         NULL
4283 };
4284
4285
4286 /*
4287  * hook function to sort monsters by level
4288  */
4289 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4290 {
4291         u16b *who = (u16b*)(u);
4292
4293         int w1 = who[a];
4294         int w2 = who[b];
4295
4296         monster_race *r_ptr1 = &r_info[w1];
4297         monster_race *r_ptr2 = &r_info[w2];
4298
4299         /* Unused */
4300         (void)v;
4301
4302         if (r_ptr2->level > r_ptr1->level) return TRUE;
4303         if (r_ptr1->level > r_ptr2->level) return FALSE;
4304
4305         if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4306         if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4307         return w1 <= w2;
4308 }
4309
4310 /*
4311  * Build a list of monster indexes in the given group. Return the number
4312  * of monsters in the group.
4313  *
4314  * mode & 0x01 : check for non-empty group
4315  * mode & 0x02 : visual operation only
4316  */
4317 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4318 {
4319         IDX i;
4320         IDX mon_cnt = 0;
4321         int dummy_why;
4322
4323         /* Get a list of x_char in this group */
4324         cptr group_char = monster_group_char[grp_cur];
4325
4326         /* XXX Hack -- Check if this is the "Uniques" group */
4327         bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4328
4329         /* XXX Hack -- Check if this is the "Riding" group */
4330         bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4331
4332         /* XXX Hack -- Check if this is the "Wanted" group */
4333         bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4334
4335         /* XXX Hack -- Check if this is the "Amberite" group */
4336         bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4337
4338
4339         /* Check every race */
4340         for (i = 0; i < max_r_idx; i++)
4341         {
4342                 /* Access the race */
4343                 monster_race *r_ptr = &r_info[i];
4344
4345                 /* Skip empty race */
4346                 if (!r_ptr->name) continue ;
4347
4348                 /* Require known monsters */
4349                 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4350
4351                 if (grp_unique)
4352                 {
4353                         if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4354                 }
4355
4356                 else if (grp_riding)
4357                 {
4358                         if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4359                 }
4360
4361                 else if (grp_wanted)
4362                 {
4363                         bool wanted = FALSE;
4364                         int j;
4365                         for (j = 0; j < MAX_KUBI; j++)
4366                         {
4367                                 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4368                                         (p_ptr->today_mon && p_ptr->today_mon == i))
4369                                 {
4370                                         wanted = TRUE;
4371                                         break;
4372                                 }
4373                         }
4374                         if (!wanted) continue;
4375                 }
4376
4377                 else if (grp_amberite)
4378                 {
4379                         if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4380                 }
4381
4382                 else
4383                 {
4384                         /* Check for race in the group */
4385                         if (!my_strchr(group_char, r_ptr->d_char)) continue;
4386                 }
4387
4388                 /* Add the race */
4389                 mon_idx[mon_cnt++] = i;
4390
4391                 /* XXX Hack -- Just checking for non-empty group */
4392                 if (mode & 0x01) break;
4393         }
4394
4395         /* Terminate the list */
4396         mon_idx[mon_cnt] = -1;
4397
4398         /* Select the sort method */
4399         ang_sort_comp = ang_sort_comp_monster_level;
4400         ang_sort_swap = ang_sort_swap_hook;
4401
4402         /* Sort by monster level */
4403         ang_sort(mon_idx, &dummy_why, mon_cnt);
4404
4405         /* Return the number of races */
4406         return mon_cnt;
4407 }
4408
4409
4410 /*
4411  * Description of each monster group.
4412  */
4413 static cptr object_group_text[] = 
4414 {
4415 #ifdef JP
4416         "キノコ",    /* "Mushrooms" */
4417         "薬",          /* "Potions" */
4418         "油つぼ",    /* "Flasks" */
4419         "巻物",               /* "Scrolls" */
4420         "指輪",               /* "Rings" */
4421         "アミュレット",   /* "Amulets" */
4422         "笛",          /* "Whistle" */
4423         "光源",               /* "Lanterns" */
4424         "魔法棒",    /* "Wands" */
4425         "杖",          /* "Staffs" */
4426         "ロッド",    /* "Rods" */
4427         "カード",    /* "Cards" */
4428         "キャプチャー・ボール",
4429         "羊皮紙",    
4430         "くさび",
4431         "箱",
4432         "人形",
4433         "像",
4434         "ゴミ",
4435         "空のビン",
4436         "骨",
4437         "死体",
4438         "刀剣類",    /* "Swords" */
4439         "鈍器",               /* "Blunt Weapons" */
4440         "長柄武器", /* "Polearms" */
4441         "採掘道具", /* "Diggers" */
4442         "飛び道具", /* "Bows" */
4443         "弾",
4444         "矢",
4445         "ボルト",
4446         "軽装鎧",    /* "Soft Armor" */
4447         "重装鎧",    /* "Hard Armor" */
4448         "ドラゴン鎧",      /* "Dragon Armor" */
4449         "盾",  /* "Shields" */
4450         "クローク", /* "Cloaks" */
4451         "籠手",       /* "Gloves" */
4452         "ヘルメット",      /* "Helms" */
4453         "冠",  /* "Crowns" */
4454         "ブーツ",    /* "Boots" */
4455         "魔法書",
4456         "財宝",
4457         "何か",
4458 #else
4459         "Mushrooms",
4460         "Potions",
4461         "Flasks",
4462         "Scrolls",
4463         "Rings",
4464         "Amulets",
4465         "Whistle",
4466         "Lanterns",
4467         "Wands",
4468         "Staves",
4469         "Rods",
4470         "Cards",
4471         "Capture Balls",
4472         "Parchments",
4473         "Spikes",
4474         "Boxs",
4475         "Figurines",
4476         "Statues",
4477         "Junks",
4478         "Bottles",
4479         "Skeletons",
4480         "Corpses",
4481         "Swords",
4482         "Blunt Weapons",
4483         "Polearms",
4484         "Diggers",
4485         "Bows",
4486         "Shots",
4487         "Arrows",
4488         "Bolts",
4489         "Soft Armor",
4490         "Hard Armor",
4491         "Dragon Armor",
4492         "Shields",
4493         "Cloaks",
4494         "Gloves",
4495         "Helms",
4496         "Crowns",
4497         "Boots",
4498         "Spellbooks",
4499         "Treasure",
4500         "Something",
4501 #endif
4502         NULL
4503 };
4504
4505
4506 /*
4507  * TVALs of items in each group
4508  */
4509 static byte object_group_tval[] = 
4510 {
4511         TV_FOOD,
4512         TV_POTION,
4513         TV_FLASK,
4514         TV_SCROLL,
4515         TV_RING,
4516         TV_AMULET,
4517         TV_WHISTLE,
4518         TV_LITE,
4519         TV_WAND,
4520         TV_STAFF,
4521         TV_ROD,
4522         TV_CARD,
4523         TV_CAPTURE,
4524         TV_PARCHMENT,
4525         TV_SPIKE,
4526         TV_CHEST,
4527         TV_FIGURINE,
4528         TV_STATUE,
4529         TV_JUNK,
4530         TV_BOTTLE,
4531         TV_SKELETON,
4532         TV_CORPSE,
4533         TV_SWORD,
4534         TV_HAFTED,
4535         TV_POLEARM,
4536         TV_DIGGING,
4537         TV_BOW,
4538         TV_SHOT,
4539         TV_ARROW,
4540         TV_BOLT,
4541         TV_SOFT_ARMOR,
4542         TV_HARD_ARMOR,
4543         TV_DRAG_ARMOR,
4544         TV_SHIELD,
4545         TV_CLOAK,
4546         TV_GLOVES,
4547         TV_HELM,
4548         TV_CROWN,
4549         TV_BOOTS,
4550         TV_LIFE_BOOK, /* Hack -- all spellbooks */
4551         TV_GOLD,
4552         0,
4553         0,
4554 };
4555
4556
4557 /*
4558  * Build a list of object indexes in the given group. Return the number
4559  * of objects in the group.
4560  *
4561  * mode & 0x01 : check for non-empty group
4562  * mode & 0x02 : visual operation only
4563  */
4564 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4565 {
4566         IDX i;
4567         int j, k, object_cnt = 0;
4568
4569         /* Get a list of x_char in this group */
4570         byte group_tval = object_group_tval[grp_cur];
4571
4572         /* Check every object */
4573         for (i = 0; i < max_k_idx; i++)
4574         {
4575                 /* Access the object */
4576                 object_kind *k_ptr = &k_info[i];
4577
4578                 /* Skip empty objects */
4579                 if (!k_ptr->name) continue;
4580
4581                 if (mode & 0x02)
4582                 {
4583                         /* Any objects will be displayed */
4584                 }
4585                 else
4586                 {
4587                         if (!p_ptr->wizard)
4588                         {
4589                                 /* Skip non-flavoured objects */
4590                                 if (!k_ptr->flavor) continue;
4591
4592                                 /* Require objects ever seen */
4593                                 if (!k_ptr->aware) continue;
4594                         }
4595
4596                         /* Skip items with no distribution (special artifacts) */
4597                         for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4598                         if (!k) continue;
4599                 }
4600
4601                 /* Check for objects in the group */
4602                 if (TV_LIFE_BOOK == group_tval)
4603                 {
4604                         /* Hack -- All spell books */
4605                         if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4606                         {
4607                                 /* Add the object */
4608                                 object_idx[object_cnt++] = i;
4609                         }
4610                         else continue;
4611                 }
4612                 else if (k_ptr->tval == group_tval)
4613                 {
4614                         /* Add the object */
4615                         object_idx[object_cnt++] = i;
4616                 }
4617                 else continue;
4618
4619                 /* XXX Hack -- Just checking for non-empty group */
4620                 if (mode & 0x01) break;
4621         }
4622
4623         /* Terminate the list */
4624         object_idx[object_cnt] = -1;
4625
4626         /* Return the number of objects */
4627         return object_cnt;
4628 }
4629
4630
4631 /*
4632  * Description of each feature group.
4633  */
4634 static cptr feature_group_text[] = 
4635 {
4636         "terrains",
4637         NULL
4638 };
4639
4640
4641 /*
4642  * Build a list of feature indexes in the given group. Return the number
4643  * of features in the group.
4644  *
4645  * mode & 0x01 : check for non-empty group
4646  */
4647 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4648 {
4649         IDX i;
4650         int feat_cnt = 0;
4651
4652         /* Unused;  There is a single group. */
4653         (void)grp_cur;
4654
4655         /* Check every feature */
4656         for (i = 0; i < max_f_idx; i++)
4657         {
4658                 /* Access the index */
4659                 feature_type *f_ptr = &f_info[i];
4660
4661                 /* Skip empty index */
4662                 if (!f_ptr->name) continue;
4663
4664                 /* Skip mimiccing features */
4665                 if (f_ptr->mimic != i) continue;
4666
4667                 /* Add the index */
4668                 feat_idx[feat_cnt++] = i;
4669
4670                 /* XXX Hack -- Just checking for non-empty group */
4671                 if (mode & 0x01) break;
4672         }
4673
4674         /* Terminate the list */
4675         feat_idx[feat_cnt] = -1;
4676
4677         /* Return the number of races */
4678         return feat_cnt;
4679 }
4680
4681
4682 #if 0
4683 /*
4684  * Build a list of monster indexes in the given group. Return the number
4685  * of monsters in the group.
4686  */
4687 static int collect_artifacts(int grp_cur, int object_idx[])
4688 {
4689         int i, object_cnt = 0;
4690
4691         /* Get a list of x_char in this group */
4692         byte group_tval = object_group_tval[grp_cur];
4693
4694         /* Check every object */
4695         for (i = 0; i < max_a_idx; i++)
4696         {
4697                 /* Access the artifact */
4698                 artifact_type *a_ptr = &a_info[i];
4699
4700                 /* Skip empty artifacts */
4701                 if (!a_ptr->name) continue;
4702
4703                 /* Skip "uncreated" artifacts */
4704                 if (!a_ptr->cur_num) continue;
4705
4706                 /* Check for race in the group */
4707                 if (a_ptr->tval == group_tval)
4708                 {
4709                         /* Add the race */
4710                         object_idx[object_cnt++] = i;
4711                 }
4712         }
4713
4714         /* Terminate the list */
4715         object_idx[object_cnt] = 0;
4716
4717         /* Return the number of races */
4718         return object_cnt;
4719 }
4720 #endif /* 0 */
4721
4722
4723 /*
4724  * Encode the screen colors
4725  */
4726 static char hack[17] = "dwsorgbuDWvyRGBU";
4727
4728
4729 /*
4730  * Hack -- load a screen dump from a file
4731  */
4732 void do_cmd_load_screen(void)
4733 {
4734         int i, y, x;
4735
4736         byte a = 0;
4737         char c = ' ';
4738
4739         bool okay = TRUE;
4740
4741         FILE *fff;
4742
4743         char buf[1024];
4744
4745         int wid, hgt;
4746
4747         Term_get_size(&wid, &hgt);
4748
4749         /* Build the filename */
4750         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4751
4752         /* Append to the file */
4753         fff = my_fopen(buf, "r");
4754
4755         /* Oops */
4756         if (!fff) {
4757                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4758                 msg_print(NULL);
4759                 return;
4760         }
4761
4762
4763         /* Save the screen */
4764         screen_save();
4765
4766         /* Clear the screen */
4767         Term_clear();
4768
4769
4770         /* Load the screen */
4771         for (y = 0; okay; y++)
4772         {
4773                 /* Get a line of data including control code */
4774                 if (!fgets(buf, 1024, fff)) okay = FALSE;
4775
4776                 /* Get the blank line */
4777                 if (buf[0] == '\n' || buf[0] == '\0') break;
4778
4779                 /* Ignore too large screen image */
4780                 if (y >= hgt) continue;
4781
4782                 /* Show each row */
4783                 for (x = 0; x < wid - 1; x++)
4784                 {
4785                         /* End of line */
4786                         if (buf[x] == '\n' || buf[x] == '\0') break;
4787
4788                         /* Put the attr/char */
4789                         Term_draw(x, y, TERM_WHITE, buf[x]);
4790                 }
4791         }
4792
4793         /* Dump the screen */
4794         for (y = 0; okay; y++)
4795         {
4796                 /* Get a line of data including control code */
4797                 if (!fgets(buf, 1024, fff)) okay = FALSE;
4798
4799                 /* Get the blank line */
4800                 if (buf[0] == '\n' || buf[0] == '\0') break;
4801
4802                 /* Ignore too large screen image */
4803                 if (y >= hgt) continue;
4804
4805                 /* Dump each row */
4806                 for (x = 0; x < wid - 1; x++)
4807                 {
4808                         /* End of line */
4809                         if (buf[x] == '\n' || buf[x] == '\0') break;
4810
4811                         /* Get the attr/char */
4812                         (void)(Term_what(x, y, &a, &c));
4813
4814                         /* Look up the attr */
4815                         for (i = 0; i < 16; i++)
4816                         {
4817                                 /* Use attr matches */
4818                                 if (hack[i] == buf[x]) a = (byte_hack)i;
4819                         }
4820
4821                         /* Put the attr/char */
4822                         Term_draw(x, y, a, c);
4823                 }
4824         }
4825
4826
4827         /* Close it */
4828         my_fclose(fff);
4829
4830
4831         /* Message */
4832         prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4833
4834         flush();
4835         inkey();
4836
4837
4838         /* Restore the screen */
4839         screen_load();
4840 }
4841
4842
4843
4844
4845 cptr inven_res_label = _("                               酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4846                                                  "                               AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4847
4848
4849 #define IM_FLAG_STR  _("*", "* ")
4850 #define HAS_FLAG_STR _("+", "+ ")
4851 #define NO_FLAG_STR  _("・", ". ")
4852
4853 #define print_im_or_res_flag(IM, RES) \
4854 { \
4855         fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4856               (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4857 }
4858
4859 #define print_flag(TR) \
4860 { \
4861         fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4862 }
4863
4864
4865 /* XTRA HACK RESLIST */
4866 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, byte tval, char *where)
4867 {
4868         char o_name[MAX_NLEN];
4869         u32b flgs[TR_FLAG_SIZE];
4870
4871         if (!o_ptr->k_idx) return;
4872         if (o_ptr->tval != tval) return;
4873
4874         /* Identified items only */
4875         if (!object_is_known(o_ptr)) return;
4876
4877         /*
4878          * HACK:Ring of Lordly protection and Dragon equipment
4879          * have random resistances.
4880          */
4881         if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4882             || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4883             || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4884             || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4885             || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4886             || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4887             || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4888             || object_is_artifact(o_ptr))
4889         {
4890                 int i = 0;
4891                 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4892
4893                 while (o_name[i] && (i < 26))
4894                 {
4895 #ifdef JP
4896                         if (iskanji(o_name[i])) i++;
4897 #endif
4898                         i++;
4899                 }
4900
4901                 if (i < 28)
4902                 {
4903                         while (i < 28)
4904                         {
4905                                 o_name[i] = ' '; i++;
4906                         }
4907                 }
4908                 o_name[i] = '\0';
4909
4910                 fprintf(fff, "%s %s", where, o_name);
4911
4912                 if (!(o_ptr->ident & (IDENT_MENTAL)))
4913                 {
4914                         fputs(_("-------不明--------------- -------不明---------\n", 
4915                                         "-------unknown------------ -------unknown------\n"), fff);
4916                 }
4917                 else
4918                 {
4919                         object_flags_known(o_ptr, flgs);
4920
4921                         print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4922                         print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4923                         print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4924                         print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4925                         print_flag(TR_RES_POIS);
4926                         print_flag(TR_RES_LITE);
4927                         print_flag(TR_RES_DARK);
4928                         print_flag(TR_RES_SHARDS);
4929                         print_flag(TR_RES_SOUND);
4930                         print_flag(TR_RES_NETHER);
4931                         print_flag(TR_RES_NEXUS);
4932                         print_flag(TR_RES_CHAOS);
4933                         print_flag(TR_RES_DISEN);
4934
4935                         fputs(" ", fff);
4936
4937                         print_flag(TR_RES_BLIND);
4938                         print_flag(TR_RES_FEAR);
4939                         print_flag(TR_RES_CONF);
4940                         print_flag(TR_FREE_ACT);
4941                         print_flag(TR_SEE_INVIS);
4942                         print_flag(TR_HOLD_EXP);
4943                         print_flag(TR_TELEPATHY);
4944                         print_flag(TR_SLOW_DIGEST);
4945                         print_flag(TR_REGEN);
4946                         print_flag(TR_LEVITATION);
4947
4948                         fputc('\n', fff);
4949                 }
4950                 (*j)++;
4951                 if (*j == 9)
4952                 {
4953                         *j = 0;
4954                         fprintf(fff, "%s\n", inven_res_label);
4955                 }
4956         }
4957 }
4958
4959 /*
4960  * Display *ID* ed weapons/armors's resistances
4961  */
4962 static void do_cmd_knowledge_inven(void)
4963 {
4964         FILE *fff;
4965
4966         char file_name[1024];
4967
4968         store_type  *st_ptr;
4969
4970         byte tval;
4971         int i = 0;
4972         int j = 0;
4973
4974         char  where[32];
4975
4976         /* Open a new file */
4977         fff = my_fopen_temp(file_name, 1024);
4978         if (!fff)
4979         {
4980             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4981             msg_print(NULL);
4982             return;
4983         }
4984         fprintf(fff, "%s\n", inven_res_label);
4985
4986         for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4987         {
4988                 if (j != 0)
4989                 {
4990                         for (; j < 9; j++) fputc('\n', fff);
4991                         j = 0;
4992                         fprintf(fff, "%s\n", inven_res_label);
4993                 }
4994                 strcpy(where, _("装", "E "));
4995                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4996                 {
4997                         do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4998                 }
4999                 strcpy(where, _("持", "I "));
5000                 for (i = 0; i < INVEN_PACK; i++)
5001                 {
5002                         do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
5003                 }
5004
5005                 st_ptr = &town[1].store[STORE_HOME];
5006                 strcpy(where, _("家", "H "));
5007                 for (i = 0; i < st_ptr->stock_num; i++)
5008                 {
5009                         do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
5010                 }
5011         }
5012
5013         /* Close the file */
5014         my_fclose(fff);
5015
5016         /* Display the file contents */
5017         show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
5018
5019         /* Remove the file */
5020         fd_kill(file_name);
5021 }
5022
5023
5024 void do_cmd_save_screen_html_aux(char *filename, int message)
5025 {
5026         int y, x, i;
5027
5028         byte a = 0, old_a = 0;
5029         char c = ' ';
5030
5031         FILE *fff, *tmpfff;
5032         char buf[2048];
5033
5034         int yomikomu = 0;
5035         cptr tags[4] = {
5036                 "HEADER_START:",
5037                 "HEADER_END:",
5038                 "FOOTER_START:",
5039                 "FOOTER_END:",
5040         };
5041
5042         cptr html_head[] = {
5043                 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
5044                 "<pre>",
5045                 0,
5046         };
5047         cptr html_foot[] = {
5048                 "</pre>\n",
5049                 "</body>\n</html>\n",
5050                 0,
5051         };
5052
5053         int wid, hgt;
5054
5055         Term_get_size(&wid, &hgt);
5056
5057         /* File type is "TEXT" */
5058         FILE_TYPE(FILE_TYPE_TEXT);
5059
5060         /* Append to the file */
5061         fff = my_fopen(filename, "w");
5062
5063         /* Oops */
5064         if (!fff) {
5065                 if (message) {
5066                     msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
5067                     msg_print(NULL);
5068                 }
5069                 
5070                 return;
5071         }
5072
5073         /* Save the screen */
5074         if (message)
5075                 screen_save();
5076
5077         /* Build the filename */
5078         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
5079         tmpfff = my_fopen(buf, "r");
5080         if (!tmpfff) {
5081                 for (i = 0; html_head[i]; i++)
5082                         fputs(html_head[i], fff);
5083         }
5084         else {
5085                 yomikomu = 0;
5086                 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
5087                         if (!yomikomu) {
5088                                 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
5089                                         yomikomu = 1;
5090                         }
5091                         else {
5092                                 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
5093                                         break;
5094                                 fprintf(fff, "%s\n", buf);
5095                         }
5096                 }
5097         }
5098
5099         /* Dump the screen */
5100         for (y = 0; y < hgt; y++)
5101         {
5102                 /* Start the row */
5103                 if (y != 0)
5104                         fprintf(fff, "\n");
5105
5106                 /* Dump each row */
5107                 for (x = 0; x < wid - 1; x++)
5108                 {
5109                         int rv, gv, bv;
5110                         cptr cc = NULL;
5111                         /* Get the attr/char */
5112                         (void)(Term_what(x, y, &a, &c));
5113
5114                         switch (c)
5115                         {
5116                         case '&': cc = "&amp;"; break;
5117                         case '<': cc = "&lt;"; break;
5118                         case '>': cc = "&gt;"; break;
5119 #ifdef WINDOWS
5120                         case 0x1f: c = '.'; break;
5121                         case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
5122 #endif
5123                         }
5124
5125                         a = a & 0x0F;
5126                         if ((y == 0 && x == 0) || a != old_a) {
5127                                 rv = angband_color_table[a][1];
5128                                 gv = angband_color_table[a][2];
5129                                 bv = angband_color_table[a][3];
5130                                 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">", 
5131                                         ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
5132                                 old_a = a;
5133                         }
5134                         if (cc)
5135                                 fprintf(fff, "%s", cc);
5136                         else
5137                                 fprintf(fff, "%c", c);
5138                 }
5139         }
5140         fprintf(fff, "</font>");
5141
5142         if (!tmpfff) {
5143                 for (i = 0; html_foot[i]; i++)
5144                         fputs(html_foot[i], fff);
5145         }
5146         else {
5147                 rewind(tmpfff);
5148                 yomikomu = 0;
5149                 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
5150                         if (!yomikomu) {
5151                                 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
5152                                         yomikomu = 1;
5153                         }
5154                         else {
5155                                 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
5156                                         break;
5157                                 fprintf(fff, "%s\n", buf);
5158                         }
5159                 }
5160                 my_fclose(tmpfff);
5161         }
5162
5163         /* Skip a line */
5164         fprintf(fff, "\n");
5165
5166         /* Close it */
5167         my_fclose(fff);
5168
5169         /* Message */
5170         if (message) {
5171                 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5172                 msg_print(NULL);
5173         }
5174
5175         /* Restore the screen */
5176         if (message)
5177                 screen_load();
5178 }
5179
5180 /*
5181  * Hack -- save a screen dump to a file
5182  */
5183 static void do_cmd_save_screen_html(void)
5184 {
5185         char buf[1024], tmp[256] = "screen.html";
5186
5187         if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
5188                 return;
5189
5190         /* Build the filename */
5191         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
5192
5193         msg_print(NULL);
5194
5195         do_cmd_save_screen_html_aux(buf, 1);
5196 }
5197
5198
5199 /*
5200  * Redefinable "save_screen" action
5201  */
5202 void (*screendump_aux)(void) = NULL;
5203
5204
5205 /*
5206  * Hack -- save a screen dump to a file
5207  */
5208 void do_cmd_save_screen(void)
5209 {
5210         bool old_use_graphics = use_graphics;
5211         bool html_dump = FALSE;
5212
5213         int wid, hgt;
5214
5215         prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5216         while(TRUE)
5217         {
5218                 char c = inkey();
5219                 if (c == 'Y' || c == 'y')
5220                         break;
5221                 else if (c == 'H' || c == 'h')
5222                 {
5223                         html_dump = TRUE;
5224                         break;
5225                 }
5226                 else
5227                 {
5228                         prt("", 0, 0);
5229                         return;
5230                 }
5231         }
5232
5233         Term_get_size(&wid, &hgt);
5234
5235         if (old_use_graphics)
5236         {
5237                 use_graphics = FALSE;
5238                 reset_visuals();
5239
5240                 /* Redraw everything */
5241                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5242
5243                 /* Hack -- update */
5244                 handle_stuff();
5245         }
5246
5247         if (html_dump)
5248         {
5249                 do_cmd_save_screen_html();
5250                 do_cmd_redraw();
5251         }
5252
5253         /* Do we use a special screendump function ? */
5254         else if (screendump_aux)
5255         {
5256                 /* Dump the screen to a graphics file */
5257                 (*screendump_aux)();
5258         }
5259         else /* Dump the screen as text */
5260         {
5261                 int y, x;
5262
5263                 byte a = 0;
5264                 char c = ' ';
5265
5266                 FILE *fff;
5267
5268                 char buf[1024];
5269
5270                 /* Build the filename */
5271                 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5272
5273                 /* File type is "TEXT" */
5274                 FILE_TYPE(FILE_TYPE_TEXT);
5275
5276                 /* Append to the file */
5277                 fff = my_fopen(buf, "w");
5278
5279                 /* Oops */
5280                 if (!fff)
5281                 {
5282                         msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5283                         msg_print(NULL);
5284                         return;
5285                 }
5286
5287
5288                 /* Save the screen */
5289                 screen_save();
5290
5291
5292                 /* Dump the screen */
5293                 for (y = 0; y < hgt; y++)
5294                 {
5295                         /* Dump each row */
5296                         for (x = 0; x < wid - 1; x++)
5297                         {
5298                                 /* Get the attr/char */
5299                                 (void)(Term_what(x, y, &a, &c));
5300
5301                                 /* Dump it */
5302                                 buf[x] = c;
5303                         }
5304
5305                         /* Terminate */
5306                         buf[x] = '\0';
5307
5308                         /* End the row */
5309                         fprintf(fff, "%s\n", buf);
5310                 }
5311
5312                 /* Skip a line */
5313                 fprintf(fff, "\n");
5314
5315
5316                 /* Dump the screen */
5317                 for (y = 0; y < hgt; y++)
5318                 {
5319                         /* Dump each row */
5320                         for (x = 0; x < wid - 1; x++)
5321                         {
5322                                 /* Get the attr/char */
5323                                 (void)(Term_what(x, y, &a, &c));
5324
5325                                 /* Dump it */
5326                                 buf[x] = hack[a&0x0F];
5327                         }
5328
5329                         /* Terminate */
5330                         buf[x] = '\0';
5331
5332                         /* End the row */
5333                         fprintf(fff, "%s\n", buf);
5334                 }
5335
5336                 /* Skip a line */
5337                 fprintf(fff, "\n");
5338
5339
5340                 /* Close it */
5341                 my_fclose(fff);
5342
5343                 /* Message */
5344                 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5345                 msg_print(NULL);
5346
5347                 /* Restore the screen */
5348                 screen_load();
5349         }
5350
5351         if (old_use_graphics)
5352         {
5353                 use_graphics = TRUE;
5354                 reset_visuals();
5355
5356                 /* Redraw everything */
5357                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5358
5359                 /* Hack -- update */
5360                 handle_stuff();
5361         }
5362 }
5363
5364
5365 /*
5366  * Sorting hook -- Comp function -- see below
5367  *
5368  * We use "u" to point to array of monster indexes,
5369  * and "v" to select the type of sorting to perform on "u".
5370  */
5371 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5372 {
5373         u16b *who = (u16b*)(u);
5374
5375         u16b *why = (u16b*)(v);
5376
5377         int w1 = who[a];
5378         int w2 = who[b];
5379
5380         int z1, z2;
5381
5382         /* Sort by total kills */
5383         if (*why >= 3)
5384         {
5385                 /* Extract total kills */
5386                 z1 = a_info[w1].tval;
5387                 z2 = a_info[w2].tval;
5388
5389                 /* Compare total kills */
5390                 if (z1 < z2) return (TRUE);
5391                 if (z1 > z2) return (FALSE);
5392         }
5393
5394
5395         /* Sort by monster level */
5396         if (*why >= 2)
5397         {
5398                 /* Extract levels */
5399                 z1 = a_info[w1].sval;
5400                 z2 = a_info[w2].sval;
5401
5402                 /* Compare levels */
5403                 if (z1 < z2) return (TRUE);
5404                 if (z1 > z2) return (FALSE);
5405         }
5406
5407
5408         /* Sort by monster experience */
5409         if (*why >= 1)
5410         {
5411                 /* Extract experience */
5412                 z1 = a_info[w1].level;
5413                 z2 = a_info[w2].level;
5414
5415                 /* Compare experience */
5416                 if (z1 < z2) return (TRUE);
5417                 if (z1 > z2) return (FALSE);
5418         }
5419
5420
5421         /* Compare indexes */
5422         return (w1 <= w2);
5423 }
5424
5425
5426 /*
5427  * Sorting hook -- Swap function -- see below
5428  *
5429  * We use "u" to point to array of monster indexes,
5430  * and "v" to select the type of sorting to perform.
5431  */
5432 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5433 {
5434         u16b *who = (u16b*)(u);
5435
5436         u16b holder;
5437
5438         /* Unused */
5439         (void)v;
5440
5441         /* Swap */
5442         holder = who[a];
5443         who[a] = who[b];
5444         who[b] = holder;
5445 }
5446
5447
5448 /*
5449  * Check the status of "artifacts"
5450  */
5451 static void do_cmd_knowledge_artifacts(void)
5452 {
5453         IDX i;
5454         IDX k;
5455         int x, y, n = 0;
5456         IDX z;
5457         u16b why = 3;
5458         IDX *who;
5459
5460         FILE *fff;
5461
5462         char file_name[1024];
5463
5464         char base_name[MAX_NLEN];
5465
5466         bool *okay;
5467
5468         /* Open a new file */
5469         fff = my_fopen_temp(file_name, 1024);
5470
5471         if (!fff) {
5472             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5473             msg_print(NULL);
5474             return;
5475         }
5476
5477         /* Allocate the "who" array */
5478         C_MAKE(who, max_a_idx, s16b);
5479
5480         /* Allocate the "okay" array */
5481         C_MAKE(okay, max_a_idx, bool);
5482
5483         /* Scan the artifacts */
5484         for (k = 0; k < max_a_idx; k++)
5485         {
5486                 artifact_type *a_ptr = &a_info[k];
5487
5488                 /* Default */
5489                 okay[k] = FALSE;
5490
5491                 /* Skip "empty" artifacts */
5492                 if (!a_ptr->name) continue;
5493
5494                 /* Skip "uncreated" artifacts */
5495                 if (!a_ptr->cur_num) continue;
5496
5497                 /* Assume okay */
5498                 okay[k] = TRUE;
5499         }
5500
5501         /* Check the dungeon */
5502         for (y = 0; y < cur_hgt; y++)
5503         {
5504                 for (x = 0; x < cur_wid; x++)
5505                 {
5506                         cave_type *c_ptr = &cave[y][x];
5507
5508                         s16b this_o_idx, next_o_idx = 0;
5509
5510                         /* Scan all objects in the grid */
5511                         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5512                         {
5513                                 object_type *o_ptr;
5514
5515                                 /* Acquire object */
5516                                 o_ptr = &o_list[this_o_idx];
5517
5518                                 /* Acquire next object */
5519                                 next_o_idx = o_ptr->next_o_idx;
5520
5521                                 /* Ignore non-artifacts */
5522                                 if (!object_is_fixed_artifact(o_ptr)) continue;
5523
5524                                 /* Ignore known items */
5525                                 if (object_is_known(o_ptr)) continue;
5526
5527                                 /* Note the artifact */
5528                                 okay[o_ptr->name1] = FALSE;
5529                         }
5530                 }
5531         }
5532
5533         /* Check the inventory and equipment */
5534         for (i = 0; i < INVEN_TOTAL; i++)
5535         {
5536                 object_type *o_ptr = &inventory[i];
5537
5538                 /* Ignore non-objects */
5539                 if (!o_ptr->k_idx) continue;
5540
5541                 /* Ignore non-artifacts */
5542                 if (!object_is_fixed_artifact(o_ptr)) continue;
5543
5544                 /* Ignore known items */
5545                 if (object_is_known(o_ptr)) continue;
5546
5547                 /* Note the artifact */
5548                 okay[o_ptr->name1] = FALSE;
5549         }
5550
5551         for (k = 0; k < max_a_idx; k++)
5552         {
5553                 if (okay[k]) who[n++] = k;
5554         }
5555
5556         /* Select the sort method */
5557         ang_sort_comp = ang_sort_art_comp;
5558         ang_sort_swap = ang_sort_art_swap;
5559
5560         /* Sort the array by dungeon depth of monsters */
5561         ang_sort(who, &why, n);
5562
5563         /* Scan the artifacts */
5564         for (k = 0; k < n; k++)
5565         {
5566                 artifact_type *a_ptr = &a_info[who[k]];
5567
5568                 /* Paranoia */
5569                 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5570
5571                 /* Obtain the base object type */
5572                 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5573
5574                 /* Real object */
5575                 if (z)
5576                 {
5577                         object_type forge;
5578                         object_type *q_ptr;
5579
5580                         /* Get local object */
5581                         q_ptr = &forge;
5582
5583                         /* Create fake object */
5584                         object_prep(q_ptr, z);
5585
5586                         /* Make it an artifact */
5587                         q_ptr->name1 = (byte)who[k];
5588
5589                         /* Display as if known */
5590                         q_ptr->ident |= IDENT_STORE;
5591
5592                         /* Describe the artifact */
5593                         object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5594                 }
5595
5596                 /* Hack -- Build the artifact name */
5597                 fprintf(fff, _("     %s\n", "     The %s\n"), base_name);
5598         }
5599
5600         /* Free the "who" array */
5601         C_KILL(who, max_a_idx, s16b);
5602
5603         /* Free the "okay" array */
5604         C_KILL(okay, max_a_idx, bool);
5605
5606         /* Close the file */
5607         my_fclose(fff);
5608
5609         /* Display the file contents */
5610         show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5611
5612         /* Remove the file */
5613         fd_kill(file_name);
5614 }
5615
5616
5617 /*
5618  * Display known uniques
5619  * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5620  */
5621 static void do_cmd_knowledge_uniques(void)
5622 {
5623         IDX i;
5624         int k, n = 0;
5625         u16b why = 2;
5626         IDX *who;
5627
5628         FILE *fff;
5629
5630         char file_name[1024];
5631
5632         int n_alive[10];
5633         int n_alive_surface = 0;
5634         int n_alive_over100 = 0;
5635         int n_alive_total = 0;
5636         int max_lev = -1;
5637
5638         for (i = 0; i < 10; i++) n_alive[i] = 0;
5639
5640         /* Open a new file */
5641         fff = my_fopen_temp(file_name, 1024);
5642
5643         if (!fff)
5644         {
5645             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5646             msg_print(NULL);
5647             return;
5648         }
5649
5650         /* Allocate the "who" array */
5651         C_MAKE(who, max_r_idx, s16b);
5652
5653         /* Scan the monsters */
5654         for (i = 1; i < max_r_idx; i++)
5655         {
5656                 monster_race *r_ptr = &r_info[i];
5657                 int          lev;
5658
5659                 if (!r_ptr->name) continue;
5660
5661                 /* Require unique monsters */
5662                 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5663
5664                 /* Only display "known" uniques */
5665                 if (!cheat_know && !r_ptr->r_sights) continue;
5666
5667                 /* Only print rarity <= 100 uniques */
5668                 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5669
5670                 /* Only "alive" uniques */
5671                 if (r_ptr->max_num == 0) continue;
5672
5673                 if (r_ptr->level)
5674                 {
5675                         lev = (r_ptr->level - 1) / 10;
5676                         if (lev < 10)
5677                         {
5678                                 n_alive[lev]++;
5679                                 if (max_lev < lev) max_lev = lev;
5680                         }
5681                         else n_alive_over100++;
5682                 }
5683                 else n_alive_surface++;
5684
5685                 /* Collect "appropriate" monsters */
5686                 who[n++] = i;
5687         }
5688
5689         /* Select the sort method */
5690         ang_sort_comp = ang_sort_comp_hook;
5691         ang_sort_swap = ang_sort_swap_hook;
5692
5693         /* Sort the array by dungeon depth of monsters */
5694         ang_sort(who, &why, n);
5695
5696         if (n_alive_surface)
5697         {
5698                 fprintf(fff, _("     地上  生存: %3d体\n", "      Surface  alive: %3d\n"), n_alive_surface);
5699                 n_alive_total += n_alive_surface;
5700         }
5701         for (i = 0; i <= max_lev; i++)
5702         {
5703                 fprintf(fff, _("%3d-%3d階  生存: %3d体\n", "Level %3d-%3d  alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5704                 n_alive_total += n_alive[i];
5705         }
5706         if (n_alive_over100)
5707         {
5708                 fprintf(fff, _("101-   階  生存: %3d体\n", "Level 101-     alive: %3d\n"), n_alive_over100);
5709                 n_alive_total += n_alive_over100;
5710         }
5711
5712         if (n_alive_total)
5713         {
5714                 fputs(_("---------  -----------\n", "-------------  ----------\n"), fff);
5715                 fprintf(fff, _("     合計  生存: %3d体\n\n", "        Total  alive: %3d\n\n"), n_alive_total);
5716         }
5717         else
5718         {
5719                 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5720         }
5721
5722         /* Scan the monster races */
5723         for (k = 0; k < n; k++)
5724         {
5725                 monster_race *r_ptr = &r_info[who[k]];
5726
5727                 /* Print a message */
5728                 fprintf(fff, _("     %s (レベル%d)\n", "     %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5729         }
5730
5731         /* Free the "who" array */
5732         C_KILL(who, max_r_idx, s16b);
5733
5734         /* Close the file */
5735         my_fclose(fff);
5736
5737         /* Display the file contents */
5738         show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5739
5740         /* Remove the file */
5741         fd_kill(file_name);
5742 }
5743
5744
5745 /*
5746  * Display weapon-exp
5747  */
5748 static void do_cmd_knowledge_weapon_exp(void)
5749 {
5750         int i, num, weapon_exp;
5751         KIND_OBJECT_IDX j;
5752
5753         FILE *fff;
5754
5755         char file_name[1024];
5756         char tmp[30];
5757
5758         /* Open a new file */
5759         fff = my_fopen_temp(file_name, 1024);
5760         if (!fff) {
5761             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5762             msg_print(NULL);
5763             return;
5764         }
5765
5766         for (i = 0; i < 5; i++)
5767         {
5768                 for (num = 0; num < 64; num++)
5769                 {
5770                         for (j = 0; j < max_k_idx; j++)
5771                         {
5772                                 object_kind *k_ptr = &k_info[j];
5773
5774                                 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5775                                 {
5776                                         if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5777
5778                                         weapon_exp = p_ptr->weapon_exp[4 - i][num];
5779                                         strip_name(tmp, j);
5780                                         fprintf(fff, "%-25s ", tmp);
5781                                         if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5782                                         else fprintf(fff, " ");
5783                                         fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5784                                         if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5785                                         fprintf(fff, "\n");
5786                                         break;
5787                                 }
5788                         }
5789                 }
5790         }
5791
5792         /* Close the file */
5793         my_fclose(fff);
5794
5795         /* Display the file contents */
5796         show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5797
5798         /* Remove the file */
5799         fd_kill(file_name);
5800 }
5801
5802
5803 /*!
5804  * @brief 魔法の経験値を表示するコマンドのメインルーチン
5805  * Display spell-exp
5806  * @return なし
5807  */
5808 static void do_cmd_knowledge_spell_exp(void)
5809 {
5810         SPELL_IDX i = 0;
5811         int spell_exp, exp_level;
5812
5813         FILE *fff;
5814         const magic_type *s_ptr;
5815
5816         char file_name[1024];
5817
5818         /* Open a new file */
5819         fff = my_fopen_temp(file_name, 1024);
5820         if (!fff) {
5821             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5822             msg_print(NULL);
5823             return;
5824         }
5825
5826         if (p_ptr->realm1 != REALM_NONE)
5827         {
5828                 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5829                 for (i = 0; i < 32; i++)
5830                 {
5831                         if (!is_magic(p_ptr->realm1))
5832                         {
5833                                 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5834                         }
5835                         else
5836                         {
5837                                 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5838                         }
5839                         if (s_ptr->slevel >= 99) continue;
5840                         spell_exp = p_ptr->spell_exp[i];
5841                         exp_level = spell_exp_level(spell_exp);
5842                         fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5843                         if (p_ptr->realm1 == REALM_HISSATSU)
5844                                 fprintf(fff, "[--]");
5845                         else
5846                         {
5847                                 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5848                                 else fprintf(fff, " ");
5849                                 fprintf(fff, "%s", exp_level_str[exp_level]);
5850                         }
5851                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5852                         fprintf(fff, "\n");
5853                 }
5854         }
5855
5856         if (p_ptr->realm2 != REALM_NONE)
5857         {
5858                 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5859                 for (i = 0; i < 32; i++)
5860                 {
5861                         if (!is_magic(p_ptr->realm1))
5862                         {
5863                                 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5864                         }
5865                         else
5866                         {
5867                                 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5868                         }
5869                         if (s_ptr->slevel >= 99) continue;
5870
5871                         spell_exp = p_ptr->spell_exp[i + 32];
5872                         exp_level = spell_exp_level(spell_exp);
5873                         fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5874                         if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5875                         else fprintf(fff, " ");
5876                         fprintf(fff, "%s", exp_level_str[exp_level]);
5877                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5878                         fprintf(fff, "\n");
5879                 }
5880         }
5881
5882         /* Close the file */
5883         my_fclose(fff);
5884
5885         /* Display the file contents */
5886         show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5887
5888         /* Remove the file */
5889         fd_kill(file_name);
5890 }
5891
5892
5893 /*!
5894  * @brief スキル情報を表示するコマンドのメインルーチン /
5895  * Display skill-exp
5896  * @return なし
5897  */
5898 static void do_cmd_knowledge_skill_exp(void)
5899 {
5900         int i = 0, skill_exp;
5901
5902         FILE *fff;
5903
5904         char file_name[1024];
5905         char skill_name[3][20]={_("マーシャルアーツ", "Martial Arts    "),
5906                                                         _("二刀流          ", "Dual Wielding   "), 
5907                                                         _("乗馬            ", "Riding          ")};
5908
5909         /* Open a new file */
5910         fff = my_fopen_temp(file_name, 1024);
5911         if (!fff) {
5912             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5913             msg_print(NULL);
5914             return;
5915         }
5916
5917         for (i = 0; i < 3; i++)
5918         {
5919                 skill_exp = p_ptr->skill_exp[i];
5920                 fprintf(fff, "%-20s ", skill_name[i]);
5921                 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5922                 else fprintf(fff, " ");
5923                 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5924                 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5925                 fprintf(fff, "\n");
5926         }
5927
5928         /* Close the file */
5929         my_fclose(fff);
5930
5931         /* Display the file contents */
5932         show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5933
5934         /* Remove the file */
5935         fd_kill(file_name);
5936 }
5937
5938
5939 /*!
5940  * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5941  * @param Name 変換したい文字列の参照ポインタ
5942  * @return なし
5943  */
5944 void plural_aux(char *Name)
5945 {
5946         int NameLen = strlen(Name);
5947
5948         if (my_strstr(Name, "Disembodied hand"))
5949         {
5950                 strcpy(Name, "Disembodied hands that strangled people");
5951         }
5952         else if (my_strstr(Name, "Colour out of space"))
5953         {
5954                 strcpy(Name, "Colours out of space");
5955         }
5956         else if (my_strstr(Name, "stairway to hell"))
5957         {
5958                 strcpy(Name, "stairways to hell");
5959         }
5960         else if (my_strstr(Name, "Dweller on the threshold"))
5961         {
5962                 strcpy(Name, "Dwellers on the threshold");
5963         }
5964         else if (my_strstr(Name, " of "))
5965         {
5966                 cptr aider = my_strstr(Name, " of ");
5967                 char dummy[80];
5968                 int i = 0;
5969                 cptr ctr = Name;
5970
5971                 while (ctr < aider)
5972                 {
5973                         dummy[i] = *ctr;
5974                         ctr++; i++;
5975                 }
5976
5977                 if (dummy[i-1] == 's')
5978                 {
5979                         strcpy(&(dummy[i]), "es");
5980                         i++;
5981                 }
5982                 else
5983                 {
5984                         strcpy(&(dummy[i]), "s");
5985                 }
5986
5987                 strcpy(&(dummy[i+1]), aider);
5988                 strcpy(Name, dummy);
5989         }
5990         else if (my_strstr(Name, "coins"))
5991         {
5992                 char dummy[80];
5993                 strcpy(dummy, "piles of ");
5994                 strcat(dummy, Name);
5995                 strcpy(Name, dummy);
5996                 return;
5997         }
5998         else if (my_strstr(Name, "Manes"))
5999         {
6000                 return;
6001         }
6002         else if (streq(&(Name[NameLen - 2]), "ey"))
6003         {
6004                 strcpy(&(Name[NameLen - 2]), "eys");
6005         }
6006         else if (Name[NameLen - 1] == 'y')
6007         {
6008                 strcpy(&(Name[NameLen - 1]), "ies");
6009         }
6010         else if (streq(&(Name[NameLen - 4]), "ouse"))
6011         {
6012                 strcpy(&(Name[NameLen - 4]), "ice");
6013         }
6014         else if (streq(&(Name[NameLen - 2]), "us"))
6015         {
6016                 strcpy(&(Name[NameLen - 2]), "i");
6017         }
6018         else if (streq(&(Name[NameLen - 6]), "kelman"))
6019         {
6020                 strcpy(&(Name[NameLen - 6]), "kelmen");
6021         }
6022         else if (streq(&(Name[NameLen - 8]), "wordsman"))
6023         {
6024                 strcpy(&(Name[NameLen - 8]), "wordsmen");
6025         }
6026         else if (streq(&(Name[NameLen - 7]), "oodsman"))
6027         {
6028                 strcpy(&(Name[NameLen - 7]), "oodsmen");
6029         }
6030         else if (streq(&(Name[NameLen - 7]), "eastman"))
6031         {
6032                 strcpy(&(Name[NameLen - 7]), "eastmen");
6033         }
6034         else if (streq(&(Name[NameLen - 8]), "izardman"))
6035         {
6036                 strcpy(&(Name[NameLen - 8]), "izardmen");
6037         }
6038         else if (streq(&(Name[NameLen - 5]), "geist"))
6039         {
6040                 strcpy(&(Name[NameLen - 5]), "geister");
6041         }
6042         else if (streq(&(Name[NameLen - 2]), "ex"))
6043         {
6044                 strcpy(&(Name[NameLen - 2]), "ices");
6045         }
6046         else if (streq(&(Name[NameLen - 2]), "lf"))
6047         {
6048                 strcpy(&(Name[NameLen - 2]), "lves");
6049         }
6050         else if (suffix(Name, "ch") ||
6051                  suffix(Name, "sh") ||
6052                          suffix(Name, "nx") ||
6053                          suffix(Name, "s") ||
6054                          suffix(Name, "o"))
6055         {
6056                 strcpy(&(Name[NameLen]), "es");
6057         }
6058         else
6059         {
6060                 strcpy(&(Name[NameLen]), "s");
6061         }
6062 }
6063
6064 /*!
6065  * @brief 現在のペットを表示するコマンドのメインルーチン /
6066  * Display current pets
6067  * @return なし
6068  */
6069 static void do_cmd_knowledge_pets(void)
6070 {
6071         int             i;
6072         FILE            *fff;
6073         monster_type    *m_ptr;
6074         char            pet_name[80];
6075         int             t_friends = 0;
6076         int             show_upkeep = 0;
6077         char            file_name[1024];
6078
6079
6080         /* Open a new file */
6081         fff = my_fopen_temp(file_name, 1024);
6082         if (!fff) {
6083             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6084             msg_print(NULL);
6085             return;
6086         }
6087
6088         /* Process the monsters (backwards) */
6089         for (i = m_max - 1; i >= 1; i--)
6090         {
6091                 /* Access the monster */
6092                 m_ptr = &m_list[i];
6093
6094                 /* Ignore "dead" monsters */
6095                 if (!m_ptr->r_idx) continue;
6096
6097                 /* Calculate "upkeep" for pets */
6098                 if (is_pet(m_ptr))
6099                 {
6100                         t_friends++;
6101                         monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
6102                         fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
6103                 }
6104         }
6105
6106         show_upkeep = calculate_upkeep();
6107
6108         fprintf(fff, "----------------------------------------------\n");
6109 #ifdef JP
6110         fprintf(fff, "    合計: %d 体のペット\n", t_friends);
6111         fprintf(fff, " 維持コスト: %d%% MP\n", show_upkeep);
6112 #else
6113         fprintf(fff, "   Total: %d pet%s.\n",
6114                 t_friends, (t_friends == 1 ? "" : "s"));
6115         fprintf(fff, "   Upkeep: %d%% mana.\n", show_upkeep);
6116 #endif
6117
6118
6119
6120         /* Close the file */
6121         my_fclose(fff);
6122
6123         /* Display the file contents */
6124         show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
6125
6126         /* Remove the file */
6127         fd_kill(file_name);
6128 }
6129
6130
6131 /*!
6132  * @brief 現在のペットを表示するコマンドのメインルーチン /
6133  * Total kill count
6134  * @return なし
6135  * @note the player ghosts are ignored.  XXX XXX XXX
6136  */
6137 static void do_cmd_knowledge_kill_count(void)
6138 {
6139         IDX i;
6140         int k, n = 0;
6141         u16b why = 2;
6142         IDX *who;
6143
6144         FILE *fff;
6145
6146         char file_name[1024];
6147
6148         s32b Total = 0;
6149
6150
6151         /* Open a new file */
6152         fff = my_fopen_temp(file_name, 1024);
6153
6154         if (!fff) {
6155             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
6156             msg_print(NULL);
6157             return;
6158         }
6159
6160         /* Allocate the "who" array */
6161         C_MAKE(who, max_r_idx, s16b);
6162
6163         {
6164                 /* Monsters slain */
6165                 int kk;
6166
6167                 for (kk = 1; kk < max_r_idx; kk++)
6168                 {
6169                         monster_race *r_ptr = &r_info[kk];
6170
6171                         if (r_ptr->flags1 & (RF1_UNIQUE))
6172                         {
6173                                 bool dead = (r_ptr->max_num == 0);
6174
6175                                 if (dead)
6176                                 {
6177                                         Total++;
6178                                 }
6179                         }
6180                         else
6181                         {
6182                                 s16b This = r_ptr->r_pkills;
6183
6184                                 if (This > 0)
6185                                 {
6186                                         Total += This;
6187                                 }
6188                         }
6189                 }
6190
6191                 if (Total < 1)
6192                         fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
6193                 else
6194 #ifdef JP
6195                         fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
6196 #else
6197                         fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
6198 #endif
6199         }
6200
6201         Total = 0;
6202
6203         /* Scan the monsters */
6204         for (i = 1; i < max_r_idx; i++)
6205         {
6206                 monster_race *r_ptr = &r_info[i];
6207
6208                 /* Use that monster */
6209                 if (r_ptr->name) who[n++] = i;
6210         }
6211
6212         /* Select the sort method */
6213         ang_sort_comp = ang_sort_comp_hook;
6214         ang_sort_swap = ang_sort_swap_hook;
6215
6216         /* Sort the array by dungeon depth of monsters */
6217         ang_sort(who, &why, n);
6218
6219         /* Scan the monster races */
6220         for (k = 0; k < n; k++)
6221         {
6222                 monster_race *r_ptr = &r_info[who[k]];
6223
6224                 if (r_ptr->flags1 & (RF1_UNIQUE))
6225                 {
6226                         bool dead = (r_ptr->max_num == 0);
6227
6228                         if (dead)
6229                         {
6230                                 /* Print a message */
6231                                 fprintf(fff, "     %s\n",
6232                                     (r_name + r_ptr->name));
6233                                 Total++;
6234                         }
6235                 }
6236                 else
6237                 {
6238                         s16b This = r_ptr->r_pkills;
6239
6240                         if (This > 0)
6241                         {
6242 #ifdef JP
6243                                 /* p,tは人と数える by ita */
6244                                 if (my_strchr("pt", r_ptr->d_char))
6245                                         fprintf(fff, "     %3d 人の %s\n", This, r_name + r_ptr->name);
6246                                 else
6247                                         fprintf(fff, "     %3d 体の %s\n", This, r_name + r_ptr->name);
6248 #else
6249                                 if (This < 2)
6250                                 {
6251                                         if (my_strstr(r_name + r_ptr->name, "coins"))
6252                                         {
6253                                                 fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
6254                                         }
6255                                         else
6256                                         {
6257                                                 fprintf(fff, "     1 %s\n", (r_name + r_ptr->name));
6258                                         }
6259                                 }
6260                                 else
6261                                 {
6262                                         char ToPlural[80];
6263                                         strcpy(ToPlural, (r_name + r_ptr->name));
6264                                         plural_aux(ToPlural);
6265                                         fprintf(fff, "     %d %s\n", This, ToPlural);
6266                                 }
6267 #endif
6268
6269
6270                                 Total += This;
6271                         }
6272                 }
6273         }
6274
6275         fprintf(fff,"----------------------------------------------\n");
6276 #ifdef JP
6277         fprintf(fff,"    合計: %lu 体を倒した。\n", (unsigned long int)Total);
6278 #else
6279         fprintf(fff,"   Total: %lu creature%s killed.\n",
6280                 (unsigned long int)Total, (Total == 1 ? "" : "s"));
6281 #endif
6282
6283
6284         /* Free the "who" array */
6285         C_KILL(who, max_r_idx, s16b);
6286
6287         /* Close the file */
6288         my_fclose(fff);
6289
6290         /* Display the file contents */
6291         show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6292
6293         /* Remove the file */
6294         fd_kill(file_name);
6295 }
6296
6297
6298 /*!
6299  * @brief モンスター情報リスト中のグループを表示する /
6300  * Display the object groups.
6301  * @param col 開始行
6302  * @param row 開始列
6303  * @param wid 表示文字数幅
6304  * @param per_page リストの表示行
6305  * @param grp_idx グループのID配列
6306  * @param group_text グループ名の文字列配列
6307  * @param grp_cur 現在の選択ID
6308  * @param grp_top 現在の選択リスト最上部ID
6309  * @return なし
6310  */
6311 static void display_group_list(int col, int row, int wid, int per_page,
6312         IDX grp_idx[], cptr group_text[], int grp_cur, int grp_top)
6313 {
6314         int i;
6315
6316         /* Display lines until done */
6317         for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6318         {
6319                 /* Get the group index */
6320                 int grp = grp_idx[grp_top + i];
6321
6322                 /* Choose a color */
6323                 byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6324
6325                 /* Erase the entire line */
6326                 Term_erase(col, row + i, wid);
6327
6328                 /* Display the group label */
6329                 c_put_str(attr, group_text[grp], row + i, col);
6330         }
6331 }
6332
6333
6334 /* 
6335  * Move the cursor in a browser window 
6336  */
6337 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt, 
6338                                                    IDX *list_cur, int list_cnt)
6339 {
6340         int d;
6341         int col = *column;
6342         IDX grp = *grp_cur;
6343         IDX list = *list_cur;
6344
6345         /* Extract direction */
6346         if (ch == ' ')
6347         {
6348                 /* Hack -- scroll up full screen */
6349                 d = 3;
6350         }
6351         else if (ch == '-')
6352         {
6353                 /* Hack -- scroll down full screen */
6354                 d = 9;
6355         }
6356         else
6357         {
6358                 d = get_keymap_dir(ch);
6359         }
6360
6361         if (!d) return;
6362
6363         /* Diagonals - hack */
6364         if ((ddx[d] > 0) && ddy[d])
6365         {
6366                 int browser_rows;
6367                 int wid, hgt;
6368
6369                 /* Get size */
6370                 Term_get_size(&wid, &hgt);
6371
6372                 browser_rows = hgt - 8;
6373
6374                 /* Browse group list */
6375                 if (!col)
6376                 {
6377                         int old_grp = grp;
6378
6379                         /* Move up or down */
6380                         grp += ddy[d] * (browser_rows - 1);
6381
6382                         /* Verify */
6383                         if (grp >= grp_cnt)     grp = grp_cnt - 1;
6384                         if (grp < 0) grp = 0;
6385                         if (grp != old_grp)     list = 0;
6386                 }
6387
6388                 /* Browse sub-list list */
6389                 else
6390                 {
6391                         /* Move up or down */
6392                         list += ddy[d] * browser_rows;
6393
6394                         /* Verify */
6395                         if (list >= list_cnt) list = list_cnt - 1;
6396                         if (list < 0) list = 0;
6397                 }
6398
6399                 (*grp_cur) = grp;
6400                 (*list_cur) = list;
6401
6402                 return;
6403         }
6404
6405         if (ddx[d])
6406         {
6407                 col += ddx[d];
6408                 if (col < 0) col = 0;
6409                 if (col > 1) col = 1;
6410
6411                 (*column) = col;
6412
6413                 return;
6414         }
6415
6416         /* Browse group list */
6417         if (!col)
6418         {
6419                 int old_grp = grp;
6420
6421                 /* Move up or down */
6422                 grp += ddy[d];
6423
6424                 /* Verify */
6425                 if (grp >= grp_cnt)     grp = grp_cnt - 1;
6426                 if (grp < 0) grp = 0;
6427                 if (grp != old_grp)     list = 0;
6428         }
6429
6430         /* Browse sub-list list */
6431         else
6432         {
6433                 /* Move up or down */
6434                 list += ddy[d];
6435
6436                 /* Verify */
6437                 if (list >= list_cnt) list = list_cnt - 1;
6438                 if (list < 0) list = 0;
6439         }
6440
6441         (*grp_cur) = grp;
6442         (*list_cur) = list;
6443 }
6444
6445
6446 /*
6447  * Display visuals.
6448  */
6449 static void display_visual_list(int col, int row, int height, int width, byte attr_top, byte char_left)
6450 {
6451         int i, j;
6452
6453         /* Clear the display lines */
6454         for (i = 0; i < height; i++)
6455         {
6456                 Term_erase(col, row + i, width);
6457         }
6458
6459         /* Bigtile mode uses double width */
6460         if (use_bigtile) width /= 2;
6461
6462         /* Display lines until done */
6463         for (i = 0; i < height; i++)
6464         {
6465                 /* Display columns until done */
6466                 for (j = 0; j < width; j++)
6467                 {
6468                         byte a;
6469                         char c;
6470                         int x = col + j;
6471                         int y = row + i;
6472                         int ia, ic;
6473
6474                         /* Bigtile mode uses double width */
6475                         if (use_bigtile) x += j;
6476
6477                         ia = attr_top + i;
6478                         ic = char_left + j;
6479
6480                         /* Ignore illegal characters */
6481                         if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6482                             (!use_graphics && ic > 0x7f))
6483                                 continue;
6484
6485                         a = (byte)ia;
6486                         c = (char)ic;
6487
6488                         /* Force correct code for both ASCII character and tile */
6489                         if (c & 0x80) a |= 0x80;
6490
6491                         /* Display symbol */
6492                         Term_queue_bigchar(x, y, a, c, 0, 0);
6493                 }
6494         }
6495 }
6496
6497
6498 /*
6499  * Place the cursor at the collect position for visual mode
6500  */
6501 static void place_visual_list_cursor(int col, int row, byte a, byte c, byte attr_top, byte char_left)
6502 {
6503         int i = (a & 0x7f) - attr_top;
6504         int j = c - char_left;
6505
6506         int x = col + j;
6507         int y = row + i;
6508
6509         /* Bigtile mode uses double width */
6510         if (use_bigtile) x += j;
6511
6512         /* Place the cursor */
6513         Term_gotoxy(x, y);
6514 }
6515
6516
6517 /*
6518  *  Clipboard variables for copy&paste in visual mode
6519  */
6520 static byte attr_idx = 0;
6521 static byte char_idx = 0;
6522
6523 /* Hack -- for feature lighting */
6524 static byte attr_idx_feat[F_LIT_MAX];
6525 static byte char_idx_feat[F_LIT_MAX];
6526
6527 /*
6528  *  Do visual mode command -- Change symbols
6529  */
6530 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6531                                 int height, int width,
6532                                 byte *attr_top_ptr, byte *char_left_ptr,
6533                                 byte *cur_attr_ptr, byte *cur_char_ptr, bool *need_redraw)
6534 {
6535         static byte attr_old = 0, char_old = 0;
6536
6537         switch (ch)
6538         {
6539         case ESCAPE:
6540                 if (*visual_list_ptr)
6541                 {
6542                         /* Cancel change */
6543                         *cur_attr_ptr = attr_old;
6544                         *cur_char_ptr = char_old;
6545                         *visual_list_ptr = FALSE;
6546
6547                         return TRUE;
6548                 }
6549                 break;
6550
6551         case '\n':
6552         case '\r':
6553                 if (*visual_list_ptr)
6554                 {
6555                         /* Accept change */
6556                         *visual_list_ptr = FALSE;
6557                         *need_redraw = TRUE;
6558
6559                         return TRUE;
6560                 }
6561                 break;
6562
6563         case 'V':
6564         case 'v':
6565                 if (!*visual_list_ptr)
6566                 {
6567                         *visual_list_ptr = TRUE;
6568
6569                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6570                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6571
6572                         attr_old = *cur_attr_ptr;
6573                         char_old = *cur_char_ptr;
6574
6575                         return TRUE;
6576                 }
6577                 break;
6578
6579         case 'C':
6580         case 'c':
6581                 {
6582                         int i;
6583
6584                         /* Set the visual */
6585                         attr_idx = *cur_attr_ptr;
6586                         char_idx = *cur_char_ptr;
6587
6588                         /* Hack -- for feature lighting */
6589                         for (i = 0; i < F_LIT_MAX; i++)
6590                         {
6591                                 attr_idx_feat[i] = 0;
6592                                 char_idx_feat[i] = 0;
6593                         }
6594                 }
6595                 return TRUE;
6596
6597         case 'P':
6598         case 'p':
6599                 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6600                 {
6601                         /* Set the char */
6602                         *cur_attr_ptr = attr_idx;
6603                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6604                         if (!*visual_list_ptr) *need_redraw = TRUE;
6605                 }
6606
6607                 if (char_idx)
6608                 {
6609                         /* Set the char */
6610                         *cur_char_ptr = char_idx;
6611                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6612                         if (!*visual_list_ptr) *need_redraw = TRUE;
6613                 }
6614
6615                 return TRUE;
6616
6617         default:
6618                 if (*visual_list_ptr)
6619                 {
6620                         int eff_width;
6621                         int d = get_keymap_dir(ch);
6622                         byte a = (*cur_attr_ptr & 0x7f);
6623                         byte c = *cur_char_ptr;
6624
6625                         if (use_bigtile) eff_width = width / 2;
6626                         else eff_width = width;
6627
6628                         /* Restrict direction */
6629                         if ((a == 0) && (ddy[d] < 0)) d = 0;
6630                         if ((c == 0) && (ddx[d] < 0)) d = 0;
6631                         if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6632                         if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6633
6634                         a += ddy[d];
6635                         c += ddx[d];
6636
6637                         /* Force correct code for both ASCII character and tile */
6638                         if (c & 0x80) a |= 0x80;
6639
6640                         /* Set the visual */
6641                         *cur_attr_ptr = a;
6642                         *cur_char_ptr = c;
6643
6644
6645                         /* Move the frame */
6646                         if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6647                         if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6648                         if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6649                         if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6650                         return TRUE;
6651                 }
6652                 break;
6653         }
6654
6655         /* Visual mode command is not used */
6656         return FALSE;
6657 }
6658
6659
6660 /*
6661  * Display the monsters in a group.
6662  */
6663 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6664         int mon_cur, int mon_top, bool visual_only)
6665 {
6666         int i;
6667
6668         /* Display lines until done */
6669         for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6670         {
6671                 byte attr;
6672
6673                 /* Get the race index */
6674                 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6675
6676                 /* Access the race */
6677                 monster_race *r_ptr = &r_info[r_idx];
6678
6679                 /* Choose a color */
6680                 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6681
6682                 /* Display the name */
6683                 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6684
6685                 /* Hack -- visual_list mode */
6686                 if (per_page == 1)
6687                 {
6688                         c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6689                 }
6690                 if (p_ptr->wizard || visual_only)
6691                 {
6692                         c_prt(attr, format("%d", r_idx), row + i, 62);
6693                 }
6694
6695                 /* Erase chars before overwritten by the race letter */
6696                 Term_erase(69, row + i, 255);
6697
6698                 /* Display symbol */
6699                 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6700
6701                 if (!visual_only)
6702                 {
6703                         /* Display kills */
6704                         if (!(r_ptr->flags1 & RF1_UNIQUE)) 
6705                                 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6706                         else 
6707                                 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), 
6708                                                   (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6709                 }
6710         }
6711
6712         /* Clear remaining lines */
6713         for (; i < per_page; i++)
6714         {
6715                 Term_erase(col, row + i, 255);
6716         }
6717 }
6718
6719
6720 /*
6721  * Display known monsters.
6722  */
6723 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6724 {
6725         IDX i;
6726         int len, max;
6727         IDX grp_cur, grp_top, old_grp_cur;
6728         IDX mon_cur, mon_top;
6729         IDX grp_cnt, grp_idx[100];
6730         IDX mon_cnt;
6731         IDX *mon_idx;
6732
6733         int column = 0;
6734         bool flag;
6735         bool redraw;
6736
6737         bool visual_list = FALSE;
6738         byte attr_top = 0, char_left = 0;
6739
6740         int browser_rows;
6741         TERM_POSITION wid, hgt;
6742
6743         BIT_FLAGS8 mode;
6744
6745         /* Get size */
6746         Term_get_size(&wid, &hgt);
6747
6748         browser_rows = hgt - 8;
6749
6750         /* Allocate the "mon_idx" array */
6751         C_MAKE(mon_idx, max_r_idx, s16b);
6752
6753         max = 0;
6754         grp_cnt = 0;
6755
6756         if (direct_r_idx < 0)
6757         {
6758                 mode = visual_only ? 0x03 : 0x01;
6759
6760                 /* Check every group */
6761                 for (i = 0; monster_group_text[i] != NULL; i++)
6762                 {
6763                         /* Measure the label */
6764                         len = strlen(monster_group_text[i]);
6765
6766                         /* Save the maximum length */
6767                         if (len > max) max = len;
6768
6769                         /* See if any monsters are known */
6770                         if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6771                         {
6772                                 /* Build a list of groups with known monsters */
6773                                 grp_idx[grp_cnt++] = i;
6774                         }
6775                 }
6776
6777                 mon_cnt = 0;
6778         }
6779         else
6780         {
6781                 mon_idx[0] = direct_r_idx;
6782                 mon_cnt = 1;
6783
6784                 /* Terminate the list */
6785                 mon_idx[1] = -1;
6786
6787                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6788                         &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6789         }
6790
6791         /* Terminate the list */
6792         grp_idx[grp_cnt] = -1;
6793
6794         old_grp_cur = -1;
6795         grp_cur = grp_top = 0;
6796         mon_cur = mon_top = 0;
6797
6798         flag = FALSE;
6799         redraw = TRUE;
6800
6801         mode = visual_only ? 0x02 : 0x00;
6802
6803         while (!flag)
6804         {
6805                 char ch;
6806                 monster_race *r_ptr;
6807
6808                 if (redraw)
6809                 {
6810                         clear_from(0);
6811
6812 #ifdef JP
6813                         prt(format("%s - モンスター", !visual_only ? "知識" : "表示"), 2, 0);
6814                         if (direct_r_idx < 0) prt("グループ", 4, 0);
6815                         prt("名前", 4, max + 3);
6816                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6817                         prt("文字", 4, 67);
6818                         if (!visual_only) prt("殺害数", 4, 72);
6819 #else
6820                         prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6821                         if (direct_r_idx < 0) prt("Group", 4, 0);
6822                         prt("Name", 4, max + 3);
6823                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6824                         prt("Sym", 4, 68);
6825                         if (!visual_only) prt("Kills", 4, 73);
6826 #endif
6827
6828                         for (i = 0; i < 78; i++)
6829                         {
6830                                 Term_putch(i, 5, TERM_WHITE, '=');
6831                         }
6832
6833                         if (direct_r_idx < 0)
6834                         {
6835                                 for (i = 0; i < browser_rows; i++)
6836                                 {
6837                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6838                                 }
6839                         }
6840
6841                         redraw = FALSE;
6842                 }
6843
6844                 if (direct_r_idx < 0)
6845                 {
6846                         /* Scroll group list */
6847                         if (grp_cur < grp_top) grp_top = grp_cur;
6848                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6849
6850                         /* Display a list of monster groups */
6851                         display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6852
6853                         if (old_grp_cur != grp_cur)
6854                         {
6855                                 old_grp_cur = grp_cur;
6856
6857                                 /* Get a list of monsters in the current group */
6858                                 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6859                         }
6860
6861                         /* Scroll monster list */
6862                         while (mon_cur < mon_top)
6863                                 mon_top = MAX(0, mon_top - browser_rows/2);
6864                         while (mon_cur >= mon_top + browser_rows)
6865                                 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6866                 }
6867
6868                 if (!visual_list)
6869                 {
6870                         /* Display a list of monsters in the current group */
6871                         display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6872                 }
6873                 else
6874                 {
6875                         mon_top = mon_cur;
6876
6877                         /* Display a monster name */
6878                         display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6879
6880                         /* Display visual list below first monster */
6881                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6882                 }
6883
6884                 /* Prompt */
6885 #ifdef JP
6886                 prt(format("<方向>%s%s%s, ESC",
6887                         (!visual_list && !visual_only) ? ", 'r'で思い出を見る" : "",
6888                         visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6889                         (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6890                         hgt - 1, 0);
6891 #else
6892                 prt(format("<dir>%s%s%s, ESC",
6893                         (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6894                         visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6895                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6896                         hgt - 1, 0);
6897 #endif
6898
6899                 /* Get the current monster */
6900                 r_ptr = &r_info[mon_idx[mon_cur]];
6901
6902                 if (!visual_only)
6903                 {
6904                         /* Mega Hack -- track this monster race */
6905                         if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6906
6907                         /* Hack -- handle stuff */
6908                         handle_stuff();
6909                 }
6910
6911                 if (visual_list)
6912                 {
6913                         place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6914                 }
6915                 else if (!column)
6916                 {
6917                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
6918                 }
6919                 else
6920                 {
6921                         Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6922                 }
6923
6924                 ch = inkey();
6925
6926                 /* Do visual mode command if needed */
6927                 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))
6928                 {
6929                         if (direct_r_idx >= 0)
6930                         {
6931                                 switch (ch)
6932                                 {
6933                                 case '\n':
6934                                 case '\r':
6935                                 case ESCAPE:
6936                                         flag = TRUE;
6937                                         break;
6938                                 }
6939                         }
6940                         continue;
6941                 }
6942
6943                 switch (ch)
6944                 {
6945                         case ESCAPE:
6946                         {
6947                                 flag = TRUE;
6948                                 break;
6949                         }
6950
6951                         case 'R':
6952                         case 'r':
6953                         {
6954                                 /* Recall on screen */
6955                                 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6956                                 {
6957                                         screen_roff(mon_idx[mon_cur], 0);
6958
6959                                         (void)inkey();
6960
6961                                         redraw = TRUE;
6962                                 }
6963                                 break;
6964                         }
6965
6966                         default:
6967                         {
6968                                 /* Move the cursor */
6969                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6970
6971                                 break;
6972                         }
6973                 }
6974         }
6975
6976         /* Free the "mon_idx" array */
6977         C_KILL(mon_idx, max_r_idx, s16b);
6978 }
6979
6980
6981 /*
6982  * Display the objects in a group.
6983  */
6984 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6985         int object_cur, int object_top, bool visual_only)
6986 {
6987         int i;
6988
6989         /* Display lines until done */
6990         for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6991         {
6992                 char o_name[80];
6993                 byte a, c;
6994                 object_kind *flavor_k_ptr;
6995
6996                 /* Get the object index */
6997                 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6998
6999                 /* Access the object */
7000                 object_kind *k_ptr = &k_info[k_idx];
7001
7002                 /* Choose a color */
7003                 byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
7004                 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
7005
7006
7007                 if (!visual_only && k_ptr->flavor)
7008                 {
7009                         /* Appearance of this object is shuffled */
7010                         flavor_k_ptr = &k_info[k_ptr->flavor];
7011                 }
7012                 else
7013                 {
7014                         /* Appearance of this object is very normal */
7015                         flavor_k_ptr = k_ptr;
7016                 }
7017
7018
7019
7020                 attr = ((i + object_top == object_cur) ? cursor : attr);
7021
7022                 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
7023                 {
7024                         /* Tidy name */
7025                         strip_name(o_name, k_idx);
7026                 }
7027                 else
7028                 {
7029                         /* Flavor name */
7030                         strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
7031                 }
7032
7033                 /* Display the name */
7034                 c_prt(attr, o_name, row + i, col);
7035
7036                 /* Hack -- visual_list mode */
7037                 if (per_page == 1)
7038                 {
7039                         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);
7040                 }
7041                 if (p_ptr->wizard || visual_only)
7042                 {
7043                         c_prt(attr, format("%d", k_idx), row + i, 70);
7044                 }
7045
7046                 a = flavor_k_ptr->x_attr;
7047                 c = flavor_k_ptr->x_char;
7048
7049                 /* Display symbol */
7050                 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
7051         }
7052
7053         /* Clear remaining lines */
7054         for (; i < per_page; i++)
7055         {
7056                 Term_erase(col, row + i, 255);
7057         }
7058 }
7059
7060 /*
7061  * Describe fake object
7062  */
7063 static void desc_obj_fake(IDX k_idx)
7064 {
7065         object_type *o_ptr;
7066         object_type object_type_body;
7067
7068         /* Get local object */
7069         o_ptr = &object_type_body;
7070
7071         /* Wipe the object */
7072         object_wipe(o_ptr);
7073
7074         /* Create the artifact */
7075         object_prep(o_ptr, k_idx);
7076
7077         /* It's fully know */
7078         o_ptr->ident |= IDENT_KNOWN;
7079
7080         /* Track the object */
7081         /* object_actual_track(o_ptr); */
7082
7083         /* Hack - mark as fake */
7084         /* term_obj_real = FALSE; */
7085
7086         /* Hack -- Handle stuff */
7087         handle_stuff();
7088
7089         if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
7090         {
7091                 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
7092                 msg_print(NULL);
7093         }
7094 }
7095
7096
7097
7098 /*
7099  * Display known objects
7100  */
7101 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
7102 {
7103         IDX i;
7104         int len, max;
7105         IDX grp_cur, grp_top, old_grp_cur;
7106         IDX object_old, object_cur, object_top;
7107         int grp_cnt;
7108         IDX grp_idx[100];
7109         int object_cnt;
7110         IDX *object_idx;
7111
7112         int column = 0;
7113         bool flag;
7114         bool redraw;
7115
7116         bool visual_list = FALSE;
7117         byte attr_top = 0, char_left = 0;
7118
7119         int browser_rows;
7120         int wid, hgt;
7121
7122         byte mode;
7123
7124         /* Get size */
7125         Term_get_size(&wid, &hgt);
7126
7127         browser_rows = hgt - 8;
7128
7129         /* Allocate the "object_idx" array */
7130         C_MAKE(object_idx, max_k_idx, IDX);
7131
7132         max = 0;
7133         grp_cnt = 0;
7134
7135         if (direct_k_idx < 0)
7136         {
7137                 mode = visual_only ? 0x03 : 0x01;
7138
7139                 /* Check every group */
7140                 for (i = 0; object_group_text[i] != NULL; i++)
7141                 {
7142                         /* Measure the label */
7143                         len = strlen(object_group_text[i]);
7144
7145                         /* Save the maximum length */
7146                         if (len > max) max = len;
7147
7148                         /* See if any monsters are known */
7149                         if (collect_objects(i, object_idx, mode))
7150                         {
7151                                 /* Build a list of groups with known monsters */
7152                                 grp_idx[grp_cnt++] = i;
7153                         }
7154                 }
7155
7156                 object_old = -1;
7157                 object_cnt = 0;
7158         }
7159         else
7160         {
7161                 object_kind *k_ptr = &k_info[direct_k_idx];
7162                 object_kind *flavor_k_ptr;
7163
7164                 if (!visual_only && k_ptr->flavor)
7165                 {
7166                         /* Appearance of this object is shuffled */
7167                         flavor_k_ptr = &k_info[k_ptr->flavor];
7168                 }
7169                 else
7170                 {
7171                         /* Appearance of this object is very normal */
7172                         flavor_k_ptr = k_ptr;
7173                 }
7174
7175                 object_idx[0] = direct_k_idx;
7176                 object_old = direct_k_idx;
7177                 object_cnt = 1;
7178
7179                 /* Terminate the list */
7180                 object_idx[1] = -1;
7181
7182                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7183                         &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
7184         }
7185
7186         /* Terminate the list */
7187         grp_idx[grp_cnt] = -1;
7188
7189         old_grp_cur = -1;
7190         grp_cur = grp_top = 0;
7191         object_cur = object_top = 0;
7192
7193         flag = FALSE;
7194         redraw = TRUE;
7195
7196         mode = visual_only ? 0x02 : 0x00;
7197
7198         while (!flag)
7199         {
7200                 char ch;
7201                 object_kind *k_ptr, *flavor_k_ptr;
7202
7203                 if (redraw)
7204                 {
7205                         clear_from(0);
7206
7207 #ifdef JP
7208                         prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
7209                         if (direct_k_idx < 0) prt("グループ", 4, 0);
7210                         prt("名前", 4, max + 3);
7211                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
7212                         prt("文字", 4, 74);
7213 #else
7214                         prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
7215                         if (direct_k_idx < 0) prt("Group", 4, 0);
7216                         prt("Name", 4, max + 3);
7217                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
7218                         prt("Sym", 4, 75);
7219 #endif
7220
7221                         for (i = 0; i < 78; i++)
7222                         {
7223                                 Term_putch(i, 5, TERM_WHITE, '=');
7224                         }
7225
7226                         if (direct_k_idx < 0)
7227                         {
7228                                 for (i = 0; i < browser_rows; i++)
7229                                 {
7230                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7231                                 }
7232                         }
7233
7234                         redraw = FALSE;
7235                 }
7236
7237                 if (direct_k_idx < 0)
7238                 {
7239                         /* Scroll group list */
7240                         if (grp_cur < grp_top) grp_top = grp_cur;
7241                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7242
7243                         /* Display a list of object groups */
7244                         display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
7245
7246                         if (old_grp_cur != grp_cur)
7247                         {
7248                                 old_grp_cur = grp_cur;
7249
7250                                 /* Get a list of objects in the current group */
7251                                 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
7252                         }
7253
7254                         /* Scroll object list */
7255                         while (object_cur < object_top)
7256                                 object_top = MAX(0, object_top - browser_rows/2);
7257                         while (object_cur >= object_top + browser_rows)
7258                                 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
7259                 }
7260
7261                 if (!visual_list)
7262                 {
7263                         /* Display a list of objects in the current group */
7264                         display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
7265                 }
7266                 else
7267                 {
7268                         object_top = object_cur;
7269
7270                         /* Display a list of objects in the current group */
7271                         display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
7272
7273                         /* Display visual list below first object */
7274                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7275                 }
7276
7277                 /* Get the current object */
7278                 k_ptr = &k_info[object_idx[object_cur]];
7279
7280                 if (!visual_only && k_ptr->flavor)
7281                 {
7282                         /* Appearance of this object is shuffled */
7283                         flavor_k_ptr = &k_info[k_ptr->flavor];
7284                 }
7285                 else
7286                 {
7287                         /* Appearance of this object is very normal */
7288                         flavor_k_ptr = k_ptr;
7289                 }
7290
7291                 /* Prompt */
7292 #ifdef JP
7293                 prt(format("<方向>%s%s%s, ESC",
7294                         (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7295                         visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7296                         (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7297                         hgt - 1, 0);
7298 #else
7299                 prt(format("<dir>%s%s%s, ESC",
7300                         (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7301                         visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7302                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7303                         hgt - 1, 0);
7304 #endif
7305
7306                 if (!visual_only)
7307                 {
7308                         /* Mega Hack -- track this object */
7309                         if (object_cnt) object_kind_track(object_idx[object_cur]);
7310
7311                         /* The "current" object changed */
7312                         if (object_old != object_idx[object_cur])
7313                         {
7314                                 /* Hack -- handle stuff */
7315                                 handle_stuff();
7316
7317                                 /* Remember the "current" object */
7318                                 object_old = object_idx[object_cur];
7319                         }
7320                 }
7321
7322                 if (visual_list)
7323                 {
7324                         place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7325                 }
7326                 else if (!column)
7327                 {
7328                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
7329                 }
7330                 else
7331                 {
7332                         Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7333                 }
7334
7335                 ch = inkey();
7336
7337                 /* Do visual mode command if needed */
7338                 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))
7339                 {
7340                         if (direct_k_idx >= 0)
7341                         {
7342                                 switch (ch)
7343                                 {
7344                                 case '\n':
7345                                 case '\r':
7346                                 case ESCAPE:
7347                                         flag = TRUE;
7348                                         break;
7349                                 }
7350                         }
7351                         continue;
7352                 }
7353
7354                 switch (ch)
7355                 {
7356                         case ESCAPE:
7357                         {
7358                                 flag = TRUE;
7359                                 break;
7360                         }
7361
7362                         case 'R':
7363                         case 'r':
7364                         {
7365                                 /* Recall on screen */
7366                                 if (!visual_list && !visual_only && (grp_cnt > 0))
7367                                 {
7368                                         desc_obj_fake(object_idx[object_cur]);
7369                                         redraw = TRUE;
7370                                 }
7371                                 break;
7372                         }
7373
7374                         default:
7375                         {
7376                                 /* Move the cursor */
7377                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7378                                 break;
7379                         }
7380                 }
7381         }
7382
7383         /* Free the "object_idx" array */
7384         C_KILL(object_idx, max_k_idx, IDX);
7385 }
7386
7387
7388 /*
7389  * Display the features in a group.
7390  */
7391 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7392         FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7393 {
7394         int lit_col[F_LIT_MAX], i, j;
7395         int f_idx_col = use_bigtile ? 62 : 64;
7396
7397         /* Correct columns 1 and 4 */
7398         lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7399         for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7400                 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7401
7402         /* Display lines until done */
7403         for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7404         {
7405                 byte attr;
7406
7407                 /* Get the index */
7408                 FEAT_IDX f_idx = feat_idx[feat_top + i];
7409
7410                 /* Access the index */
7411                 feature_type *f_ptr = &f_info[f_idx];
7412
7413                 int row_i = row + i;
7414
7415                 /* Choose a color */
7416                 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7417
7418                 /* Display the name */
7419                 c_prt(attr, f_name + f_ptr->name, row_i, col);
7420
7421                 /* Hack -- visual_list mode */
7422                 if (per_page == 1)
7423                 {
7424                         /* Display lighting level */
7425                         c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7426
7427                         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));
7428                 }
7429                 if (p_ptr->wizard || visual_only)
7430                 {
7431                         c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7432                 }
7433
7434                 /* Display symbol */
7435                 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);
7436
7437                 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7438                 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7439                 {
7440                         Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7441                 }
7442                 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7443
7444                 /* Mega-hack -- Use non-standard colour */
7445                 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7446                 {
7447                         Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7448                 }
7449         }
7450
7451         /* Clear remaining lines */
7452         for (; i < per_page; i++)
7453         {
7454                 Term_erase(col, row + i, 255);
7455         }
7456 }
7457
7458
7459 /*
7460  * Interact with feature visuals.
7461  */
7462 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7463 {
7464         IDX i;
7465         int len, max;
7466         IDX grp_cur, grp_top, old_grp_cur;
7467         IDX feat_cur, feat_top;
7468         int grp_cnt;
7469         IDX grp_idx[100];
7470         int feat_cnt;
7471         IDX *feat_idx;
7472
7473         int column = 0;
7474         bool flag;
7475         bool redraw;
7476
7477         bool visual_list = FALSE;
7478         byte attr_top = 0, char_left = 0;
7479
7480         int browser_rows;
7481         int wid, hgt;
7482
7483         byte attr_old[F_LIT_MAX];
7484         byte char_old[F_LIT_MAX];
7485         byte *cur_attr_ptr, *cur_char_ptr;
7486
7487         (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7488         (void)C_WIPE(char_old, F_LIT_MAX, byte);
7489
7490         /* Get size */
7491         Term_get_size(&wid, &hgt);
7492
7493         browser_rows = hgt - 8;
7494
7495         /* Allocate the "feat_idx" array */
7496         C_MAKE(feat_idx, max_f_idx, IDX);
7497
7498         max = 0;
7499         grp_cnt = 0;
7500
7501         if (direct_f_idx < 0)
7502         {
7503                 /* Check every group */
7504                 for (i = 0; feature_group_text[i] != NULL; i++)
7505                 {
7506                         /* Measure the label */
7507                         len = strlen(feature_group_text[i]);
7508
7509                         /* Save the maximum length */
7510                         if (len > max) max = len;
7511
7512                         /* See if any features are known */
7513                         if (collect_features(i, feat_idx, 0x01))
7514                         {
7515                                 /* Build a list of groups with known features */
7516                                 grp_idx[grp_cnt++] = i;
7517                         }
7518                 }
7519
7520                 feat_cnt = 0;
7521         }
7522         else
7523         {
7524                 feature_type *f_ptr = &f_info[direct_f_idx];
7525
7526                 feat_idx[0] = direct_f_idx;
7527                 feat_cnt = 1;
7528
7529                 /* Terminate the list */
7530                 feat_idx[1] = -1;
7531
7532                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7533                         &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7534
7535                 for (i = 0; i < F_LIT_MAX; i++)
7536                 {
7537                         attr_old[i] = f_ptr->x_attr[i];
7538                         char_old[i] = f_ptr->x_char[i];
7539                 }
7540         }
7541
7542         /* Terminate the list */
7543         grp_idx[grp_cnt] = -1;
7544
7545         old_grp_cur = -1;
7546         grp_cur = grp_top = 0;
7547         feat_cur = feat_top = 0;
7548
7549         flag = FALSE;
7550         redraw = TRUE;
7551
7552         while (!flag)
7553         {
7554                 char ch;
7555                 feature_type *f_ptr;
7556
7557                 if (redraw)
7558                 {
7559                         clear_from(0);
7560
7561 #ifdef JP
7562                         prt("表示 - 地形", 2, 0);
7563                         if (direct_f_idx < 0) prt("グループ", 4, 0);
7564                         prt("名前", 4, max + 3);
7565                         if (use_bigtile)
7566                         {
7567                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7568                                 prt("文字 ( l/ d)", 4, 66);
7569                         }
7570                         else
7571                         {
7572                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7573                                 prt("文字 (l/d)", 4, 68);
7574                         }
7575 #else
7576                         prt("Visuals - features", 2, 0);
7577                         if (direct_f_idx < 0) prt("Group", 4, 0);
7578                         prt("Name", 4, max + 3);
7579                         if (use_bigtile)
7580                         {
7581                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7582                                 prt("Sym ( l/ d)", 4, 67);
7583                         }
7584                         else
7585                         {
7586                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7587                                 prt("Sym (l/d)", 4, 69);
7588                         }
7589 #endif
7590
7591                         for (i = 0; i < 78; i++)
7592                         {
7593                                 Term_putch(i, 5, TERM_WHITE, '=');
7594                         }
7595
7596                         if (direct_f_idx < 0)
7597                         {
7598                                 for (i = 0; i < browser_rows; i++)
7599                                 {
7600                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7601                                 }
7602                         }
7603
7604                         redraw = FALSE;
7605                 }
7606
7607                 if (direct_f_idx < 0)
7608                 {
7609                         /* Scroll group list */
7610                         if (grp_cur < grp_top) grp_top = grp_cur;
7611                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7612
7613                         /* Display a list of feature groups */
7614                         display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7615
7616                         if (old_grp_cur != grp_cur)
7617                         {
7618                                 old_grp_cur = grp_cur;
7619
7620                                 /* Get a list of features in the current group */
7621                                 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7622                         }
7623
7624                         /* Scroll feature list */
7625                         while (feat_cur < feat_top)
7626                                 feat_top = MAX(0, feat_top - browser_rows/2);
7627                         while (feat_cur >= feat_top + browser_rows)
7628                                 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7629                 }
7630
7631                 if (!visual_list)
7632                 {
7633                         /* Display a list of features in the current group */
7634                         display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7635                 }
7636                 else
7637                 {
7638                         feat_top = feat_cur;
7639
7640                         /* Display a list of features in the current group */
7641                         display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7642
7643                         /* Display visual list below first object */
7644                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7645                 }
7646
7647                 /* Prompt */
7648 #ifdef JP
7649                 prt(format("<方向>%s, 'd'で標準光源効果%s, ESC",
7650                         visual_list ? ", ENTERで決定, 'a'で対象明度変更" : ", 'v'でシンボル変更",
7651                         (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7652                         hgt - 1, 0);
7653 #else
7654                 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
7655                         visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
7656                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7657                         hgt - 1, 0);
7658 #endif
7659
7660                 /* Get the current feature */
7661                 f_ptr = &f_info[feat_idx[feat_cur]];
7662                 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7663                 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7664
7665                 if (visual_list)
7666                 {
7667                         place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7668                 }
7669                 else if (!column)
7670                 {
7671                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
7672                 }
7673                 else
7674                 {
7675                         Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7676                 }
7677
7678                 ch = inkey();
7679
7680                 if (visual_list && ((ch == 'A') || (ch == 'a')))
7681                 {
7682                         int prev_lighting_level = *lighting_level;
7683
7684                         if (ch == 'A')
7685                         {
7686                                 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7687                                 else (*lighting_level)--;
7688                         }
7689                         else
7690                         {
7691                                 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7692                                 else (*lighting_level)++;
7693                         }
7694
7695                         if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7696                                 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7697
7698                         if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7699                                 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7700
7701                         continue;
7702                 }
7703
7704                 else if ((ch == 'D') || (ch == 'd'))
7705                 {
7706                         byte prev_x_attr = f_ptr->x_attr[*lighting_level];
7707                         byte prev_x_char = f_ptr->x_char[*lighting_level];
7708
7709                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7710
7711                         if (visual_list)
7712                         {
7713                                 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7714                                          attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7715
7716                                 if (prev_x_char != f_ptr->x_char[*lighting_level])
7717                                         char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7718                         }
7719                         else *need_redraw = TRUE;
7720
7721                         continue;
7722                 }
7723
7724                 /* Do visual mode command if needed */
7725                 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))
7726                 {
7727                         switch (ch)
7728                         {
7729                         /* Restore previous visual settings */
7730                         case ESCAPE:
7731                                 for (i = 0; i < F_LIT_MAX; i++)
7732                                 {
7733                                         f_ptr->x_attr[i] = attr_old[i];
7734                                         f_ptr->x_char[i] = char_old[i];
7735                                 }
7736
7737                                 /* Fall through */
7738
7739                         case '\n':
7740                         case '\r':
7741                                 if (direct_f_idx >= 0) flag = TRUE;
7742                                 else *lighting_level = F_LIT_STANDARD;
7743                                 break;
7744
7745                         /* Preserve current visual settings */
7746                         case 'V':
7747                         case 'v':
7748                                 for (i = 0; i < F_LIT_MAX; i++)
7749                                 {
7750                                         attr_old[i] = f_ptr->x_attr[i];
7751                                         char_old[i] = f_ptr->x_char[i];
7752                                 }
7753                                 *lighting_level = F_LIT_STANDARD;
7754                                 break;
7755
7756                         case 'C':
7757                         case 'c':
7758                                 if (!visual_list)
7759                                 {
7760                                         for (i = 0; i < F_LIT_MAX; i++)
7761                                         {
7762                                                 attr_idx_feat[i] = f_ptr->x_attr[i];
7763                                                 char_idx_feat[i] = f_ptr->x_char[i];
7764                                         }
7765                                 }
7766                                 break;
7767
7768                         case 'P':
7769                         case 'p':
7770                                 if (!visual_list)
7771                                 {
7772                                         /* Allow TERM_DARK text */
7773                                         for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7774                                         {
7775                                                 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7776                                                 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7777                                         }
7778                                 }
7779                                 break;
7780                         }
7781                         continue;
7782                 }
7783
7784                 switch (ch)
7785                 {
7786                         case ESCAPE:
7787                         {
7788                                 flag = TRUE;
7789                                 break;
7790                         }
7791
7792                         default:
7793                         {
7794                                 /* Move the cursor */
7795                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7796                                 break;
7797                         }
7798                 }
7799         }
7800
7801         /* Free the "feat_idx" array */
7802         C_KILL(feat_idx, max_f_idx, IDX);
7803 }
7804
7805
7806 /*
7807  * List wanted monsters
7808  */
7809 static void do_cmd_knowledge_kubi(void)
7810 {
7811         int i;
7812         FILE *fff;
7813         
7814         char file_name[1024];
7815         
7816         
7817         /* Open a new file */
7818         fff = my_fopen_temp(file_name, 1024);
7819         if (!fff) {
7820             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7821             msg_print(NULL);
7822             return;
7823         }
7824         
7825         if (fff)
7826         {
7827                 bool listed = FALSE;
7828
7829 #ifdef JP
7830                 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7831                 fprintf(fff, "\n");
7832                 fprintf(fff, "賞金首リスト\n");
7833 #else
7834                 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7835                 fprintf(fff, "\n");
7836                 fprintf(fff, "List of wanted monsters\n");
7837 #endif
7838                 fprintf(fff, "----------------------------------------------\n");
7839
7840                 for (i = 0; i < MAX_KUBI; i++)
7841                 {
7842                         if (kubi_r_idx[i] <= 10000)
7843                         {
7844                                 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7845
7846                                 listed = TRUE;
7847                         }
7848                 }
7849
7850                 if (!listed)
7851                 {
7852                         fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7853                 }
7854         }
7855         
7856         /* Close the file */
7857         my_fclose(fff);
7858         
7859         /* Display the file contents */
7860         show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7861         
7862         /* Remove the file */
7863         fd_kill(file_name);
7864 }
7865
7866 /*
7867  * List virtues & status
7868  */
7869 static void do_cmd_knowledge_virtues(void)
7870 {
7871         FILE *fff;
7872         
7873         char file_name[1024];
7874         
7875         
7876         /* Open a new file */
7877         fff = my_fopen_temp(file_name, 1024);
7878         if (!fff) {
7879             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7880             msg_print(NULL);
7881             return;
7882         }
7883         
7884         if (fff)
7885         {
7886                 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7887                 dump_virtues(fff);
7888         }
7889         
7890         /* Close the file */
7891         my_fclose(fff);
7892         
7893         /* Display the file contents */
7894         show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7895         
7896         /* Remove the file */
7897         fd_kill(file_name);
7898 }
7899
7900 /*
7901 * Dungeon
7902 *
7903 */
7904 static void do_cmd_knowledge_dungeon(void)
7905 {
7906         FILE *fff;
7907         
7908         char file_name[1024];
7909         int i;
7910         
7911         
7912         /* Open a new file */
7913         fff = my_fopen_temp(file_name, 1024);
7914         if (!fff) {
7915             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7916             msg_print(NULL);
7917             return;
7918         }
7919         
7920         if (fff)
7921         {
7922                 for (i = 1; i < max_d_idx; i++)
7923                 {
7924                         bool seiha = FALSE;
7925
7926                         if (!d_info[i].maxdepth) continue;
7927                         if (!max_dlv[i]) continue;
7928                         if (d_info[i].final_guardian)
7929                         {
7930                                 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7931                         }
7932                         else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7933                         
7934                         fprintf(fff, _("%c%-12s :  %3d 階\n", "%c%-16s :  level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7935                 }
7936         }
7937         
7938         /* Close the file */
7939         my_fclose(fff);
7940         
7941         /* Display the file contents */
7942         show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7943         
7944         /* Remove the file */
7945         fd_kill(file_name);
7946 }
7947
7948 /*
7949 * List virtues & status
7950 *
7951 */
7952 static void do_cmd_knowledge_stat(void)
7953 {
7954         FILE *fff;
7955         
7956         char file_name[1024];
7957         int percent, v_nr;
7958         
7959         /* Open a new file */
7960         fff = my_fopen_temp(file_name, 1024);
7961         if (!fff) {
7962             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7963             msg_print(NULL);
7964             return;
7965         }
7966         
7967         if (fff)
7968         {
7969                 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7970                         (2 * p_ptr->hitdie +
7971                         ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7972
7973 #ifdef JP
7974                 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7975                 else fprintf(fff, "現在の体力ランク : ???\n\n");
7976                 fprintf(fff, "能力の最大値\n\n");
7977 #else
7978                 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7979                 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7980                 fprintf(fff, "Limits of maximum stats\n\n");
7981 #endif
7982                 for (v_nr = 0; v_nr < 6; v_nr++)
7983                 {
7984                         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);
7985                         else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7986                 }
7987         }
7988
7989         dump_yourself(fff);
7990
7991         /* Close the file */
7992         my_fclose(fff);
7993         
7994         /* Display the file contents */
7995         show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7996         
7997         /* Remove the file */
7998         fd_kill(file_name);
7999 }
8000
8001
8002 /*
8003  * Print all active quests
8004  */
8005 static void do_cmd_knowledge_quests_current(FILE *fff)
8006 {
8007         char tmp_str[120];
8008         char rand_tmp_str[120] = "\0";
8009         char name[80];
8010         monster_race *r_ptr;
8011         IDX i;
8012         int rand_level = 100;
8013         int total = 0;
8014
8015         fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
8016
8017         for (i = 1; i < max_quests; i++)
8018         {
8019                 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
8020                         ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
8021                         (quest[i].status == QUEST_STATUS_COMPLETED))
8022                 {
8023                         /* Set the quest number temporary */
8024                         IDX old_quest = p_ptr->inside_quest;
8025                         int j;
8026
8027                         /* Clear the text */
8028                         for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
8029                         quest_text_line = 0;
8030
8031                         p_ptr->inside_quest = i;
8032
8033                         /* Get the quest text */
8034                         init_flags = INIT_SHOW_TEXT;
8035
8036                         process_dungeon_file("q_info.txt", 0, 0, 0, 0);
8037
8038                         /* Reset the old quest number */
8039                         p_ptr->inside_quest = old_quest;
8040
8041                         /* No info from "silent" quests */
8042                         if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8043
8044                         total++;
8045
8046                         if (quest[i].type != QUEST_TYPE_RANDOM)
8047                         {
8048                                 char note[80] = "\0";
8049
8050                                 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
8051                                 {
8052                                         switch (quest[i].type)
8053                                         {
8054                                         case QUEST_TYPE_KILL_LEVEL:
8055                                         case QUEST_TYPE_KILL_ANY_LEVEL:
8056                                                 r_ptr = &r_info[quest[i].r_idx];
8057                                                 strcpy(name, r_name + r_ptr->name);
8058                                                 if (quest[i].max_num > 1)
8059                                                 {
8060 #ifdef JP
8061                                                         sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
8062                                                                 quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
8063 #else
8064                                                         plural_aux(name);
8065                                                         sprintf(note," - kill %d %s, have killed %d.",
8066                                                                 quest[i].max_num, name, quest[i].cur_num);
8067 #endif
8068                                                 }
8069                                                 else
8070                                                         sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
8071                                                 break;
8072
8073                                         case QUEST_TYPE_FIND_ARTIFACT:
8074                                                 if (quest[i].k_idx)
8075                                                 {
8076                                                         artifact_type *a_ptr = &a_info[quest[i].k_idx];
8077                                                         object_type forge;
8078                                                         object_type *q_ptr = &forge;
8079                                                         IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
8080                                                         object_prep(q_ptr, k_idx);
8081                                                         q_ptr->name1 = quest[i].k_idx;
8082                                                         q_ptr->ident = IDENT_STORE;
8083                                                         object_desc(name, q_ptr, OD_NAME_ONLY);
8084                                                 }
8085                                                 sprintf(note,_("\n   - %sを見つけ出す。", "\n   - Find out %s."), name);
8086                                                 break;
8087                                         case QUEST_TYPE_FIND_EXIT:
8088                                                 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
8089                                                 break;
8090
8091                                         case QUEST_TYPE_KILL_NUMBER:
8092 #ifdef JP
8093                                                 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
8094                                                         quest[i].max_num, quest[i].max_num - quest[i].cur_num);
8095 #else
8096                                                 sprintf(note," - Kill %d monsters, have killed %d.",
8097                                                         quest[i].max_num, quest[i].cur_num);
8098 #endif
8099                                                 break;
8100
8101                                         case QUEST_TYPE_KILL_ALL:
8102                                         case QUEST_TYPE_TOWER:
8103                                                 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
8104                                                 break;
8105                                         }
8106                                 }
8107
8108                                 /* Print the quest info */
8109                                 sprintf(tmp_str, _("  %s (危険度:%d階相当)%s\n", "  %s (Danger level: %d)%s\n"),
8110                                         quest[i].name, (int)quest[i].level, note);
8111
8112                                 fputs(tmp_str, fff);
8113
8114                                 if (quest[i].status == QUEST_STATUS_COMPLETED)
8115                                 {
8116                                         sprintf(tmp_str, _("    クエスト達成 - まだ報酬を受けとってない。\n", "    Quest Completed - Unrewarded\n"));
8117                                         fputs(tmp_str, fff);
8118                                 }
8119                                 else
8120                                 {
8121                                         j = 0;
8122
8123                                         while (quest_text[j][0] && j < 10)
8124                                         {
8125                                                 fprintf(fff, "    %s\n", quest_text[j]);
8126                                                 j++;
8127                                         }
8128                                 }
8129                         }
8130                         else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
8131                         {
8132                                 /* New random */
8133                                 rand_level = quest[i].level;
8134
8135                                 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
8136                                 {
8137                                         /* Print the quest info */
8138                                         r_ptr = &r_info[quest[i].r_idx];
8139                                         strcpy(name, r_name + r_ptr->name);
8140
8141                                         if (quest[i].max_num > 1)
8142                                         {
8143 #ifdef JP
8144                                                 sprintf(rand_tmp_str,"  %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
8145                                                         quest[i].name, (int)quest[i].level,
8146                                                         quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
8147 #else
8148                                                 plural_aux(name);
8149
8150                                                 sprintf(rand_tmp_str,"  %s (Dungeon level: %d)\n  Kill %d %s, have killed %d.\n",
8151                                                         quest[i].name, (idx)quest[i].level,
8152                                                         quest[i].max_num, name, quest[i].cur_num);
8153 #endif
8154                                         }
8155                                         else
8156                                         {
8157                                                 sprintf(rand_tmp_str,_("  %s (%d 階) - %sを倒す。\n", "  %s (Dungeon level: %d)\n  Kill %s.\n"),
8158                                                         quest[i].name, (int)quest[i].level, name);
8159                                         }
8160                                 }
8161                         }
8162                 }
8163         }
8164
8165         /* Print the current random quest  */
8166         if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
8167
8168         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
8169 }
8170
8171
8172 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
8173 {
8174         char tmp_str[120];
8175         char playtime_str[16];
8176         quest_type* const q_ptr = &quest[q_idx];
8177
8178         if (is_fixed_quest_idx(q_idx))
8179         {
8180                 /* Set the quest number temporary */
8181                 IDX old_quest = p_ptr->inside_quest;
8182
8183                 p_ptr->inside_quest = q_idx;
8184
8185                 /* Get the quest */
8186                 init_flags = INIT_NAME_ONLY;
8187
8188                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
8189
8190                 /* Reset the old quest number */
8191                 p_ptr->inside_quest = old_quest;
8192
8193                 /* No info from "silent" quests */
8194                 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
8195         }
8196
8197         strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
8198                 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
8199
8200         if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
8201         {
8202                 /* Print the quest info */
8203                 if (q_ptr->complev == 0)
8204                 {
8205                         sprintf(tmp_str,
8206                                 _("  %-35s (%3d階)            -   不戦勝 - %s\n",
8207                                   "  %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
8208                                 r_name+r_info[q_ptr->r_idx].name,
8209                                 (int)q_ptr->level, playtime_str);
8210                 }
8211                 else
8212                 {
8213                         sprintf(tmp_str,
8214                                 _("  %-35s (%3d階)            - レベル%2d - %s\n",
8215                                   "  %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
8216                                 r_name+r_info[q_ptr->r_idx].name,
8217                                 (int)q_ptr->level,
8218                                 q_ptr->complev,
8219                                 playtime_str);
8220                 }
8221         }
8222         else
8223         {
8224                 /* Print the quest info */
8225                 sprintf(tmp_str,
8226                         _("  %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
8227                           "  %-35s (Danger  level: %3d) - level %2d - %s\n") ,
8228                         q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
8229         }
8230
8231         fputs(tmp_str, fff);
8232
8233         return TRUE;
8234 }
8235
8236 /*
8237  * Print all finished quests
8238  */
8239 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
8240 {
8241         int i;
8242         int total = 0;
8243
8244         fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
8245         for (i = 1; i < max_quests; i++)
8246         {
8247                 IDX q_idx = quest_num[i];
8248                 quest_type* const q_ptr = &quest[q_idx];
8249
8250                 if (q_ptr->status == QUEST_STATUS_FINISHED &&
8251                     do_cmd_knowledge_quests_aux(fff, q_idx))
8252                 {
8253                         ++ total;
8254                 }
8255         }
8256         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
8257 }
8258
8259
8260 /*
8261  * Print all failed quests
8262  */
8263 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
8264 {
8265         IDX i;
8266         int total = 0;
8267
8268         fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
8269         for (i = 1; i < max_quests; i++)
8270         {
8271                 IDX q_idx = quest_num[i];
8272                 quest_type* const q_ptr = &quest[q_idx];
8273
8274                 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
8275                     do_cmd_knowledge_quests_aux(fff, q_idx))
8276                 {
8277                         ++ total;
8278                 }
8279         }
8280         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
8281 }
8282
8283
8284 /*
8285  * Print all random quests
8286  */
8287 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
8288 {
8289         char tmp_str[120];
8290         int i;
8291         int total = 0;
8292
8293         fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
8294         for (i = 1; i < max_quests; i++)
8295         {
8296                 /* No info from "silent" quests */
8297                 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8298
8299                 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
8300                 {
8301                         total++;
8302
8303                         /* Print the quest info */
8304                         sprintf(tmp_str, _("  %s (%d階, %s)\n", "  %s (%d, %s)\n"),
8305                                 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
8306                         fputs(tmp_str, fff);
8307                 }
8308         }
8309         if (!total) fprintf(fff, _("  なし\n", "  Nothing.\n"));
8310 }
8311
8312
8313 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8314 {
8315         int *q_num = (int *)u;
8316         quest_type *qa = &quest[q_num[a]];
8317         quest_type *qb = &quest[q_num[b]];
8318
8319         /* Unused */
8320         (void)v;
8321
8322         return (qa->comptime <= qb->comptime);
8323 }
8324
8325 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8326 {
8327         int *q_num = (int *)u;
8328         int tmp;
8329
8330         /* Unused */
8331         (void)v;
8332
8333         tmp = q_num[a];
8334         q_num[a] = q_num[b];
8335         q_num[b] = tmp;
8336 }
8337
8338
8339 /*
8340  * Print quest status of all active quests
8341  */
8342 static void do_cmd_knowledge_quests(void)
8343 {
8344         FILE *fff;
8345         char file_name[1024];
8346         IDX *quest_num;
8347         int dummy;
8348         IDX i;
8349
8350         /* Open a new file */
8351         fff = my_fopen_temp(file_name, 1024);
8352         if (!fff)
8353         {
8354             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8355             msg_print(NULL);
8356             return;
8357         }
8358
8359         /* Allocate Memory */
8360         C_MAKE(quest_num, max_quests, IDX);
8361
8362         /* Sort by compete level */
8363         for (i = 1; i < max_quests; i++) quest_num[i] = i;
8364         ang_sort_comp = ang_sort_comp_quest_num;
8365         ang_sort_swap = ang_sort_swap_quest_num;
8366         ang_sort(quest_num, &dummy, max_quests);
8367
8368         /* Dump Quest Information */
8369         do_cmd_knowledge_quests_current(fff);
8370         fputc('\n', fff);
8371         do_cmd_knowledge_quests_completed(fff, quest_num);
8372         fputc('\n', fff);
8373         do_cmd_knowledge_quests_failed(fff, quest_num);
8374         if (p_ptr->wizard)
8375         {
8376                 fputc('\n', fff);
8377                 do_cmd_knowledge_quests_wiz_random(fff);
8378         }
8379
8380         /* Close the file */
8381         my_fclose(fff);
8382
8383         /* Display the file contents */
8384         show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8385
8386         /* Remove the file */
8387         fd_kill(file_name);
8388
8389         /* Free Memory */
8390         C_KILL(quest_num, max_quests, IDX);
8391 }
8392
8393
8394 /*
8395  * List my home
8396  */
8397 static void do_cmd_knowledge_home(void)
8398 {
8399         FILE *fff;
8400
8401         int i;
8402         char file_name[1024];
8403         store_type  *st_ptr;
8404         char o_name[MAX_NLEN];
8405         cptr            paren = ")";
8406
8407         process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8408
8409         /* Open a new file */
8410         fff = my_fopen_temp(file_name, 1024);
8411         if (!fff) {
8412                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8413                 msg_print(NULL);
8414                 return;
8415         }
8416
8417         if (fff)
8418         {
8419                 /* Print all homes in the different towns */
8420                 st_ptr = &town[1].store[STORE_HOME];
8421
8422                 /* Home -- if anything there */
8423                 if (st_ptr->stock_num)
8424                 {
8425 #ifdef JP
8426                         int x = 1;
8427 #endif
8428                         /* Header with name of the town */
8429                         fprintf(fff, _("  [ 我が家のアイテム ]\n", "  [Home Inventory]\n"));
8430
8431                         /* Dump all available items */
8432                         for (i = 0; i < st_ptr->stock_num; i++)
8433                         {
8434 #ifdef JP
8435                                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8436                                 object_desc(o_name, &st_ptr->stock[i], 0);
8437                                 if (strlen(o_name) <= 80-3)
8438                                 {
8439                                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8440                                 }
8441                                 else
8442                                 {
8443                                         int n;
8444                                         char *t;
8445                                         for (n = 0, t = o_name; n < 80-3; n++, t++)
8446                                                 if(iskanji(*t)) {t++; n++;}
8447                                         if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8448
8449                                         fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8450                                         fprintf(fff, "   %.77s\n", o_name+n);
8451                                 }
8452 #else
8453                                 object_desc(o_name, &st_ptr->stock[i], 0);
8454                                 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8455 #endif
8456
8457                         }
8458
8459                         /* Add an empty line */
8460                         fprintf(fff, "\n\n");
8461                 }
8462         }
8463
8464         /* Close the file */
8465         my_fclose(fff);
8466
8467         /* Display the file contents */
8468         show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8469
8470         /* Remove the file */
8471         fd_kill(file_name);
8472 }
8473
8474
8475 /*
8476  * Check the status of "autopick"
8477  */
8478 static void do_cmd_knowledge_autopick(void)
8479 {
8480         int k;
8481         FILE *fff;
8482         char file_name[1024];
8483
8484         /* Open a new file */
8485         fff = my_fopen_temp(file_name, 1024);
8486
8487         if (!fff)
8488         {
8489             msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8490             msg_print(NULL);
8491             return;
8492         }
8493
8494         if (!max_autopick)
8495         {
8496             fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8497         }
8498         else
8499         {
8500                 fprintf(fff, _("   自動拾い/破壊には現在 %d行登録されています。\n\n",
8501                                            "   There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8502         }
8503
8504         for (k = 0; k < max_autopick; k++)
8505         {
8506                 cptr tmp;
8507                 byte act = autopick_list[k].action;
8508                 if (act & DONT_AUTOPICK)
8509                 {
8510                         tmp = _("放置", "Leave");
8511                 }
8512                 else if (act & DO_AUTODESTROY)
8513                 {
8514                         tmp = _("破壊", "Destroy");
8515                 }
8516                 else if (act & DO_AUTOPICK)
8517                 {
8518                         tmp = _("拾う", "Pickup");
8519                 }
8520                 else /* if (act & DO_QUERY_AUTOPICK) */ /* Obvious */
8521                 {
8522                         tmp = _("確認", "Query");
8523                 }
8524
8525                 if (act & DO_DISPLAY)
8526                         fprintf(fff, "%11s", format("[%s]", tmp));
8527                 else
8528                         fprintf(fff, "%11s", format("(%s)", tmp));
8529
8530                 tmp = autopick_line_from_entry(&autopick_list[k]);
8531                 fprintf(fff, " %s", tmp);
8532                 string_free(tmp);
8533                 fprintf(fff, "\n");
8534         }
8535         /* Close the file */
8536         my_fclose(fff);
8537         /* Display the file contents */
8538         show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8539
8540         /* Remove the file */
8541         fd_kill(file_name);
8542 }
8543
8544
8545 /*
8546  * Interact with "knowledge"
8547  */
8548 void do_cmd_knowledge(void)
8549 {
8550         int i, p = 0;
8551         bool need_redraw = FALSE;
8552
8553         /* File type is "TEXT" */
8554         FILE_TYPE(FILE_TYPE_TEXT);
8555
8556         /* Save the screen */
8557         screen_save();
8558
8559         /* Interact until done */
8560         while (1)
8561         {
8562                 /* Clear screen */
8563                 Term_clear();
8564
8565                 /* Ask for a choice */
8566 #ifdef JP
8567                 prt(format("%d/2 ページ", (p+1)), 2, 65);
8568                 prt("現在の知識を確認する", 3, 0);
8569 #else
8570                 prt(format("page %d/2", (p+1)), 2, 65);
8571                 prt("Display current knowledge", 3, 0);
8572 #endif
8573
8574                 /* Give some choices */
8575 #ifdef JP
8576                 if (p == 0)
8577                 {
8578                         prt("(1) 既知の伝説のアイテム                 の一覧", 6, 5);
8579                         prt("(2) 既知のアイテム                       の一覧", 7, 5);
8580                         prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8581                         prt("(4) 既知のモンスター                     の一覧", 9, 5);
8582                         prt("(5) 倒した敵の数                         の一覧", 10, 5);
8583                         if (!vanilla_town) prt("(6) 賞金首                               の一覧", 11, 5);
8584                         prt("(7) 現在のペット                         の一覧", 12, 5);
8585                         prt("(8) 我が家のアイテム                     の一覧", 13, 5);
8586                         prt("(9) *鑑定*済み装備の耐性                 の一覧", 14, 5);
8587                         prt("(0) 地形の表示文字/タイル                の一覧", 15, 5);
8588                 }
8589                 else
8590                 {
8591                         prt("(a) 自分に関する情報                     の一覧", 6, 5);
8592                         prt("(b) 突然変異                             の一覧", 7, 5);
8593                         prt("(c) 武器の経験値                         の一覧", 8, 5);
8594                         prt("(d) 魔法の経験値                         の一覧", 9, 5);
8595                         prt("(e) 技能の経験値                         の一覧", 10, 5);
8596                         prt("(f) プレイヤーの徳                       の一覧", 11, 5);
8597                         prt("(g) 入ったダンジョン                     の一覧", 12, 5);
8598                         prt("(h) 実行中のクエスト                     の一覧", 13, 5);
8599                         prt("(i) 現在の自動拾い/破壊設定              の一覧", 14, 5);
8600                 }
8601 #else
8602                 if (p == 0)
8603                 {
8604                         prt("(1) Display known artifacts", 6, 5);
8605                         prt("(2) Display known objects", 7, 5);
8606                         prt("(3) Display remaining uniques", 8, 5);
8607                         prt("(4) Display known monster", 9, 5);
8608                         prt("(5) Display kill count", 10, 5);
8609                         if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8610                         prt("(7) Display current pets", 12, 5);
8611                         prt("(8) Display home inventory", 13, 5);
8612                         prt("(9) Display *identified* equip.", 14, 5);
8613                         prt("(0) Display terrain symbols.", 15, 5);
8614                 }
8615                 else
8616                 {
8617                         prt("(a) Display about yourself", 6, 5);
8618                         prt("(b) Display mutations", 7, 5);
8619                         prt("(c) Display weapon proficiency", 8, 5);
8620                         prt("(d) Display spell proficiency", 9, 5);
8621                         prt("(e) Display misc. proficiency", 10, 5);
8622                         prt("(f) Display virtues", 11, 5);
8623                         prt("(g) Display dungeons", 12, 5);
8624                         prt("(h) Display current quests", 13, 5);
8625                         prt("(i) Display auto pick/destroy", 14, 5);
8626                 }
8627 #endif
8628                 /* Prompt */
8629 #ifdef JP
8630                 prt("-続く-", 17, 8);
8631                 prt("ESC) 抜ける", 21, 1);
8632                 prt("SPACE) 次ページ", 21, 30);
8633                 /*prt("-) 前ページ", 21, 60);*/
8634                 prt("コマンド:", 20, 0);
8635 #else
8636                 prt("-more-", 17, 8);
8637                 prt("ESC) Exit menu", 21, 1);
8638                 prt("SPACE) Next page", 21, 30);
8639                 /*prt("-) Previous page", 21, 60);*/
8640                 prt("Command: ", 20, 0);
8641 #endif
8642
8643                 /* Prompt */
8644                 i = inkey();
8645
8646                 /* Done */
8647                 if (i == ESCAPE) break;
8648                 switch (i)
8649                 {
8650                 case ' ': /* Page change */
8651                 case '-':
8652                         p = 1 - p;
8653                         break;
8654                 case '1': /* Artifacts */
8655                         do_cmd_knowledge_artifacts();
8656                         break;
8657                 case '2': /* Objects */
8658                         do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8659                         break;
8660                 case '3': /* Uniques */
8661                         do_cmd_knowledge_uniques();
8662                         break;
8663                 case '4': /* Monsters */
8664                         do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8665                         break;
8666                 case '5': /* Kill count  */
8667                         do_cmd_knowledge_kill_count();
8668                         break;
8669                 case '6': /* wanted */
8670                         if (!vanilla_town) do_cmd_knowledge_kubi();
8671                         break;
8672                 case '7': /* Pets */
8673                         do_cmd_knowledge_pets();
8674                         break;
8675                 case '8': /* Home */
8676                         do_cmd_knowledge_home();
8677                         break;
8678                 case '9': /* Resist list */
8679                         do_cmd_knowledge_inven();
8680                         break;
8681                 case '0': /* Feature list */
8682                         {
8683                                 IDX lighting_level = F_LIT_STANDARD;
8684                                 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8685                         }
8686                         break;
8687                 /* Next page */
8688                 case 'a': /* Max stat */
8689                         do_cmd_knowledge_stat();
8690                         break;
8691                 case 'b': /* Mutations */
8692                         do_cmd_knowledge_mutations();
8693                         break;
8694                 case 'c': /* weapon-exp */
8695                         do_cmd_knowledge_weapon_exp();
8696                         break;
8697                 case 'd': /* spell-exp */
8698                         do_cmd_knowledge_spell_exp();
8699                         break;
8700                 case 'e': /* skill-exp */
8701                         do_cmd_knowledge_skill_exp();
8702                         break;
8703                 case 'f': /* Virtues */
8704                         do_cmd_knowledge_virtues();
8705                         break;
8706                 case 'g': /* Dungeon */
8707                         do_cmd_knowledge_dungeon();
8708                         break;
8709                 case 'h': /* Quests */
8710                         do_cmd_knowledge_quests();
8711                         break;
8712                 case 'i': /* Autopick */
8713                         do_cmd_knowledge_autopick();
8714                         break;
8715                 default: /* Unknown option */
8716                         bell();
8717                 }
8718
8719                 /* Flush messages */
8720                 msg_print(NULL);
8721         }
8722
8723         /* Restore the screen */
8724         screen_load();
8725
8726         if (need_redraw) do_cmd_redraw();
8727 }
8728
8729
8730 /*
8731  * Check on the status of an active quest
8732  */
8733 void do_cmd_checkquest(void)
8734 {
8735         /* File type is "TEXT" */
8736         FILE_TYPE(FILE_TYPE_TEXT);
8737
8738         /* Save the screen */
8739         screen_save();
8740
8741         /* Quest info */
8742         do_cmd_knowledge_quests();
8743
8744         /* Restore the screen */
8745         screen_load();
8746 }
8747
8748
8749 /*
8750  * Display the time and date
8751  */
8752 void do_cmd_time(void)
8753 {
8754         int day, hour, min, full, start, end, num;
8755         char desc[1024];
8756
8757         char buf[1024];
8758         char day_buf[10];
8759
8760         FILE *fff;
8761
8762         extract_day_hour_min(&day, &hour, &min);
8763
8764         full = hour * 100 + min;
8765
8766         start = 9999;
8767         end = -9999;
8768
8769         num = 0;
8770
8771         strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8772
8773         if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8774         else strcpy(day_buf, "*****");
8775
8776         /* Message */
8777 #ifdef JP
8778         msg_format("%s日目, 時刻は%d:%02d %sです。",
8779                    day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8780                    min, (hour < 12) ? "AM" : "PM");
8781 #else
8782         msg_format("This is day %s. The time is %d:%02d %s.",
8783                    day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8784                    min, (hour < 12) ? "AM" : "PM");
8785 #endif
8786
8787
8788         /* Find the path */
8789         if (!randint0(10) || p_ptr->image)
8790         {
8791                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8792         }
8793         else
8794         {
8795                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8796         }
8797
8798         /* Open this file */
8799         fff = my_fopen(buf, "rt");
8800
8801         /* Oops */
8802         if (!fff) return;
8803
8804         /* Find this time */
8805         while (!my_fgets(fff, buf, sizeof(buf)))
8806         {
8807                 /* Ignore comments */
8808                 if (!buf[0] || (buf[0] == '#')) continue;
8809
8810                 /* Ignore invalid lines */
8811                 if (buf[1] != ':') continue;
8812
8813                 /* Process 'Start' */
8814                 if (buf[0] == 'S')
8815                 {
8816                         /* Extract the starting time */
8817                         start = atoi(buf + 2);
8818
8819                         /* Assume valid for an hour */
8820                         end = start + 59;
8821
8822                         /* Next... */
8823                         continue;
8824                 }
8825
8826                 /* Process 'End' */
8827                 if (buf[0] == 'E')
8828                 {
8829                         /* Extract the ending time */
8830                         end = atoi(buf + 2);
8831
8832                         /* Next... */
8833                         continue;
8834                 }
8835
8836                 /* Ignore incorrect range */
8837                 if ((start > full) || (full > end)) continue;
8838
8839                 /* Process 'Description' */
8840                 if (buf[0] == 'D')
8841                 {
8842                         num++;
8843
8844                         /* Apply the randomizer */
8845                         if (!randint0(num)) strcpy(desc, buf + 2);
8846
8847                         /* Next... */
8848                         continue;
8849                 }
8850         }
8851
8852         /* Message */
8853         msg_print(desc);
8854
8855         /* Close the file */
8856         my_fclose(fff);
8857 }