OSDN Git Service

889255b6e9485b72f7342b78416d7a5d0a701857
[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_NAME_ONLY;
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                                                         PW_MONSTER_LIST);
2611                                 break;
2612                         }
2613
2614                         /* Auto-picker/destroyer editor */
2615                         case 'P':
2616                         case 'p':
2617                         {
2618                                 do_cmd_edit_autopick();
2619                                 break;
2620                         }
2621
2622                         /* Hack -- Delay Speed */
2623                         case 'D':
2624                         case 'd':
2625                         {
2626                                 /* Prompt */
2627                                 clear_from(18);
2628 #ifdef JP
2629                                 prt("¥³¥Þ¥ó¥É: ´ðËÜ¥¦¥§¥¤¥ÈÎÌ", 19, 0);
2630 #else
2631                                 prt("Command: Base Delay Factor", 19, 0);
2632 #endif
2633
2634                                 /* Get a new value */
2635                                 while (1)
2636                                 {
2637                                         int msec = delay_factor * delay_factor * delay_factor;
2638 #ifdef JP
2639                                         prt(format("¸½ºß¤Î¥¦¥§¥¤¥È: %d (%d¥ß¥êÉÃ)",
2640                                                    delay_factor, msec), 22, 0);
2641 #else
2642                                         prt(format("Current base delay factor: %d (%d msec)",
2643                                                    delay_factor, msec), 22, 0);
2644 #endif
2645
2646 #ifdef JP
2647                                         prt("¥¦¥§¥¤¥È (0-9) ESC¤Ç·èÄê: ", 20, 0);
2648 #else
2649                                         prt("Delay Factor (0-9 or ESC to accept): ", 20, 0);
2650 #endif
2651
2652                                         k = inkey();
2653                                         if (k == ESCAPE) break;
2654                                         else if (k == '?')
2655                                         {
2656 #ifdef JP
2657                                                 (void)show_file(TRUE, "joption.txt#BaseDelay", NULL, 0, 0);
2658 #else
2659                                                 (void)show_file(TRUE, "option.txt#BaseDelay", NULL, 0, 0);
2660 #endif
2661                                                 Term_clear(); 
2662                                         }
2663                                         else if (isdigit(k)) delay_factor = D2I(k);
2664                                         else bell();
2665                                 }
2666
2667                                 break;
2668                         }
2669
2670                         /* Hack -- hitpoint warning factor */
2671                         case 'H':
2672                         case 'h':
2673                         {
2674                                 /* Prompt */
2675                                 clear_from(18);
2676 #ifdef JP
2677                                 prt("¥³¥Þ¥ó¥É: Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð", 19, 0);
2678 #else
2679                                 prt("Command: Hitpoint Warning", 19, 0);
2680 #endif
2681
2682                                 /* Get a new value */
2683                                 while (1)
2684                                 {
2685 #ifdef JP
2686                                         prt(format("¸½ºß¤ÎÄã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð: %d0%%",
2687                                                    hitpoint_warn), 22, 0);
2688 #else
2689                                         prt(format("Current hitpoint warning: %d0%%",
2690                                                    hitpoint_warn), 22, 0);
2691 #endif
2692
2693 #ifdef JP
2694                                         prt("Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð (0-9) ESC¤Ç·èÄê: ", 20, 0);
2695 #else
2696                                         prt("Hitpoint Warning (0-9 or ESC to accept): ", 20, 0);
2697 #endif
2698
2699                                         k = inkey();
2700                                         if (k == ESCAPE) break;
2701                                         else if (k == '?')
2702                                         {
2703 #ifdef JP
2704                                                 (void)show_file(TRUE, "joption.txt#Hitpoint", NULL, 0, 0);
2705 #else
2706                                                 (void)show_file(TRUE, "option.txt#Hitpoint", NULL, 0, 0);
2707 #endif
2708                                                 Term_clear(); 
2709                                         }
2710                                         else if (isdigit(k)) hitpoint_warn = D2I(k);
2711                                         else bell();
2712                                 }
2713
2714                                 break;
2715                         }
2716
2717                         /* Hack -- mana color factor */
2718                         case 'M':
2719                         case 'm':
2720                         {
2721                                 /* Prompt */
2722                                 clear_from(18);
2723 #ifdef JP
2724                                 prt("¥³¥Þ¥ó¥É: ÄãËâÎÏ¿§ïçÃÍ", 19, 0);
2725 #else
2726                                 prt("Command: Mana Color Threshold", 19, 0);
2727 #endif
2728
2729                                 /* Get a new value */
2730                                 while (1)
2731                                 {
2732 #ifdef JP
2733                                         prt(format("¸½ºß¤ÎÄãËâÎÏ¿§ïçÃÍ: %d0%%",
2734                                                    mana_warn), 22, 0);
2735 #else
2736                                         prt(format("Current mana color threshold: %d0%%",
2737                                                    mana_warn), 22, 0);
2738 #endif
2739
2740 #ifdef JP
2741                                         prt("ÄãËâÎÏïçÃÍ (0-9) ESC¤Ç·èÄê: ", 20, 0);
2742 #else
2743                                         prt("Mana color Threshold (0-9 or ESC to accept): ", 20, 0);
2744 #endif
2745
2746                                         k = inkey();
2747                                         if (k == ESCAPE) break;
2748                                         else if (k == '?')
2749                                         {
2750 #ifdef JP
2751                                                 (void)show_file(TRUE, "joption.txt#Manapoint", NULL, 0, 0);
2752 #else
2753                                                 (void)show_file(TRUE, "option.txt#Manapoint", NULL, 0, 0);
2754 #endif
2755                                                 Term_clear(); 
2756                                         }
2757                                         else if (isdigit(k)) mana_warn = D2I(k);
2758                                         else bell();
2759                                 }
2760
2761                                 break;
2762                         }
2763
2764                         case '?':
2765 #ifdef JP
2766                                 (void)show_file(TRUE, "joption.txt", NULL, 0, 0);
2767 #else
2768                                 (void)show_file(TRUE, "option.txt", NULL, 0, 0);
2769 #endif
2770                                 Term_clear(); 
2771                                 break;
2772
2773                         /* Unknown option */
2774                         default:
2775                         {
2776                                 /* Oops */
2777                                 bell();
2778                                 break;
2779                         }
2780                 }
2781
2782                 /* Flush messages */
2783                 msg_print(NULL);
2784         }
2785
2786
2787         /* Restore the screen */
2788         screen_load();
2789
2790         /* Hack - Redraw equippy chars */
2791         p_ptr->redraw |= (PR_EQUIPPY);
2792 }
2793
2794
2795
2796 /*
2797  * Ask for a "user pref line" and process it
2798  *
2799  * XXX XXX XXX Allow absolute file names?
2800  */
2801 void do_cmd_pref(void)
2802 {
2803         char buf[80];
2804
2805         /* Default */
2806         strcpy(buf, "");
2807
2808         /* Ask for a "user pref command" */
2809 #ifdef JP
2810         if (!get_string("ÀßÄêÊѹ¹¥³¥Þ¥ó¥É: ", buf, 80)) return;
2811 #else
2812         if (!get_string("Pref: ", buf, 80)) return;
2813 #endif
2814
2815
2816         /* Process that pref command */
2817         (void)process_pref_file_command(buf);
2818 }
2819
2820 void do_cmd_reload_autopick(void)
2821 {
2822 #ifdef JP
2823         if (!get_check("¼«Æ°½¦¤¤ÀßÄê¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤·¤Þ¤¹¤«? ")) return;
2824 #else
2825         if (!get_check("Reload auto-pick preference file? ")) return;
2826 #endif
2827
2828         /* Load the file with messages */
2829         autopick_load_pref(TRUE);
2830 }
2831
2832 #ifdef ALLOW_MACROS
2833
2834 /*
2835  * Hack -- append all current macros to the given file
2836  */
2837 static errr macro_dump(cptr fname)
2838 {
2839         static cptr mark = "Macro Dump";
2840
2841         int i;
2842
2843         char buf[1024];
2844
2845         /* Build the filename */
2846         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2847
2848         /* File type is "TEXT" */
2849         FILE_TYPE(FILE_TYPE_TEXT);
2850
2851         /* Append to the file */
2852         if (!open_auto_dump(buf, mark)) return (-1);
2853
2854         /* Start dumping */
2855 #ifdef JP
2856         auto_dump_printf("\n# ¼«Æ°¥Þ¥¯¥í¥»¡¼¥Ö\n\n");
2857 #else
2858         auto_dump_printf("\n# Automatic macro dump\n\n");
2859 #endif
2860
2861         /* Dump them */
2862         for (i = 0; i < macro__num; i++)
2863         {
2864                 /* Extract the action */
2865                 ascii_to_text(buf, macro__act[i]);
2866
2867                 /* Dump the macro */
2868                 auto_dump_printf("A:%s\n", buf);
2869
2870                 /* Extract the action */
2871                 ascii_to_text(buf, macro__pat[i]);
2872
2873                 /* Dump normal macros */
2874                 auto_dump_printf("P:%s\n", buf);
2875
2876                 /* End the macro */
2877                 auto_dump_printf("\n");
2878         }
2879
2880         /* Close */
2881         close_auto_dump();
2882
2883         /* Success */
2884         return (0);
2885 }
2886
2887
2888 /*
2889  * Hack -- ask for a "trigger" (see below)
2890  *
2891  * Note the complex use of the "inkey()" function from "util.c".
2892  *
2893  * Note that both "flush()" calls are extremely important.
2894  */
2895 static void do_cmd_macro_aux(char *buf)
2896 {
2897         int i, n = 0;
2898
2899         char tmp[1024];
2900
2901
2902         /* Flush */
2903         flush();
2904
2905         /* Do not process macros */
2906         inkey_base = TRUE;
2907
2908         /* First key */
2909         i = inkey();
2910
2911         /* Read the pattern */
2912         while (i)
2913         {
2914                 /* Save the key */
2915                 buf[n++] = i;
2916
2917                 /* Do not process macros */
2918                 inkey_base = TRUE;
2919
2920                 /* Do not wait for keys */
2921                 inkey_scan = TRUE;
2922
2923                 /* Attempt to read a key */
2924                 i = inkey();
2925         }
2926
2927         /* Terminate */
2928         buf[n] = '\0';
2929
2930         /* Flush */
2931         flush();
2932
2933
2934         /* Convert the trigger */
2935         ascii_to_text(tmp, buf);
2936
2937         /* Hack -- display the trigger */
2938         Term_addstr(-1, TERM_WHITE, tmp);
2939 }
2940
2941 #endif
2942
2943
2944 /*
2945  * Hack -- ask for a keymap "trigger" (see below)
2946  *
2947  * Note that both "flush()" calls are extremely important.  This may
2948  * no longer be true, since "util.c" is much simpler now.  XXX XXX XXX
2949  */
2950 static void do_cmd_macro_aux_keymap(char *buf)
2951 {
2952         char tmp[1024];
2953
2954
2955         /* Flush */
2956         flush();
2957
2958
2959         /* Get a key */
2960         buf[0] = inkey();
2961         buf[1] = '\0';
2962
2963
2964         /* Convert to ascii */
2965         ascii_to_text(tmp, buf);
2966
2967         /* Hack -- display the trigger */
2968         Term_addstr(-1, TERM_WHITE, tmp);
2969
2970
2971         /* Flush */
2972         flush();
2973 }
2974
2975
2976 /*
2977  * Hack -- append all keymaps to the given file
2978  */
2979 static errr keymap_dump(cptr fname)
2980 {
2981         static cptr mark = "Keymap Dump";
2982         int i;
2983
2984         char key[1024];
2985         char buf[1024];
2986
2987         int mode;
2988
2989         /* Roguelike */
2990         if (rogue_like_commands)
2991         {
2992                 mode = KEYMAP_MODE_ROGUE;
2993         }
2994
2995         /* Original */
2996         else
2997         {
2998                 mode = KEYMAP_MODE_ORIG;
2999         }
3000
3001
3002         /* Build the filename */
3003         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
3004
3005         /* File type is "TEXT" */
3006         FILE_TYPE(FILE_TYPE_TEXT);
3007
3008         /* Append to the file */
3009         if (!open_auto_dump(buf, mark)) return -1;
3010
3011         /* Start dumping */
3012 #ifdef JP
3013         auto_dump_printf("\n# ¼«Æ°¥­¡¼ÇÛÃÖ¥»¡¼¥Ö\n\n");
3014 #else
3015         auto_dump_printf("\n# Automatic keymap dump\n\n");
3016 #endif
3017
3018         /* Dump them */
3019         for (i = 0; i < 256; i++)
3020         {
3021                 cptr act;
3022
3023                 /* Loop up the keymap */
3024                 act = keymap_act[mode][i];
3025
3026                 /* Skip empty keymaps */
3027                 if (!act) continue;
3028
3029                 /* Encode the key */
3030                 buf[0] = i;
3031                 buf[1] = '\0';
3032                 ascii_to_text(key, buf);
3033
3034                 /* Encode the action */
3035                 ascii_to_text(buf, act);
3036
3037                 /* Dump the macro */
3038                 auto_dump_printf("A:%s\n", buf);
3039                 auto_dump_printf("C:%d:%s\n", mode, key);
3040         }
3041
3042         /* Close */
3043         close_auto_dump();
3044
3045         /* Success */
3046         return (0);
3047 }
3048
3049
3050
3051 /*
3052  * Interact with "macros"
3053  *
3054  * Note that the macro "action" must be defined before the trigger.
3055  *
3056  * Could use some helpful instructions on this page.  XXX XXX XXX
3057  */
3058 void do_cmd_macros(void)
3059 {
3060         int i;
3061
3062         char tmp[1024];
3063
3064         char buf[1024];
3065
3066         int mode;
3067
3068
3069         /* Roguelike */
3070         if (rogue_like_commands)
3071         {
3072                 mode = KEYMAP_MODE_ROGUE;
3073         }
3074
3075         /* Original */
3076         else
3077         {
3078                 mode = KEYMAP_MODE_ORIG;
3079         }
3080
3081         /* File type is "TEXT" */
3082         FILE_TYPE(FILE_TYPE_TEXT);
3083
3084
3085         /* Save screen */
3086         screen_save();
3087
3088
3089         /* Process requests until done */
3090         while (1)
3091         {
3092                 /* Clear screen */
3093                 Term_clear();
3094
3095                 /* Describe */
3096 #ifdef JP
3097                 prt("[ ¥Þ¥¯¥í¤ÎÀßÄê ]", 2, 0);
3098 #else
3099                 prt("Interact with Macros", 2, 0);
3100 #endif
3101
3102
3103
3104                 /* Describe that action */
3105 #ifdef JP
3106                 prt("¥Þ¥¯¥í¹ÔÆ°¤¬(¤â¤·¤¢¤ì¤Ð)²¼¤Ëɽ¼¨¤µ¤ì¤Þ¤¹:", 20, 0);
3107 #else
3108                 prt("Current action (if any) shown below:", 20, 0);
3109 #endif
3110
3111
3112                 /* Analyze the current action */
3113                 ascii_to_text(buf, macro__buf);
3114
3115                 /* Display the current action */
3116                 prt(buf, 22, 0);
3117
3118
3119                 /* Selections */
3120 #ifdef JP
3121                 prt("(1) ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 4, 5);
3122 #else
3123                 prt("(1) Load a user pref file", 4, 5);
3124 #endif
3125
3126 #ifdef ALLOW_MACROS
3127 #ifdef JP
3128                 prt("(2) ¥Õ¥¡¥¤¥ë¤Ë¥Þ¥¯¥í¤òÄɲÃ", 5, 5);
3129                 prt("(3) ¥Þ¥¯¥í¤Î³Îǧ", 6, 5);
3130                 prt("(4) ¥Þ¥¯¥í¤ÎºîÀ®", 7, 5);
3131                 prt("(5) ¥Þ¥¯¥í¤Îºï½ü", 8, 5);
3132                 prt("(6) ¥Õ¥¡¥¤¥ë¤Ë¥­¡¼ÇÛÃÖ¤òÄɲÃ", 9, 5);
3133                 prt("(7) ¥­¡¼ÇÛÃ֤γÎǧ", 10, 5);
3134                 prt("(8) ¥­¡¼ÇÛÃ֤κîÀ®", 11, 5);
3135                 prt("(9) ¥­¡¼ÇÛÃ֤κï½ü", 12, 5);
3136                 prt("(0) ¥Þ¥¯¥í¹ÔÆ°¤ÎÆþÎÏ", 13, 5);
3137 #else
3138                 prt("(2) Append macros to a file", 5, 5);
3139                 prt("(3) Query a macro", 6, 5);
3140                 prt("(4) Create a macro", 7, 5);
3141                 prt("(5) Remove a macro", 8, 5);
3142                 prt("(6) Append keymaps to a file", 9, 5);
3143                 prt("(7) Query a keymap", 10, 5);
3144                 prt("(8) Create a keymap", 11, 5);
3145                 prt("(9) Remove a keymap", 12, 5);
3146                 prt("(0) Enter a new action", 13, 5);
3147 #endif
3148
3149 #endif /* ALLOW_MACROS */
3150
3151                 /* Prompt */
3152 #ifdef JP
3153                 prt("¥³¥Þ¥ó¥É: ", 16, 0);
3154 #else
3155                 prt("Command: ", 16, 0);
3156 #endif
3157
3158
3159                 /* Get a command */
3160                 i = inkey();
3161
3162                 /* Leave */
3163                 if (i == ESCAPE) break;
3164
3165                 /* Load a 'macro' file */
3166                 else if (i == '1')
3167                 {
3168                         errr err;
3169
3170                         /* Prompt */
3171 #ifdef JP
3172                         prt("¥³¥Þ¥ó¥É: ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 16, 0);
3173 #else
3174                         prt("Command: Load a user pref file", 16, 0);
3175 #endif
3176
3177
3178                         /* Prompt */
3179 #ifdef JP
3180                         prt("¥Õ¥¡¥¤¥ë: ", 18, 0);
3181 #else
3182                         prt("File: ", 18, 0);
3183 #endif
3184
3185
3186                         /* Default filename */
3187                         sprintf(tmp, "%s.prf", player_base);
3188
3189                         /* Ask for a file */
3190                         if (!askfor(tmp, 80)) continue;
3191
3192                         /* Process the given filename */
3193                         err = process_pref_file(tmp);
3194                         if (-2 == err)
3195                         {
3196 #ifdef JP
3197                                 msg_format("ɸ½à¤ÎÀßÄê¥Õ¥¡¥¤¥ë'%s'¤òÆɤ߹þ¤ß¤Þ¤·¤¿¡£", tmp);
3198 #else
3199                                 msg_format("Loaded default '%s'.", tmp);
3200 #endif
3201                         }
3202                         else if (err)
3203                         {
3204                                 /* Prompt */
3205 #ifdef JP
3206                                 msg_format("'%s'¤ÎÆɤ߹þ¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª", tmp);
3207 #else
3208                                 msg_format("Failed to load '%s'!");
3209 #endif
3210                         }
3211                         else
3212                         {
3213 #ifdef JP
3214                                 msg_format("'%s'¤òÆɤ߹þ¤ß¤Þ¤·¤¿¡£", tmp);
3215 #else
3216                                 msg_format("Loaded '%s'.", tmp);
3217 #endif
3218                         }
3219                 }
3220
3221 #ifdef ALLOW_MACROS
3222
3223                 /* Save macros */
3224                 else if (i == '2')
3225                 {
3226                         /* Prompt */
3227 #ifdef JP
3228                         prt("¥³¥Þ¥ó¥É: ¥Þ¥¯¥í¤ò¥Õ¥¡¥¤¥ë¤ËÄɲ乤ë", 16, 0);
3229 #else
3230                         prt("Command: Append macros to a file", 16, 0);
3231 #endif
3232
3233
3234                         /* Prompt */
3235 #ifdef JP
3236                         prt("¥Õ¥¡¥¤¥ë: ", 18, 0);
3237 #else
3238                         prt("File: ", 18, 0);
3239 #endif
3240
3241
3242                         /* Default filename */
3243                         sprintf(tmp, "%s.prf", player_base);
3244
3245                         /* Ask for a file */
3246                         if (!askfor(tmp, 80)) continue;
3247
3248                         /* Dump the macros */
3249                         (void)macro_dump(tmp);
3250
3251                         /* Prompt */
3252 #ifdef JP
3253                         msg_print("¥Þ¥¯¥í¤òÄɲä·¤Þ¤·¤¿¡£");
3254 #else
3255                         msg_print("Appended macros.");
3256 #endif
3257
3258                 }
3259
3260                 /* Query a macro */
3261                 else if (i == '3')
3262                 {
3263                         int k;
3264
3265                         /* Prompt */
3266 #ifdef JP
3267                         prt("¥³¥Þ¥ó¥É: ¥Þ¥¯¥í¤Î³Îǧ", 16, 0);
3268 #else
3269                         prt("Command: Query a macro", 16, 0);
3270 #endif
3271
3272
3273                         /* Prompt */
3274 #ifdef JP
3275                         prt("¥È¥ê¥¬¡¼¥­¡¼: ", 18, 0);
3276 #else
3277                         prt("Trigger: ", 18, 0);
3278 #endif
3279
3280
3281                         /* Get a macro trigger */
3282                         do_cmd_macro_aux(buf);
3283
3284                         /* Acquire action */
3285                         k = macro_find_exact(buf);
3286
3287                         /* Nothing found */
3288                         if (k < 0)
3289                         {
3290                                 /* Prompt */
3291 #ifdef JP
3292                                 msg_print("¤½¤Î¥­¡¼¤Ë¤Ï¥Þ¥¯¥í¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£");
3293 #else
3294                                 msg_print("Found no macro.");
3295 #endif
3296
3297                         }
3298
3299                         /* Found one */
3300                         else
3301                         {
3302                                 /* Obtain the action */
3303                                 strcpy(macro__buf, macro__act[k]);
3304
3305                                 /* Analyze the current action */
3306                                 ascii_to_text(buf, macro__buf);
3307
3308                                 /* Display the current action */
3309                                 prt(buf, 22, 0);
3310
3311                                 /* Prompt */
3312 #ifdef JP
3313                                 msg_print("¥Þ¥¯¥í¤ò³Îǧ¤·¤Þ¤·¤¿¡£");
3314 #else
3315                                 msg_print("Found a macro.");
3316 #endif
3317
3318                         }
3319                 }
3320
3321                 /* Create a macro */
3322                 else if (i == '4')
3323                 {
3324                         /* Prompt */
3325 #ifdef JP
3326                         prt("¥³¥Þ¥ó¥É: ¥Þ¥¯¥í¤ÎºîÀ®", 16, 0);
3327 #else
3328                         prt("Command: Create a macro", 16, 0);
3329 #endif
3330
3331
3332                         /* Prompt */
3333 #ifdef JP
3334                         prt("¥È¥ê¥¬¡¼¥­¡¼: ", 18, 0);
3335 #else
3336                         prt("Trigger: ", 18, 0);
3337 #endif
3338
3339
3340                         /* Get a macro trigger */
3341                         do_cmd_macro_aux(buf);
3342
3343                         /* Clear */
3344                         clear_from(20);
3345
3346                         /* Help message */
3347 #ifdef JP
3348                         c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
3349 #else
3350                         c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
3351 #endif
3352
3353                         /* Prompt */
3354 #ifdef JP
3355                         prt("¥Þ¥¯¥í¹ÔÆ°: ", 20, 0);
3356 #else
3357                         prt("Action: ", 20, 0);
3358 #endif
3359
3360
3361                         /* Convert to text */
3362                         ascii_to_text(tmp, macro__buf);
3363
3364                         /* Get an encoded action */
3365                         if (askfor(tmp, 80))
3366                         {
3367                                 /* Convert to ascii */
3368                                 text_to_ascii(macro__buf, tmp);
3369
3370                                 /* Link the macro */
3371                                 macro_add(buf, macro__buf);
3372
3373                                 /* Prompt */
3374 #ifdef JP
3375                                 msg_print("¥Þ¥¯¥í¤òÄɲä·¤Þ¤·¤¿¡£");
3376 #else
3377                                 msg_print("Added a macro.");
3378 #endif
3379
3380                         }
3381                 }
3382
3383                 /* Remove a macro */
3384                 else if (i == '5')
3385                 {
3386                         /* Prompt */
3387 #ifdef JP
3388                         prt("¥³¥Þ¥ó¥É: ¥Þ¥¯¥í¤Îºï½ü", 16, 0);
3389 #else
3390                         prt("Command: Remove a macro", 16, 0);
3391 #endif
3392
3393
3394                         /* Prompt */
3395 #ifdef JP
3396                         prt("¥È¥ê¥¬¡¼¥­¡¼: ", 18, 0);
3397 #else
3398                         prt("Trigger: ", 18, 0);
3399 #endif
3400
3401
3402                         /* Get a macro trigger */
3403                         do_cmd_macro_aux(buf);
3404
3405                         /* Link the macro */
3406                         macro_add(buf, buf);
3407
3408                         /* Prompt */
3409 #ifdef JP
3410                         msg_print("¥Þ¥¯¥í¤òºï½ü¤·¤Þ¤·¤¿¡£");
3411 #else
3412                         msg_print("Removed a macro.");
3413 #endif
3414
3415                 }
3416
3417                 /* Save keymaps */
3418                 else if (i == '6')
3419                 {
3420                         /* Prompt */
3421 #ifdef JP
3422                         prt("¥³¥Þ¥ó¥É: ¥­¡¼ÇÛÃÖ¤ò¥Õ¥¡¥¤¥ë¤ËÄɲ乤ë", 16, 0);
3423 #else
3424                         prt("Command: Append keymaps to a file", 16, 0);
3425 #endif
3426
3427
3428                         /* Prompt */
3429 #ifdef JP
3430                         prt("¥Õ¥¡¥¤¥ë: ", 18, 0);
3431 #else
3432                         prt("File: ", 18, 0);
3433 #endif
3434
3435
3436                         /* Default filename */
3437                         sprintf(tmp, "%s.prf", player_base);
3438
3439                         /* Ask for a file */
3440                         if (!askfor(tmp, 80)) continue;
3441
3442                         /* Dump the macros */
3443                         (void)keymap_dump(tmp);
3444
3445                         /* Prompt */
3446 #ifdef JP
3447                         msg_print("¥­¡¼ÇÛÃÖ¤òÄɲä·¤Þ¤·¤¿¡£");
3448 #else
3449                         msg_print("Appended keymaps.");
3450 #endif
3451
3452                 }
3453
3454                 /* Query a keymap */
3455                 else if (i == '7')
3456                 {
3457                         cptr act;
3458
3459                         /* Prompt */
3460 #ifdef JP
3461                         prt("¥³¥Þ¥ó¥É: ¥­¡¼ÇÛÃ֤γÎǧ", 16, 0);
3462 #else
3463                         prt("Command: Query a keymap", 16, 0);
3464 #endif
3465
3466
3467                         /* Prompt */
3468 #ifdef JP
3469                         prt("²¡¤¹¥­¡¼: ", 18, 0);
3470 #else
3471                         prt("Keypress: ", 18, 0);
3472 #endif
3473
3474
3475                         /* Get a keymap trigger */
3476                         do_cmd_macro_aux_keymap(buf);
3477
3478                         /* Look up the keymap */
3479                         act = keymap_act[mode][(byte)(buf[0])];
3480
3481                         /* Nothing found */
3482                         if (!act)
3483                         {
3484                                 /* Prompt */
3485 #ifdef JP
3486                                 msg_print("¥­¡¼ÇÛÃÖ¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£");
3487 #else
3488                                 msg_print("Found no keymap.");
3489 #endif
3490
3491                         }
3492
3493                         /* Found one */
3494                         else
3495                         {
3496                                 /* Obtain the action */
3497                                 strcpy(macro__buf, act);
3498
3499                                 /* Analyze the current action */
3500                                 ascii_to_text(buf, macro__buf);
3501
3502                                 /* Display the current action */
3503                                 prt(buf, 22, 0);
3504
3505                                 /* Prompt */
3506 #ifdef JP
3507                                 msg_print("¥­¡¼ÇÛÃÖ¤ò³Îǧ¤·¤Þ¤·¤¿¡£");
3508 #else
3509                                 msg_print("Found a keymap.");
3510 #endif
3511
3512                         }
3513                 }
3514
3515                 /* Create a keymap */
3516                 else if (i == '8')
3517                 {
3518                         /* Prompt */
3519 #ifdef JP
3520                         prt("¥³¥Þ¥ó¥É: ¥­¡¼ÇÛÃ֤κîÀ®", 16, 0);
3521 #else
3522                         prt("Command: Create a keymap", 16, 0);
3523 #endif
3524
3525
3526                         /* Prompt */
3527 #ifdef JP
3528                         prt("²¡¤¹¥­¡¼: ", 18, 0);
3529 #else
3530                         prt("Keypress: ", 18, 0);
3531 #endif
3532
3533
3534                         /* Get a keymap trigger */
3535                         do_cmd_macro_aux_keymap(buf);
3536
3537                         /* Clear */
3538                         clear_from(20);
3539
3540                         /* Help message */
3541 #ifdef JP
3542                         c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
3543 #else
3544                         c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
3545 #endif
3546
3547                         /* Prompt */
3548 #ifdef JP
3549                         prt("¹ÔÆ°: ", 20, 0);
3550 #else
3551                         prt("Action: ", 20, 0);
3552 #endif
3553
3554
3555                         /* Convert to text */
3556                         ascii_to_text(tmp, macro__buf);
3557
3558                         /* Get an encoded action */
3559                         if (askfor(tmp, 80))
3560                         {
3561                                 /* Convert to ascii */
3562                                 text_to_ascii(macro__buf, tmp);
3563
3564                                 /* Free old keymap */
3565                                 string_free(keymap_act[mode][(byte)(buf[0])]);
3566
3567                                 /* Make new keymap */
3568                                 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
3569
3570                                 /* Prompt */
3571 #ifdef JP
3572                                 msg_print("¥­¡¼ÇÛÃÖ¤òÄɲä·¤Þ¤·¤¿¡£");
3573 #else
3574                                 msg_print("Added a keymap.");
3575 #endif
3576
3577                         }
3578                 }
3579
3580                 /* Remove a keymap */
3581                 else if (i == '9')
3582                 {
3583                         /* Prompt */
3584 #ifdef JP
3585                         prt("¥³¥Þ¥ó¥É: ¥­¡¼ÇÛÃ֤κï½ü", 16, 0);
3586 #else
3587                         prt("Command: Remove a keymap", 16, 0);
3588 #endif
3589
3590
3591                         /* Prompt */
3592 #ifdef JP
3593                         prt("²¡¤¹¥­¡¼: ", 18, 0);
3594 #else
3595                         prt("Keypress: ", 18, 0);
3596 #endif
3597
3598
3599                         /* Get a keymap trigger */
3600                         do_cmd_macro_aux_keymap(buf);
3601
3602                         /* Free old keymap */
3603                         string_free(keymap_act[mode][(byte)(buf[0])]);
3604
3605                         /* Make new keymap */
3606                         keymap_act[mode][(byte)(buf[0])] = NULL;
3607
3608                         /* Prompt */
3609 #ifdef JP
3610                         msg_print("¥­¡¼ÇÛÃÖ¤òºï½ü¤·¤Þ¤·¤¿¡£");
3611 #else
3612                         msg_print("Removed a keymap.");
3613 #endif
3614
3615                 }
3616
3617                 /* Enter a new action */
3618                 else if (i == '0')
3619                 {
3620                         /* Prompt */
3621 #ifdef JP
3622                         prt("¥³¥Þ¥ó¥É: ¥Þ¥¯¥í¹ÔÆ°¤ÎÆþÎÏ", 16, 0);
3623 #else
3624                         prt("Command: Enter a new action", 16, 0);
3625 #endif
3626
3627                         /* Clear */
3628                         clear_from(20);
3629
3630                         /* Help message */
3631 #ifdef JP
3632                         c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
3633 #else
3634                         c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
3635 #endif
3636
3637                         /* Prompt */
3638 #ifdef JP
3639                         prt("¥Þ¥¯¥í¹ÔÆ°: ", 20, 0);
3640 #else
3641                         prt("Action: ", 20, 0);
3642 #endif
3643
3644                         /* Hack -- limit the value */
3645                         tmp[80] = '\0';
3646
3647                         /* Get an encoded action */
3648                         if (!askfor(buf, 80)) continue;
3649
3650                         /* Extract an action */
3651                         text_to_ascii(macro__buf, buf);
3652                 }
3653
3654 #endif /* ALLOW_MACROS */
3655
3656                 /* Oops */
3657                 else
3658                 {
3659                         /* Oops */
3660                         bell();
3661                 }
3662
3663                 /* Flush messages */
3664                 msg_print(NULL);
3665         }
3666
3667         /* Load screen */
3668         screen_load();
3669 }
3670
3671
3672 static cptr lighting_level_str[F_LIT_MAX] =
3673 {
3674 #ifdef JP
3675         "ɸ½à¿§",
3676         "ÌÀ¿§",
3677         "°Å¿§",
3678 #else
3679         "standard",
3680         "brightly lit",
3681         "darkened",
3682 #endif
3683 };
3684
3685
3686 static bool cmd_visuals_aux(int i, int *num, int max)
3687 {
3688         if (iscntrl(i))
3689         {
3690                 char str[10] = "";
3691                 int tmp;
3692
3693                 sprintf(str, "%d", *num);
3694
3695                 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
3696                         return FALSE;
3697
3698                 tmp = strtol(str, NULL, 0);
3699                 if (tmp >= 0 && tmp < max)
3700                         *num = tmp;
3701         }
3702         else if (isupper(i))
3703                 *num = (*num + max - 1) % max;
3704         else
3705                 *num = (*num + 1) % max;
3706
3707         return TRUE;
3708 }
3709
3710 static void print_visuals_menu(cptr choice_msg)
3711 {
3712 #ifdef JP
3713         prt("[ ²èÌÌɽ¼¨¤ÎÀßÄê ]", 1, 0);
3714 #else
3715         prt("Interact with Visuals", 1, 0);
3716 #endif
3717
3718         /* Give some choices */
3719 #ifdef JP
3720         prt("(0) ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 3, 5);
3721 #else
3722         prt("(0) Load a user pref file", 3, 5);
3723 #endif
3724
3725 #ifdef ALLOW_VISUALS
3726 #ifdef JP
3727         prt("(1) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 4, 5);
3728         prt("(2) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
3729         prt("(3) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 6, 5);
3730         prt("(4) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 7, 5);
3731         prt("(5) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 8, 5);
3732         prt("(6) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 9, 5);
3733         prt("(7) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 10, 5);
3734         prt("(8) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 11, 5);
3735         prt("(9) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 12, 5);
3736 #else
3737         prt("(1) Dump monster attr/chars", 4, 5);
3738         prt("(2) Dump object attr/chars", 5, 5);
3739         prt("(3) Dump feature attr/chars", 6, 5);
3740         prt("(4) Change monster attr/chars (numeric operation)", 7, 5);
3741         prt("(5) Change object attr/chars (numeric operation)", 8, 5);
3742         prt("(6) Change feature attr/chars (numeric operation)", 9, 5);
3743         prt("(7) Change monster attr/chars (visual mode)", 10, 5);
3744         prt("(8) Change object attr/chars (visual mode)", 11, 5);
3745         prt("(9) Change feature attr/chars (visual mode)", 12, 5);
3746 #endif
3747
3748 #endif /* ALLOW_VISUALS */
3749
3750 #ifdef JP
3751         prt("(R) ²èÌÌɽ¼¨ÊýË¡¤Î½é´ü²½", 13, 5);
3752 #else
3753         prt("(R) Reset visuals", 13, 5);
3754 #endif
3755
3756         /* Prompt */
3757 #ifdef JP
3758         prt(format("¥³¥Þ¥ó¥É: %s", choice_msg ? choice_msg : ""), 15, 0);
3759 #else
3760         prt(format("Command: %s", choice_msg ? choice_msg : ""), 15, 0);
3761 #endif
3762 }
3763
3764 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx);
3765 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx);
3766 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level);
3767
3768 /*
3769  * Interact with "visuals"
3770  */
3771 void do_cmd_visuals(void)
3772 {
3773         int i;
3774         char tmp[160];
3775         char buf[1024];
3776         bool need_redraw = FALSE;
3777         const char *empty_symbol = "<< ? >>";
3778
3779         if (use_bigtile) empty_symbol = "<< ?? >>";
3780
3781         /* File type is "TEXT" */
3782         FILE_TYPE(FILE_TYPE_TEXT);
3783
3784         /* Save the screen */
3785         screen_save();
3786
3787         /* Interact until done */
3788         while (1)
3789         {
3790                 /* Clear screen */
3791                 Term_clear();
3792
3793                 /* Ask for a choice */
3794                 print_visuals_menu(NULL);
3795
3796                 /* Prompt */
3797                 i = inkey();
3798
3799                 /* Done */
3800                 if (i == ESCAPE) break;
3801
3802                 switch (i)
3803                 {
3804                 /* Load a 'pref' file */
3805                 case '0':
3806                         /* Prompt */
3807 #ifdef JP
3808                         prt("¥³¥Þ¥ó¥É: ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 15, 0);
3809 #else
3810                         prt("Command: Load a user pref file", 15, 0);
3811 #endif
3812
3813                         /* Prompt */
3814 #ifdef JP
3815                         prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
3816 #else
3817                         prt("File: ", 17, 0);
3818 #endif
3819
3820                         /* Default filename */
3821                         sprintf(tmp, "%s.prf", player_base);
3822
3823                         /* Query */
3824                         if (!askfor(tmp, 70)) continue;
3825
3826                         /* Process the given filename */
3827                         (void)process_pref_file(tmp);
3828
3829                         need_redraw = TRUE;
3830                         break;
3831
3832 #ifdef ALLOW_VISUALS
3833
3834                 /* Dump monster attr/chars */
3835                 case '1':
3836                 {
3837                         static cptr mark = "Monster attr/chars";
3838
3839                         /* Prompt */
3840 #ifdef JP
3841                         prt("¥³¥Þ¥ó¥É: ¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤¹", 15, 0);
3842 #else
3843                         prt("Command: Dump monster attr/chars", 15, 0);
3844 #endif
3845
3846                         /* Prompt */
3847 #ifdef JP
3848                         prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
3849 #else
3850                         prt("File: ", 17, 0);
3851 #endif
3852
3853                         /* Default filename */
3854                         sprintf(tmp, "%s.prf", player_base);
3855
3856                         /* Get a filename */
3857                         if (!askfor(tmp, 70)) continue;
3858
3859                         /* Build the filename */
3860                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3861
3862                         /* Append to the file */
3863                         if (!open_auto_dump(buf, mark)) continue;
3864
3865                         /* Start dumping */
3866 #ifdef JP
3867                         auto_dump_printf("\n# ¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
3868 #else
3869                         auto_dump_printf("\n# Monster attr/char definitions\n\n");
3870 #endif
3871
3872                         /* Dump monsters */
3873                         for (i = 0; i < max_r_idx; i++)
3874                         {
3875                                 monster_race *r_ptr = &r_info[i];
3876
3877                                 /* Skip non-entries */
3878                                 if (!r_ptr->name) continue;
3879
3880                                 /* Dump a comment */
3881                                 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3882
3883                                 /* Dump the monster attr/char info */
3884                                 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3885                                         (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3886                         }
3887
3888                         /* Close */
3889                         close_auto_dump();
3890
3891                         /* Message */
3892 #ifdef JP
3893                         msg_print("¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
3894 #else
3895                         msg_print("Dumped monster attr/chars.");
3896 #endif
3897
3898                         break;
3899                 }
3900
3901                 /* Dump object attr/chars */
3902                 case '2':
3903                 {
3904                         static cptr mark = "Object attr/chars";
3905
3906                         /* Prompt */
3907 #ifdef JP
3908                         prt("¥³¥Þ¥ó¥É: ¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤¹", 15, 0);
3909 #else
3910                         prt("Command: Dump object attr/chars", 15, 0);
3911 #endif
3912
3913                         /* Prompt */
3914 #ifdef JP
3915                         prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
3916 #else
3917                         prt("File: ", 17, 0);
3918 #endif
3919
3920                         /* Default filename */
3921                         sprintf(tmp, "%s.prf", player_base);
3922
3923                         /* Get a filename */
3924                         if (!askfor(tmp, 70)) continue;
3925
3926                         /* Build the filename */
3927                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3928
3929                         /* Append to the file */
3930                         if (!open_auto_dump(buf, mark)) continue;
3931
3932                         /* Start dumping */
3933 #ifdef JP
3934                         auto_dump_printf("\n# ¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
3935 #else
3936                         auto_dump_printf("\n# Object attr/char definitions\n\n");
3937 #endif
3938
3939                         /* Dump objects */
3940                         for (i = 0; i < max_k_idx; i++)
3941                         {
3942                                 char o_name[80];
3943                                 object_kind *k_ptr = &k_info[i];
3944
3945                                 /* Skip non-entries */
3946                                 if (!k_ptr->name) continue;
3947
3948                                 if (!k_ptr->flavor)
3949                                 {
3950                                         /* Tidy name */
3951                                         strip_name(o_name, i);
3952                                 }
3953                                 else
3954                                 {
3955                                         object_type forge;
3956
3957                                         /* Prepare dummy object */
3958                                         object_prep(&forge, i);
3959
3960                                         /* Get un-shuffled flavor name */
3961                                         object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3962                                 }
3963
3964                                 /* Dump a comment */
3965                                 auto_dump_printf("# %s\n", o_name);
3966
3967                                 /* Dump the object attr/char info */
3968                                 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", i,
3969                                         (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3970                         }
3971
3972                         /* Close */
3973                         close_auto_dump();
3974
3975                         /* Message */
3976 #ifdef JP
3977                         msg_print("¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
3978 #else
3979                         msg_print("Dumped object attr/chars.");
3980 #endif
3981
3982                         break;
3983                 }
3984
3985                 /* Dump feature attr/chars */
3986                 case '3':
3987                 {
3988                         static cptr mark = "Feature attr/chars";
3989
3990                         /* Prompt */
3991 #ifdef JP
3992                         prt("¥³¥Þ¥ó¥É: ÃÏ·Á¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤¹", 15, 0);
3993 #else
3994                         prt("Command: Dump feature attr/chars", 15, 0);
3995 #endif
3996
3997                         /* Prompt */
3998 #ifdef JP
3999                         prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
4000 #else
4001                         prt("File: ", 17, 0);
4002 #endif
4003
4004                         /* Default filename */
4005                         sprintf(tmp, "%s.prf", player_base);
4006
4007                         /* Get a filename */
4008                         if (!askfor(tmp, 70)) continue;
4009
4010                         /* Build the filename */
4011                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4012
4013                         /* Append to the file */
4014                         if (!open_auto_dump(buf, mark)) continue;
4015
4016                         /* Start dumping */
4017 #ifdef JP
4018                         auto_dump_printf("\n# ÃÏ·Á¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
4019 #else
4020                         auto_dump_printf("\n# Feature attr/char definitions\n\n");
4021 #endif
4022
4023                         /* Dump features */
4024                         for (i = 0; i < max_f_idx; i++)
4025                         {
4026                                 feature_type *f_ptr = &f_info[i];
4027
4028                                 /* Skip non-entries */
4029                                 if (!f_ptr->name) continue;
4030
4031                                 /* Skip mimiccing features */
4032                                 if (f_ptr->mimic != i) continue;
4033
4034                                 /* Dump a comment */
4035                                 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
4036
4037                                 /* Dump the feature attr/char info */
4038                                 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
4039                                         (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
4040                                         (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
4041                                         (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
4042                         }
4043
4044                         /* Close */
4045                         close_auto_dump();
4046
4047                         /* Message */
4048 #ifdef JP
4049                         msg_print("ÃÏ·Á¤Î[¿§/ʸ»ú]¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
4050 #else
4051                         msg_print("Dumped feature attr/chars.");
4052 #endif
4053
4054                         break;
4055                 }
4056
4057                 /* Modify monster attr/chars (numeric operation) */
4058                 case '4':
4059                 {
4060 #ifdef JP
4061                         static cptr choice_msg = "¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
4062 #else
4063                         static cptr choice_msg = "Change monster attr/chars";
4064 #endif
4065                         static int r = 0;
4066
4067 #ifdef JP
4068                         prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
4069 #else
4070                         prt(format("Command: %s", choice_msg), 15, 0);
4071 #endif
4072
4073                         /* Hack -- query until done */
4074                         while (1)
4075                         {
4076                                 monster_race *r_ptr = &r_info[r];
4077                                 char c;
4078                                 int t;
4079
4080                                 byte da = r_ptr->d_attr;
4081                                 byte dc = r_ptr->d_char;
4082                                 byte ca = r_ptr->x_attr;
4083                                 byte cc = r_ptr->x_char;
4084
4085                                 /* Label the object */
4086 #ifdef JP
4087                                 Term_putstr(5, 17, -1, TERM_WHITE,
4088                                             format("¥â¥ó¥¹¥¿¡¼ = %d, Ì¾Á° = %-40.40s",
4089                                                    r, (r_name + r_ptr->name)));
4090 #else
4091                                 Term_putstr(5, 17, -1, TERM_WHITE,
4092                                             format("Monster = %d, Name = %-40.40s",
4093                                                    r, (r_name + r_ptr->name)));
4094 #endif
4095
4096                                 /* Label the Default values */
4097 #ifdef JP
4098                                 Term_putstr(10, 19, -1, TERM_WHITE,
4099                                             format("½é´üÃÍ  ¿§ / Ê¸»ú = %3u / %3u", da, dc));
4100 #else
4101                                 Term_putstr(10, 19, -1, TERM_WHITE,
4102                                             format("Default attr/char = %3u / %3u", da, dc));
4103 #endif
4104
4105                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
4106                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
4107
4108                                 /* Label the Current values */
4109 #ifdef JP
4110                                 Term_putstr(10, 20, -1, TERM_WHITE,
4111                                             format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3u / %3u", ca, cc));
4112 #else
4113                                 Term_putstr(10, 20, -1, TERM_WHITE,
4114                                             format("Current attr/char = %3u / %3u", ca, cc));
4115 #endif
4116
4117                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
4118                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
4119
4120                                 /* Prompt */
4121 #ifdef JP
4122                                 Term_putstr(0, 22, -1, TERM_WHITE,
4123                                             "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
4124 #else
4125                                 Term_putstr(0, 22, -1, TERM_WHITE,
4126                                             "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
4127 #endif
4128
4129                                 /* Get a command */
4130                                 i = inkey();
4131
4132                                 /* All done */
4133                                 if (i == ESCAPE) break;
4134
4135                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
4136                                 else if (isupper(i)) c = 'a' + i - 'A';
4137                                 else c = i;
4138
4139                                 switch (c)
4140                                 {
4141                                 case 'n':
4142                                         {
4143                                                 int prev_r = r;
4144                                                 do
4145                                                 {
4146                                                         if (!cmd_visuals_aux(i, &r, max_r_idx))
4147                                                         {
4148                                                                 r = prev_r;
4149                                                                 break;
4150                                                         }
4151                                                 }
4152                                                 while (!r_info[r].name);
4153                                         }
4154                                         break;
4155                                 case 'a':
4156                                         t = (int)r_ptr->x_attr;
4157                                         (void)cmd_visuals_aux(i, &t, 256);
4158                                         r_ptr->x_attr = (byte)t;
4159                                         need_redraw = TRUE;
4160                                         break;
4161                                 case 'c':
4162                                         t = (int)r_ptr->x_char;
4163                                         (void)cmd_visuals_aux(i, &t, 256);
4164                                         r_ptr->x_char = (byte)t;
4165                                         need_redraw = TRUE;
4166                                         break;
4167                                 case 'v':
4168                                         do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
4169
4170                                         /* Clear screen */
4171                                         Term_clear();
4172                                         print_visuals_menu(choice_msg);
4173                                         break;
4174                                 }
4175                         }
4176
4177                         break;
4178                 }
4179
4180                 /* Modify object attr/chars (numeric operation) */
4181                 case '5':
4182                 {
4183 #ifdef JP
4184                         static cptr choice_msg = "¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
4185 #else
4186                         static cptr choice_msg = "Change object attr/chars";
4187 #endif
4188                         static int k = 0;
4189
4190 #ifdef JP
4191                         prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
4192 #else
4193                         prt(format("Command: %s", choice_msg), 15, 0);
4194 #endif
4195
4196                         /* Hack -- query until done */
4197                         while (1)
4198                         {
4199                                 object_kind *k_ptr = &k_info[k];
4200                                 char c;
4201                                 int t;
4202
4203                                 byte da = k_ptr->d_attr;
4204                                 byte dc = k_ptr->d_char;
4205                                 byte ca = k_ptr->x_attr;
4206                                 byte cc = k_ptr->x_char;
4207
4208                                 /* Label the object */
4209 #ifdef JP
4210                                 Term_putstr(5, 17, -1, TERM_WHITE,
4211                                             format("¥¢¥¤¥Æ¥à = %d, Ì¾Á° = %-40.40s",
4212                                                    k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
4213 #else
4214                                 Term_putstr(5, 17, -1, TERM_WHITE,
4215                                             format("Object = %d, Name = %-40.40s",
4216                                                    k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
4217 #endif
4218
4219                                 /* Label the Default values */
4220 #ifdef JP
4221                                 Term_putstr(10, 19, -1, TERM_WHITE,
4222                                             format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
4223 #else
4224                                 Term_putstr(10, 19, -1, TERM_WHITE,
4225                                             format("Default attr/char = %3d / %3d", da, dc));
4226 #endif
4227
4228                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
4229                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
4230
4231                                 /* Label the Current values */
4232 #ifdef JP
4233                                 Term_putstr(10, 20, -1, TERM_WHITE,
4234                                             format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
4235 #else
4236                                 Term_putstr(10, 20, -1, TERM_WHITE,
4237                                             format("Current attr/char = %3d / %3d", ca, cc));
4238 #endif
4239
4240                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
4241                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
4242
4243                                 /* Prompt */
4244 #ifdef JP
4245                                 Term_putstr(0, 22, -1, TERM_WHITE,
4246                                             "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
4247 #else
4248                                 Term_putstr(0, 22, -1, TERM_WHITE,
4249                                             "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
4250 #endif
4251
4252                                 /* Get a command */
4253                                 i = inkey();
4254
4255                                 /* All done */
4256                                 if (i == ESCAPE) break;
4257
4258                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
4259                                 else if (isupper(i)) c = 'a' + i - 'A';
4260                                 else c = i;
4261
4262                                 switch (c)
4263                                 {
4264                                 case 'n':
4265                                         {
4266                                                 int prev_k = k;
4267                                                 do
4268                                                 {
4269                                                         if (!cmd_visuals_aux(i, &k, max_k_idx))
4270                                                         {
4271                                                                 k = prev_k;
4272                                                                 break;
4273                                                         }
4274                                                 }
4275                                                 while (!k_info[k].name);
4276                                         }
4277                                         break;
4278                                 case 'a':
4279                                         t = (int)k_ptr->x_attr;
4280                                         (void)cmd_visuals_aux(i, &t, 256);
4281                                         k_ptr->x_attr = (byte)t;
4282                                         need_redraw = TRUE;
4283                                         break;
4284                                 case 'c':
4285                                         t = (int)k_ptr->x_char;
4286                                         (void)cmd_visuals_aux(i, &t, 256);
4287                                         k_ptr->x_char = (byte)t;
4288                                         need_redraw = TRUE;
4289                                         break;
4290                                 case 'v':
4291                                         do_cmd_knowledge_objects(&need_redraw, TRUE, k);
4292
4293                                         /* Clear screen */
4294                                         Term_clear();
4295                                         print_visuals_menu(choice_msg);
4296                                         break;
4297                                 }
4298                         }
4299
4300                         break;
4301                 }
4302
4303                 /* Modify feature attr/chars (numeric operation) */
4304                 case '6':
4305                 {
4306 #ifdef JP
4307                         static cptr choice_msg = "ÃÏ·Á¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
4308 #else
4309                         static cptr choice_msg = "Change feature attr/chars";
4310 #endif
4311                         static int f = 0;
4312                         static int lighting_level = F_LIT_STANDARD;
4313
4314 #ifdef JP
4315                         prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
4316 #else
4317                         prt(format("Command: %s", choice_msg), 15, 0);
4318 #endif
4319
4320                         /* Hack -- query until done */
4321                         while (1)
4322                         {
4323                                 feature_type *f_ptr = &f_info[f];
4324                                 char c;
4325                                 int t;
4326
4327                                 byte da = f_ptr->d_attr[lighting_level];
4328                                 byte dc = f_ptr->d_char[lighting_level];
4329                                 byte ca = f_ptr->x_attr[lighting_level];
4330                                 byte cc = f_ptr->x_char[lighting_level];
4331
4332                                 /* Label the object */
4333                                 prt("", 17, 5);
4334 #ifdef JP
4335                                 Term_putstr(5, 17, -1, TERM_WHITE,
4336                                             format("ÃÏ·Á = %d, Ì¾Á° = %s, ÌÀÅÙ = %s",
4337                                                    f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
4338 #else
4339                                 Term_putstr(5, 17, -1, TERM_WHITE,
4340                                             format("Terrain = %d, Name = %s, Lighting = %s",
4341                                                    f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
4342 #endif
4343
4344                                 /* Label the Default values */
4345 #ifdef JP
4346                                 Term_putstr(10, 19, -1, TERM_WHITE,
4347                                             format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
4348 #else
4349                                 Term_putstr(10, 19, -1, TERM_WHITE,
4350                                             format("Default attr/char = %3d / %3d", da, dc));
4351 #endif
4352
4353                                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
4354
4355                                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
4356
4357                                 /* Label the Current values */
4358 #ifdef JP
4359                                 Term_putstr(10, 20, -1, TERM_WHITE,
4360                                             format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
4361 #else
4362                                 Term_putstr(10, 20, -1, TERM_WHITE,
4363                                             format("Current attr/char = %3d / %3d", ca, cc));
4364 #endif
4365
4366                                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
4367                                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
4368
4369                                 /* Prompt */
4370 #ifdef JP
4371                                 Term_putstr(0, 22, -1, TERM_WHITE,
4372                                             "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
4373 #else
4374                                 Term_putstr(0, 22, -1, TERM_WHITE,
4375                                             "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
4376 #endif
4377
4378                                 /* Get a command */
4379                                 i = inkey();
4380
4381                                 /* All done */
4382                                 if (i == ESCAPE) break;
4383
4384                                 if (iscntrl(i)) c = 'a' + i - KTRL('A');
4385                                 else if (isupper(i)) c = 'a' + i - 'A';
4386                                 else c = i;
4387
4388                                 switch (c)
4389                                 {
4390                                 case 'n':
4391                                         {
4392                                                 int prev_f = f;
4393                                                 do
4394                                                 {
4395                                                         if (!cmd_visuals_aux(i, &f, max_f_idx))
4396                                                         {
4397                                                                 f = prev_f;
4398                                                                 break;
4399                                                         }
4400                                                 }
4401                                                 while (!f_info[f].name || (f_info[f].mimic != f));
4402                                         }
4403                                         break;
4404                                 case 'a':
4405                                         t = (int)f_ptr->x_attr[lighting_level];
4406                                         (void)cmd_visuals_aux(i, &t, 256);
4407                                         f_ptr->x_attr[lighting_level] = (byte)t;
4408                                         need_redraw = TRUE;
4409                                         break;
4410                                 case 'c':
4411                                         t = (int)f_ptr->x_char[lighting_level];
4412                                         (void)cmd_visuals_aux(i, &t, 256);
4413                                         f_ptr->x_char[lighting_level] = (byte)t;
4414                                         need_redraw = TRUE;
4415                                         break;
4416                                 case 'l':
4417                                         (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
4418                                         break;
4419                                 case 'd':
4420                                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
4421                                         need_redraw = TRUE;
4422                                         break;
4423                                 case 'v':
4424                                         do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
4425
4426                                         /* Clear screen */
4427                                         Term_clear();
4428                                         print_visuals_menu(choice_msg);
4429                                         break;
4430                                 }
4431                         }
4432
4433                         break;
4434                 }
4435
4436                 /* Modify monster attr/chars (visual mode) */
4437                 case '7':
4438                         do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
4439                         break;
4440
4441                 /* Modify object attr/chars (visual mode) */
4442                 case '8':
4443                         do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
4444                         break;
4445
4446                 /* Modify feature attr/chars (visual mode) */
4447                 case '9':
4448                 {
4449                         int lighting_level = F_LIT_STANDARD;
4450                         do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
4451                         break;
4452                 }
4453
4454 #endif /* ALLOW_VISUALS */
4455
4456                 /* Reset visuals */
4457                 case 'R':
4458                 case 'r':
4459                         /* Reset */
4460                         reset_visuals();
4461
4462                         /* Message */
4463 #ifdef JP
4464                         msg_print("²èÌ̾å¤Î[¿§/ʸ»ú]¤ò½é´üÃͤ˥ꥻ¥Ã¥È¤·¤Þ¤·¤¿¡£");
4465 #else
4466                         msg_print("Visual attr/char tables reset.");
4467 #endif
4468
4469                         need_redraw = TRUE;
4470                         break;
4471
4472                 /* Unknown option */
4473                 default:
4474                         bell();
4475                         break;
4476                 }
4477
4478                 /* Flush messages */
4479                 msg_print(NULL);
4480         }
4481
4482         /* Restore the screen */
4483         screen_load();
4484
4485         if (need_redraw) do_cmd_redraw();
4486 }
4487
4488
4489 /*
4490  * Interact with "colors"
4491  */
4492 void do_cmd_colors(void)
4493 {
4494         int i;
4495
4496         char tmp[160];
4497
4498         char buf[1024];
4499
4500
4501         /* File type is "TEXT" */
4502         FILE_TYPE(FILE_TYPE_TEXT);
4503
4504
4505         /* Save the screen */
4506         screen_save();
4507
4508
4509         /* Interact until done */
4510         while (1)
4511         {
4512                 /* Clear screen */
4513                 Term_clear();
4514
4515                 /* Ask for a choice */
4516 #ifdef JP
4517                 prt("[ ¥«¥é¡¼¤ÎÀßÄê ]", 2, 0);
4518 #else
4519                 prt("Interact with Colors", 2, 0);
4520 #endif
4521
4522
4523                 /* Give some choices */
4524 #ifdef JP
4525                 prt("(1) ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 4, 5);
4526 #else
4527                 prt("(1) Load a user pref file", 4, 5);
4528 #endif
4529
4530 #ifdef ALLOW_COLORS
4531 #ifdef JP
4532                 prt("(2) ¥«¥é¡¼¤ÎÀßÄê¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
4533                 prt("(3) ¥«¥é¡¼¤ÎÀßÄê¤òÊѹ¹¤¹¤ë", 6, 5);
4534 #else
4535                 prt("(2) Dump colors", 5, 5);
4536                 prt("(3) Modify colors", 6, 5);
4537 #endif
4538
4539 #endif
4540
4541                 /* Prompt */
4542 #ifdef JP
4543                 prt("¥³¥Þ¥ó¥É: ", 8, 0);
4544 #else
4545                 prt("Command: ", 8, 0);
4546 #endif
4547
4548
4549                 /* Prompt */
4550                 i = inkey();
4551
4552                 /* Done */
4553                 if (i == ESCAPE) break;
4554
4555                 /* Load a 'pref' file */
4556                 if (i == '1')
4557                 {
4558                         /* Prompt */
4559 #ifdef JP
4560                         prt("¥³¥Þ¥ó¥É: ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤·¤Þ¤¹", 8, 0);
4561 #else
4562                         prt("Command: Load a user pref file", 8, 0);
4563 #endif
4564
4565
4566                         /* Prompt */
4567 #ifdef JP
4568                         prt("¥Õ¥¡¥¤¥ë: ", 10, 0);
4569 #else
4570                         prt("File: ", 10, 0);
4571 #endif
4572
4573
4574                         /* Default file */
4575                         sprintf(tmp, "%s.prf", player_base);
4576
4577                         /* Query */
4578                         if (!askfor(tmp, 70)) continue;
4579
4580                         /* Process the given filename */
4581                         (void)process_pref_file(tmp);
4582
4583                         /* Mega-Hack -- react to changes */
4584                         Term_xtra(TERM_XTRA_REACT, 0);
4585
4586                         /* Mega-Hack -- redraw */
4587                         Term_redraw();
4588                 }
4589
4590 #ifdef ALLOW_COLORS
4591
4592                 /* Dump colors */
4593                 else if (i == '2')
4594                 {
4595                         static cptr mark = "Colors";
4596
4597                         /* Prompt */
4598 #ifdef JP
4599                         prt("¥³¥Þ¥ó¥É: ¥«¥é¡¼¤ÎÀßÄê¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤¹", 8, 0);
4600 #else
4601                         prt("Command: Dump colors", 8, 0);
4602 #endif
4603
4604
4605                         /* Prompt */
4606 #ifdef JP
4607                         prt("¥Õ¥¡¥¤¥ë: ", 10, 0);
4608 #else
4609                         prt("File: ", 10, 0);
4610 #endif
4611
4612
4613                         /* Default filename */
4614                         sprintf(tmp, "%s.prf", player_base);
4615
4616                         /* Get a filename */
4617                         if (!askfor(tmp, 70)) continue;
4618
4619                         /* Build the filename */
4620                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4621
4622                         /* Append to the file */
4623                         if (!open_auto_dump(buf, mark)) continue;
4624
4625                         /* Start dumping */
4626 #ifdef JP
4627                         auto_dump_printf("\n# ¥«¥é¡¼¤ÎÀßÄê\n\n");
4628 #else
4629                         auto_dump_printf("\n# Color redefinitions\n\n");
4630 #endif
4631
4632                         /* Dump colors */
4633                         for (i = 0; i < 256; i++)
4634                         {
4635                                 int kv = angband_color_table[i][0];
4636                                 int rv = angband_color_table[i][1];
4637                                 int gv = angband_color_table[i][2];
4638                                 int bv = angband_color_table[i][3];
4639
4640 #ifdef JP
4641                                 cptr name = "̤ÃÎ";
4642 #else
4643                                 cptr name = "unknown";
4644 #endif
4645
4646
4647                                 /* Skip non-entries */
4648                                 if (!kv && !rv && !gv && !bv) continue;
4649
4650                                 /* Extract the color name */
4651                                 if (i < 16) name = color_names[i];
4652
4653                                 /* Dump a comment */
4654 #ifdef JP
4655                                 auto_dump_printf("# ¥«¥é¡¼ '%s'\n", name);
4656 #else
4657                                 auto_dump_printf("# Color '%s'\n", name);
4658 #endif
4659
4660                                 /* Dump the monster attr/char info */
4661                                 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
4662                                         i, kv, rv, gv, bv);
4663                         }
4664
4665                         /* Close */
4666                         close_auto_dump();
4667
4668                         /* Message */
4669 #ifdef JP
4670                         msg_print("¥«¥é¡¼¤ÎÀßÄê¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
4671 #else
4672                         msg_print("Dumped color redefinitions.");
4673 #endif
4674
4675                 }
4676
4677                 /* Edit colors */
4678                 else if (i == '3')
4679                 {
4680                         static byte a = 0;
4681
4682                         /* Prompt */
4683 #ifdef JP
4684                         prt("¥³¥Þ¥ó¥É: ¥«¥é¡¼¤ÎÀßÄê¤òÊѹ¹¤·¤Þ¤¹", 8, 0);
4685 #else
4686                         prt("Command: Modify colors", 8, 0);
4687 #endif
4688
4689
4690                         /* Hack -- query until done */
4691                         while (1)
4692                         {
4693                                 cptr name;
4694                                 byte j;
4695
4696                                 /* Clear */
4697                                 clear_from(10);
4698
4699                                 /* Exhibit the normal colors */
4700                                 for (j = 0; j < 16; j++)
4701                                 {
4702                                         /* Exhibit this color */
4703                                         Term_putstr(j*4, 20, -1, a, "###");
4704
4705                                         /* Exhibit all colors */
4706                                         Term_putstr(j*4, 22, -1, j, format("%3d", j));
4707                                 }
4708
4709                                 /* Describe the color */
4710 #ifdef JP
4711                                 name = ((a < 16) ? color_names[a] : "̤ÄêµÁ");
4712 #else
4713                                 name = ((a < 16) ? color_names[a] : "undefined");
4714 #endif
4715
4716
4717                                 /* Describe the color */
4718 #ifdef JP
4719                                 Term_putstr(5, 10, -1, TERM_WHITE,
4720                                             format("¥«¥é¡¼ = %d, Ì¾Á° = %s", a, name));
4721 #else
4722                                 Term_putstr(5, 10, -1, TERM_WHITE,
4723                                             format("Color = %d, Name = %s", a, name));
4724 #endif
4725
4726
4727                                 /* Label the Current values */
4728                                 Term_putstr(5, 12, -1, TERM_WHITE,
4729                                             format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
4730                                                    angband_color_table[a][0],
4731                                                    angband_color_table[a][1],
4732                                                    angband_color_table[a][2],
4733                                                    angband_color_table[a][3]));
4734
4735                                 /* Prompt */
4736 #ifdef JP
4737                                 Term_putstr(0, 14, -1, TERM_WHITE,
4738                                             "¥³¥Þ¥ó¥É (n/N/k/K/r/R/g/G/b/B): ");
4739 #else
4740                                 Term_putstr(0, 14, -1, TERM_WHITE,
4741                                             "Command (n/N/k/K/r/R/g/G/b/B): ");
4742 #endif
4743
4744
4745                                 /* Get a command */
4746                                 i = inkey();
4747
4748                                 /* All done */
4749                                 if (i == ESCAPE) break;
4750
4751                                 /* Analyze */
4752                                 if (i == 'n') a = (byte)(a + 1);
4753                                 if (i == 'N') a = (byte)(a - 1);
4754                                 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
4755                                 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
4756                                 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
4757                                 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
4758                                 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
4759                                 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
4760                                 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
4761                                 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
4762
4763                                 /* Hack -- react to changes */
4764                                 Term_xtra(TERM_XTRA_REACT, 0);
4765
4766                                 /* Hack -- redraw */
4767                                 Term_redraw();
4768                         }
4769                 }
4770
4771 #endif
4772
4773                 /* Unknown option */
4774                 else
4775                 {
4776                         bell();
4777                 }
4778
4779                 /* Flush messages */
4780                 msg_print(NULL);
4781         }
4782
4783
4784         /* Restore the screen */
4785         screen_load();
4786 }
4787
4788
4789 /*
4790  * Note something in the message recall
4791  */
4792 void do_cmd_note(void)
4793 {
4794         char buf[80];
4795
4796         /* Default */
4797         strcpy(buf, "");
4798
4799         /* Input */
4800 #ifdef JP
4801         if (!get_string("¥á¥â: ", buf, 60)) return;
4802 #else
4803         if (!get_string("Note: ", buf, 60)) return;
4804 #endif
4805
4806
4807         /* Ignore empty notes */
4808         if (!buf[0] || (buf[0] == ' ')) return;
4809
4810         /* Add the note to the message recall */
4811 #ifdef JP
4812         msg_format("¥á¥â: %s", buf);
4813 #else
4814         msg_format("Note: %s", buf);
4815 #endif
4816
4817 }
4818
4819
4820 /*
4821  * Mention the current version
4822  */
4823 void do_cmd_version(void)
4824 {
4825
4826         /* Silly message */
4827 #ifdef JP
4828         msg_format("ÊѶòÈÚÅÜ(Hengband) %d.%d.%d",
4829                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4830 #else
4831         msg_format("You are playing Hengband %d.%d.%d.",
4832                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4833 #endif
4834 }
4835
4836
4837
4838 /*
4839  * Array of feeling strings
4840  */
4841 static cptr do_cmd_feeling_text[11] =
4842 {
4843 #ifdef JP
4844         "¤³¤Î³¬¤ÎÊ·°Ïµ¤¤ò´¶¤¸¤È¤ì¤Ê¤«¤Ã¤¿...",
4845 #else
4846         "Looks like any other level.",
4847 #endif
4848
4849 #ifdef JP
4850         "¤³¤Î³¬¤Ë¤Ï²¿¤«ÆÃÊ̤ʤâ¤Î¤¬¤¢¤ë¤è¤¦¤Êµ¤¤¬¤¹¤ë¡£",
4851 #else
4852         "You feel there is something special about this level.",
4853 #endif
4854
4855 #ifdef JP
4856         "¶²¤í¤·¤¤»à¤Î¸¸¤¬ÌܤËÉ⤫¤Ó¡¢µ¤À䤷¤½¤¦¤Ë¤Ê¤Ã¤¿¡ª",
4857 #else
4858         "You nearly faint as horrible visions of death fill your mind!",
4859 #endif
4860
4861 #ifdef JP
4862         "¤³¤Î³¬¤Ï¤È¤Æ¤â´í¸±¤Ê¤è¤¦¤À¡£",
4863 #else
4864         "This level looks very dangerous.",
4865 #endif
4866
4867 #ifdef JP
4868         "¤È¤Æ¤â°­¤¤Í½´¶¤¬¤¹¤ë...",
4869 #else
4870         "You have a very bad feeling...",
4871 #endif
4872
4873 #ifdef JP
4874         "°­¤¤Í½´¶¤¬¤¹¤ë...",
4875 #else
4876         "You have a bad feeling...",
4877 #endif
4878
4879 #ifdef JP
4880         "²¿¤«¶ÛÄ¥¤¹¤ë¡£",
4881 #else
4882         "You feel nervous.",
4883 #endif
4884
4885 #ifdef JP
4886         "¾¯¤·ÉÔ±¿¤Êµ¤¤¬¤¹¤ë...",
4887 #else
4888         "You feel your luck is turning...",
4889 #endif
4890
4891 #ifdef JP
4892         "¤³¤Î¾ì½ê¤Ï¹¥¤­¤Ë¤Ê¤ì¤Ê¤¤¡£",
4893 #else
4894         "You don't like the look of this place.",
4895 #endif
4896
4897 #ifdef JP
4898         "¤³¤Î³¬¤Ï¤½¤ì¤Ê¤ê¤Ë°ÂÁ´¤Ê¤è¤¦¤À¡£",
4899 #else
4900         "This level looks reasonably safe.",
4901 #endif
4902
4903 #ifdef JP
4904         "¤Ê¤ó¤ÆÂà¶þ¤Ê¤È¤³¤í¤À..."
4905 #else
4906         "What a boring place..."
4907 #endif
4908
4909 };
4910
4911 static cptr do_cmd_feeling_text_combat[11] =
4912 {
4913 #ifdef JP
4914         "¤³¤Î³¬¤ÎÊ·°Ïµ¤¤ò´¶¤¸¤È¤ì¤Ê¤«¤Ã¤¿...",
4915 #else
4916         "Looks like any other level.",
4917 #endif
4918
4919 #ifdef JP
4920         "¤³¤Î³¬¤Ë¤Ï²¿¤«ÆÃÊ̤ʤâ¤Î¤¬¤¢¤ë¤è¤¦¤Êµ¤¤¬¤¹¤ë¡£",
4921 #else
4922         "You feel there is something special about this level.",
4923 #endif
4924
4925 #ifdef JP
4926         "º£Ìë¤â¤Þ¤¿¡¢Ã¯¤«¤¬Ì¿¤òÍî¤È¤¹...",
4927 #else
4928         "You nearly faint as horrible visions of death fill your mind!",
4929 #endif
4930
4931 #ifdef JP
4932         "¤³¤Î³¬¤Ï¤È¤Æ¤â´í¸±¤Ê¤è¤¦¤À¡£",
4933 #else
4934         "This level looks very dangerous.",
4935 #endif
4936
4937 #ifdef JP
4938         "¤È¤Æ¤â°­¤¤Í½´¶¤¬¤¹¤ë...",
4939 #else
4940         "You have a very bad feeling...",
4941 #endif
4942
4943 #ifdef JP
4944         "°­¤¤Í½´¶¤¬¤¹¤ë...",
4945 #else
4946         "You have a bad feeling...",
4947 #endif
4948
4949 #ifdef JP
4950         "²¿¤«¶ÛÄ¥¤¹¤ë¡£",
4951 #else
4952         "You feel nervous.",
4953 #endif
4954
4955 #ifdef JP
4956         "¾¯¤·ÉÔ±¿¤Êµ¤¤¬¤¹¤ë...",
4957 #else
4958         "You feel your luck is turning...",
4959 #endif
4960
4961 #ifdef JP
4962         "¤³¤Î¾ì½ê¤Ï¹¥¤­¤Ë¤Ê¤ì¤Ê¤¤¡£",
4963 #else
4964         "You don't like the look of this place.",
4965 #endif
4966
4967 #ifdef JP
4968         "¤³¤Î³¬¤Ï¤½¤ì¤Ê¤ê¤Ë°ÂÁ´¤Ê¤è¤¦¤À¡£",
4969 #else
4970         "This level looks reasonably safe.",
4971 #endif
4972
4973 #ifdef JP
4974         "¤Ê¤ó¤ÆÂà¶þ¤Ê¤È¤³¤í¤À..."
4975 #else
4976         "What a boring place..."
4977 #endif
4978
4979 };
4980
4981 static cptr do_cmd_feeling_text_lucky[11] =
4982 {
4983 #ifdef JP
4984         "¤³¤Î³¬¤ÎÊ·°Ïµ¤¤ò´¶¤¸¤È¤ì¤Ê¤«¤Ã¤¿...",
4985         "¤³¤Î³¬¤Ë¤Ï²¿¤«ÆÃÊ̤ʤâ¤Î¤¬¤¢¤ë¤è¤¦¤Êµ¤¤¬¤¹¤ë¡£",
4986         "¤³¤Î³¬¤Ï¤³¤Î¾å¤Ê¤¯ÁÇÀ²¤é¤·¤¤´¶¤¸¤¬¤¹¤ë¡£",
4987         "ÁÇÀ²¤é¤·¤¤´¶¤¸¤¬¤¹¤ë...",
4988         "¤È¤Æ¤âÎɤ¤´¶¤¸¤¬¤¹¤ë...",
4989         "Îɤ¤´¶¤¸¤¬¤¹¤ë...",
4990         "¤Á¤ç¤Ã¤È¹¬±¿¤Ê´¶¤¸¤¬¤¹¤ë...",
4991         "¿¾¯¤Ï±¿¤¬¸þ¤¤¤Æ¤­¤¿¤«...",
4992         "¸«¤¿´¶¤¸°­¤¯¤Ï¤Ê¤¤...",
4993         "Á´Á³ÂÌÌܤȤ¤¤¦¤³¤È¤Ï¤Ê¤¤¤¬...",
4994         "¤Ê¤ó¤ÆÂà¶þ¤Ê¤È¤³¤í¤À..."
4995 #else
4996         "Looks like any other level.",
4997         "You feel there is something special about this level.",
4998         "You have a superb feeling about this level.",
4999         "You have an excellent feeling...",
5000         "You have a very good feeling...",
5001         "You have a good feeling...",
5002         "You feel strangely lucky...",
5003         "You feel your luck is turning...",
5004         "You like the look of this place...",
5005         "This level can't be all bad...",
5006         "What a boring place..."
5007 #endif
5008 };
5009
5010
5011 /*
5012  * Note that "feeling" is set to zero unless some time has passed.
5013  * Note that this is done when the level is GENERATED, not entered.
5014  */
5015 void do_cmd_feeling(void)
5016 {
5017         /* No useful feeling in quests */
5018         if (p_ptr->inside_quest && !random_quest_number(dun_level))
5019         {
5020 #ifdef JP
5021                 msg_print("ŵ·¿Åª¤Ê¥¯¥¨¥¹¥È¤Î¥À¥ó¥¸¥ç¥ó¤Î¤è¤¦¤À¡£");
5022 #else
5023                 msg_print("Looks like a typical quest level.");
5024 #endif
5025
5026                 return;
5027         }
5028
5029         /* No useful feeling in town */
5030         else if (p_ptr->town_num && !dun_level)
5031         {
5032 #ifdef JP
5033                 if (!strcmp(town[p_ptr->town_num].name, "¹ÓÌî"))
5034 #else
5035                 if (!strcmp(town[p_ptr->town_num].name, "wilderness"))
5036 #endif
5037                 {
5038 #ifdef JP
5039                         msg_print("²¿¤«¤¢¤ê¤½¤¦¤Ê¹ÓÌî¤Î¤è¤¦¤À¡£");
5040 #else
5041                         msg_print("Looks like a strange wilderness.");
5042 #endif
5043
5044                         return;
5045                 }
5046                 else
5047                 {
5048 #ifdef JP
5049                         msg_print("ŵ·¿Åª¤ÊÄ®¤Î¤è¤¦¤À¡£");
5050 #else
5051                         msg_print("Looks like a typical town.");
5052 #endif
5053
5054                         return;
5055                 }
5056         }
5057
5058         /* No useful feeling in the wilderness */
5059         else if (!dun_level)
5060         {
5061 #ifdef JP
5062                 msg_print("ŵ·¿Åª¤Ê¹ÓÌî¤Î¤è¤¦¤À¡£");
5063 #else
5064                 msg_print("Looks like a typical wilderness.");
5065 #endif
5066
5067                 return;
5068         }
5069
5070         /* Display the feeling */
5071         if (p_ptr->muta3 & MUT3_GOOD_LUCK)
5072                 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
5073         else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
5074                  inventory[INVEN_BOW].name1 == ART_CRIMSON)
5075                 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
5076         else
5077                 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
5078 }
5079
5080
5081
5082 /*
5083  * Description of each monster group.
5084  */
5085 static cptr monster_group_text[] = 
5086 {
5087 #ifdef JP
5088         "¥æ¥Ë¡¼¥¯",     /* "Uniques" */
5089         "¾èÇϲÄǽ¤Ê¥â¥ó¥¹¥¿¡¼", /* "Riding" */
5090         "¾Þ¶â¼ó", /* "Wanted */
5091         "¥¢¥ó¥Ð¡¼¤Î²¦Â²", /* "Ambertite" */
5092         "¥¢¥ê",
5093         "¥³¥¦¥â¥ê",
5094         "¥à¥«¥Ç",
5095         "¥É¥é¥´¥ó",
5096         "ÌܶÌ",
5097         "¥Í¥³",
5098         "¥´¡¼¥ì¥à",
5099         "ɸ½à¿Í´Ö·¿À¸Êª",
5100         "¥Ù¥È¥Ù¥È",
5101         "¥¼¥ê¡¼",
5102         "¥³¥Ü¥ë¥É",
5103         "¿åÀ³À¸Êª",
5104         "¥â¥ë¥É",
5105         "¥Ê¡¼¥¬",
5106         "¥ª¡¼¥¯",
5107         "¿Í´Ö",
5108         "»Í­½Ã",
5109         "¥Í¥º¥ß",
5110         "¥¹¥±¥ë¥È¥ó",
5111         "¥Ç¡¼¥â¥ó",
5112         "¥Ü¥ë¥Æ¥Ã¥¯¥¹",
5113         "¥¤¥â¥à¥·/Âç·²",
5114         /* "unused", */
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         "¥×¥ì¥¤¥ä¡¼",
5148 #else
5149         "Uniques",
5150         "Ridable monsters",
5151         "Wanted monsters",
5152         "Ambertite",
5153         "Ant",
5154         "Bat",
5155         "Centipede",
5156         "Dragon",
5157         "Floating Eye",
5158         "Feline",
5159         "Golem",
5160         "Hobbit/Elf/Dwarf",
5161         "Icky Thing",
5162         "Jelly",
5163         "Kobold",
5164         "Aquatic monster",
5165         "Mold",
5166         "Naga",
5167         "Orc",
5168         "Person/Human",
5169         "Quadruped",
5170         "Rodent",
5171         "Skeleton",
5172         "Demon",
5173         "Vortex",
5174         "Worm/Worm-Mass",
5175         /* "unused", */
5176         "Yeek",
5177         "Zombie/Mummy",
5178         "Angel",
5179         "Bird",
5180         "Canine",
5181         /* "Ancient Dragon/Wyrm", */
5182         "Elemental",
5183         "Dragon Fly",
5184         "Ghost",
5185         "Hybrid",
5186         "Insect",
5187         "Snake",
5188         "Killer Beetle",
5189         "Lich",
5190         "Multi-Headed Reptile",
5191         "Mystery Living",
5192         "Ogre",
5193         "Giant Humanoid",
5194         "Quylthulg",
5195         "Reptile/Amphibian",
5196         "Spider/Scorpion/Tick",
5197         "Troll",
5198         /* "Major Demon", */
5199         "Vampire",
5200         "Wight/Wraith/etc",
5201         "Xorn/Xaren/etc",
5202         "Yeti",
5203         "Zephyr Hound",
5204         "Mimic",
5205         "Wall/Plant/Gas",
5206         "Mushroom patch",
5207         "Ball",
5208         "Player",
5209 #endif
5210         NULL
5211 };
5212
5213
5214 /*
5215  * Symbols of monsters in each group. Note the "Uniques" group
5216  * is handled differently.
5217  */
5218 static cptr monster_group_char[] =
5219 {
5220         (char *) -1L,
5221         (char *) -2L,
5222         (char *) -3L,
5223         (char *) -4L,
5224         "a",
5225         "b",
5226         "c",
5227         "dD",
5228         "e",
5229         "f",
5230         "g",
5231         "h",
5232         "i",
5233         "j",
5234         "k",
5235         "l",
5236         "m",
5237         "n",
5238         "o",
5239         "pt",
5240         "q",
5241         "r",
5242         "s",
5243         "uU",
5244         "v",
5245         "w",
5246         /* "x", */
5247         "y",
5248         "z",
5249         "A",
5250         "B",
5251         "C",
5252         /* "D", */
5253         "E",
5254         "F",
5255         "G",
5256         "H",
5257         "I",
5258         "J",
5259         "K",
5260         "L",
5261         "M",
5262         "N",
5263         "O",
5264         "P",
5265         "Q",
5266         "R",
5267         "S",
5268         "T",
5269         /* "U", */
5270         "V",
5271         "W",
5272         "X",
5273         "Y",
5274         "Z",
5275         "!$&()+./=>?[\\]`{|~",
5276         "#%",
5277         ",",
5278         "*",
5279         "@",
5280         NULL
5281 };
5282
5283
5284 /*
5285  * hook function to sort monsters by level
5286  */
5287 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
5288 {
5289         u16b *who = (u16b*)(u);
5290
5291         int w1 = who[a];
5292         int w2 = who[b];
5293
5294         monster_race *r_ptr1 = &r_info[w1];
5295         monster_race *r_ptr2 = &r_info[w2];
5296
5297         /* Unused */
5298         (void)v;
5299
5300         if (r_ptr2->level > r_ptr1->level) return TRUE;
5301         if (r_ptr1->level > r_ptr2->level) return FALSE;
5302
5303         if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
5304         if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
5305         return w1 <= w2;
5306 }
5307
5308 /*
5309  * Build a list of monster indexes in the given group. Return the number
5310  * of monsters in the group.
5311  *
5312  * mode & 0x01 : check for non-empty group
5313  * mode & 0x02 : visual operation only
5314  */
5315 static int collect_monsters(int grp_cur, s16b mon_idx[], byte mode)
5316 {
5317         int i, mon_cnt = 0;
5318         int dummy_why;
5319
5320         /* Get a list of x_char in this group */
5321         cptr group_char = monster_group_char[grp_cur];
5322
5323         /* XXX Hack -- Check if this is the "Uniques" group */
5324         bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
5325
5326         /* XXX Hack -- Check if this is the "Riding" group */
5327         bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
5328
5329         /* XXX Hack -- Check if this is the "Wanted" group */
5330         bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
5331
5332         /* XXX Hack -- Check if this is the "Amberite" group */
5333         bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
5334
5335
5336         /* Check every race */
5337         for (i = 0; i < max_r_idx; i++)
5338         {
5339                 /* Access the race */
5340                 monster_race *r_ptr = &r_info[i];
5341
5342                 /* Skip empty race */
5343                 if (!r_ptr->name) continue ;
5344
5345                 /* Require known monsters */
5346                 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
5347
5348                 if (grp_unique)
5349                 {
5350                         if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5351                 }
5352
5353                 else if (grp_riding)
5354                 {
5355                         if (!(r_ptr->flags7 & RF7_RIDING)) continue;
5356                 }
5357
5358                 else if (grp_wanted)
5359                 {
5360                         bool wanted = FALSE;
5361                         int j;
5362                         for (j = 0; j < MAX_KUBI; j++)
5363                         {
5364                                 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
5365                                         (p_ptr->today_mon && p_ptr->today_mon == i))
5366                                 {
5367                                         wanted = TRUE;
5368                                         break;
5369                                 }
5370                         }
5371                         if (!wanted) continue;
5372                 }
5373
5374                 else if (grp_amberite)
5375                 {
5376                         if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
5377                 }
5378
5379                 else
5380                 {
5381                         /* Check for race in the group */
5382                         if (!my_strchr(group_char, r_ptr->d_char)) continue;
5383                 }
5384
5385                 /* Add the race */
5386                 mon_idx[mon_cnt++] = i;
5387
5388                 /* XXX Hack -- Just checking for non-empty group */
5389                 if (mode & 0x01) break;
5390         }
5391
5392         /* Terminate the list */
5393         mon_idx[mon_cnt] = -1;
5394
5395         /* Select the sort method */
5396         ang_sort_comp = ang_sort_comp_monster_level;
5397         ang_sort_swap = ang_sort_swap_hook;
5398
5399         /* Sort by monster level */
5400         ang_sort(mon_idx, &dummy_why, mon_cnt);
5401
5402         /* Return the number of races */
5403         return mon_cnt;
5404 }
5405
5406
5407 /*
5408  * Description of each monster group.
5409  */
5410 static cptr object_group_text[] = 
5411 {
5412 #ifdef JP
5413         "¥­¥Î¥³",       /* "Mushrooms" */
5414         "Ìô",           /* "Potions" */
5415         "Ìý¤Ä¤Ü",       /* "Flasks" */
5416         "´¬Êª",         /* "Scrolls" */
5417         "»ØÎØ",         /* "Rings" */
5418         "¥¢¥ß¥å¥ì¥Ã¥È", /* "Amulets" */
5419         "ū",           /* "Whistle" */
5420         "¸÷¸»",         /* "Lanterns" */
5421         "ËâË¡ËÀ",       /* "Wands" */
5422         "¾ó",           /* "Staffs" */
5423         "¥í¥Ã¥É",       /* "Rods" */
5424         "¥«¡¼¥É",       /* "Cards" */
5425         "¥­¥ã¥×¥Á¥ã¡¼¡¦¥Ü¡¼¥ë",
5426         "ÍÓÈé»æ",       
5427         "¤¯¤µ¤Ó",
5428         "Ȣ",
5429         "¿Í·Á",
5430         "Áü",
5431         "¥´¥ß",
5432         "¶õ¤Î¥Ó¥ó",
5433         "¹ü",
5434         "»àÂÎ",
5435         "Åá·õÎà",       /* "Swords" */
5436         "Æß´ï",         /* "Blunt Weapons" */
5437         "ĹÊÁÉð´ï",     /* "Polearms" */
5438         "ºÎ·¡Æ»¶ñ",     /* "Diggers" */
5439         "Èô¤ÓÆ»¶ñ",     /* "Bows" */
5440         "ÃÆ",
5441         "Ìð",
5442         "¥Ü¥ë¥È",
5443         "·ÚÁõ³»",       /* "Soft Armor" */
5444         "½ÅÁõ³»",       /* "Hard Armor" */
5445         "¥É¥é¥´¥ó³»",   /* "Dragon Armor" */
5446         "½â",   /* "Shields" */
5447         "¥¯¥í¡¼¥¯",     /* "Cloaks" */
5448         "äƼê", /* "Gloves" */
5449         "¥Ø¥ë¥á¥Ã¥È",   /* "Helms" */
5450         "´§",   /* "Crowns" */
5451         "¥Ö¡¼¥Ä",       /* "Boots" */
5452         "ËâË¡½ñ",
5453         "ºâÊõ",
5454         "²¿¤«",
5455 #else
5456         "Mushrooms",
5457         "Potions",
5458         "Flasks",
5459         "Scrolls",
5460         "Rings",
5461         "Amulets",
5462         "Whistle",
5463         "Lanterns",
5464         "Wands",
5465         "Staves",
5466         "Rods",
5467         "Cards",
5468         "Capture Balls",
5469         "Parchments",
5470         "Spikes",
5471         "Boxs",
5472         "Figurines",
5473         "Statues",
5474         "Junks",
5475         "Bottles",
5476         "Skeletons",
5477         "Corpses",
5478         "Swords",
5479         "Blunt Weapons",
5480         "Polearms",
5481         "Diggers",
5482         "Bows",
5483         "Shots",
5484         "Arrows",
5485         "Bolts",
5486         "Soft Armor",
5487         "Hard Armor",
5488         "Dragon Armor",
5489         "Shields",
5490         "Cloaks",
5491         "Gloves",
5492         "Helms",
5493         "Crowns",
5494         "Boots",
5495         "Spellbooks",
5496         "Treasure",
5497         "Something",
5498 #endif
5499         NULL
5500 };
5501
5502
5503 /*
5504  * TVALs of items in each group
5505  */
5506 static byte object_group_tval[] = 
5507 {
5508         TV_FOOD,
5509         TV_POTION,
5510         TV_FLASK,
5511         TV_SCROLL,
5512         TV_RING,
5513         TV_AMULET,
5514         TV_WHISTLE,
5515         TV_LITE,
5516         TV_WAND,
5517         TV_STAFF,
5518         TV_ROD,
5519         TV_CARD,
5520         TV_CAPTURE,
5521         TV_PARCHMENT,
5522         TV_SPIKE,
5523         TV_CHEST,
5524         TV_FIGURINE,
5525         TV_STATUE,
5526         TV_JUNK,
5527         TV_BOTTLE,
5528         TV_SKELETON,
5529         TV_CORPSE,
5530         TV_SWORD,
5531         TV_HAFTED,
5532         TV_POLEARM,
5533         TV_DIGGING,
5534         TV_BOW,
5535         TV_SHOT,
5536         TV_ARROW,
5537         TV_BOLT,
5538         TV_SOFT_ARMOR,
5539         TV_HARD_ARMOR,
5540         TV_DRAG_ARMOR,
5541         TV_SHIELD,
5542         TV_CLOAK,
5543         TV_GLOVES,
5544         TV_HELM,
5545         TV_CROWN,
5546         TV_BOOTS,
5547         TV_LIFE_BOOK, /* Hack -- all spellbooks */
5548         TV_GOLD,
5549         0,
5550         0,
5551 };
5552
5553
5554 /*
5555  * Build a list of object indexes in the given group. Return the number
5556  * of objects in the group.
5557  *
5558  * mode & 0x01 : check for non-empty group
5559  * mode & 0x02 : visual operation only
5560  */
5561 static int collect_objects(int grp_cur, int object_idx[], byte mode)
5562 {
5563         int i, j, k, object_cnt = 0;
5564
5565         /* Get a list of x_char in this group */
5566         byte group_tval = object_group_tval[grp_cur];
5567
5568         /* Check every object */
5569         for (i = 0; i < max_k_idx; i++)
5570         {
5571                 /* Access the object */
5572                 object_kind *k_ptr = &k_info[i];
5573
5574                 /* Skip empty objects */
5575                 if (!k_ptr->name) continue;
5576
5577                 if (mode & 0x02)
5578                 {
5579                         /* Any objects will be displayed */
5580                 }
5581                 else
5582                 {
5583                         if (!p_ptr->wizard)
5584                         {
5585                                 /* Skip non-flavoured objects */
5586                                 if (!k_ptr->flavor) continue;
5587
5588                                 /* Require objects ever seen */
5589                                 if (!k_ptr->aware) continue;
5590                         }
5591
5592                         /* Skip items with no distribution (special artifacts) */
5593                         for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
5594                         if (!k) continue;
5595                 }
5596
5597                 /* Check for objects in the group */
5598                 if (TV_LIFE_BOOK == group_tval)
5599                 {
5600                         /* Hack -- All spell books */
5601                         if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
5602                         {
5603                                 /* Add the object */
5604                                 object_idx[object_cnt++] = i;
5605                         }
5606                         else continue;
5607                 }
5608                 else if (k_ptr->tval == group_tval)
5609                 {
5610                         /* Add the object */
5611                         object_idx[object_cnt++] = i;
5612                 }
5613                 else continue;
5614
5615                 /* XXX Hack -- Just checking for non-empty group */
5616                 if (mode & 0x01) break;
5617         }
5618
5619         /* Terminate the list */
5620         object_idx[object_cnt] = -1;
5621
5622         /* Return the number of objects */
5623         return object_cnt;
5624 }
5625
5626
5627 /*
5628  * Description of each feature group.
5629  */
5630 static cptr feature_group_text[] = 
5631 {
5632         "terrains",
5633         NULL
5634 };
5635
5636
5637 /*
5638  * Build a list of feature indexes in the given group. Return the number
5639  * of features in the group.
5640  *
5641  * mode & 0x01 : check for non-empty group
5642  */
5643 static int collect_features(int grp_cur, int *feat_idx, byte mode)
5644 {
5645         int i, feat_cnt = 0;
5646
5647         /* Unused;  There is a single group. */
5648         (void)grp_cur;
5649
5650         /* Check every feature */
5651         for (i = 0; i < max_f_idx; i++)
5652         {
5653                 /* Access the index */
5654                 feature_type *f_ptr = &f_info[i];
5655
5656                 /* Skip empty index */
5657                 if (!f_ptr->name) continue;
5658
5659                 /* Skip mimiccing features */
5660                 if (f_ptr->mimic != i) continue;
5661
5662                 /* Add the index */
5663                 feat_idx[feat_cnt++] = i;
5664
5665                 /* XXX Hack -- Just checking for non-empty group */
5666                 if (mode & 0x01) break;
5667         }
5668
5669         /* Terminate the list */
5670         feat_idx[feat_cnt] = -1;
5671
5672         /* Return the number of races */
5673         return feat_cnt;
5674 }
5675
5676
5677 #if 0
5678 /*
5679  * Build a list of monster indexes in the given group. Return the number
5680  * of monsters in the group.
5681  */
5682 static int collect_artifacts(int grp_cur, int object_idx[])
5683 {
5684         int i, object_cnt = 0;
5685
5686         /* Get a list of x_char in this group */
5687         byte group_tval = object_group_tval[grp_cur];
5688
5689         /* Check every object */
5690         for (i = 0; i < max_a_idx; i++)
5691         {
5692                 /* Access the artifact */
5693                 artifact_type *a_ptr = &a_info[i];
5694
5695                 /* Skip empty artifacts */
5696                 if (!a_ptr->name) continue;
5697
5698                 /* Skip "uncreated" artifacts */
5699                 if (!a_ptr->cur_num) continue;
5700
5701                 /* Check for race in the group */
5702                 if (a_ptr->tval == group_tval)
5703                 {
5704                         /* Add the race */
5705                         object_idx[object_cnt++] = i;
5706                 }
5707         }
5708
5709         /* Terminate the list */
5710         object_idx[object_cnt] = 0;
5711
5712         /* Return the number of races */
5713         return object_cnt;
5714 }
5715 #endif /* 0 */
5716
5717
5718 /*
5719  * Encode the screen colors
5720  */
5721 static char hack[17] = "dwsorgbuDWvyRGBU";
5722
5723
5724 /*
5725  * Hack -- load a screen dump from a file
5726  */
5727 void do_cmd_load_screen(void)
5728 {
5729         int i, y, x;
5730
5731         byte a = 0;
5732         char c = ' ';
5733
5734         bool okay = TRUE;
5735
5736         FILE *fff;
5737
5738         char buf[1024];
5739
5740         int wid, hgt;
5741
5742         Term_get_size(&wid, &hgt);
5743
5744         /* Build the filename */
5745         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5746
5747         /* Append to the file */
5748         fff = my_fopen(buf, "r");
5749
5750         /* Oops */
5751         if (!fff) {
5752 #ifdef JP
5753                 msg_format("%s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", buf);
5754 #else
5755                 msg_format("Failed to open %s.", buf);
5756 #endif
5757                 msg_print(NULL);
5758                 return;
5759         }
5760
5761
5762         /* Save the screen */
5763         screen_save();
5764
5765         /* Clear the screen */
5766         Term_clear();
5767
5768
5769         /* Load the screen */
5770         for (y = 0; okay; y++)
5771         {
5772                 /* Get a line of data including control code */
5773                 if (!fgets(buf, 1024, fff)) okay = FALSE;
5774
5775                 /* Get the blank line */
5776                 if (buf[0] == '\n' || buf[0] == '\0') break;
5777
5778                 /* Ignore too large screen image */
5779                 if (y >= hgt) continue;
5780
5781                 /* Show each row */
5782                 for (x = 0; x < wid - 1; x++)
5783                 {
5784                         /* End of line */
5785                         if (buf[x] == '\n' || buf[x] == '\0') break;
5786
5787                         /* Put the attr/char */
5788                         Term_draw(x, y, TERM_WHITE, buf[x]);
5789                 }
5790         }
5791
5792         /* Dump the screen */
5793         for (y = 0; okay; y++)
5794         {
5795                 /* Get a line of data including control code */
5796                 if (!fgets(buf, 1024, fff)) okay = FALSE;
5797
5798                 /* Get the blank line */
5799                 if (buf[0] == '\n' || buf[0] == '\0') break;
5800
5801                 /* Ignore too large screen image */
5802                 if (y >= hgt) continue;
5803
5804                 /* Dump each row */
5805                 for (x = 0; x < wid - 1; x++)
5806                 {
5807                         /* End of line */
5808                         if (buf[x] == '\n' || buf[x] == '\0') break;
5809
5810                         /* Get the attr/char */
5811                         (void)(Term_what(x, y, &a, &c));
5812
5813                         /* Look up the attr */
5814                         for (i = 0; i < 16; i++)
5815                         {
5816                                 /* Use attr matches */
5817                                 if (hack[i] == buf[x]) a = i;
5818                         }
5819
5820                         /* Put the attr/char */
5821                         Term_draw(x, y, a, c);
5822                 }
5823         }
5824
5825
5826         /* Close it */
5827         my_fclose(fff);
5828
5829
5830         /* Message */
5831 #ifdef JP
5832         prt("¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤µ¤ì¤¿²èÌÌ(µ­Ç°»£±Æ)¤ò¥í¡¼¥É¤·¤Þ¤·¤¿¡£", 0, 0);
5833 #else
5834         msg_print("Screen dump loaded.");
5835 #endif
5836
5837         flush();
5838         inkey();
5839
5840
5841         /* Restore the screen */
5842         screen_load();
5843 }
5844
5845
5846
5847
5848 cptr inven_res_label = 
5849 #ifdef JP
5850  "                               »ÀÅŲÐÎäÆǸ÷°ÇÇ˹ì¹ö°øÆÙÎô ÌÕÉÝÍðáãÆ©Ì¿´¶¾ÃÉüÉâ";
5851 #else
5852  "                               AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv";
5853 #endif
5854
5855
5856 #ifdef JP
5857 #define IM_FLAG_STR  "¡ö"
5858 #define HAS_FLAG_STR "¡Ü"
5859 #define NO_FLAG_STR  "¡¦"
5860 #else
5861 #define IM_FLAG_STR  "* "
5862 #define HAS_FLAG_STR "+ "
5863 #define NO_FLAG_STR  ". "
5864 #endif
5865
5866 #define print_im_or_res_flag(IM, RES) \
5867 { \
5868         fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
5869               (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
5870 }
5871
5872 #define print_flag(TR) \
5873 { \
5874         fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
5875 }
5876
5877
5878 /* XTRA HACK RESLIST */
5879 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, byte tval, char *where)
5880 {
5881         char o_name[MAX_NLEN];
5882         u32b flgs[TR_FLAG_SIZE];
5883
5884         if (!o_ptr->k_idx) return;
5885         if (o_ptr->tval != tval) return;
5886
5887         /* Identified items only */
5888         if (!object_is_known(o_ptr)) return;
5889
5890         /*
5891          * HACK:Ring of Lordly protection and Dragon equipment
5892          * have random resistances.
5893          */
5894         if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
5895             || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
5896             || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
5897             || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
5898             || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
5899             || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
5900             || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
5901             || object_is_artifact(o_ptr))
5902         {
5903                 int i = 0;
5904                 object_desc(o_name, o_ptr, OD_NAME_ONLY);
5905
5906                 while (o_name[i] && (i < 26))
5907                 {
5908 #ifdef JP
5909                         if (iskanji(o_name[i])) i++;
5910 #endif
5911                         i++;
5912                 }
5913
5914                 if (i < 28)
5915                 {
5916                         while (i < 28)
5917                         {
5918                                 o_name[i] = ' '; i++;
5919                         }
5920                 }
5921                 o_name[i] = '\0';
5922
5923                 fprintf(fff, "%s %s", where, o_name);
5924
5925                 if (!(o_ptr->ident & (IDENT_MENTAL)))
5926                 {
5927 #ifdef JP
5928                         fputs("-------ÉÔÌÀ--------------- -------ÉÔÌÀ---------\n", fff);
5929 #else
5930                         fputs("-------unknown------------ -------unknown------\n", fff);
5931 #endif
5932                 }
5933                 else
5934                 {
5935                         object_flags_known(o_ptr, flgs);
5936
5937                         print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
5938                         print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
5939                         print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
5940                         print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
5941                         print_flag(TR_RES_POIS);
5942                         print_flag(TR_RES_LITE);
5943                         print_flag(TR_RES_DARK);
5944                         print_flag(TR_RES_SHARDS);
5945                         print_flag(TR_RES_SOUND);
5946                         print_flag(TR_RES_NETHER);
5947                         print_flag(TR_RES_NEXUS);
5948                         print_flag(TR_RES_CHAOS);
5949                         print_flag(TR_RES_DISEN);
5950
5951                         fputs(" ", fff);
5952
5953                         print_flag(TR_RES_BLIND);
5954                         print_flag(TR_RES_FEAR);
5955                         print_flag(TR_RES_CONF);
5956                         print_flag(TR_FREE_ACT);
5957                         print_flag(TR_SEE_INVIS);
5958                         print_flag(TR_HOLD_LIFE);
5959                         print_flag(TR_TELEPATHY);
5960                         print_flag(TR_SLOW_DIGEST);
5961                         print_flag(TR_REGEN);
5962                         print_flag(TR_LEVITATION);
5963
5964                         fputc('\n', fff);
5965                 }
5966                 (*j)++;
5967                 if (*j == 9)
5968                 {
5969                         *j = 0;
5970                         fprintf(fff, "%s\n", inven_res_label);
5971                 }
5972         }
5973 }
5974
5975 /*
5976  * Display *ID* ed weapons/armors's resistances
5977  */
5978 static void do_cmd_knowledge_inven(void)
5979 {
5980         FILE *fff;
5981
5982         char file_name[1024];
5983
5984         store_type  *st_ptr;
5985
5986         byte tval;
5987         int i = 0;
5988         int j = 0;
5989
5990         char  where[32];
5991
5992         /* Open a new file */
5993         fff = my_fopen_temp(file_name, 1024);
5994         if (!fff)
5995         {
5996 #ifdef JP
5997             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
5998 #else
5999             msg_format("Failed to create temporary file %s.", file_name);
6000 #endif
6001             msg_print(NULL);
6002             return;
6003         }
6004         fprintf(fff, "%s\n", inven_res_label);
6005
6006         for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
6007         {
6008                 if (j != 0)
6009                 {
6010                         for (; j < 9; j++) fputc('\n', fff);
6011                         j = 0;
6012                         fprintf(fff, "%s\n", inven_res_label);
6013                 }
6014
6015 #ifdef JP
6016                 strcpy(where, "Áõ");
6017 #else
6018                 strcpy(where, "E ");
6019 #endif
6020                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
6021                 {
6022                         do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
6023                 }
6024
6025 #ifdef JP
6026                 strcpy(where, "»ý");
6027 #else
6028                 strcpy(where, "I ");
6029 #endif
6030                 for (i = 0; i < INVEN_PACK; i++)
6031                 {
6032                         do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
6033                 }
6034
6035                 st_ptr = &town[1].store[STORE_HOME];
6036 #ifdef JP
6037                 strcpy(where, "²È");
6038 #else
6039                 strcpy(where, "H ");
6040 #endif
6041
6042                 for (i = 0; i < st_ptr->stock_num; i++)
6043                 {
6044                         do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
6045                 }
6046         }
6047
6048         /* Close the file */
6049         my_fclose(fff);
6050
6051         /* Display the file contents */
6052 #ifdef JP
6053         show_file(TRUE, file_name, "*´ÕÄê*ºÑ¤ßÉð´ï/Ëɶñ¤ÎÂÑÀ­¥ê¥¹¥È", 0, 0);
6054 #else
6055         show_file(TRUE, file_name, "Resistances of *identified* equipment", 0, 0);
6056 #endif
6057
6058         /* Remove the file */
6059         fd_kill(file_name);
6060 }
6061
6062
6063 void do_cmd_save_screen_html_aux(char *filename, int message)
6064 {
6065         int y, x, i;
6066
6067         byte a = 0, old_a = 0;
6068         char c = ' ';
6069
6070         FILE *fff, *tmpfff;
6071         char buf[2048];
6072
6073         int yomikomu = 0;
6074         cptr tags[4] = {
6075                 "HEADER_START:",
6076                 "HEADER_END:",
6077                 "FOOTER_START:",
6078                 "FOOTER_END:",
6079         };
6080
6081         cptr html_head[] = {
6082                 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
6083                 "<pre>",
6084                 0,
6085         };
6086         cptr html_foot[] = {
6087                 "</pre>\n",
6088                 "</body>\n</html>\n",
6089                 0,
6090         };
6091
6092         int wid, hgt;
6093
6094         Term_get_size(&wid, &hgt);
6095
6096         /* File type is "TEXT" */
6097         FILE_TYPE(FILE_TYPE_TEXT);
6098
6099         /* Append to the file */
6100         fff = my_fopen(filename, "w");
6101
6102         /* Oops */
6103         if (!fff) {
6104                 if (message) {
6105 #ifdef JP
6106                     msg_format("¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿¡£", filename);
6107 #else
6108                     msg_format("Failed to open file %s.", filename);
6109 #endif
6110                     msg_print(NULL);
6111                 }
6112                 
6113                 return;
6114         }
6115
6116         /* Save the screen */
6117         if (message)
6118                 screen_save();
6119
6120         /* Build the filename */
6121         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
6122         tmpfff = my_fopen(buf, "r");
6123         if (!tmpfff) {
6124                 for (i = 0; html_head[i]; i++)
6125                         fputs(html_head[i], fff);
6126         }
6127         else {
6128                 yomikomu = 0;
6129                 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
6130                         if (!yomikomu) {
6131                                 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
6132                                         yomikomu = 1;
6133                         }
6134                         else {
6135                                 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
6136                                         break;
6137                                 fprintf(fff, "%s\n", buf);
6138                         }
6139                 }
6140         }
6141
6142         /* Dump the screen */
6143         for (y = 0; y < hgt; y++)
6144         {
6145                 /* Start the row */
6146                 if (y != 0)
6147                         fprintf(fff, "\n");
6148
6149                 /* Dump each row */
6150                 for (x = 0; x < wid - 1; x++)
6151                 {
6152                         int rv, gv, bv;
6153                         cptr cc = NULL;
6154                         /* Get the attr/char */
6155                         (void)(Term_what(x, y, &a, &c));
6156
6157                         switch (c)
6158                         {
6159                         case '&': cc = "&amp;"; break;
6160                         case '<': cc = "&lt;"; break;
6161                         case '>': cc = "&gt;"; break;
6162 #ifdef WINDOWS
6163                         case 0x1f: c = '.'; break;
6164                         case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
6165 #endif
6166                         }
6167
6168                         a = a & 0x0F;
6169                         if ((y == 0 && x == 0) || a != old_a) {
6170                                 rv = angband_color_table[a][1];
6171                                 gv = angband_color_table[a][2];
6172                                 bv = angband_color_table[a][3];
6173                                 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">", 
6174                                         ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
6175                                 old_a = a;
6176                         }
6177                         if (cc)
6178                                 fprintf(fff, "%s", cc);
6179                         else
6180                                 fprintf(fff, "%c", c);
6181                 }
6182         }
6183         fprintf(fff, "</font>");
6184
6185         if (!tmpfff) {
6186                 for (i = 0; html_foot[i]; i++)
6187                         fputs(html_foot[i], fff);
6188         }
6189         else {
6190                 rewind(tmpfff);
6191                 yomikomu = 0;
6192                 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
6193                         if (!yomikomu) {
6194                                 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
6195                                         yomikomu = 1;
6196                         }
6197                         else {
6198                                 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
6199                                         break;
6200                                 fprintf(fff, "%s\n", buf);
6201                         }
6202                 }
6203                 my_fclose(tmpfff);
6204         }
6205
6206         /* Skip a line */
6207         fprintf(fff, "\n");
6208
6209         /* Close it */
6210         my_fclose(fff);
6211
6212         /* Message */
6213         if (message) {
6214 #ifdef JP
6215         msg_print("²èÌÌ(µ­Ç°»£±Æ)¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
6216 #else
6217                 msg_print("Screen dump saved.");
6218 #endif
6219                 msg_print(NULL);
6220         }
6221
6222         /* Restore the screen */
6223         if (message)
6224                 screen_load();
6225 }
6226
6227 /*
6228  * Hack -- save a screen dump to a file
6229  */
6230 static void do_cmd_save_screen_html(void)
6231 {
6232         char buf[1024], tmp[256] = "screen.html";
6233
6234 #ifdef JP
6235         if (!get_string("¥Õ¥¡¥¤¥ë̾: ", tmp, 80))
6236 #else
6237         if (!get_string("File name: ", tmp, 80))
6238 #endif
6239                 return;
6240
6241         /* Build the filename */
6242         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
6243
6244         msg_print(NULL);
6245
6246         do_cmd_save_screen_html_aux(buf, 1);
6247 }
6248
6249
6250 /*
6251  * Redefinable "save_screen" action
6252  */
6253 void (*screendump_aux)(void) = NULL;
6254
6255
6256 /*
6257  * Hack -- save a screen dump to a file
6258  */
6259 void do_cmd_save_screen(void)
6260 {
6261         bool old_use_graphics = use_graphics;
6262         bool html_dump = FALSE;
6263
6264         int wid, hgt;
6265
6266 #ifdef JP
6267         prt("µ­Ç°»£±Æ¤·¤Þ¤¹¤«¡© [(y)es/(h)tml/(n)o] ", 0, 0);
6268 #else
6269         prt("Save screen dump? [(y)es/(h)tml/(n)o] ", 0, 0);
6270 #endif
6271         while(TRUE)
6272         {
6273                 char c = inkey();
6274                 if (c == 'Y' || c == 'y')
6275                         break;
6276                 else if (c == 'H' || c == 'h')
6277                 {
6278                         html_dump = TRUE;
6279                         break;
6280                 }
6281                 else
6282                 {
6283                         prt("", 0, 0);
6284                         return;
6285                 }
6286         }
6287
6288         Term_get_size(&wid, &hgt);
6289
6290         if (old_use_graphics)
6291         {
6292                 use_graphics = FALSE;
6293                 reset_visuals();
6294
6295                 /* Redraw everything */
6296                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
6297
6298                 /* Hack -- update */
6299                 handle_stuff();
6300         }
6301
6302         if (html_dump)
6303         {
6304                 do_cmd_save_screen_html();
6305                 do_cmd_redraw();
6306         }
6307
6308         /* Do we use a special screendump function ? */
6309         else if (screendump_aux)
6310         {
6311                 /* Dump the screen to a graphics file */
6312                 (*screendump_aux)();
6313         }
6314         else /* Dump the screen as text */
6315         {
6316                 int y, x;
6317
6318                 byte a = 0;
6319                 char c = ' ';
6320
6321                 FILE *fff;
6322
6323                 char buf[1024];
6324
6325                 /* Build the filename */
6326                 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
6327
6328                 /* File type is "TEXT" */
6329                 FILE_TYPE(FILE_TYPE_TEXT);
6330
6331                 /* Append to the file */
6332                 fff = my_fopen(buf, "w");
6333
6334                 /* Oops */
6335                 if (!fff)
6336                 {
6337 #ifdef JP
6338                         msg_format("¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿¡£", buf);
6339 #else
6340                         msg_format("Failed to open file %s.", buf);
6341 #endif
6342                         msg_print(NULL);
6343                         return;
6344                 }
6345
6346
6347                 /* Save the screen */
6348                 screen_save();
6349
6350
6351                 /* Dump the screen */
6352                 for (y = 0; y < hgt; y++)
6353                 {
6354                         /* Dump each row */
6355                         for (x = 0; x < wid - 1; x++)
6356                         {
6357                                 /* Get the attr/char */
6358                                 (void)(Term_what(x, y, &a, &c));
6359
6360                                 /* Dump it */
6361                                 buf[x] = c;
6362                         }
6363
6364                         /* Terminate */
6365                         buf[x] = '\0';
6366
6367                         /* End the row */
6368                         fprintf(fff, "%s\n", buf);
6369                 }
6370
6371                 /* Skip a line */
6372                 fprintf(fff, "\n");
6373
6374
6375                 /* Dump the screen */
6376                 for (y = 0; y < hgt; y++)
6377                 {
6378                         /* Dump each row */
6379                         for (x = 0; x < wid - 1; x++)
6380                         {
6381                                 /* Get the attr/char */
6382                                 (void)(Term_what(x, y, &a, &c));
6383
6384                                 /* Dump it */
6385                                 buf[x] = hack[a&0x0F];
6386                         }
6387
6388                         /* Terminate */
6389                         buf[x] = '\0';
6390
6391                         /* End the row */
6392                         fprintf(fff, "%s\n", buf);
6393                 }
6394
6395                 /* Skip a line */
6396                 fprintf(fff, "\n");
6397
6398
6399                 /* Close it */
6400                 my_fclose(fff);
6401
6402                 /* Message */
6403 #ifdef JP
6404         msg_print("²èÌÌ(µ­Ç°»£±Æ)¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
6405 #else
6406                 msg_print("Screen dump saved.");
6407 #endif
6408
6409                 msg_print(NULL);
6410
6411
6412                 /* Restore the screen */
6413                 screen_load();
6414         }
6415
6416         if (old_use_graphics)
6417         {
6418                 use_graphics = TRUE;
6419                 reset_visuals();
6420
6421                 /* Redraw everything */
6422                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
6423
6424                 /* Hack -- update */
6425                 handle_stuff();
6426         }
6427 }
6428
6429
6430 /*
6431  * Sorting hook -- Comp function -- see below
6432  *
6433  * We use "u" to point to array of monster indexes,
6434  * and "v" to select the type of sorting to perform on "u".
6435  */
6436 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
6437 {
6438         u16b *who = (u16b*)(u);
6439
6440         u16b *why = (u16b*)(v);
6441
6442         int w1 = who[a];
6443         int w2 = who[b];
6444
6445         int z1, z2;
6446
6447         /* Sort by total kills */
6448         if (*why >= 3)
6449         {
6450                 /* Extract total kills */
6451                 z1 = a_info[w1].tval;
6452                 z2 = a_info[w2].tval;
6453
6454                 /* Compare total kills */
6455                 if (z1 < z2) return (TRUE);
6456                 if (z1 > z2) return (FALSE);
6457         }
6458
6459
6460         /* Sort by monster level */
6461         if (*why >= 2)
6462         {
6463                 /* Extract levels */
6464                 z1 = a_info[w1].sval;
6465                 z2 = a_info[w2].sval;
6466
6467                 /* Compare levels */
6468                 if (z1 < z2) return (TRUE);
6469                 if (z1 > z2) return (FALSE);
6470         }
6471
6472
6473         /* Sort by monster experience */
6474         if (*why >= 1)
6475         {
6476                 /* Extract experience */
6477                 z1 = a_info[w1].level;
6478                 z2 = a_info[w2].level;
6479
6480                 /* Compare experience */
6481                 if (z1 < z2) return (TRUE);
6482                 if (z1 > z2) return (FALSE);
6483         }
6484
6485
6486         /* Compare indexes */
6487         return (w1 <= w2);
6488 }
6489
6490
6491 /*
6492  * Sorting hook -- Swap function -- see below
6493  *
6494  * We use "u" to point to array of monster indexes,
6495  * and "v" to select the type of sorting to perform.
6496  */
6497 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
6498 {
6499         u16b *who = (u16b*)(u);
6500
6501         u16b holder;
6502
6503         /* Unused */
6504         (void)v;
6505
6506         /* Swap */
6507         holder = who[a];
6508         who[a] = who[b];
6509         who[b] = holder;
6510 }
6511
6512
6513 /*
6514  * Check the status of "artifacts"
6515  */
6516 static void do_cmd_knowledge_artifacts(void)
6517 {
6518         int i, k, z, x, y, n = 0;
6519         u16b why = 3;
6520         s16b *who;
6521
6522         FILE *fff;
6523
6524         char file_name[1024];
6525
6526         char base_name[MAX_NLEN];
6527
6528         bool *okay;
6529
6530         /* Open a new file */
6531         fff = my_fopen_temp(file_name, 1024);
6532
6533         if (!fff) {
6534 #ifdef JP
6535             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
6536 #else
6537             msg_format("Failed to create temporary file %s.", file_name);
6538 #endif
6539             msg_print(NULL);
6540             return;
6541         }
6542
6543         /* Allocate the "who" array */
6544         C_MAKE(who, max_a_idx, s16b);
6545
6546         /* Allocate the "okay" array */
6547         C_MAKE(okay, max_a_idx, bool);
6548
6549         /* Scan the artifacts */
6550         for (k = 0; k < max_a_idx; k++)
6551         {
6552                 artifact_type *a_ptr = &a_info[k];
6553
6554                 /* Default */
6555                 okay[k] = FALSE;
6556
6557                 /* Skip "empty" artifacts */
6558                 if (!a_ptr->name) continue;
6559
6560                 /* Skip "uncreated" artifacts */
6561                 if (!a_ptr->cur_num) continue;
6562
6563                 /* Assume okay */
6564                 okay[k] = TRUE;
6565         }
6566
6567         /* Check the dungeon */
6568         for (y = 0; y < cur_hgt; y++)
6569         {
6570                 for (x = 0; x < cur_wid; x++)
6571                 {
6572                         cave_type *c_ptr = &cave[y][x];
6573
6574                         s16b this_o_idx, next_o_idx = 0;
6575
6576                         /* Scan all objects in the grid */
6577                         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
6578                         {
6579                                 object_type *o_ptr;
6580
6581                                 /* Acquire object */
6582                                 o_ptr = &o_list[this_o_idx];
6583
6584                                 /* Acquire next object */
6585                                 next_o_idx = o_ptr->next_o_idx;
6586
6587                                 /* Ignore non-artifacts */
6588                                 if (!object_is_fixed_artifact(o_ptr)) continue;
6589
6590                                 /* Ignore known items */
6591                                 if (object_is_known(o_ptr)) continue;
6592
6593                                 /* Note the artifact */
6594                                 okay[o_ptr->name1] = FALSE;
6595                         }
6596                 }
6597         }
6598
6599         /* Check the inventory and equipment */
6600         for (i = 0; i < INVEN_TOTAL; i++)
6601         {
6602                 object_type *o_ptr = &inventory[i];
6603
6604                 /* Ignore non-objects */
6605                 if (!o_ptr->k_idx) continue;
6606
6607                 /* Ignore non-artifacts */
6608                 if (!object_is_fixed_artifact(o_ptr)) continue;
6609
6610                 /* Ignore known items */
6611                 if (object_is_known(o_ptr)) continue;
6612
6613                 /* Note the artifact */
6614                 okay[o_ptr->name1] = FALSE;
6615         }
6616
6617         for (k = 0; k < max_a_idx; k++)
6618         {
6619                 if (okay[k]) who[n++] = k;
6620         }
6621
6622         /* Select the sort method */
6623         ang_sort_comp = ang_sort_art_comp;
6624         ang_sort_swap = ang_sort_art_swap;
6625
6626         /* Sort the array by dungeon depth of monsters */
6627         ang_sort(who, &why, n);
6628
6629         /* Scan the artifacts */
6630         for (k = 0; k < n; k++)
6631         {
6632                 artifact_type *a_ptr = &a_info[who[k]];
6633
6634                 /* Paranoia */
6635 #ifdef JP
6636                 strcpy(base_name, "̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à");
6637 #else
6638                 strcpy(base_name, "Unknown Artifact");
6639 #endif
6640
6641
6642                 /* Obtain the base object type */
6643                 z = lookup_kind(a_ptr->tval, a_ptr->sval);
6644
6645                 /* Real object */
6646                 if (z)
6647                 {
6648                         object_type forge;
6649                         object_type *q_ptr;
6650
6651                         /* Get local object */
6652                         q_ptr = &forge;
6653
6654                         /* Create fake object */
6655                         object_prep(q_ptr, z);
6656
6657                         /* Make it an artifact */
6658                         q_ptr->name1 = (byte)who[k];
6659
6660                         /* Display as if known */
6661                         q_ptr->ident |= IDENT_STORE;
6662
6663                         /* Describe the artifact */
6664                         object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
6665                 }
6666
6667                 /* Hack -- Build the artifact name */
6668 #ifdef JP
6669                 fprintf(fff, "     %s\n", base_name);
6670 #else
6671                 fprintf(fff, "     The %s\n", base_name);
6672 #endif
6673
6674         }
6675
6676         /* Free the "who" array */
6677         C_KILL(who, max_a_idx, s16b);
6678
6679         /* Free the "okay" array */
6680         C_KILL(okay, max_a_idx, bool);
6681
6682         /* Close the file */
6683         my_fclose(fff);
6684
6685         /* Display the file contents */
6686 #ifdef JP
6687         show_file(TRUE, file_name, "´ûÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à", 0, 0);
6688 #else
6689         show_file(TRUE, file_name, "Artifacts Seen", 0, 0);
6690 #endif
6691
6692
6693         /* Remove the file */
6694         fd_kill(file_name);
6695 }
6696
6697
6698 /*
6699  * Display known uniques
6700  * With "XTRA HACK UNIQHIST" (Originally from XAngband)
6701  */
6702 static void do_cmd_knowledge_uniques(void)
6703 {
6704         int i, k, n = 0;
6705         u16b why = 2;
6706         s16b *who;
6707
6708         FILE *fff;
6709
6710         char file_name[1024];
6711
6712         int n_alive[10];
6713         int n_alive_surface = 0;
6714         int n_alive_over100 = 0;
6715         int n_alive_total = 0;
6716         int max_lev = -1;
6717
6718         for (i = 0; i < 10; i++) n_alive[i] = 0;
6719
6720         /* Open a new file */
6721         fff = my_fopen_temp(file_name, 1024);
6722
6723         if (!fff)
6724         {
6725 #ifdef JP
6726             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
6727 #else
6728             msg_format("Failed to create temporary file %s.", file_name);
6729 #endif
6730             msg_print(NULL);
6731             return;
6732         }
6733
6734         /* Allocate the "who" array */
6735         C_MAKE(who, max_r_idx, s16b);
6736
6737         /* Scan the monsters */
6738         for (i = 1; i < max_r_idx; i++)
6739         {
6740                 monster_race *r_ptr = &r_info[i];
6741                 int          lev;
6742
6743                 if (!r_ptr->name) continue;
6744
6745                 /* Require unique monsters */
6746                 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
6747
6748                 /* Only display "known" uniques */
6749                 if (!cheat_know && !r_ptr->r_sights) continue;
6750
6751                 /* Only print rarity <= 100 uniques */
6752                 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
6753
6754                 /* Only "alive" uniques */
6755                 if (r_ptr->max_num == 0) continue;
6756
6757                 if (r_ptr->level)
6758                 {
6759                         lev = (r_ptr->level - 1) / 10;
6760                         if (lev < 10)
6761                         {
6762                                 n_alive[lev]++;
6763                                 if (max_lev < lev) max_lev = lev;
6764                         }
6765                         else n_alive_over100++;
6766                 }
6767                 else n_alive_surface++;
6768
6769                 /* Collect "appropriate" monsters */
6770                 who[n++] = i;
6771         }
6772
6773         /* Select the sort method */
6774         ang_sort_comp = ang_sort_comp_hook;
6775         ang_sort_swap = ang_sort_swap_hook;
6776
6777         /* Sort the array by dungeon depth of monsters */
6778         ang_sort(who, &why, n);
6779
6780         if (n_alive_surface)
6781         {
6782 #ifdef JP
6783                 fprintf(fff, "     ÃϾ堠À¸Â¸: %3dÂÎ\n", n_alive_surface);
6784 #else
6785                 fprintf(fff, "      Surface  alive: %3d\n", n_alive_surface);
6786 #endif
6787                 n_alive_total += n_alive_surface;
6788         }
6789         for (i = 0; i <= max_lev; i++)
6790         {
6791 #ifdef JP
6792                 fprintf(fff, "%3d-%3d³¬  À¸Â¸: %3dÂÎ\n", 1 + i * 10, 10 + i * 10, n_alive[i]);
6793 #else
6794                 fprintf(fff, "Level %3d-%3d  alive: %3d\n", 1 + i * 10, 10 + i * 10, n_alive[i]);
6795 #endif
6796                 n_alive_total += n_alive[i];
6797         }
6798         if (n_alive_over100)
6799         {
6800 #ifdef JP
6801                 fprintf(fff, "101-   ³¬  À¸Â¸: %3dÂÎ\n", n_alive_over100);
6802 #else
6803                 fprintf(fff, "Level 101-     alive: %3d\n", n_alive_over100);
6804 #endif
6805                 n_alive_total += n_alive_over100;
6806         }
6807
6808         if (n_alive_total)
6809         {
6810 #ifdef JP
6811                 fputs("---------  -----------\n", fff);
6812                 fprintf(fff, "     ¹ç·×  À¸Â¸: %3dÂÎ\n\n", n_alive_total);
6813 #else
6814                 fputs("-------------  ----------\n", fff);
6815                 fprintf(fff, "        Total  alive: %3d\n\n", n_alive_total);
6816 #endif
6817         }
6818         else
6819         {
6820 #ifdef JP
6821                 fputs("¸½ºß¤Ï´ûÃΤÎÀ¸Â¸¥æ¥Ë¡¼¥¯¤Ï¤¤¤Þ¤»¤ó¡£\n", fff);
6822 #else
6823                 fputs("No known uniques alive.\n", fff);
6824 #endif
6825         }
6826
6827         /* Scan the monster races */
6828         for (k = 0; k < n; k++)
6829         {
6830                 monster_race *r_ptr = &r_info[who[k]];
6831
6832                 /* Print a message */
6833 #ifdef JP
6834                 fprintf(fff, "     %s (¥ì¥Ù¥ë%d)\n", r_name + r_ptr->name, r_ptr->level);
6835 #else
6836                 fprintf(fff, "     %s (level %d)\n", r_name + r_ptr->name, r_ptr->level);
6837 #endif
6838         }
6839
6840         /* Free the "who" array */
6841         C_KILL(who, max_r_idx, s16b);
6842
6843         /* Close the file */
6844         my_fclose(fff);
6845
6846         /* Display the file contents */
6847 #ifdef JP
6848         show_file(TRUE, file_name, "¤Þ¤ÀÀ¸¤­¤Æ¤¤¤ë¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼", 0, 0);
6849 #else
6850         show_file(TRUE, file_name, "Alive Uniques", 0, 0);
6851 #endif
6852
6853
6854         /* Remove the file */
6855         fd_kill(file_name);
6856 }
6857
6858
6859 /*
6860  * Display weapon-exp
6861  */
6862 static void do_cmd_knowledge_weapon_exp(void)
6863 {
6864         int i, j, num, weapon_exp;
6865
6866         FILE *fff;
6867
6868         char file_name[1024];
6869         char tmp[30];
6870
6871         /* Open a new file */
6872         fff = my_fopen_temp(file_name, 1024);
6873         if (!fff) {
6874 #ifdef JP
6875             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
6876 #else
6877             msg_format("Failed to create temporary file %s.", file_name);
6878 #endif
6879             msg_print(NULL);
6880             return;
6881         }
6882
6883         for (i = 0; i < 5; i++)
6884         {
6885                 for (num = 0; num < 64; num++)
6886                 {
6887                         for (j = 0; j < max_k_idx; j++)
6888                         {
6889                                 object_kind *k_ptr = &k_info[j];
6890
6891                                 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
6892                                 {
6893                                         if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON)) continue;
6894
6895                                         weapon_exp = p_ptr->weapon_exp[4 - i][num];
6896                                         strip_name(tmp, j);
6897                                         fprintf(fff, "%-25s ", tmp);
6898                                         if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
6899                                         else fprintf(fff, " ");
6900                                         fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
6901                                         if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
6902                                         fprintf(fff, "\n");
6903                                         break;
6904                                 }
6905                         }
6906                 }
6907         }
6908
6909         /* Close the file */
6910         my_fclose(fff);
6911
6912         /* Display the file contents */
6913 #ifdef JP
6914         show_file(TRUE, file_name, "Éð´ï¤Î·Ð¸³ÃÍ", 0, 0);
6915 #else
6916         show_file(TRUE, file_name, "Weapon Proficiency", 0, 0);
6917 #endif
6918
6919
6920         /* Remove the file */
6921         fd_kill(file_name);
6922 }
6923
6924
6925 /*
6926  * Display spell-exp
6927  */
6928 static void do_cmd_knowledge_spell_exp(void)
6929 {
6930         int i = 0, spell_exp, exp_level;
6931
6932         FILE *fff;
6933         const magic_type *s_ptr;
6934
6935         char file_name[1024];
6936
6937         /* Open a new file */
6938         fff = my_fopen_temp(file_name, 1024);
6939         if (!fff) {
6940 #ifdef JP
6941             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
6942 #else
6943             msg_format("Failed to create temporary file %s.", file_name);
6944 #endif
6945             msg_print(NULL);
6946             return;
6947         }
6948
6949         if (p_ptr->realm1 != REALM_NONE)
6950         {
6951 #ifdef JP
6952                 fprintf(fff, "%s¤ÎËâË¡½ñ\n", realm_names[p_ptr->realm1]);
6953 #else
6954                 fprintf(fff, "%s Spellbook\n", realm_names[p_ptr->realm1]);
6955 #endif
6956                 for (i = 0; i < 32; i++)
6957                 {
6958                         if (!is_magic(p_ptr->realm1))
6959                         {
6960                                 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
6961                         }
6962                         else
6963                         {
6964                                 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
6965                         }
6966                         if (s_ptr->slevel >= 99) continue;
6967                         spell_exp = p_ptr->spell_exp[i];
6968                         exp_level = spell_exp_level(spell_exp);
6969                         fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
6970                         if (p_ptr->realm1 == REALM_HISSATSU)
6971                                 fprintf(fff, "[--]");
6972                         else
6973                         {
6974                                 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
6975                                 else fprintf(fff, " ");
6976                                 fprintf(fff, "%s", exp_level_str[exp_level]);
6977                         }
6978                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
6979                         fprintf(fff, "\n");
6980                 }
6981         }
6982
6983         if (p_ptr->realm2 != REALM_NONE)
6984         {
6985 #ifdef JP
6986                 fprintf(fff, "%s¤ÎËâË¡½ñ\n", realm_names[p_ptr->realm2]);
6987 #else
6988                 fprintf(fff, "\n%s Spellbook\n", realm_names[p_ptr->realm2]);
6989 #endif
6990                 for (i = 0; i < 32; i++)
6991                 {
6992                         if (!is_magic(p_ptr->realm1))
6993                         {
6994                                 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
6995                         }
6996                         else
6997                         {
6998                                 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
6999                         }
7000                         if (s_ptr->slevel >= 99) continue;
7001
7002                         spell_exp = p_ptr->spell_exp[i + 32];
7003                         exp_level = spell_exp_level(spell_exp);
7004                         fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
7005                         if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
7006                         else fprintf(fff, " ");
7007                         fprintf(fff, "%s", exp_level_str[exp_level]);
7008                         if (cheat_xtra) fprintf(fff, " %d", spell_exp);
7009                         fprintf(fff, "\n");
7010                 }
7011         }
7012
7013         /* Close the file */
7014         my_fclose(fff);
7015
7016         /* Display the file contents */
7017 #ifdef JP
7018         show_file(TRUE, file_name, "ËâË¡¤Î·Ð¸³ÃÍ", 0, 0);
7019 #else
7020         show_file(TRUE, file_name, "Spell Proficiency", 0, 0);
7021 #endif
7022
7023
7024         /* Remove the file */
7025         fd_kill(file_name);
7026 }
7027
7028
7029 /*
7030  * Display skill-exp
7031  */
7032 static void do_cmd_knowledge_skill_exp(void)
7033 {
7034         int i = 0, skill_exp;
7035
7036         FILE *fff;
7037
7038         char file_name[1024];
7039 #ifdef JP
7040         char skill_name[3][17]={"¥Þ¡¼¥·¥ã¥ë¥¢¡¼¥Ä", "ÆóÅáή          ", "¾èÇÏ            "};
7041 #else
7042         char skill_name[3][20]={"Martial Arts    ", "Dual Wielding   ", "Riding          "};
7043 #endif
7044
7045         /* Open a new file */
7046         fff = my_fopen_temp(file_name, 1024);
7047         if (!fff) {
7048 #ifdef JP
7049             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
7050 #else
7051             msg_format("Failed to create temporary file %s.", file_name);
7052 #endif
7053             msg_print(NULL);
7054             return;
7055         }
7056
7057         for (i = 0; i < 3; i++)
7058         {
7059                 skill_exp = p_ptr->skill_exp[i];
7060                 fprintf(fff, "%-20s ", skill_name[i]);
7061                 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
7062                 else fprintf(fff, " ");
7063                 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
7064                 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
7065                 fprintf(fff, "\n");
7066         }
7067
7068         /* Close the file */
7069         my_fclose(fff);
7070
7071         /* Display the file contents */
7072 #ifdef JP
7073         show_file(TRUE, file_name, "µ»Ç½¤Î·Ð¸³ÃÍ", 0, 0);
7074 #else
7075         show_file(TRUE, file_name, "Miscellaneous Proficiency", 0, 0);
7076 #endif
7077
7078
7079         /* Remove the file */
7080         fd_kill(file_name);
7081 }
7082
7083
7084 /*
7085  * Pluralize a monster name
7086  */
7087 void plural_aux(char *Name)
7088 {
7089         int NameLen = strlen(Name);
7090
7091         if (my_strstr(Name, "Disembodied hand"))
7092         {
7093                 strcpy(Name, "Disembodied hands that strangled people");
7094         }
7095         else if (my_strstr(Name, "Colour out of space"))
7096         {
7097                 strcpy(Name, "Colours out of space");
7098         }
7099         else if (my_strstr(Name, "stairway to hell"))
7100         {
7101                 strcpy(Name, "stairways to hell");
7102         }
7103         else if (my_strstr(Name, "Dweller on the threshold"))
7104         {
7105                 strcpy(Name, "Dwellers on the threshold");
7106         }
7107         else if (my_strstr(Name, " of "))
7108         {
7109                 cptr aider = my_strstr(Name, " of ");
7110                 char dummy[80];
7111                 int i = 0;
7112                 cptr ctr = Name;
7113
7114                 while (ctr < aider)
7115                 {
7116                         dummy[i] = *ctr;
7117                         ctr++; i++;
7118                 }
7119
7120                 if (dummy[i-1] == 's')
7121                 {
7122                         strcpy(&(dummy[i]), "es");
7123                         i++;
7124                 }
7125                 else
7126                 {
7127                         strcpy(&(dummy[i]), "s");
7128                 }
7129
7130                 strcpy(&(dummy[i+1]), aider);
7131                 strcpy(Name, dummy);
7132         }
7133         else if (my_strstr(Name, "coins"))
7134         {
7135                 char dummy[80];
7136                 strcpy(dummy, "piles of ");
7137                 strcat(dummy, Name);
7138                 strcpy(Name, dummy);
7139                 return;
7140         }
7141         else if (my_strstr(Name, "Manes"))
7142         {
7143                 return;
7144         }
7145         else if (streq(&(Name[NameLen - 2]), "ey"))
7146         {
7147                 strcpy(&(Name[NameLen - 2]), "eys");
7148         }
7149         else if (Name[NameLen - 1] == 'y')
7150         {
7151                 strcpy(&(Name[NameLen - 1]), "ies");
7152         }
7153         else if (streq(&(Name[NameLen - 4]), "ouse"))
7154         {
7155                 strcpy(&(Name[NameLen - 4]), "ice");
7156         }
7157         else if (streq(&(Name[NameLen - 2]), "us"))
7158         {
7159                 strcpy(&(Name[NameLen - 2]), "i");
7160         }
7161         else if (streq(&(Name[NameLen - 6]), "kelman"))
7162         {
7163                 strcpy(&(Name[NameLen - 6]), "kelmen");
7164         }
7165         else if (streq(&(Name[NameLen - 8]), "wordsman"))
7166         {
7167                 strcpy(&(Name[NameLen - 8]), "wordsmen");
7168         }
7169         else if (streq(&(Name[NameLen - 7]), "oodsman"))
7170         {
7171                 strcpy(&(Name[NameLen - 7]), "oodsmen");
7172         }
7173         else if (streq(&(Name[NameLen - 7]), "eastman"))
7174         {
7175                 strcpy(&(Name[NameLen - 7]), "eastmen");
7176         }
7177         else if (streq(&(Name[NameLen - 8]), "izardman"))
7178         {
7179                 strcpy(&(Name[NameLen - 8]), "izardmen");
7180         }
7181         else if (streq(&(Name[NameLen - 5]), "geist"))
7182         {
7183                 strcpy(&(Name[NameLen - 5]), "geister");
7184         }
7185         else if (streq(&(Name[NameLen - 2]), "ex"))
7186         {
7187                 strcpy(&(Name[NameLen - 2]), "ices");
7188         }
7189         else if (streq(&(Name[NameLen - 2]), "lf"))
7190         {
7191                 strcpy(&(Name[NameLen - 2]), "lves");
7192         }
7193         else if (suffix(Name, "ch") ||
7194                  suffix(Name, "sh") ||
7195                          suffix(Name, "nx") ||
7196                          suffix(Name, "s") ||
7197                          suffix(Name, "o"))
7198         {
7199                 strcpy(&(Name[NameLen]), "es");
7200         }
7201         else
7202         {
7203                 strcpy(&(Name[NameLen]), "s");
7204         }
7205 }
7206
7207 /*
7208  * Display current pets
7209  */
7210 static void do_cmd_knowledge_pets(void)
7211 {
7212         int             i;
7213         FILE            *fff;
7214         monster_type    *m_ptr;
7215         char            pet_name[80];
7216         int             t_friends = 0;
7217         int             show_upkeep = 0;
7218         char            file_name[1024];
7219
7220
7221         /* Open a new file */
7222         fff = my_fopen_temp(file_name, 1024);
7223         if (!fff) {
7224 #ifdef JP
7225             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
7226 #else
7227             msg_format("Failed to create temporary file %s.", file_name);
7228 #endif
7229             msg_print(NULL);
7230             return;
7231         }
7232
7233         /* Process the monsters (backwards) */
7234         for (i = m_max - 1; i >= 1; i--)
7235         {
7236                 /* Access the monster */
7237                 m_ptr = &m_list[i];
7238
7239                 /* Ignore "dead" monsters */
7240                 if (!m_ptr->r_idx) continue;
7241
7242                 /* Calculate "upkeep" for pets */
7243                 if (is_pet(m_ptr))
7244                 {
7245                         t_friends++;
7246                         monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
7247                         fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
7248                 }
7249         }
7250
7251         show_upkeep = calculate_upkeep();
7252
7253         fprintf(fff, "----------------------------------------------\n");
7254 #ifdef JP
7255         fprintf(fff, "    ¹ç·×: %d ÂΤΥڥåÈ\n", t_friends);
7256         fprintf(fff, " °Ý»ý¥³¥¹¥È: %d%% MP\n", show_upkeep);
7257 #else
7258         fprintf(fff, "   Total: %d pet%s.\n",
7259                 t_friends, (t_friends == 1 ? "" : "s"));
7260         fprintf(fff, "   Upkeep: %d%% mana.\n", show_upkeep);
7261 #endif
7262
7263
7264
7265         /* Close the file */
7266         my_fclose(fff);
7267
7268         /* Display the file contents */
7269 #ifdef JP
7270         show_file(TRUE, file_name, "¸½ºß¤Î¥Ú¥Ã¥È", 0, 0);
7271 #else
7272         show_file(TRUE, file_name, "Current Pets", 0, 0);
7273 #endif
7274
7275
7276         /* Remove the file */
7277         fd_kill(file_name);
7278 }
7279
7280
7281 /*
7282  * Total kill count
7283  *
7284  * Note that the player ghosts are ignored.  XXX XXX XXX
7285  */
7286 static void do_cmd_knowledge_kill_count(void)
7287 {
7288         int i, k, n = 0;
7289         u16b why = 2;
7290         s16b *who;
7291
7292         FILE *fff;
7293
7294         char file_name[1024];
7295
7296         s32b Total = 0;
7297
7298
7299         /* Open a new file */
7300         fff = my_fopen_temp(file_name, 1024);
7301
7302         if (!fff) {
7303 #ifdef JP
7304             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
7305 #else
7306             msg_format("Failed to create temporary file %s.", file_name);
7307 #endif
7308             msg_print(NULL);
7309             return;
7310         }
7311
7312         /* Allocate the "who" array */
7313         C_MAKE(who, max_r_idx, s16b);
7314
7315         {
7316                 /* Monsters slain */
7317                 int kk;
7318
7319                 for (kk = 1; kk < max_r_idx; kk++)
7320                 {
7321                         monster_race *r_ptr = &r_info[kk];
7322
7323                         if (r_ptr->flags1 & (RF1_UNIQUE))
7324                         {
7325                                 bool dead = (r_ptr->max_num == 0);
7326
7327                                 if (dead)
7328                                 {
7329                                         Total++;
7330                                 }
7331                         }
7332                         else
7333                         {
7334                                 s16b This = r_ptr->r_pkills;
7335
7336                                 if (This > 0)
7337                                 {
7338                                         Total += This;
7339                                 }
7340                         }
7341                 }
7342
7343                 if (Total < 1)
7344 #ifdef JP
7345                         fprintf(fff,"¤¢¤Ê¤¿¤Ï¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Ê¤¤¡£\n\n");
7346 #else
7347                         fprintf(fff,"You have defeated no enemies yet.\n\n");
7348 #endif
7349                 else
7350 #ifdef JP
7351                         fprintf(fff,"¤¢¤Ê¤¿¤Ï%ldÂΤÎŨ¤òÅݤ·¤Æ¤¤¤ë¡£\n\n", (long int)Total);
7352 #else
7353                         fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
7354 #endif
7355         }
7356
7357         Total = 0;
7358
7359         /* Scan the monsters */
7360         for (i = 1; i < max_r_idx; i++)
7361         {
7362                 monster_race *r_ptr = &r_info[i];
7363
7364                 /* Use that monster */
7365                 if (r_ptr->name) who[n++] = i;
7366         }
7367
7368         /* Select the sort method */
7369         ang_sort_comp = ang_sort_comp_hook;
7370         ang_sort_swap = ang_sort_swap_hook;
7371
7372         /* Sort the array by dungeon depth of monsters */
7373         ang_sort(who, &why, n);
7374
7375         /* Scan the monster races */
7376         for (k = 0; k < n; k++)
7377         {
7378                 monster_race *r_ptr = &r_info[who[k]];
7379
7380                 if (r_ptr->flags1 & (RF1_UNIQUE))
7381                 {
7382                         bool dead = (r_ptr->max_num == 0);
7383
7384                         if (dead)
7385                         {
7386                                 /* Print a message */
7387                                 fprintf(fff, "     %s\n",
7388                                     (r_name + r_ptr->name));
7389                                 Total++;
7390                         }
7391                 }
7392                 else
7393                 {
7394                         s16b This = r_ptr->r_pkills;
7395
7396                         if (This > 0)
7397                         {
7398 #ifdef JP
7399                                 /* p,t¤Ï¿Í¤È¿ô¤¨¤ë by ita */
7400                                 if (my_strchr("pt", r_ptr->d_char))
7401                                         fprintf(fff, "     %3d ¿Í¤Î %s\n", This, r_name + r_ptr->name);
7402                                 else
7403                                         fprintf(fff, "     %3d ÂΤΠ%s\n", This, r_name + r_ptr->name);
7404 #else
7405                                 if (This < 2)
7406                                 {
7407                                         if (my_strstr(r_name + r_ptr->name, "coins"))
7408                                         {
7409                                                 fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
7410                                         }
7411                                         else
7412                                         {
7413                                                 fprintf(fff, "     1 %s\n", (r_name + r_ptr->name));
7414                                         }
7415                                 }
7416                                 else
7417                                 {
7418                                         char ToPlural[80];
7419                                         strcpy(ToPlural, (r_name + r_ptr->name));
7420                                         plural_aux(ToPlural);
7421                                         fprintf(fff, "     %d %s\n", This, ToPlural);
7422                                 }
7423 #endif
7424
7425
7426                                 Total += This;
7427                         }
7428                 }
7429         }
7430
7431         fprintf(fff,"----------------------------------------------\n");
7432 #ifdef JP
7433         fprintf(fff,"    ¹ç·×: %lu ÂΤòÅݤ·¤¿¡£\n", (unsigned long int)Total);
7434 #else
7435         fprintf(fff,"   Total: %lu creature%s killed.\n",
7436                 (unsigned long int)Total, (Total == 1 ? "" : "s"));
7437 #endif
7438
7439
7440         /* Free the "who" array */
7441         C_KILL(who, max_r_idx, s16b);
7442
7443         /* Close the file */
7444         my_fclose(fff);
7445
7446         /* Display the file contents */
7447 #ifdef JP
7448         show_file(TRUE, file_name, "Åݤ·¤¿Å¨¤Î¿ô", 0, 0);
7449 #else
7450         show_file(TRUE, file_name, "Kill Count", 0, 0);
7451 #endif
7452
7453
7454         /* Remove the file */
7455         fd_kill(file_name);
7456 }
7457
7458
7459 /*
7460  * Display the object groups.
7461  */
7462 static void display_group_list(int col, int row, int wid, int per_page,
7463         int grp_idx[], cptr group_text[], int grp_cur, int grp_top)
7464 {
7465         int i;
7466
7467         /* Display lines until done */
7468         for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
7469         {
7470                 /* Get the group index */
7471                 int grp = grp_idx[grp_top + i];
7472
7473                 /* Choose a color */
7474                 byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
7475
7476                 /* Erase the entire line */
7477                 Term_erase(col, row + i, wid);
7478
7479                 /* Display the group label */
7480                 c_put_str(attr, group_text[grp], row + i, col);
7481         }
7482 }
7483
7484
7485 /* 
7486  * Move the cursor in a browser window 
7487  */
7488 static void browser_cursor(char ch, int *column, int *grp_cur, int grp_cnt, 
7489                                                    int *list_cur, int list_cnt)
7490 {
7491         int d;
7492         int col = *column;
7493         int grp = *grp_cur;
7494         int list = *list_cur;
7495
7496         /* Extract direction */
7497         if (ch == ' ')
7498         {
7499                 /* Hack -- scroll up full screen */
7500                 d = 3;
7501         }
7502         else if (ch == '-')
7503         {
7504                 /* Hack -- scroll down full screen */
7505                 d = 9;
7506         }
7507         else
7508         {
7509                 d = get_keymap_dir(ch);
7510         }
7511
7512         if (!d) return;
7513
7514         /* Diagonals - hack */
7515         if ((ddx[d] > 0) && ddy[d])
7516         {
7517                 int browser_rows;
7518                 int wid, hgt;
7519
7520                 /* Get size */
7521                 Term_get_size(&wid, &hgt);
7522
7523                 browser_rows = hgt - 8;
7524
7525                 /* Browse group list */
7526                 if (!col)
7527                 {
7528                         int old_grp = grp;
7529
7530                         /* Move up or down */
7531                         grp += ddy[d] * (browser_rows - 1);
7532
7533                         /* Verify */
7534                         if (grp >= grp_cnt)     grp = grp_cnt - 1;
7535                         if (grp < 0) grp = 0;
7536                         if (grp != old_grp)     list = 0;
7537                 }
7538
7539                 /* Browse sub-list list */
7540                 else
7541                 {
7542                         /* Move up or down */
7543                         list += ddy[d] * browser_rows;
7544
7545                         /* Verify */
7546                         if (list >= list_cnt) list = list_cnt - 1;
7547                         if (list < 0) list = 0;
7548                 }
7549
7550                 (*grp_cur) = grp;
7551                 (*list_cur) = list;
7552
7553                 return;
7554         }
7555
7556         if (ddx[d])
7557         {
7558                 col += ddx[d];
7559                 if (col < 0) col = 0;
7560                 if (col > 1) col = 1;
7561
7562                 (*column) = col;
7563
7564                 return;
7565         }
7566
7567         /* Browse group list */
7568         if (!col)
7569         {
7570                 int old_grp = grp;
7571
7572                 /* Move up or down */
7573                 grp += ddy[d];
7574
7575                 /* Verify */
7576                 if (grp >= grp_cnt)     grp = grp_cnt - 1;
7577                 if (grp < 0) grp = 0;
7578                 if (grp != old_grp)     list = 0;
7579         }
7580
7581         /* Browse sub-list list */
7582         else
7583         {
7584                 /* Move up or down */
7585                 list += ddy[d];
7586
7587                 /* Verify */
7588                 if (list >= list_cnt) list = list_cnt - 1;
7589                 if (list < 0) list = 0;
7590         }
7591
7592         (*grp_cur) = grp;
7593         (*list_cur) = list;
7594 }
7595
7596
7597 /*
7598  * Display visuals.
7599  */
7600 static void display_visual_list(int col, int row, int height, int width, byte attr_top, byte char_left)
7601 {
7602         int i, j;
7603
7604         /* Clear the display lines */
7605         for (i = 0; i < height; i++)
7606         {
7607                 Term_erase(col, row + i, width);
7608         }
7609
7610         /* Bigtile mode uses double width */
7611         if (use_bigtile) width /= 2;
7612
7613         /* Display lines until done */
7614         for (i = 0; i < height; i++)
7615         {
7616                 /* Display columns until done */
7617                 for (j = 0; j < width; j++)
7618                 {
7619                         byte a;
7620                         char c;
7621                         int x = col + j;
7622                         int y = row + i;
7623                         int ia, ic;
7624
7625                         /* Bigtile mode uses double width */
7626                         if (use_bigtile) x += j;
7627
7628                         ia = attr_top + i;
7629                         ic = char_left + j;
7630
7631                         /* Ignore illegal characters */
7632                         if (ia > 0x7f || ic > 0xff || ic < ' ' ||
7633                             (!use_graphics && ic > 0x7f))
7634                                 continue;
7635
7636                         a = (byte)ia;
7637                         c = (char)ic;
7638
7639                         /* Force correct code for both ASCII character and tile */
7640                         if (c & 0x80) a |= 0x80;
7641
7642                         /* Display symbol */
7643                         Term_queue_bigchar(x, y, a, c, 0, 0);
7644                 }
7645         }
7646 }
7647
7648
7649 /*
7650  * Place the cursor at the collect position for visual mode
7651  */
7652 static void place_visual_list_cursor(int col, int row, byte a, byte c, byte attr_top, byte char_left)
7653 {
7654         int i = (a & 0x7f) - attr_top;
7655         int j = c - char_left;
7656
7657         int x = col + j;
7658         int y = row + i;
7659
7660         /* Bigtile mode uses double width */
7661         if (use_bigtile) x += j;
7662
7663         /* Place the cursor */
7664         Term_gotoxy(x, y);
7665 }
7666
7667
7668 /*
7669  *  Clipboard variables for copy&paste in visual mode
7670  */
7671 static byte attr_idx = 0;
7672 static byte char_idx = 0;
7673
7674 /* Hack -- for feature lighting */
7675 static byte attr_idx_feat[F_LIT_MAX];
7676 static byte char_idx_feat[F_LIT_MAX];
7677
7678 /*
7679  *  Do visual mode command -- Change symbols
7680  */
7681 static bool visual_mode_command(char ch, bool *visual_list_ptr,
7682                                 int height, int width,
7683                                 byte *attr_top_ptr, byte *char_left_ptr,
7684                                 byte *cur_attr_ptr, byte *cur_char_ptr, bool *need_redraw)
7685 {
7686         static byte attr_old = 0, char_old = 0;
7687
7688         switch (ch)
7689         {
7690         case ESCAPE:
7691                 if (*visual_list_ptr)
7692                 {
7693                         /* Cancel change */
7694                         *cur_attr_ptr = attr_old;
7695                         *cur_char_ptr = char_old;
7696                         *visual_list_ptr = FALSE;
7697
7698                         return TRUE;
7699                 }
7700                 break;
7701
7702         case '\n':
7703         case '\r':
7704                 if (*visual_list_ptr)
7705                 {
7706                         /* Accept change */
7707                         *visual_list_ptr = FALSE;
7708                         *need_redraw = TRUE;
7709
7710                         return TRUE;
7711                 }
7712                 break;
7713
7714         case 'V':
7715         case 'v':
7716                 if (!*visual_list_ptr)
7717                 {
7718                         *visual_list_ptr = TRUE;
7719
7720                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
7721                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
7722
7723                         attr_old = *cur_attr_ptr;
7724                         char_old = *cur_char_ptr;
7725
7726                         return TRUE;
7727                 }
7728                 break;
7729
7730         case 'C':
7731         case 'c':
7732                 {
7733                         int i;
7734
7735                         /* Set the visual */
7736                         attr_idx = *cur_attr_ptr;
7737                         char_idx = *cur_char_ptr;
7738
7739                         /* Hack -- for feature lighting */
7740                         for (i = 0; i < F_LIT_MAX; i++)
7741                         {
7742                                 attr_idx_feat[i] = 0;
7743                                 char_idx_feat[i] = 0;
7744                         }
7745                 }
7746                 return TRUE;
7747
7748         case 'P':
7749         case 'p':
7750                 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
7751                 {
7752                         /* Set the char */
7753                         *cur_attr_ptr = attr_idx;
7754                         *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
7755                         if (!*visual_list_ptr) *need_redraw = TRUE;
7756                 }
7757
7758                 if (char_idx)
7759                 {
7760                         /* Set the char */
7761                         *cur_char_ptr = char_idx;
7762                         *char_left_ptr = MAX(0, *cur_char_ptr - 10);
7763                         if (!*visual_list_ptr) *need_redraw = TRUE;
7764                 }
7765
7766                 return TRUE;
7767
7768         default:
7769                 if (*visual_list_ptr)
7770                 {
7771                         int eff_width;
7772                         int d = get_keymap_dir(ch);
7773                         byte a = (*cur_attr_ptr & 0x7f);
7774                         byte c = *cur_char_ptr;
7775
7776                         if (use_bigtile) eff_width = width / 2;
7777                         else eff_width = width;
7778
7779                         /* Restrict direction */
7780                         if ((a == 0) && (ddy[d] < 0)) d = 0;
7781                         if ((c == 0) && (ddx[d] < 0)) d = 0;
7782                         if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
7783                         if ((c == 0xff) && (ddx[d] > 0)) d = 0;
7784
7785                         a += ddy[d];
7786                         c += ddx[d];
7787
7788                         /* Force correct code for both ASCII character and tile */
7789                         if (c & 0x80) a |= 0x80;
7790
7791                         /* Set the visual */
7792                         *cur_attr_ptr = a;
7793                         *cur_char_ptr = c;
7794
7795
7796                         /* Move the frame */
7797                         if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
7798                         if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
7799                         if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
7800                         if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
7801                         return TRUE;
7802                 }
7803                 break;
7804         }
7805
7806         /* Visual mode command is not used */
7807         return FALSE;
7808 }
7809
7810
7811 /*
7812  * Display the monsters in a group.
7813  */
7814 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
7815         int mon_cur, int mon_top, bool visual_only)
7816 {
7817         int i;
7818
7819         /* Display lines until done */
7820         for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
7821         {
7822                 byte attr;
7823
7824                 /* Get the race index */
7825                 int r_idx = mon_idx[mon_top + i] ;
7826
7827                 /* Access the race */
7828                 monster_race *r_ptr = &r_info[r_idx];
7829
7830                 /* Choose a color */
7831                 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
7832
7833                 /* Display the name */
7834                 c_prt(attr, (r_name + r_ptr->name), row + i, col);
7835
7836                 /* Hack -- visual_list mode */
7837                 if (per_page == 1)
7838                 {
7839                         c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
7840                 }
7841                 if (p_ptr->wizard || visual_only)
7842                 {
7843                         c_prt(attr, format("%d", r_idx), row + i, 62);
7844                 }
7845
7846                 /* Erase chars before overwritten by the race letter */
7847                 Term_erase(69, row + i, 255);
7848
7849                 /* Display symbol */
7850                 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
7851
7852                 if (!visual_only)
7853                 {
7854                         /* Display kills */
7855                         if (!(r_ptr->flags1 & RF1_UNIQUE)) put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
7856 #ifdef JP
7857                         else c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), (r_ptr->max_num == 0 ? "»àË´" : "À¸Â¸"), row + i, 74);
7858 #else
7859                         else c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), (r_ptr->max_num == 0 ? " dead" : "alive"), row + i, 73);
7860 #endif
7861                 }
7862         }
7863
7864         /* Clear remaining lines */
7865         for (; i < per_page; i++)
7866         {
7867                 Term_erase(col, row + i, 255);
7868         }
7869 }
7870
7871
7872 /*
7873  * Display known monsters.
7874  */
7875 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx)
7876 {
7877         int i, len, max;
7878         int grp_cur, grp_top, old_grp_cur;
7879         int mon_cur, mon_top;
7880         int grp_cnt, grp_idx[100];
7881         int mon_cnt;
7882         s16b *mon_idx;
7883
7884         int column = 0;
7885         bool flag;
7886         bool redraw;
7887
7888         bool visual_list = FALSE;
7889         byte attr_top = 0, char_left = 0;
7890
7891         int browser_rows;
7892         int wid, hgt;
7893
7894         byte mode;
7895
7896         /* Get size */
7897         Term_get_size(&wid, &hgt);
7898
7899         browser_rows = hgt - 8;
7900
7901         /* Allocate the "mon_idx" array */
7902         C_MAKE(mon_idx, max_r_idx, s16b);
7903
7904         max = 0;
7905         grp_cnt = 0;
7906
7907         if (direct_r_idx < 0)
7908         {
7909                 mode = visual_only ? 0x03 : 0x01;
7910
7911                 /* Check every group */
7912                 for (i = 0; monster_group_text[i] != NULL; i++)
7913                 {
7914                         /* Measure the label */
7915                         len = strlen(monster_group_text[i]);
7916
7917                         /* Save the maximum length */
7918                         if (len > max) max = len;
7919
7920                         /* See if any monsters are known */
7921                         if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
7922                         {
7923                                 /* Build a list of groups with known monsters */
7924                                 grp_idx[grp_cnt++] = i;
7925                         }
7926                 }
7927
7928                 mon_cnt = 0;
7929         }
7930         else
7931         {
7932                 mon_idx[0] = direct_r_idx;
7933                 mon_cnt = 1;
7934
7935                 /* Terminate the list */
7936                 mon_idx[1] = -1;
7937
7938                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7939                         &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
7940         }
7941
7942         /* Terminate the list */
7943         grp_idx[grp_cnt] = -1;
7944
7945         old_grp_cur = -1;
7946         grp_cur = grp_top = 0;
7947         mon_cur = mon_top = 0;
7948
7949         flag = FALSE;
7950         redraw = TRUE;
7951
7952         mode = visual_only ? 0x02 : 0x00;
7953
7954         while (!flag)
7955         {
7956                 char ch;
7957                 monster_race *r_ptr;
7958
7959                 if (redraw)
7960                 {
7961                         clear_from(0);
7962
7963 #ifdef JP
7964                         prt(format("%s - ¥â¥ó¥¹¥¿¡¼", !visual_only ? "Ãμ±" : "ɽ¼¨"), 2, 0);
7965                         if (direct_r_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
7966                         prt("̾Á°", 4, max + 3);
7967                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7968                         prt("ʸ»ú", 4, 67);
7969                         if (!visual_only) prt("»¦³²¿ô", 4, 72);
7970 #else
7971                         prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
7972                         if (direct_r_idx < 0) prt("Group", 4, 0);
7973                         prt("Name", 4, max + 3);
7974                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7975                         prt("Sym", 4, 68);
7976                         if (!visual_only) prt("Kills", 4, 73);
7977 #endif
7978
7979                         for (i = 0; i < 78; i++)
7980                         {
7981                                 Term_putch(i, 5, TERM_WHITE, '=');
7982                         }
7983
7984                         if (direct_r_idx < 0)
7985                         {
7986                                 for (i = 0; i < browser_rows; i++)
7987                                 {
7988                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7989                                 }
7990                         }
7991
7992                         redraw = FALSE;
7993                 }
7994
7995                 if (direct_r_idx < 0)
7996                 {
7997                         /* Scroll group list */
7998                         if (grp_cur < grp_top) grp_top = grp_cur;
7999                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
8000
8001                         /* Display a list of monster groups */
8002                         display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
8003
8004                         if (old_grp_cur != grp_cur)
8005                         {
8006                                 old_grp_cur = grp_cur;
8007
8008                                 /* Get a list of monsters in the current group */
8009                                 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
8010                         }
8011
8012                         /* Scroll monster list */
8013                         while (mon_cur < mon_top)
8014                                 mon_top = MAX(0, mon_top - browser_rows/2);
8015                         while (mon_cur >= mon_top + browser_rows)
8016                                 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
8017                 }
8018
8019                 if (!visual_list)
8020                 {
8021                         /* Display a list of monsters in the current group */
8022                         display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
8023                 }
8024                 else
8025                 {
8026                         mon_top = mon_cur;
8027
8028                         /* Display a monster name */
8029                         display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
8030
8031                         /* Display visual list below first monster */
8032                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
8033                 }
8034
8035                 /* Prompt */
8036 #ifdef JP
8037                 prt(format("<Êý¸þ>%s%s%s, ESC",
8038                         (!visual_list && !visual_only) ? ", 'r'¤Ç»×¤¤½Ð¤ò¸«¤ë" : "",
8039                         visual_list ? ", ENTER¤Ç·èÄê" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
8040                         (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
8041                         hgt - 1, 0);
8042 #else
8043                 prt(format("<dir>%s%s%s, ESC",
8044                         (!visual_list && !visual_only) ? ", 'r' to recall" : "",
8045                         visual_list ? ", ENTER to accept" : ", 'v' for visuals",
8046                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
8047                         hgt - 1, 0);
8048 #endif
8049
8050                 /* Get the current monster */
8051                 r_ptr = &r_info[mon_idx[mon_cur]];
8052
8053                 if (!visual_only)
8054                 {
8055                         /* Mega Hack -- track this monster race */
8056                         if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
8057
8058                         /* Hack -- handle stuff */
8059                         handle_stuff();
8060                 }
8061
8062                 if (visual_list)
8063                 {
8064                         place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
8065                 }
8066                 else if (!column)
8067                 {
8068                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
8069                 }
8070                 else
8071                 {
8072                         Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
8073                 }
8074
8075                 ch = inkey();
8076
8077                 /* Do visual mode command if needed */
8078                 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))
8079                 {
8080                         if (direct_r_idx >= 0)
8081                         {
8082                                 switch (ch)
8083                                 {
8084                                 case '\n':
8085                                 case '\r':
8086                                 case ESCAPE:
8087                                         flag = TRUE;
8088                                         break;
8089                                 }
8090                         }
8091                         continue;
8092                 }
8093
8094                 switch (ch)
8095                 {
8096                         case ESCAPE:
8097                         {
8098                                 flag = TRUE;
8099                                 break;
8100                         }
8101
8102                         case 'R':
8103                         case 'r':
8104                         {
8105                                 /* Recall on screen */
8106                                 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
8107                                 {
8108                                         screen_roff(mon_idx[mon_cur], 0);
8109
8110                                         (void)inkey();
8111
8112                                         redraw = TRUE;
8113                                 }
8114                                 break;
8115                         }
8116
8117                         default:
8118                         {
8119                                 /* Move the cursor */
8120                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
8121
8122                                 break;
8123                         }
8124                 }
8125         }
8126
8127         /* Free the "mon_idx" array */
8128         C_KILL(mon_idx, max_r_idx, s16b);
8129 }
8130
8131
8132 /*
8133  * Display the objects in a group.
8134  */
8135 static void display_object_list(int col, int row, int per_page, int object_idx[],
8136         int object_cur, int object_top, bool visual_only)
8137 {
8138         int i;
8139
8140         /* Display lines until done */
8141         for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
8142         {
8143                 char o_name[80];
8144                 byte a, c;
8145                 object_kind *flavor_k_ptr;
8146
8147                 /* Get the object index */
8148                 int k_idx = object_idx[object_top + i];
8149
8150                 /* Access the object */
8151                 object_kind *k_ptr = &k_info[k_idx];
8152
8153                 /* Choose a color */
8154                 byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
8155                 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
8156
8157
8158                 if (!visual_only && k_ptr->flavor)
8159                 {
8160                         /* Appearance of this object is shuffled */
8161                         flavor_k_ptr = &k_info[k_ptr->flavor];
8162                 }
8163                 else
8164                 {
8165                         /* Appearance of this object is very normal */
8166                         flavor_k_ptr = k_ptr;
8167                 }
8168
8169
8170
8171                 attr = ((i + object_top == object_cur) ? cursor : attr);
8172
8173                 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
8174                 {
8175                         /* Tidy name */
8176                         strip_name(o_name, k_idx);
8177                 }
8178                 else
8179                 {
8180                         /* Flavor name */
8181                         strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
8182                 }
8183
8184                 /* Display the name */
8185                 c_prt(attr, o_name, row + i, col);
8186
8187                 /* Hack -- visual_list mode */
8188                 if (per_page == 1)
8189                 {
8190                         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);
8191                 }
8192                 if (p_ptr->wizard || visual_only)
8193                 {
8194                         c_prt(attr, format("%d", k_idx), row + i, 70);
8195                 }
8196
8197                 a = flavor_k_ptr->x_attr;
8198                 c = flavor_k_ptr->x_char;
8199
8200                 /* Display symbol */
8201                 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
8202         }
8203
8204         /* Clear remaining lines */
8205         for (; i < per_page; i++)
8206         {
8207                 Term_erase(col, row + i, 255);
8208         }
8209 }
8210
8211 /*
8212  * Describe fake object
8213  */
8214 static void desc_obj_fake(int k_idx)
8215 {
8216         object_type *o_ptr;
8217         object_type object_type_body;
8218
8219         /* Get local object */
8220         o_ptr = &object_type_body;
8221
8222         /* Wipe the object */
8223         object_wipe(o_ptr);
8224
8225         /* Create the artifact */
8226         object_prep(o_ptr, k_idx);
8227
8228         /* It's fully know */
8229         o_ptr->ident |= IDENT_KNOWN;
8230
8231         /* Track the object */
8232         /* object_actual_track(o_ptr); */
8233
8234         /* Hack - mark as fake */
8235         /* term_obj_real = FALSE; */
8236
8237         /* Hack -- Handle stuff */
8238         handle_stuff();
8239
8240         if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
8241         {
8242 #ifdef JP
8243                 msg_print("ÆäËÊѤï¤Ã¤¿¤È¤³¤í¤Ï¤Ê¤¤¤è¤¦¤À¡£");
8244 #else
8245                 msg_print("You see nothing special.");
8246 #endif
8247                 msg_print(NULL);
8248         }
8249 }
8250
8251
8252
8253 /*
8254  * Display known objects
8255  */
8256 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx)
8257 {
8258         int i, len, max;
8259         int grp_cur, grp_top, old_grp_cur;
8260         int object_old, object_cur, object_top;
8261         int grp_cnt, grp_idx[100];
8262         int object_cnt;
8263         int *object_idx;
8264
8265         int column = 0;
8266         bool flag;
8267         bool redraw;
8268
8269         bool visual_list = FALSE;
8270         byte attr_top = 0, char_left = 0;
8271
8272         int browser_rows;
8273         int wid, hgt;
8274
8275         byte mode;
8276
8277         /* Get size */
8278         Term_get_size(&wid, &hgt);
8279
8280         browser_rows = hgt - 8;
8281
8282         /* Allocate the "object_idx" array */
8283         C_MAKE(object_idx, max_k_idx, int);
8284
8285         max = 0;
8286         grp_cnt = 0;
8287
8288         if (direct_k_idx < 0)
8289         {
8290                 mode = visual_only ? 0x03 : 0x01;
8291
8292                 /* Check every group */
8293                 for (i = 0; object_group_text[i] != NULL; i++)
8294                 {
8295                         /* Measure the label */
8296                         len = strlen(object_group_text[i]);
8297
8298                         /* Save the maximum length */
8299                         if (len > max) max = len;
8300
8301                         /* See if any monsters are known */
8302                         if (collect_objects(i, object_idx, mode))
8303                         {
8304                                 /* Build a list of groups with known monsters */
8305                                 grp_idx[grp_cnt++] = i;
8306                         }
8307                 }
8308
8309                 object_old = -1;
8310                 object_cnt = 0;
8311         }
8312         else
8313         {
8314                 object_kind *k_ptr = &k_info[direct_k_idx];
8315                 object_kind *flavor_k_ptr;
8316
8317                 if (!visual_only && k_ptr->flavor)
8318                 {
8319                         /* Appearance of this object is shuffled */
8320                         flavor_k_ptr = &k_info[k_ptr->flavor];
8321                 }
8322                 else
8323                 {
8324                         /* Appearance of this object is very normal */
8325                         flavor_k_ptr = k_ptr;
8326                 }
8327
8328                 object_idx[0] = direct_k_idx;
8329                 object_old = direct_k_idx;
8330                 object_cnt = 1;
8331
8332                 /* Terminate the list */
8333                 object_idx[1] = -1;
8334
8335                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
8336                         &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
8337         }
8338
8339         /* Terminate the list */
8340         grp_idx[grp_cnt] = -1;
8341
8342         old_grp_cur = -1;
8343         grp_cur = grp_top = 0;
8344         object_cur = object_top = 0;
8345
8346         flag = FALSE;
8347         redraw = TRUE;
8348
8349         mode = visual_only ? 0x02 : 0x00;
8350
8351         while (!flag)
8352         {
8353                 char ch;
8354                 object_kind *k_ptr, *flavor_k_ptr;
8355
8356                 if (redraw)
8357                 {
8358                         clear_from(0);
8359
8360 #ifdef JP
8361                         prt(format("%s - ¥¢¥¤¥Æ¥à", !visual_only ? "Ãμ±" : "ɽ¼¨"), 2, 0);
8362                         if (direct_k_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
8363                         prt("̾Á°", 4, max + 3);
8364                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
8365                         prt("ʸ»ú", 4, 74);
8366 #else
8367                         prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
8368                         if (direct_k_idx < 0) prt("Group", 4, 0);
8369                         prt("Name", 4, max + 3);
8370                         if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
8371                         prt("Sym", 4, 75);
8372 #endif
8373
8374                         for (i = 0; i < 78; i++)
8375                         {
8376                                 Term_putch(i, 5, TERM_WHITE, '=');
8377                         }
8378
8379                         if (direct_k_idx < 0)
8380                         {
8381                                 for (i = 0; i < browser_rows; i++)
8382                                 {
8383                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
8384                                 }
8385                         }
8386
8387                         redraw = FALSE;
8388                 }
8389
8390                 if (direct_k_idx < 0)
8391                 {
8392                         /* Scroll group list */
8393                         if (grp_cur < grp_top) grp_top = grp_cur;
8394                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
8395
8396                         /* Display a list of object groups */
8397                         display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
8398
8399                         if (old_grp_cur != grp_cur)
8400                         {
8401                                 old_grp_cur = grp_cur;
8402
8403                                 /* Get a list of objects in the current group */
8404                                 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
8405                         }
8406
8407                         /* Scroll object list */
8408                         while (object_cur < object_top)
8409                                 object_top = MAX(0, object_top - browser_rows/2);
8410                         while (object_cur >= object_top + browser_rows)
8411                                 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
8412                 }
8413
8414                 if (!visual_list)
8415                 {
8416                         /* Display a list of objects in the current group */
8417                         display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
8418                 }
8419                 else
8420                 {
8421                         object_top = object_cur;
8422
8423                         /* Display a list of objects in the current group */
8424                         display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
8425
8426                         /* Display visual list below first object */
8427                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
8428                 }
8429
8430                 /* Get the current object */
8431                 k_ptr = &k_info[object_idx[object_cur]];
8432
8433                 if (!visual_only && k_ptr->flavor)
8434                 {
8435                         /* Appearance of this object is shuffled */
8436                         flavor_k_ptr = &k_info[k_ptr->flavor];
8437                 }
8438                 else
8439                 {
8440                         /* Appearance of this object is very normal */
8441                         flavor_k_ptr = k_ptr;
8442                 }
8443
8444                 /* Prompt */
8445 #ifdef JP
8446                 prt(format("<Êý¸þ>%s%s%s, ESC",
8447                         (!visual_list && !visual_only) ? ", 'r'¤Ç¾ÜºÙ¤ò¸«¤ë" : "",
8448                         visual_list ? ", ENTER¤Ç·èÄê" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
8449                         (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
8450                         hgt - 1, 0);
8451 #else
8452                 prt(format("<dir>%s%s%s, ESC",
8453                         (!visual_list && !visual_only) ? ", 'r' to recall" : "",
8454                         visual_list ? ", ENTER to accept" : ", 'v' for visuals",
8455                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
8456                         hgt - 1, 0);
8457 #endif
8458
8459                 if (!visual_only)
8460                 {
8461                         /* Mega Hack -- track this object */
8462                         if (object_cnt) object_kind_track(object_idx[object_cur]);
8463
8464                         /* The "current" object changed */
8465                         if (object_old != object_idx[object_cur])
8466                         {
8467                                 /* Hack -- handle stuff */
8468                                 handle_stuff();
8469
8470                                 /* Remember the "current" object */
8471                                 object_old = object_idx[object_cur];
8472                         }
8473                 }
8474
8475                 if (visual_list)
8476                 {
8477                         place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
8478                 }
8479                 else if (!column)
8480                 {
8481                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
8482                 }
8483                 else
8484                 {
8485                         Term_gotoxy(max + 3, 6 + (object_cur - object_top));
8486                 }
8487
8488                 ch = inkey();
8489
8490                 /* Do visual mode command if needed */
8491                 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))
8492                 {
8493                         if (direct_k_idx >= 0)
8494                         {
8495                                 switch (ch)
8496                                 {
8497                                 case '\n':
8498                                 case '\r':
8499                                 case ESCAPE:
8500                                         flag = TRUE;
8501                                         break;
8502                                 }
8503                         }
8504                         continue;
8505                 }
8506
8507                 switch (ch)
8508                 {
8509                         case ESCAPE:
8510                         {
8511                                 flag = TRUE;
8512                                 break;
8513                         }
8514
8515                         case 'R':
8516                         case 'r':
8517                         {
8518                                 /* Recall on screen */
8519                                 if (!visual_list && !visual_only && (grp_cnt > 0))
8520                                 {
8521                                         desc_obj_fake(object_idx[object_cur]);
8522                                         redraw = TRUE;
8523                                 }
8524                                 break;
8525                         }
8526
8527                         default:
8528                         {
8529                                 /* Move the cursor */
8530                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
8531                                 break;
8532                         }
8533                 }
8534         }
8535
8536         /* Free the "object_idx" array */
8537         C_KILL(object_idx, max_k_idx, int);
8538 }
8539
8540
8541 /*
8542  * Display the features in a group.
8543  */
8544 static void display_feature_list(int col, int row, int per_page, int *feat_idx,
8545         int feat_cur, int feat_top, bool visual_only, int lighting_level)
8546 {
8547         int lit_col[F_LIT_MAX], i, j;
8548         int f_idx_col = use_bigtile ? 62 : 64;
8549
8550         /* Correct columns 1 and 4 */
8551         lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
8552         for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
8553                 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
8554
8555         /* Display lines until done */
8556         for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
8557         {
8558                 byte attr;
8559
8560                 /* Get the index */
8561                 int f_idx = feat_idx[feat_top + i];
8562
8563                 /* Access the index */
8564                 feature_type *f_ptr = &f_info[f_idx];
8565
8566                 int row_i = row + i;
8567
8568                 /* Choose a color */
8569                 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
8570
8571                 /* Display the name */
8572                 c_prt(attr, f_name + f_ptr->name, row_i, col);
8573
8574                 /* Hack -- visual_list mode */
8575                 if (per_page == 1)
8576                 {
8577                         /* Display lighting level */
8578                         c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
8579
8580                         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));
8581                 }
8582                 if (p_ptr->wizard || visual_only)
8583                 {
8584                         c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
8585                 }
8586
8587                 /* Display symbol */
8588                 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);
8589
8590                 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
8591                 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
8592                 {
8593                         Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
8594                 }
8595                 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
8596
8597                 /* Mega-hack -- Use non-standard colour */
8598                 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
8599                 {
8600                         Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
8601                 }
8602         }
8603
8604         /* Clear remaining lines */
8605         for (; i < per_page; i++)
8606         {
8607                 Term_erase(col, row + i, 255);
8608         }
8609 }
8610
8611
8612 /*
8613  * Interact with feature visuals.
8614  */
8615 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level)
8616 {
8617         int i, len, max;
8618         int grp_cur, grp_top, old_grp_cur;
8619         int feat_cur, feat_top;
8620         int grp_cnt, grp_idx[100];
8621         int feat_cnt;
8622         int *feat_idx;
8623
8624         int column = 0;
8625         bool flag;
8626         bool redraw;
8627
8628         bool visual_list = FALSE;
8629         byte attr_top = 0, char_left = 0;
8630
8631         int browser_rows;
8632         int wid, hgt;
8633
8634         byte attr_old[F_LIT_MAX];
8635         byte char_old[F_LIT_MAX];
8636         byte *cur_attr_ptr, *cur_char_ptr;
8637
8638         C_WIPE(attr_old, F_LIT_MAX, byte);
8639         C_WIPE(char_old, F_LIT_MAX, byte);
8640
8641         /* Get size */
8642         Term_get_size(&wid, &hgt);
8643
8644         browser_rows = hgt - 8;
8645
8646         /* Allocate the "feat_idx" array */
8647         C_MAKE(feat_idx, max_f_idx, int);
8648
8649         max = 0;
8650         grp_cnt = 0;
8651
8652         if (direct_f_idx < 0)
8653         {
8654                 /* Check every group */
8655                 for (i = 0; feature_group_text[i] != NULL; i++)
8656                 {
8657                         /* Measure the label */
8658                         len = strlen(feature_group_text[i]);
8659
8660                         /* Save the maximum length */
8661                         if (len > max) max = len;
8662
8663                         /* See if any features are known */
8664                         if (collect_features(i, feat_idx, 0x01))
8665                         {
8666                                 /* Build a list of groups with known features */
8667                                 grp_idx[grp_cnt++] = i;
8668                         }
8669                 }
8670
8671                 feat_cnt = 0;
8672         }
8673         else
8674         {
8675                 feature_type *f_ptr = &f_info[direct_f_idx];
8676
8677                 feat_idx[0] = direct_f_idx;
8678                 feat_cnt = 1;
8679
8680                 /* Terminate the list */
8681                 feat_idx[1] = -1;
8682
8683                 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
8684                         &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
8685
8686                 for (i = 0; i < F_LIT_MAX; i++)
8687                 {
8688                         attr_old[i] = f_ptr->x_attr[i];
8689                         char_old[i] = f_ptr->x_char[i];
8690                 }
8691         }
8692
8693         /* Terminate the list */
8694         grp_idx[grp_cnt] = -1;
8695
8696         old_grp_cur = -1;
8697         grp_cur = grp_top = 0;
8698         feat_cur = feat_top = 0;
8699
8700         flag = FALSE;
8701         redraw = TRUE;
8702
8703         while (!flag)
8704         {
8705                 char ch;
8706                 feature_type *f_ptr;
8707
8708                 if (redraw)
8709                 {
8710                         clear_from(0);
8711
8712 #ifdef JP
8713                         prt("ɽ¼¨ - ÃÏ·Á", 2, 0);
8714                         if (direct_f_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
8715                         prt("̾Á°", 4, max + 3);
8716                         if (use_bigtile)
8717                         {
8718                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
8719                                 prt("ʸ»ú ( l/ d)", 4, 66);
8720                         }
8721                         else
8722                         {
8723                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
8724                                 prt("ʸ»ú (l/d)", 4, 68);
8725                         }
8726 #else
8727                         prt("Visuals - features", 2, 0);
8728                         if (direct_f_idx < 0) prt("Group", 4, 0);
8729                         prt("Name", 4, max + 3);
8730                         if (use_bigtile)
8731                         {
8732                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
8733                                 prt("Sym ( l/ d)", 4, 67);
8734                         }
8735                         else
8736                         {
8737                                 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
8738                                 prt("Sym (l/d)", 4, 69);
8739                         }
8740 #endif
8741
8742                         for (i = 0; i < 78; i++)
8743                         {
8744                                 Term_putch(i, 5, TERM_WHITE, '=');
8745                         }
8746
8747                         if (direct_f_idx < 0)
8748                         {
8749                                 for (i = 0; i < browser_rows; i++)
8750                                 {
8751                                         Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
8752                                 }
8753                         }
8754
8755                         redraw = FALSE;
8756                 }
8757
8758                 if (direct_f_idx < 0)
8759                 {
8760                         /* Scroll group list */
8761                         if (grp_cur < grp_top) grp_top = grp_cur;
8762                         if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
8763
8764                         /* Display a list of feature groups */
8765                         display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
8766
8767                         if (old_grp_cur != grp_cur)
8768                         {
8769                                 old_grp_cur = grp_cur;
8770
8771                                 /* Get a list of features in the current group */
8772                                 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
8773                         }
8774
8775                         /* Scroll feature list */
8776                         while (feat_cur < feat_top)
8777                                 feat_top = MAX(0, feat_top - browser_rows/2);
8778                         while (feat_cur >= feat_top + browser_rows)
8779                                 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
8780                 }
8781
8782                 if (!visual_list)
8783                 {
8784                         /* Display a list of features in the current group */
8785                         display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
8786                 }
8787                 else
8788                 {
8789                         feat_top = feat_cur;
8790
8791                         /* Display a list of features in the current group */
8792                         display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
8793
8794                         /* Display visual list below first object */
8795                         display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
8796                 }
8797
8798                 /* Prompt */
8799 #ifdef JP
8800                 prt(format("<Êý¸þ>%s, 'd'¤Çɸ½à¸÷¸»¸ú²Ì%s, ESC",
8801                         visual_list ? ", ENTER¤Ç·èÄê, 'a'¤ÇÂоÝÌÀÅÙÊѹ¹" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
8802                         (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
8803                         hgt - 1, 0);
8804 #else
8805                 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
8806                         visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
8807                         (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
8808                         hgt - 1, 0);
8809 #endif
8810
8811                 /* Get the current feature */
8812                 f_ptr = &f_info[feat_idx[feat_cur]];
8813                 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
8814                 cur_char_ptr = &f_ptr->x_char[*lighting_level];
8815
8816                 if (visual_list)
8817                 {
8818                         place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
8819                 }
8820                 else if (!column)
8821                 {
8822                         Term_gotoxy(0, 6 + (grp_cur - grp_top));
8823                 }
8824                 else
8825                 {
8826                         Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
8827                 }
8828
8829                 ch = inkey();
8830
8831                 if (visual_list && ((ch == 'A') || (ch == 'a')))
8832                 {
8833                         int prev_lighting_level = *lighting_level;
8834
8835                         if (ch == 'A')
8836                         {
8837                                 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
8838                                 else (*lighting_level)--;
8839                         }
8840                         else
8841                         {
8842                                 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
8843                                 else (*lighting_level)++;
8844                         }
8845
8846                         if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
8847                                 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
8848
8849                         if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
8850                                 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
8851
8852                         continue;
8853                 }
8854
8855                 else if ((ch == 'D') || (ch == 'd'))
8856                 {
8857                         byte prev_x_attr = f_ptr->x_attr[*lighting_level];
8858                         byte prev_x_char = f_ptr->x_char[*lighting_level];
8859
8860                         apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
8861
8862                         if (visual_list)
8863                         {
8864                                 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
8865                                          attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
8866
8867                                 if (prev_x_char != f_ptr->x_char[*lighting_level])
8868                                         char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
8869                         }
8870                         else *need_redraw = TRUE;
8871
8872                         continue;
8873                 }
8874
8875                 /* Do visual mode command if needed */
8876                 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))
8877                 {
8878                         switch (ch)
8879                         {
8880                         /* Restore previous visual settings */
8881                         case ESCAPE:
8882                                 for (i = 0; i < F_LIT_MAX; i++)
8883                                 {
8884                                         f_ptr->x_attr[i] = attr_old[i];
8885                                         f_ptr->x_char[i] = char_old[i];
8886                                 }
8887
8888                                 /* Fall through */
8889
8890                         case '\n':
8891                         case '\r':
8892                                 if (direct_f_idx >= 0) flag = TRUE;
8893                                 else *lighting_level = F_LIT_STANDARD;
8894                                 break;
8895
8896                         /* Preserve current visual settings */
8897                         case 'V':
8898                         case 'v':
8899                                 for (i = 0; i < F_LIT_MAX; i++)
8900                                 {
8901                                         attr_old[i] = f_ptr->x_attr[i];
8902                                         char_old[i] = f_ptr->x_char[i];
8903                                 }
8904                                 *lighting_level = F_LIT_STANDARD;
8905                                 break;
8906
8907                         case 'C':
8908                         case 'c':
8909                                 if (!visual_list)
8910                                 {
8911                                         for (i = 0; i < F_LIT_MAX; i++)
8912                                         {
8913                                                 attr_idx_feat[i] = f_ptr->x_attr[i];
8914                                                 char_idx_feat[i] = f_ptr->x_char[i];
8915                                         }
8916                                 }
8917                                 break;
8918
8919                         case 'P':
8920                         case 'p':
8921                                 if (!visual_list)
8922                                 {
8923                                         /* Allow TERM_DARK text */
8924                                         for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
8925                                         {
8926                                                 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
8927                                                 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
8928                                         }
8929                                 }
8930                                 break;
8931                         }
8932                         continue;
8933                 }
8934
8935                 switch (ch)
8936                 {
8937                         case ESCAPE:
8938                         {
8939                                 flag = TRUE;
8940                                 break;
8941                         }
8942
8943                         default:
8944                         {
8945                                 /* Move the cursor */
8946                                 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
8947                                 break;
8948                         }
8949                 }
8950         }
8951
8952         /* Free the "feat_idx" array */
8953         C_KILL(feat_idx, max_f_idx, int);
8954 }
8955
8956
8957 /*
8958  * List wanted monsters
8959  */
8960 static void do_cmd_knowledge_kubi(void)
8961 {
8962         int i;
8963         FILE *fff;
8964         
8965         char file_name[1024];
8966         
8967         
8968         /* Open a new file */
8969         fff = my_fopen_temp(file_name, 1024);
8970         if (!fff) {
8971 #ifdef JP
8972             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
8973 #else
8974             msg_format("Failed to create temporary file %s.", file_name);
8975 #endif
8976             msg_print(NULL);
8977             return;
8978         }
8979         
8980         if (fff)
8981         {
8982                 bool listed = FALSE;
8983
8984 #ifdef JP
8985                 fprintf(fff, "º£Æü¤Î¥¿¡¼¥²¥Ã¥È : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "ÉÔÌÀ"));
8986                 fprintf(fff, "\n");
8987                 fprintf(fff, "¾Þ¶â¼ó¥ê¥¹¥È\n");
8988 #else
8989                 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
8990                 fprintf(fff, "\n");
8991                 fprintf(fff, "List of wanted monsters\n");
8992 #endif
8993                 fprintf(fff, "----------------------------------------------\n");
8994
8995                 for (i = 0; i < MAX_KUBI; i++)
8996                 {
8997                         if (kubi_r_idx[i] <= 10000)
8998                         {
8999                                 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
9000
9001                                 listed = TRUE;
9002                         }
9003                 }
9004
9005                 if (!listed)
9006                 {
9007 #ifdef JP
9008                         fprintf(fff,"\n%s\n", "¾Þ¶â¼ó¤Ï¤â¤¦»Ä¤Ã¤Æ¤¤¤Þ¤»¤ó¡£");
9009 #else
9010                         fprintf(fff,"\n%s\n", "There is no more wanted monster.");
9011 #endif
9012                 }
9013         }
9014         
9015         /* Close the file */
9016         my_fclose(fff);
9017         
9018         /* Display the file contents */
9019 #ifdef JP
9020         show_file(TRUE, file_name, "¾Þ¶â¼ó¤Î°ìÍ÷", 0, 0);
9021 #else
9022         show_file(TRUE, file_name, "Wanted monsters", 0, 0);
9023 #endif
9024
9025         
9026         /* Remove the file */
9027         fd_kill(file_name);
9028 }
9029
9030 /*
9031  * List virtues & status
9032  */
9033 static void do_cmd_knowledge_virtues(void)
9034 {
9035         FILE *fff;
9036         
9037         char file_name[1024];
9038         
9039         
9040         /* Open a new file */
9041         fff = my_fopen_temp(file_name, 1024);
9042         if (!fff) {
9043 #ifdef JP
9044             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9045 #else
9046             msg_format("Failed to create temporary file %s.", file_name);
9047 #endif
9048             msg_print(NULL);
9049             return;
9050         }
9051         
9052         if (fff)
9053         {
9054 #ifdef JP
9055                 fprintf(fff, "¸½ºß¤Î°À­ : %s\n\n", your_alignment());
9056 #else
9057                 fprintf(fff, "Your alighnment : %s\n\n", your_alignment());
9058 #endif
9059                 dump_virtues(fff);
9060         }
9061         
9062         /* Close the file */
9063         my_fclose(fff);
9064         
9065         /* Display the file contents */
9066 #ifdef JP
9067         show_file(TRUE, file_name, "Ȭ¤Ä¤ÎÆÁ", 0, 0);
9068 #else
9069         show_file(TRUE, file_name, "Virtues", 0, 0);
9070 #endif
9071
9072         
9073         /* Remove the file */
9074         fd_kill(file_name);
9075 }
9076
9077 /*
9078 * Dungeon
9079 *
9080 */
9081 static void do_cmd_knowledge_dungeon(void)
9082 {
9083         FILE *fff;
9084         
9085         char file_name[1024];
9086         int i;
9087         
9088         
9089         /* Open a new file */
9090         fff = my_fopen_temp(file_name, 1024);
9091         if (!fff) {
9092 #ifdef JP
9093             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9094 #else
9095             msg_format("Failed to create temporary file %s.", file_name);
9096 #endif
9097             msg_print(NULL);
9098             return;
9099         }
9100         
9101         if (fff)
9102         {
9103                 for (i = 1; i < max_d_idx; i++)
9104                 {
9105                         bool seiha = FALSE;
9106
9107                         if (!d_info[i].maxdepth) continue;
9108                         if (!max_dlv[i]) continue;
9109                         if (d_info[i].final_guardian)
9110                         {
9111                                 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
9112                         }
9113                         else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
9114 #ifdef JP
9115                         fprintf(fff,"%c%-12s :  %3d ³¬\n", seiha ? '!' : ' ', d_name + d_info[i].name, max_dlv[i]);
9116 #else
9117                         fprintf(fff,"%c%-16s :  level %3d\n", seiha ? '!' : ' ', d_name + d_info[i].name, max_dlv[i]);
9118 #endif
9119                 }
9120         }
9121         
9122         /* Close the file */
9123         my_fclose(fff);
9124         
9125         /* Display the file contents */
9126 #ifdef JP
9127         show_file(TRUE, file_name, "º£¤Þ¤Ç¤ËÆþ¤Ã¤¿¥À¥ó¥¸¥ç¥ó", 0, 0);
9128 #else
9129         show_file(TRUE, file_name, "Dungeon", 0, 0);
9130 #endif
9131
9132         
9133         /* Remove the file */
9134         fd_kill(file_name);
9135 }
9136
9137 /*
9138 * List virtues & status
9139 *
9140 */
9141 static void do_cmd_knowledge_stat(void)
9142 {
9143         FILE *fff;
9144         
9145         char file_name[1024];
9146         int percent, v_nr;
9147         
9148         /* Open a new file */
9149         fff = my_fopen_temp(file_name, 1024);
9150         if (!fff) {
9151 #ifdef JP
9152             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9153 #else
9154             msg_format("Failed to create temporary file %s.", file_name);
9155 #endif
9156             msg_print(NULL);
9157             return;
9158         }
9159         
9160         if (fff)
9161         {
9162                 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
9163                         (2 * p_ptr->hitdie +
9164                         ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
9165
9166 #ifdef JP
9167                 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : %d/100\n\n", percent);
9168                 else fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : ???\n\n");
9169                 fprintf(fff, "ǽÎϤκÇÂçÃÍ\n\n");
9170 #else
9171                 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
9172                 else fprintf(fff, "Your current Life Rating is ???.\n\n");
9173                 fprintf(fff, "Limits of maximum stats\n\n");
9174 #endif
9175                 for (v_nr = 0; v_nr < 6; v_nr++)
9176                 {
9177                         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);
9178                         else fprintf(fff, "%s ???\n", stat_names[v_nr]);
9179                 }
9180         }
9181
9182         dump_yourself(fff);
9183
9184         /* Close the file */
9185         my_fclose(fff);
9186         
9187         /* Display the file contents */
9188 #ifdef JP
9189         show_file(TRUE, file_name, "¼«Ê¬¤Ë´Ø¤¹¤ë¾ðÊó", 0, 0);
9190 #else
9191         show_file(TRUE, file_name, "HP-rate & Max stat", 0, 0);
9192 #endif
9193
9194         
9195         /* Remove the file */
9196         fd_kill(file_name);
9197 }
9198
9199
9200 /*
9201  * Print all active quests
9202  */
9203 static void do_cmd_knowledge_quests_current(FILE *fff)
9204 {
9205         char tmp_str[120];
9206         char rand_tmp_str[120] = "\0";
9207         char name[80];
9208         monster_race *r_ptr;
9209         int i;
9210         int rand_level = 100;
9211         int total = 0;
9212
9213 #ifdef JP
9214         fprintf(fff, "¡Ô¿ë¹ÔÃæ¤Î¥¯¥¨¥¹¥È¡Õ\n");
9215 #else
9216         fprintf(fff, "< Current Quest >\n");
9217 #endif
9218
9219         for (i = 1; i < max_quests; i++)
9220         {
9221                 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
9222                         ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
9223                         (quest[i].status == QUEST_STATUS_COMPLETED))
9224                 {
9225                         /* Set the quest number temporary */
9226                         int old_quest = p_ptr->inside_quest;
9227                         int j;
9228
9229                         /* Clear the text */
9230                         for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
9231                         quest_text_line = 0;
9232
9233                         p_ptr->inside_quest = i;
9234
9235                         /* Get the quest text */
9236                         init_flags = INIT_SHOW_TEXT;
9237
9238                         process_dungeon_file("q_info.txt", 0, 0, 0, 0);
9239
9240                         /* Reset the old quest number */
9241                         p_ptr->inside_quest = old_quest;
9242
9243                         /* No info from "silent" quests */
9244                         if (quest[i].flags & QUEST_FLAG_SILENT) continue;
9245
9246                         total++;
9247
9248                         if (quest[i].type != QUEST_TYPE_RANDOM)
9249                         {
9250                                 char note[80] = "\0";
9251
9252                                 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
9253                                 {
9254                                         switch (quest[i].type)
9255                                         {
9256                                         case QUEST_TYPE_KILL_LEVEL:
9257                                         case QUEST_TYPE_KILL_ANY_LEVEL:
9258                                                 r_ptr = &r_info[quest[i].r_idx];
9259                                                 strcpy(name, r_name + r_ptr->name);
9260                                                 if (quest[i].max_num > 1)
9261                                                 {
9262 #ifdef JP
9263                                                         sprintf(note," - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",
9264                                                                 quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
9265 #else
9266                                                         plural_aux(name);
9267                                                         sprintf(note," - kill %d %s, have killed %d.",
9268                                                                 quest[i].max_num, name, quest[i].cur_num);
9269 #endif
9270                                                 }
9271                                                 else
9272 #ifdef JP
9273                                                         sprintf(note," - %s¤òÅݤ¹¡£",name);
9274 #else
9275                                                         sprintf(note," - kill %s.",name);
9276 #endif
9277                                                 break;
9278
9279                                         case QUEST_TYPE_FIND_ARTIFACT:
9280                                                 if (quest[i].k_idx)
9281                                                 {
9282                                                         artifact_type *a_ptr = &a_info[quest[i].k_idx];
9283                                                         object_type forge;
9284                                                         object_type *q_ptr = &forge;
9285                                                         int k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
9286                                                         object_prep(q_ptr, k_idx);
9287                                                         q_ptr->name1 = quest[i].k_idx;
9288                                                         q_ptr->ident = IDENT_STORE;
9289                                                         object_desc(name, q_ptr, OD_NAME_ONLY);
9290                                                 }
9291 #ifdef JP
9292                                                 sprintf(note,"\n   - %s¤ò¸«¤Ä¤±½Ð¤¹¡£", name);
9293 #else
9294                                                 sprintf(note,"\n   - Find out %s.", name);
9295 #endif
9296                                                 break;
9297                                         case QUEST_TYPE_FIND_EXIT:
9298 #ifdef JP
9299                                                 sprintf(note," - Ãµº÷¤¹¤ë¡£");
9300 #else
9301                                                 sprintf(note," - Search.");
9302 #endif
9303                                                 break;
9304
9305                                         case QUEST_TYPE_KILL_NUMBER:
9306 #ifdef JP
9307                                                 sprintf(note," - %d ÂΤΥâ¥ó¥¹¥¿¡¼¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",
9308                                                         quest[i].max_num, quest[i].max_num - quest[i].cur_num);
9309 #else
9310                                                 sprintf(note," - Kill %d monsters, have killed %d.",
9311                                                         quest[i].max_num, quest[i].cur_num);
9312 #endif
9313                                                 break;
9314
9315                                         case QUEST_TYPE_KILL_ALL:
9316                                         case QUEST_TYPE_TOWER:
9317 #ifdef JP
9318                                                 sprintf(note," - Á´¤Æ¤Î¥â¥ó¥¹¥¿¡¼¤òÅݤ¹¡£");
9319 #else
9320                                                 sprintf(note," - Kill all monsters.");
9321 #endif
9322                                                 break;
9323                                         }
9324                                 }
9325
9326                                 /* Print the quest info */
9327 #ifdef JP
9328                                 sprintf(tmp_str, "  %s (´í¸±ÅÙ:%d³¬ÁêÅö)%s\n",
9329                                         quest[i].name, quest[i].level, note);
9330 #else
9331                                 sprintf(tmp_str, "  %s (Danger level: %d)%s\n",
9332                                         quest[i].name, quest[i].level, note);
9333 #endif
9334
9335                                 fputs(tmp_str, fff);
9336
9337                                 if (quest[i].status == QUEST_STATUS_COMPLETED)
9338                                 {
9339 #ifdef JP
9340                                         sprintf(tmp_str, "    ¥¯¥¨¥¹¥ÈãÀ® - ¤Þ¤ÀÊó½·¤ò¼õ¤±¤È¤Ã¤Æ¤Ê¤¤¡£\n");
9341 #else
9342                                         sprintf(tmp_str, "    Quest Completed - Unrewarded\n");
9343 #endif
9344                                         fputs(tmp_str, fff);
9345                                 }
9346                                 else
9347                                 {
9348                                         j = 0;
9349
9350                                         while (quest_text[j][0] && j < 10)
9351                                         {
9352                                                 fprintf(fff, "    %s\n", quest_text[j]);
9353                                                 j++;
9354                                         }
9355                                 }
9356                         }
9357                         else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
9358                         {
9359                                 /* New random */
9360                                 rand_level = quest[i].level;
9361
9362                                 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
9363                                 {
9364                                         /* Print the quest info */
9365                                         r_ptr = &r_info[quest[i].r_idx];
9366                                         strcpy(name, r_name + r_ptr->name);
9367
9368                                         if (quest[i].max_num > 1)
9369                                         {
9370 #ifdef JP
9371                                                 sprintf(rand_tmp_str,"  %s (%d ³¬) - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)\n",
9372                                                         quest[i].name, quest[i].level,
9373                                                         quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
9374 #else
9375                                                 plural_aux(name);
9376
9377                                                 sprintf(rand_tmp_str,"  %s (Dungeon level: %d)\n  Kill %d %s, have killed %d.\n",
9378                                                         quest[i].name, quest[i].level,
9379                                                         quest[i].max_num, name, quest[i].cur_num);
9380 #endif
9381                                         }
9382                                         else
9383                                         {
9384 #ifdef JP
9385                                                 sprintf(rand_tmp_str,"  %s (%d ³¬) - %s¤òÅݤ¹¡£\n",
9386                                                         quest[i].name, quest[i].level, name);
9387 #else
9388                                                 sprintf(rand_tmp_str,"  %s (Dungeon level: %d)\n  Kill %s.\n",
9389                                                         quest[i].name, quest[i].level, name);
9390 #endif
9391                                         }
9392                                 }
9393                         }
9394                 }
9395         }
9396
9397         /* Print the current random quest  */
9398         if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
9399
9400 #ifdef JP
9401         if (!total) fprintf(fff, "  ¤Ê¤·\n");
9402 #else
9403         if (!total) fprintf(fff, "  Nothing.\n");
9404 #endif
9405 }
9406
9407
9408 /*
9409  * Print all finished quests
9410  */
9411 void do_cmd_knowledge_quests_completed(FILE *fff, int quest_num[])
9412 {
9413         char tmp_str[120];
9414         int i;
9415         int total = 0;
9416
9417 #ifdef JP
9418         fprintf(fff, "¡ÔãÀ®¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
9419 #else
9420         fprintf(fff, "< Completed Quest >\n");
9421 #endif
9422         for (i = 1; i < max_quests; i++)
9423         {
9424                 int q_idx = quest_num[i];
9425
9426                 if (quest[q_idx].status == QUEST_STATUS_FINISHED)
9427                 {
9428                         if (is_fixed_quest_idx(q_idx))
9429                         {
9430                                 /* Set the quest number temporary */
9431                                 int old_quest = p_ptr->inside_quest;
9432
9433                                 p_ptr->inside_quest = q_idx;
9434
9435                                 /* Get the quest */
9436                                 init_flags = INIT_NAME_ONLY;
9437
9438                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
9439
9440                                 /* Reset the old quest number */
9441                                 p_ptr->inside_quest = old_quest;
9442
9443                                 /* No info from "silent" quests */
9444                                 if (quest[q_idx].flags & QUEST_FLAG_SILENT) continue;
9445                         }
9446
9447                         total++;
9448
9449                         if (!is_fixed_quest_idx(q_idx) && quest[q_idx].r_idx)
9450                         {
9451                                 /* Print the quest info */
9452
9453                                 if (quest[q_idx].complev == 0)
9454                                 {
9455                                         sprintf(tmp_str,
9456 #ifdef JP
9457                                                 "  %-40s (%3d³¬)            -   ÉÔÀᄀ\n",
9458 #else
9459                                                 "  %-40s (Dungeon level: %3d) - (Cancelled)\n",
9460 #endif
9461                                                 r_name+r_info[quest[q_idx].r_idx].name,
9462                                                 quest[q_idx].level);
9463                                 }
9464                                 else
9465                                 {
9466                                         sprintf(tmp_str,
9467 #ifdef JP
9468                                                 "  %-40s (%3d³¬)            - ¥ì¥Ù¥ë%2d\n",
9469 #else
9470                                                 "  %-40s (Dungeon level: %3d) - level %2d\n",
9471 #endif
9472                                                 r_name+r_info[quest[q_idx].r_idx].name,
9473                                                 quest[q_idx].level,
9474                                                 quest[q_idx].complev);
9475                                 }
9476                         }
9477                         else
9478                         {
9479                                 /* Print the quest info */
9480 #ifdef JP
9481                                 sprintf(tmp_str, "  %-40s (´í¸±ÅÙ:%3d³¬ÁêÅö) - ¥ì¥Ù¥ë%2d\n",
9482                                         quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
9483 #else
9484                                 sprintf(tmp_str, "  %-40s (Danger  level: %3d) - level %2d\n",
9485                                         quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
9486 #endif
9487                         }
9488
9489                         fputs(tmp_str, fff);
9490                 }
9491         }
9492 #ifdef JP
9493         if (!total) fprintf(fff, "  ¤Ê¤·\n");
9494 #else
9495         if (!total) fprintf(fff, "  Nothing.\n");
9496 #endif
9497 }
9498
9499
9500 /*
9501  * Print all failed quests
9502  */
9503 void do_cmd_knowledge_quests_failed(FILE *fff, int quest_num[])
9504 {
9505         char tmp_str[120];
9506         int i;
9507         int total = 0;
9508
9509 #ifdef JP
9510         fprintf(fff, "¡Ô¼ºÇÔ¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
9511 #else
9512         fprintf(fff, "< Failed Quest >\n");
9513 #endif
9514         for (i = 1; i < max_quests; i++)
9515         {
9516                 int q_idx = quest_num[i];
9517
9518                 if ((quest[q_idx].status == QUEST_STATUS_FAILED_DONE) || (quest[q_idx].status == QUEST_STATUS_FAILED))
9519                 {
9520                         if (is_fixed_quest_idx(q_idx))
9521                         {
9522                                 /* Set the quest number temporary */
9523                                 int old_quest = p_ptr->inside_quest;
9524
9525                                 p_ptr->inside_quest = q_idx;
9526
9527                                 /* Get the quest text */
9528                                 init_flags = INIT_NAME_ONLY;
9529
9530                                 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
9531
9532                                 /* Reset the old quest number */
9533                                 p_ptr->inside_quest = old_quest;
9534
9535                                 /* No info from "silent" quests */
9536                                 if (quest[q_idx].flags & QUEST_FLAG_SILENT) continue;
9537                         }
9538
9539                         total++;
9540
9541                         if (!is_fixed_quest_idx(q_idx) && quest[q_idx].r_idx)
9542                         {
9543                                 /* Print the quest info */
9544 #ifdef JP
9545                                 sprintf(tmp_str, "  %-40s (%3d³¬)            - ¥ì¥Ù¥ë%2d\n",
9546                                         r_name+r_info[quest[q_idx].r_idx].name, quest[q_idx].level, quest[q_idx].complev);
9547 #else
9548                                 sprintf(tmp_str, "  %-40s (Dungeon level: %3d) - level %2d\n",
9549                                         r_name+r_info[quest[q_idx].r_idx].name, quest[q_idx].level, quest[q_idx].complev);
9550 #endif
9551                         }
9552                         else
9553                         {
9554                                 /* Print the quest info */
9555 #ifdef JP
9556                                 sprintf(tmp_str, "  %-40s (´í¸±ÅÙ:%3d³¬ÁêÅö) - ¥ì¥Ù¥ë%2d\n",
9557                                         quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
9558 #else
9559                                 sprintf(tmp_str, "  %-40s (Danger  level: %3d) - level %2d\n",
9560                                         quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
9561 #endif
9562                         }
9563                         fputs(tmp_str, fff);
9564                 }
9565         }
9566 #ifdef JP
9567         if (!total) fprintf(fff, "  ¤Ê¤·\n");
9568 #else
9569         if (!total) fprintf(fff, "  Nothing.\n");
9570 #endif
9571 }
9572
9573
9574 /*
9575  * Print all random quests
9576  */
9577 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
9578 {
9579         char tmp_str[120];
9580         int i;
9581         int total = 0;
9582
9583 #ifdef JP
9584         fprintf(fff, "¡Ô»Ä¤ê¤Î¥é¥ó¥À¥à¥¯¥¨¥¹¥È¡Õ\n");
9585 #else
9586         fprintf(fff, "< Remaining Random Quest >\n");
9587 #endif
9588         for (i = 1; i < max_quests; i++)
9589         {
9590                 /* No info from "silent" quests */
9591                 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
9592
9593                 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
9594                 {
9595                         total++;
9596
9597                         /* Print the quest info */
9598 #ifdef JP
9599                         sprintf(tmp_str, "  %s (%d³¬, %s)\n",
9600                                 quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
9601 #else
9602                         sprintf(tmp_str, "  %s (%d, %s)\n",
9603                                 quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
9604 #endif
9605                         fputs(tmp_str, fff);
9606                 }
9607         }
9608 #ifdef JP
9609         if (!total) fprintf(fff, "  ¤Ê¤·\n");
9610 #else
9611         if (!total) fprintf(fff, "  Nothing.\n");
9612 #endif
9613 }
9614
9615
9616 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
9617 {
9618         int *q_num = (int *)u;
9619         quest_type *qa = &quest[q_num[a]];
9620         quest_type *qb = &quest[q_num[b]];
9621
9622         /* Unused */
9623         (void)v;
9624
9625         if (qa->complev < qb->complev) return TRUE;
9626         if (qa->complev > qb->complev) return FALSE;
9627         if (qa->level <= qb->level) return TRUE;
9628         return FALSE;
9629 }
9630
9631 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
9632 {
9633         int *q_num = (int *)u;
9634         int tmp;
9635
9636         /* Unused */
9637         (void)v;
9638
9639         tmp = q_num[a];
9640         q_num[a] = q_num[b];
9641         q_num[b] = tmp;
9642 }
9643
9644
9645 /*
9646  * Print quest status of all active quests
9647  */
9648 static void do_cmd_knowledge_quests(void)
9649 {
9650         FILE *fff;
9651         char file_name[1024];
9652         int *quest_num, dummy, i;
9653
9654         /* Open a new file */
9655         fff = my_fopen_temp(file_name, 1024);
9656         if (!fff)
9657         {
9658 #ifdef JP
9659             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9660 #else
9661             msg_format("Failed to create temporary file %s.", file_name);
9662 #endif
9663             msg_print(NULL);
9664             return;
9665         }
9666
9667         /* Allocate Memory */
9668         C_MAKE(quest_num, max_quests, int);
9669
9670         /* Sort by compete level */
9671         for (i = 1; i < max_quests; i++) quest_num[i] = i;
9672         ang_sort_comp = ang_sort_comp_quest_num;
9673         ang_sort_swap = ang_sort_swap_quest_num;
9674         ang_sort(quest_num, &dummy, max_quests);
9675
9676         /* Dump Quest Information */
9677         do_cmd_knowledge_quests_current(fff);
9678         fputc('\n', fff);
9679         do_cmd_knowledge_quests_completed(fff, quest_num);
9680         fputc('\n', fff);
9681         do_cmd_knowledge_quests_failed(fff, quest_num);
9682         if (p_ptr->wizard)
9683         {
9684                 fputc('\n', fff);
9685                 do_cmd_knowledge_quests_wiz_random(fff);
9686         }
9687
9688         /* Close the file */
9689         my_fclose(fff);
9690
9691         /* Display the file contents */
9692 #ifdef JP
9693         show_file(TRUE, file_name, "¥¯¥¨¥¹¥ÈãÀ®¾õ¶·", 0, 0);
9694 #else
9695         show_file(TRUE, file_name, "Quest status", 0, 0);
9696 #endif
9697
9698         /* Remove the file */
9699         fd_kill(file_name);
9700
9701         /* Free Memory */
9702         C_KILL(quest_num, max_quests, int);
9703 }
9704
9705
9706 /*
9707  * List my home
9708  */
9709 static void do_cmd_knowledge_home(void)
9710 {
9711         FILE *fff;
9712
9713         int i;
9714         char file_name[1024];
9715         store_type  *st_ptr;
9716         char o_name[MAX_NLEN];
9717         cptr            paren = ")";
9718
9719         process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
9720
9721         /* Open a new file */
9722         fff = my_fopen_temp(file_name, 1024);
9723         if (!fff) {
9724 #ifdef JP
9725                 msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9726 #else
9727                 msg_format("Failed to create temporary file %s.", file_name);
9728 #endif
9729                 msg_print(NULL);
9730                 return;
9731         }
9732
9733         if (fff)
9734         {
9735                 /* Print all homes in the different towns */
9736                 st_ptr = &town[1].store[STORE_HOME];
9737
9738                 /* Home -- if anything there */
9739                 if (st_ptr->stock_num)
9740                 {
9741 #ifdef JP
9742                         int x = 1;
9743 #endif
9744                         /* Header with name of the town */
9745 #ifdef JP
9746                         fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
9747 #else
9748                         fprintf(fff, "  [Home Inventory]\n");
9749 #endif
9750
9751                         /* Dump all available items */
9752                         for (i = 0; i < st_ptr->stock_num; i++)
9753                         {
9754 #ifdef JP
9755                                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
9756                                 object_desc(o_name, &st_ptr->stock[i], 0);
9757                                 if (strlen(o_name) <= 80-3)
9758                                 {
9759                                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
9760                                 }
9761                                 else
9762                                 {
9763                                         int n;
9764                                         char *t;
9765                                         for (n = 0, t = o_name; n < 80-3; n++, t++)
9766                                                 if(iskanji(*t)) {t++; n++;}
9767                                         if (n == 81-3) n = 79-3; /* ºÇ¸å¤¬´Á»úȾʬ */
9768
9769                                         fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
9770                                         fprintf(fff, "   %.77s\n", o_name+n);
9771                                 }
9772 #else
9773                                 object_desc(o_name, &st_ptr->stock[i], 0);
9774                                 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
9775 #endif
9776
9777                         }
9778
9779                         /* Add an empty line */
9780                         fprintf(fff, "\n\n");
9781                 }
9782         }
9783
9784         /* Close the file */
9785         my_fclose(fff);
9786
9787         /* Display the file contents */
9788 #ifdef JP
9789         show_file(TRUE, file_name, "²æ¤¬²È¤Î¥¢¥¤¥Æ¥à", 0, 0);
9790 #else
9791         show_file(TRUE, file_name, "Home Inventory", 0, 0);
9792 #endif
9793
9794
9795         /* Remove the file */
9796         fd_kill(file_name);
9797 }
9798
9799
9800 /*
9801  * Check the status of "autopick"
9802  */
9803 static void do_cmd_knowledge_autopick(void)
9804 {
9805         int k;
9806         FILE *fff;
9807         char file_name[1024];
9808
9809         /* Open a new file */
9810         fff = my_fopen_temp(file_name, 1024);
9811
9812         if (!fff)
9813         {
9814 #ifdef JP
9815             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
9816 #else
9817             msg_format("Failed to create temporary file %s.", file_name);
9818 #endif
9819             msg_print(NULL);
9820             return;
9821         }
9822
9823         if (!max_autopick)
9824         {
9825 #ifdef JP
9826             fprintf(fff, "¼«Æ°Ç˲õ/½¦¤¤¤Ë¤Ï²¿¤âÅÐÏ¿¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£");
9827 #else
9828             fprintf(fff, "No preference for auto picker/destroyer.");
9829 #endif
9830         }
9831         else
9832         {
9833 #ifdef JP
9834             fprintf(fff, "   ¼«Æ°½¦¤¤/Ç˲õ¤Ë¤Ï¸½ºß %d¹ÔÅÐÏ¿¤µ¤ì¤Æ¤¤¤Þ¤¹¡£\n\n", max_autopick);
9835 #else
9836             fprintf(fff, "   There are %d registered lines for auto picker/destroyer.\n\n", max_autopick);
9837 #endif
9838         }
9839
9840         for (k = 0; k < max_autopick; k++)
9841         {
9842                 cptr tmp;
9843                 byte act = autopick_list[k].action;
9844                 if (act & DONT_AUTOPICK)
9845                 {
9846 #ifdef JP
9847                         tmp = "ÊüÃÖ";
9848 #else
9849                         tmp = "Leave";
9850 #endif
9851                 }
9852                 else if (act & DO_AUTODESTROY)
9853                 {
9854 #ifdef JP
9855                         tmp = "Ç˲õ";
9856 #else
9857                         tmp = "Destroy";
9858 #endif
9859                 }
9860                 else if (act & DO_AUTOPICK)
9861                 {
9862 #ifdef JP
9863                         tmp = "½¦¤¦";
9864 #else
9865                         tmp = "Pickup";
9866 #endif
9867                 }
9868                 else /* if (act & DO_QUERY_AUTOPICK) */ /* Obvious */
9869                 {
9870 #ifdef JP
9871                         tmp = "³Îǧ";
9872 #else
9873                         tmp = "Query";
9874 #endif
9875                 }
9876
9877                 if (act & DO_DISPLAY)
9878                         fprintf(fff, "%11s", format("[%s]", tmp));
9879                 else
9880                         fprintf(fff, "%11s", format("(%s)", tmp));
9881
9882                 tmp = autopick_line_from_entry(&autopick_list[k]);
9883                 fprintf(fff, " %s", tmp);
9884                 string_free(tmp);
9885                 fprintf(fff, "\n");
9886         }
9887         /* Close the file */
9888         my_fclose(fff);
9889         /* Display the file contents */
9890 #ifdef JP
9891         show_file(TRUE, file_name, "¼«Æ°½¦¤¤/Ç˲õ ÀßÄê¥ê¥¹¥È", 0, 0);
9892 #else
9893         show_file(TRUE, file_name, "Auto-picker/Destroyer", 0, 0);
9894 #endif
9895
9896         /* Remove the file */
9897         fd_kill(file_name);
9898 }
9899
9900
9901 /*
9902  * Interact with "knowledge"
9903  */
9904 void do_cmd_knowledge(void)
9905 {
9906         int i, p = 0;
9907         bool need_redraw = FALSE;
9908
9909         /* File type is "TEXT" */
9910         FILE_TYPE(FILE_TYPE_TEXT);
9911
9912         /* Save the screen */
9913         screen_save();
9914
9915         /* Interact until done */
9916         while (1)
9917         {
9918                 /* Clear screen */
9919                 Term_clear();
9920
9921                 /* Ask for a choice */
9922 #ifdef JP
9923                 prt(format("%d/2 ¥Ú¡¼¥¸", (p+1)), 2, 65);
9924                 prt("¸½ºß¤ÎÃ챤ò³Îǧ¤¹¤ë", 3, 0);
9925 #else
9926                 prt(format("page %d/2", (p+1)), 2, 65);
9927                 prt("Display current knowledge", 3, 0);
9928 #endif
9929
9930                 /* Give some choices */
9931 #ifdef JP
9932                 if (p == 0)
9933                 {
9934                         prt("(1) ´ûÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à                 ¤Î°ìÍ÷", 6, 5);
9935                         prt("(2) ´ûÃΤΥ¢¥¤¥Æ¥à                       ¤Î°ìÍ÷", 7, 5);
9936                         prt("(3) ´ûÃΤÎÀ¸¤­¤Æ¤¤¤ë¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼ ¤Î°ìÍ÷", 8, 5);
9937                         prt("(4) ´ûÃΤΥâ¥ó¥¹¥¿¡¼                     ¤Î°ìÍ÷", 9, 5);
9938                         prt("(5) Åݤ·¤¿Å¨¤Î¿ô                         ¤Î°ìÍ÷", 10, 5);
9939                         if (!vanilla_town) prt("(6) ¾Þ¶â¼ó                               ¤Î°ìÍ÷", 11, 5);
9940                         prt("(7) ¸½ºß¤Î¥Ú¥Ã¥È                         ¤Î°ìÍ÷", 12, 5);
9941                         prt("(8) ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à                     ¤Î°ìÍ÷", 13, 5);
9942                         prt("(9) *´ÕÄê*ºÑ¤ßÁõÈ÷¤ÎÂÑÀ­                 ¤Î°ìÍ÷", 14, 5);
9943                         prt("(0) ÃÏ·Á¤Îɽ¼¨Ê¸»ú/¥¿¥¤¥ë                ¤Î°ìÍ÷", 15, 5);
9944                 }
9945                 else
9946                 {
9947                         prt("(a) ¼«Ê¬¤Ë´Ø¤¹¤ë¾ðÊó                     ¤Î°ìÍ÷", 6, 5);
9948                         prt("(b) ÆÍÁ³ÊÑ°Û                             ¤Î°ìÍ÷", 7, 5);
9949                         prt("(c) Éð´ï¤Î·Ð¸³ÃÍ                         ¤Î°ìÍ÷", 8, 5);
9950                         prt("(d) ËâË¡¤Î·Ð¸³ÃÍ                         ¤Î°ìÍ÷", 9, 5);
9951                         prt("(e) µ»Ç½¤Î·Ð¸³ÃÍ                         ¤Î°ìÍ÷", 10, 5);
9952                         prt("(f) ¥×¥ì¥¤¥ä¡¼¤ÎÆÁ                       ¤Î°ìÍ÷", 11, 5);
9953                         prt("(g) Æþ¤Ã¤¿¥À¥ó¥¸¥ç¥ó                     ¤Î°ìÍ÷", 12, 5);
9954                         prt("(h) ¼Â¹ÔÃæ¤Î¥¯¥¨¥¹¥È                     ¤Î°ìÍ÷", 13, 5);
9955                         prt("(i) ¸½ºß¤Î¼«Æ°½¦¤¤/Ç˲õÀßÄê              ¤Î°ìÍ÷", 14, 5);
9956                 }
9957 #else
9958                 if (p == 0)
9959                 {
9960                         prt("(1) Display known artifacts", 6, 5);
9961                         prt("(2) Display known objects", 7, 5);
9962                         prt("(3) Display remaining uniques", 8, 5);
9963                         prt("(4) Display known monster", 9, 5);
9964                         prt("(5) Display kill count", 10, 5);
9965                         if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
9966                         prt("(7) Display current pets", 12, 5);
9967                         prt("(8) Display home inventory", 13, 5);
9968                         prt("(9) Display *identified* equip.", 14, 5);
9969                         prt("(0) Display terrain symbols.", 15, 5);
9970                 }
9971                 else
9972                 {
9973                         prt("(a) Display about yourself", 6, 5);
9974                         prt("(b) Display mutations", 7, 5);
9975                         prt("(c) Display weapon proficiency", 8, 5);
9976                         prt("(d) Display spell proficiency", 9, 5);
9977                         prt("(e) Display misc. proficiency", 10, 5);
9978                         prt("(f) Display virtues", 11, 5);
9979                         prt("(g) Display dungeons", 12, 5);
9980                         prt("(h) Display current quests", 13, 5);
9981                         prt("(i) Display auto pick/destroy", 14, 5);
9982                 }
9983 #endif
9984                 /* Prompt */
9985 #ifdef JP
9986                 prt("-³¤¯-", 17, 8);
9987                 prt("ESC) È´¤±¤ë", 21, 1);
9988                 prt("SPACE) ¼¡¥Ú¡¼¥¸", 21, 30);
9989                 /*prt("-) Á°¥Ú¡¼¥¸", 21, 60);*/
9990                 prt("¥³¥Þ¥ó¥É:", 20, 0);
9991 #else
9992                 prt("-more-", 17, 8);
9993                 prt("ESC) Exit menu", 21, 1);
9994                 prt("SPACE) Next page", 21, 30);
9995                 /*prt("-) Previous page", 21, 60);*/
9996                 prt("Command: ", 20, 0);
9997 #endif
9998
9999                 /* Prompt */
10000                 i = inkey();
10001
10002                 /* Done */
10003                 if (i == ESCAPE) break;
10004                 switch (i)
10005                 {
10006                 case ' ': /* Page change */
10007                 case '-':
10008                         p = 1 - p;
10009                         break;
10010                 case '1': /* Artifacts */
10011                         do_cmd_knowledge_artifacts();
10012                         break;
10013                 case '2': /* Objects */
10014                         do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
10015                         break;
10016                 case '3': /* Uniques */
10017                         do_cmd_knowledge_uniques();
10018                         break;
10019                 case '4': /* Monsters */
10020                         do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
10021                         break;
10022                 case '5': /* Kill count  */
10023                         do_cmd_knowledge_kill_count();
10024                         break;
10025                 case '6': /* wanted */
10026                         if (!vanilla_town) do_cmd_knowledge_kubi();
10027                         break;
10028                 case '7': /* Pets */
10029                         do_cmd_knowledge_pets();
10030                         break;
10031                 case '8': /* Home */
10032                         do_cmd_knowledge_home();
10033                         break;
10034                 case '9': /* Resist list */
10035                         do_cmd_knowledge_inven();
10036                         break;
10037                 case '0': /* Feature list */
10038                         {
10039                                 int lighting_level = F_LIT_STANDARD;
10040                                 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
10041                         }
10042                         break;
10043                 /* Next page */
10044                 case 'a': /* Max stat */
10045                         do_cmd_knowledge_stat();
10046                         break;
10047                 case 'b': /* Mutations */
10048                         do_cmd_knowledge_mutations();
10049                         break;
10050                 case 'c': /* weapon-exp */
10051                         do_cmd_knowledge_weapon_exp();
10052                         break;
10053                 case 'd': /* spell-exp */
10054                         do_cmd_knowledge_spell_exp();
10055                         break;
10056                 case 'e': /* skill-exp */
10057                         do_cmd_knowledge_skill_exp();
10058                         break;
10059                 case 'f': /* Virtues */
10060                         do_cmd_knowledge_virtues();
10061                         break;
10062                 case 'g': /* Dungeon */
10063                         do_cmd_knowledge_dungeon();
10064                         break;
10065                 case 'h': /* Quests */
10066                         do_cmd_knowledge_quests();
10067                         break;
10068                 case 'i': /* Autopick */
10069                         do_cmd_knowledge_autopick();
10070                         break;
10071                 default: /* Unknown option */
10072                         bell();
10073                 }
10074
10075                 /* Flush messages */
10076                 msg_print(NULL);
10077         }
10078
10079         /* Restore the screen */
10080         screen_load();
10081
10082         if (need_redraw) do_cmd_redraw();
10083 }
10084
10085
10086 /*
10087  * Check on the status of an active quest
10088  */
10089 void do_cmd_checkquest(void)
10090 {
10091         /* File type is "TEXT" */
10092         FILE_TYPE(FILE_TYPE_TEXT);
10093
10094         /* Save the screen */
10095         screen_save();
10096
10097         /* Quest info */
10098         do_cmd_knowledge_quests();
10099
10100         /* Restore the screen */
10101         screen_load();
10102 }
10103
10104
10105 /*
10106  * Display the time and date
10107  */
10108 void do_cmd_time(void)
10109 {
10110         int day, hour, min, full, start, end, num;
10111         char desc[1024];
10112
10113         char buf[1024];
10114         char day_buf[10];
10115
10116         FILE *fff;
10117
10118         extract_day_hour_min(&day, &hour, &min);
10119
10120         full = hour * 100 + min;
10121
10122         start = 9999;
10123         end = -9999;
10124
10125         num = 0;
10126
10127 #ifdef JP
10128         strcpy(desc, "ÊѤʻþ¹ï¤À¡£");
10129 #else
10130         strcpy(desc, "It is a strange time.");
10131 #endif
10132
10133
10134         if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
10135         else strcpy(day_buf, "*****");
10136
10137         /* Message */
10138 #ifdef JP
10139         msg_format("%sÆüÌÜ, »þ¹ï¤Ï%d:%02d %s¤Ç¤¹¡£",
10140                    day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
10141                    min, (hour < 12) ? "AM" : "PM");
10142 #else
10143         msg_format("This is day %s. The time is %d:%02d %s.",
10144                    day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
10145                    min, (hour < 12) ? "AM" : "PM");
10146 #endif
10147
10148
10149         /* Find the path */
10150         if (!randint0(10) || p_ptr->image)
10151         {
10152 #ifdef JP
10153                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timefun_j.txt");
10154 #else
10155                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timefun.txt");
10156 #endif
10157
10158         }
10159         else
10160         {
10161 #ifdef JP
10162                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timenorm_j.txt");
10163 #else
10164                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timenorm.txt");
10165 #endif
10166
10167         }
10168
10169         /* Open this file */
10170         fff = my_fopen(buf, "rt");
10171
10172         /* Oops */
10173         if (!fff) return;
10174
10175         /* Find this time */
10176         while (!my_fgets(fff, buf, sizeof(buf)))
10177         {
10178                 /* Ignore comments */
10179                 if (!buf[0] || (buf[0] == '#')) continue;
10180
10181                 /* Ignore invalid lines */
10182                 if (buf[1] != ':') continue;
10183
10184                 /* Process 'Start' */
10185                 if (buf[0] == 'S')
10186                 {
10187                         /* Extract the starting time */
10188                         start = atoi(buf + 2);
10189
10190                         /* Assume valid for an hour */
10191                         end = start + 59;
10192
10193                         /* Next... */
10194                         continue;
10195                 }
10196
10197                 /* Process 'End' */
10198                 if (buf[0] == 'E')
10199                 {
10200                         /* Extract the ending time */
10201                         end = atoi(buf + 2);
10202
10203                         /* Next... */
10204                         continue;
10205                 }
10206
10207                 /* Ignore incorrect range */
10208                 if ((start > full) || (full > end)) continue;
10209
10210                 /* Process 'Description' */
10211                 if (buf[0] == 'D')
10212                 {
10213                         num++;
10214
10215                         /* Apply the randomizer */
10216                         if (!randint0(num)) strcpy(desc, buf + 2);
10217
10218                         /* Next... */
10219                         continue;
10220                 }
10221         }
10222
10223         /* Message */
10224         msg_print(desc);
10225
10226         /* Close the file */
10227         my_fclose(fff);
10228 }