OSDN Git Service

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