OSDN Git Service

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