OSDN Git Service

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