OSDN Git Service

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