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