OSDN Git Service

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