OSDN Git Service

get_check_strict() を作った。modeの指定によってESCを受けつけないようにしたり、
[hengband/hengband.git] / src / files.c
1 /* File: files.c */
2
3 /* Purpose: code dealing with files (and death) */
4
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12
13 #include "angband.h"
14
15
16 /*
17  * You may or may not want to use the following "#undef".
18  */
19 /* #undef _POSIX_SAVED_IDS */
20
21
22 /*
23  * Hack -- drop permissions
24  */
25 void safe_setuid_drop(void)
26 {
27
28 #ifdef SET_UID
29
30 # ifdef SAFE_SETUID
31
32 #  ifdef SAFE_SETUID_POSIX
33
34         if (setuid(getuid()) != 0)
35         {
36 #ifdef JP
37 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
38 #else
39                 quit("setuid(): cannot set permissions correctly!");
40 #endif
41
42         }
43         if (setgid(getgid()) != 0)
44         {
45 #ifdef JP
46 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
47 #else
48                 quit("setgid(): cannot set permissions correctly!");
49 #endif
50
51         }
52
53 #  else
54
55         if (setreuid(geteuid(), getuid()) != 0)
56         {
57 #ifdef JP
58 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
59 #else
60                 quit("setreuid(): cannot set permissions correctly!");
61 #endif
62
63         }
64         if (setregid(getegid(), getgid()) != 0)
65         {
66 #ifdef JP
67 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
68 #else
69                 quit("setregid(): cannot set permissions correctly!");
70 #endif
71
72         }
73
74 #  endif
75
76 # endif
77
78 #endif
79
80 }
81
82
83 /*
84  * Hack -- grab permissions
85  */
86 void safe_setuid_grab(void)
87 {
88
89 #ifdef SET_UID
90
91 # ifdef SAFE_SETUID
92
93 #  ifdef SAFE_SETUID_POSIX
94
95         if (setuid(player_euid) != 0)
96         {
97 #ifdef JP
98 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
99 #else
100                 quit("setuid(): cannot set permissions correctly!");
101 #endif
102
103         }
104         if (setgid(player_egid) != 0)
105         {
106 #ifdef JP
107 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
108 #else
109                 quit("setgid(): cannot set permissions correctly!");
110 #endif
111
112         }
113
114 #  else
115
116         if (setreuid(geteuid(), getuid()) != 0)
117         {
118 #ifdef JP
119 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
120 #else
121                 quit("setreuid(): cannot set permissions correctly!");
122 #endif
123
124         }
125         if (setregid(getegid(), getgid()) != 0)
126         {
127 #ifdef JP
128 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
129 #else
130                 quit("setregid(): cannot set permissions correctly!");
131 #endif
132
133         }
134
135 #  endif /* SAFE_SETUID_POSIX */
136
137 # endif /* SAFE_SETUID */
138
139 #endif /* SET_UID */
140
141 }
142
143
144 /*
145  * Extract the first few "tokens" from a buffer
146  *
147  * This function uses "colon" and "slash" as the delimeter characters.
148  *
149  * We never extract more than "num" tokens.  The "last" token may include
150  * "delimeter" characters, allowing the buffer to include a "string" token.
151  *
152  * We save pointers to the tokens in "tokens", and return the number found.
153  *
154  * Hack -- Attempt to handle the 'c' character formalism
155  *
156  * Hack -- An empty buffer, or a final delimeter, yields an "empty" token.
157  *
158  * Hack -- We will always extract at least one token
159  */
160 s16b tokenize(char *buf, s16b num, char **tokens, int mode)
161 {
162         int i = 0;
163
164         char *s = buf;
165
166
167         /* Process */
168         while (i < num - 1)
169         {
170                 char *t;
171
172                 /* Scan the string */
173                 for (t = s; *t; t++)
174                 {
175                         /* Found a delimiter */
176                         if ((*t == ':') || (*t == '/')) break;
177
178                         /* Handle single quotes */
179                         if ((mode & TOKENIZE_CHECKQUOTE) && (*t == '\''))
180                         {
181                                 /* Advance */
182                                 t++;
183
184                                 /* Handle backslash */
185                                 if (*t == '\\') t++;
186
187                                 /* Require a character */
188                                 if (!*t) break;
189
190                                 /* Advance */
191                                 t++;
192
193                                 /* Hack -- Require a close quote */
194                                 if (*t != '\'') *t = '\'';
195                         }
196
197                         /* Handle back-slash */
198                         if (*t == '\\') t++;
199                 }
200
201                 /* Nothing left */
202                 if (!*t) break;
203
204                 /* Nuke and advance */
205                 *t++ = '\0';
206
207                 /* Save the token */
208                 tokens[i++] = s;
209
210                 /* Advance */
211                 s = t;
212         }
213
214         /* Save the token */
215         tokens[i++] = s;
216
217         /* Number found */
218         return (i);
219 }
220
221
222 /* A number with a name */
223 typedef struct named_num named_num;
224
225 struct named_num
226 {
227         cptr name;              /* The name of this thing */
228         int num;                        /* A number associated with it */
229 };
230
231
232 /* Index of spell type names */
233 static named_num gf_desc[] =
234 {
235         {"GF_ELEC",                             GF_ELEC                         },
236         {"GF_POIS",                             GF_POIS                         },
237         {"GF_ACID",                             GF_ACID                         },
238         {"GF_COLD",                             GF_COLD                         },
239         {"GF_FIRE",                                     GF_FIRE                         },
240         {"GF_PSY_SPEAR",                        GF_PSY_SPEAR                    },
241         {"GF_MISSILE",                          GF_MISSILE                      },
242         {"GF_ARROW",                            GF_ARROW                                },
243         {"GF_PLASMA",                           GF_PLASMA                       },
244         {"GF_WATER",                            GF_WATER                                },
245         {"GF_LITE",                                     GF_LITE                         },
246         {"GF_DARK",                                     GF_DARK                         },
247         {"GF_LITE_WEAK",                        GF_LITE_WEAK            },
248         {"GF_DARK_WEAK",                        GF_DARK_WEAK            },
249         {"GF_SHARDS",                           GF_SHARDS                       },
250         {"GF_SOUND",                            GF_SOUND                                },
251         {"GF_CONFUSION",                        GF_CONFUSION            },
252         {"GF_FORCE",                            GF_FORCE                                },
253         {"GF_INERTIA",                          GF_INERTIA                      },
254         {"GF_MANA",                                     GF_MANA                         },
255         {"GF_METEOR",                           GF_METEOR                       },
256         {"GF_ICE",                                      GF_ICE                          },
257         {"GF_CHAOS",                            GF_CHAOS                                },
258         {"GF_NETHER",                           GF_NETHER                       },
259         {"GF_DISENCHANT",                       GF_DISENCHANT           },
260         {"GF_NEXUS",                            GF_NEXUS                                },
261         {"GF_TIME",                                     GF_TIME                         },
262         {"GF_GRAVITY",                          GF_GRAVITY                      },
263         {"GF_KILL_WALL",                        GF_KILL_WALL            },
264         {"GF_KILL_DOOR",                        GF_KILL_DOOR            },
265         {"GF_KILL_TRAP",                        GF_KILL_TRAP            },
266         {"GF_MAKE_WALL",                        GF_MAKE_WALL            },
267         {"GF_MAKE_DOOR",                        GF_MAKE_DOOR            },
268         {"GF_MAKE_TRAP",                        GF_MAKE_TRAP            },
269         {"GF_MAKE_TREE",                        GF_MAKE_TREE            },
270         {"GF_OLD_CLONE",                        GF_OLD_CLONE            },
271         {"GF_OLD_POLY",                 GF_OLD_POLY                     },
272         {"GF_OLD_HEAL",                 GF_OLD_HEAL                     },
273         {"GF_OLD_SPEED",                        GF_OLD_SPEED            },
274         {"GF_OLD_SLOW",                 GF_OLD_SLOW                     },
275         {"GF_OLD_CONF",                 GF_OLD_CONF                     },
276         {"GF_OLD_SLEEP",                        GF_OLD_SLEEP            },
277         {"GF_OLD_DRAIN",                        GF_OLD_DRAIN            },
278         {"GF_AWAY_UNDEAD",              GF_AWAY_UNDEAD          },
279         {"GF_AWAY_EVIL",                        GF_AWAY_EVIL            },
280         {"GF_AWAY_ALL",                 GF_AWAY_ALL                     },
281         {"GF_TURN_UNDEAD",              GF_TURN_UNDEAD          },
282         {"GF_TURN_EVIL",                        GF_TURN_EVIL            },
283         {"GF_TURN_ALL",                 GF_TURN_ALL                     },
284         {"GF_DISP_UNDEAD",              GF_DISP_UNDEAD          },
285         {"GF_DISP_EVIL",                        GF_DISP_EVIL            },
286         {"GF_DISP_ALL",                 GF_DISP_ALL                     },
287         {"GF_DISP_DEMON",                       GF_DISP_DEMON           },
288         {"GF_DISP_LIVING",              GF_DISP_LIVING          },
289         {"GF_ROCKET",                           GF_ROCKET                       },
290         {"GF_NUKE",                                     GF_NUKE                         },
291         {"GF_MAKE_GLYPH",                       GF_MAKE_GLYPH           },
292         {"GF_STASIS",                           GF_STASIS                       },
293         {"GF_STONE_WALL",                       GF_STONE_WALL           },
294         {"GF_DEATH_RAY",                        GF_DEATH_RAY            },
295         {"GF_STUN",                                     GF_STUN                         },
296         {"GF_HOLY_FIRE",                        GF_HOLY_FIRE            },
297         {"GF_HELL_FIRE",                        GF_HELL_FIRE            },
298         {"GF_DISINTEGRATE",             GF_DISINTEGRATE },
299         {"GF_CHARM",                            GF_CHARM                                },
300         {"GF_CONTROL_UNDEAD",   GF_CONTROL_UNDEAD       },
301         {"GF_CONTROL_ANIMAL",   GF_CONTROL_ANIMAL       },
302         {"GF_PSI",                                      GF_PSI                          },
303         {"GF_PSI_DRAIN",                        GF_PSI_DRAIN            },
304         {"GF_TELEKINESIS",              GF_TELEKINESIS          },
305         {"GF_JAM_DOOR",                 GF_JAM_DOOR                     },
306         {"GF_DOMINATION",                       GF_DOMINATION           },
307         {"GF_DISP_GOOD",                        GF_DISP_GOOD            },
308         {"GF_DRAIN_MANA",                       GF_DRAIN_MANA           },
309         {"GF_MIND_BLAST",                       GF_MIND_BLAST           },
310         {"GF_BRAIN_SMASH",                      GF_BRAIN_SMASH          },
311         {"GF_CAUSE_1",                  GF_CAUSE_1              },
312         {"GF_CAUSE_2",                  GF_CAUSE_2              },
313         {"GF_CAUSE_3",                  GF_CAUSE_3              },
314         {"GF_CAUSE_4",                  GF_CAUSE_4              },
315         {"GF_HAND_DOOM",                        GF_HAND_DOOM            },
316         {"GF_CAPTURE",                  GF_CAPTURE              },
317         {"GF_ANIM_DEAD",                        GF_ANIM_DEAD            },
318         {"GF_CONTROL_LIVING",           GF_CONTROL_LIVING       },
319         {"GF_IDENTIFY",                 GF_IDENTIFY     },
320         {"GF_ATTACK",                   GF_ATTACK       },
321         {"GF_ENGETSU",                  GF_ENGETSU      },
322         {"GF_GENOCIDE",                 GF_GENOCIDE     },
323         {"GF_PHOTO",                    GF_PHOTO        },
324         {"GF_CONTROL_DEMON",    GF_CONTROL_DEMON        },
325         {"GF_LAVA_FLOW",        GF_LAVA_FLOW    },
326         {"GF_BLOOD_CURSE",      GF_BLOOD_CURSE  },
327         {"GF_SEEKER",                   GF_SEEKER                       },
328         {"GF_SUPER_RAY",                GF_SUPER_RAY                    },
329         {"GF_STAR_HEAL",                GF_STAR_HEAL                    },
330         {NULL,                                          0                                               }
331 };
332
333
334 /*
335  * Parse a sub-file of the "extra info" (format shown below)
336  *
337  * Each "action" line has an "action symbol" in the first column,
338  * followed by a colon, followed by some command specific info,
339  * usually in the form of "tokens" separated by colons or slashes.
340  *
341  * Blank lines, lines starting with white space, and lines starting
342  * with pound signs ("#") are ignored (as comments).
343  *
344  * Note the use of "tokenize()" to allow the use of both colons and
345  * slashes as delimeters, while still allowing final tokens which
346  * may contain any characters including "delimiters".
347  *
348  * Note the use of "strtol()" to allow all "integers" to be encoded
349  * in decimal, hexidecimal, or octal form.
350  *
351  * Note that "monster zero" is used for the "player" attr/char, "object
352  * zero" will be used for the "stack" attr/char, and "feature zero" is
353  * used for the "nothing" attr/char.
354  *
355  * Parse another file recursively, see below for details
356  *   %:<filename>
357  *
358  * Specify the attr/char values for "monsters" by race index
359  *   R:<num>:<a>:<c>
360  *
361  * Specify the attr/char values for "objects" by kind index
362  *   K:<num>:<a>:<c>
363  *
364  * Specify the attr/char values for "features" by feature index
365  *   F:<num>:<a>:<c>
366  *
367  * Specify the attr/char values for unaware "objects" by kind tval
368  *   U:<tv>:<a>:<c>
369  *
370  * Specify the attr/char values for inventory "objects" by kind tval
371  *   E:<tv>:<a>:<c>
372  *
373  * Define a macro action, given an encoded macro action
374  *   A:<str>
375  *
376  * Create a normal macro, given an encoded macro trigger
377  *   P:<str>
378  *
379  * Create a command macro, given an encoded macro trigger
380  *   C:<str>
381  *
382  * Create a keyset mapping
383  *   S:<key>:<key>:<dir>
384  *
385  * Turn an option off, given its name
386  *   X:<str>
387  *
388  * Turn an option on, given its name
389  *   Y:<str>
390  *
391  * Specify visual information, given an index, and some data
392  *   V:<num>:<kv>:<rv>:<gv>:<bv>
393  *
394  * Specify the set of colors to use when drawing a zapped spell
395  *   Z:<type>:<str>
396  *
397  * Specify a macro trigger template and macro trigger names.
398  *   T:<template>:<modifier chr>:<modifier name1>:<modifier name2>:...
399  *   T:<trigger>:<keycode>:<shift-keycode>
400  *
401  */
402
403 errr process_pref_file_command(char *buf)
404 {
405         int i, j, n1, n2;
406
407         char *zz[16];
408
409
410         /* Require "?:*" format */
411         if (buf[1] != ':') return (1);
412
413
414         /* Process "%:<fname>" */
415         if (buf[0] == '%')
416         {
417                 /* Attempt to Process the given file */
418                 return (process_pref_file(buf + 2));
419         }
420
421
422         /* Process "R:<num>:<a>/<c>" -- attr/char for monster races */
423         if (buf[0] == 'R')
424         {
425                 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
426                 {
427                         monster_race *r_ptr;
428                         i = (huge)strtol(zz[0], NULL, 0);
429                         n1 = strtol(zz[1], NULL, 0);
430                         n2 = strtol(zz[2], NULL, 0);
431                         if (i >= max_r_idx) return (1);
432                         r_ptr = &r_info[i];
433                         if (n1) r_ptr->x_attr = n1;
434                         if (n2) r_ptr->x_char = n2;
435                         return (0);
436                 }
437         }
438
439         /* Process "K:<num>:<a>/<c>"  -- attr/char for object kinds */
440         else if (buf[0] == 'K')
441         {
442                 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
443                 {
444                         object_kind *k_ptr;
445                         i = (huge)strtol(zz[0], NULL, 0);
446                         n1 = strtol(zz[1], NULL, 0);
447                         n2 = strtol(zz[2], NULL, 0);
448                         if (i >= max_k_idx) return (1);
449                         k_ptr = &k_info[i];
450                         if (n1) k_ptr->x_attr = n1;
451                         if (n2) k_ptr->x_char = n2;
452                         return (0);
453                 }
454         }
455
456         /* Process "F:<num>:<a>/<c>" -- attr/char for terrain features */
457         else if (buf[0] == 'F')
458         {
459                 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
460                 {
461                         feature_type *f_ptr;
462                         i = (huge)strtol(zz[0], NULL, 0);
463                         n1 = strtol(zz[1], NULL, 0);
464                         n2 = strtol(zz[2], NULL, 0);
465                         if (i >= max_f_idx) return (1);
466                         f_ptr = &f_info[i];
467                         if (n1) f_ptr->x_attr = n1;
468                         if (n2) f_ptr->x_char = n2;
469                         return (0);
470                 }
471         }
472
473         /* Process "S:<num>:<a>/<c>" -- attr/char for special things */
474         else if (buf[0] == 'S')
475         {
476                 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
477                 {
478                         j = (byte)strtol(zz[0], NULL, 0);
479                         n1 = strtol(zz[1], NULL, 0);
480                         n2 = strtol(zz[2], NULL, 0);
481                         misc_to_attr[j] = n1;
482                         misc_to_char[j] = n2;
483                         return (0);
484                 }
485         }
486
487         /* Process "U:<tv>:<a>/<c>" -- attr/char for unaware items */
488         else if (buf[0] == 'U')
489         {
490                 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
491                 {
492                         j = (huge)strtol(zz[0], NULL, 0);
493                         n1 = strtol(zz[1], NULL, 0);
494                         n2 = strtol(zz[2], NULL, 0);
495                         for (i = 1; i < max_k_idx; i++)
496                         {
497                                 object_kind *k_ptr = &k_info[i];
498                                 if (k_ptr->tval == j)
499                                 {
500                                         if (n1) k_ptr->d_attr = n1;
501                                         if (n2) k_ptr->d_char = n2;
502                                 }
503                         }
504                         return (0);
505                 }
506         }
507
508         /* Process "E:<tv>:<a>" -- attribute for inventory objects */
509         else if (buf[0] == 'E')
510         {
511                 if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) == 2)
512                 {
513                         j = (byte)strtol(zz[0], NULL, 0) % 128;
514                         n1 = strtol(zz[1], NULL, 0);
515                         if (n1) tval_to_attr[j] = n1;
516                         return (0);
517                 }
518         }
519
520
521         /* Process "A:<str>" -- save an "action" for later */
522         else if (buf[0] == 'A')
523         {
524                 text_to_ascii(macro__buf, buf+2);
525                 return (0);
526         }
527
528         /* Process "P:<str>" -- normal macro */
529         else if (buf[0] == 'P')
530         {
531                 char tmp[1024];
532                 text_to_ascii(tmp, buf+2);
533                 macro_add(tmp, macro__buf);
534                 return (0);
535         }
536
537
538         /* Process "C:<str>" -- create keymap */
539         else if (buf[0] == 'C')
540         {
541                 int mode;
542
543                 char tmp[1024];
544
545                 if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) != 2) return (1);
546
547                 mode = strtol(zz[0], NULL, 0);
548                 if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1);
549
550                 text_to_ascii(tmp, zz[1]);
551                 if (!tmp[0] || tmp[1]) return (1);
552                 i = (byte)(tmp[0]);
553
554                 string_free(keymap_act[mode][i]);
555
556                 keymap_act[mode][i] = string_make(macro__buf);
557
558                 return (0);
559         }
560
561
562         /* Process "V:<num>:<kv>:<rv>:<gv>:<bv>" -- visual info */
563         else if (buf[0] == 'V')
564         {
565                 if (tokenize(buf+2, 5, zz, TOKENIZE_CHECKQUOTE) == 5)
566                 {
567                         i = (byte)strtol(zz[0], NULL, 0);
568                         angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0);
569                         angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0);
570                         angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0);
571                         angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0);
572                         return (0);
573                 }
574         }
575
576
577         /* Process "X:<str>" -- turn option off */
578         else if (buf[0] == 'X')
579         {
580                 for (i = 0; option_info[i].o_desc; i++)
581                 {
582                         int os = option_info[i].o_set;
583                         int ob = option_info[i].o_bit;
584
585                         if (option_info[i].o_var &&
586                                  option_info[i].o_text &&
587                                  streq(option_info[i].o_text, buf + 2) &&
588                                 (!alive || option_info[i].o_page !=6))
589                         {
590                                 /* Clear */
591                                 option_flag[os] &= ~(1L << ob);
592                                 (*option_info[i].o_var) = FALSE;
593                                 return (0);
594                         }
595                 }
596
597                 /* don't know that option. ignore it.*/
598                 msg_format("Ignored wrong option %s.", buf+2);
599                 msg_print(NULL);
600                 return 0;
601         }
602
603         /* Process "Y:<str>" -- turn option on */
604         else if (buf[0] == 'Y')
605         {
606                 for (i = 0; option_info[i].o_desc; i++)
607                 {
608                         int os = option_info[i].o_set;
609                         int ob = option_info[i].o_bit;
610
611                         if (option_info[i].o_var &&
612                                  option_info[i].o_text &&
613                                  streq(option_info[i].o_text, buf + 2) &&
614                                 (!alive || option_info[i].o_page !=6))
615                         {
616                                 /* Set */
617                                 option_flag[os] |= (1L << ob);
618                                 (*option_info[i].o_var) = TRUE;
619                                 return (0);
620                         }
621                 }
622
623                 /* don't know that option. ignore it.*/
624                 msg_format("Ignored wrong option %s.", buf+2);
625                 msg_print(NULL);
626                 return 0;
627         }
628
629         /* Process "Z:<type>:<str>" -- set spell color */
630         else if (buf[0] == 'Z')
631         {
632                 /* Find the colon */
633                 char *t = strchr(buf + 2, ':');
634
635                 /* Oops */
636                 if (!t) return (1);
637
638                 /* Nuke the colon */
639                 *(t++) = '\0';
640
641                 for (i = 0; gf_desc[i].name; i++)
642                 {
643                         /* Match this type */
644                         if (streq(gf_desc[i].name, buf + 2))
645                         {
646                                 /* Remember this color set */
647                                 gf_color[gf_desc[i].num] = quark_add(t);
648
649                                 /* Success */
650                                 return (0);
651                         }
652                 }
653         }
654         /* set macro trigger names and a template */
655         /* Process "T:<trigger>:<keycode>:<shift-keycode>" */
656         /* Process "T:<template>:<modifier chr>:<modifier name>:..." */
657         else if (buf[0] == 'T')
658         {
659                 int len, tok;
660                 tok = tokenize(buf+2, 2+MAX_MACRO_MOD, zz, 0);
661                 if (tok >= 4)
662                 {
663                         int i;
664                         int num;
665
666                         if (macro_template != NULL)
667                         {
668                                 free(macro_template);
669                                 macro_template = NULL;
670                                 for (i = 0; i < max_macrotrigger; i++)
671                                         free(macro_trigger_name[i]);
672                                 max_macrotrigger = 0;
673                         }
674                         
675                         if (*zz[0] == '\0') return 0; /* clear template */
676                         num = strlen(zz[1]);
677                         if (2 + num != tok) return 1; /* error */
678
679                         len = strlen(zz[0])+1+num+1;
680                         for (i = 0; i < num; i++)
681                                 len += strlen(zz[2+i])+1;
682                         macro_template = malloc(len);
683
684                         strcpy(macro_template, zz[0]);
685                         macro_modifier_chr =
686                                 macro_template + strlen(macro_template) + 1;
687                         strcpy(macro_modifier_chr, zz[1]);
688                         macro_modifier_name[0] =
689                                 macro_modifier_chr + strlen(macro_modifier_chr) + 1;
690                         for (i = 0; i < num; i++)
691                         {
692                                 strcpy(macro_modifier_name[i], zz[2+i]);
693                                 macro_modifier_name[i+1] = macro_modifier_name[i] + 
694                                         strlen(macro_modifier_name[i]) + 1;
695                         }
696                 }
697                 else if (tok >= 2)
698                 {
699                         int m;
700                         char *t, *s;
701                         if (max_macrotrigger >= MAX_MACRO_TRIG)
702                         {
703 #ifdef JP
704                                 msg_print("¥Þ¥¯¥í¥È¥ê¥¬¡¼¤ÎÀßÄ꤬¿¤¹¤®¤Þ¤¹!");
705 #else
706                                 msg_print("Too many macro triggers!");
707 #endif
708                                 return 1;
709                         }
710                         m = max_macrotrigger;
711                         max_macrotrigger++;
712
713                         len = strlen(zz[0]) + 1 + strlen(zz[1]) + 1;
714                         if (tok == 3)
715                                 len += strlen(zz[2]) + 1;
716                         macro_trigger_name[m] = malloc(len);
717
718                         t = macro_trigger_name[m];
719                         s = zz[0];
720                         while (*s)
721                         {
722                                 if ('\\' == *s) s++;
723                                 *t++ = *s++;
724                         }
725                         *t = '\0';
726
727                         macro_trigger_keycode[0][m] = macro_trigger_name[m] +
728                                 strlen(macro_trigger_name[m]) + 1;
729                         strcpy(macro_trigger_keycode[0][m], zz[1]);
730                         if (tok == 3)
731                         {
732                                 macro_trigger_keycode[1][m] = macro_trigger_keycode[0][m] +
733                                         strlen(macro_trigger_keycode[0][m]) + 1;
734                                 strcpy(macro_trigger_keycode[1][m], zz[2]);
735                         }
736                         else
737                         {
738                                 macro_trigger_keycode[1][m] = macro_trigger_keycode[0][m];
739                         }
740                 }
741                 return 0;
742         }
743
744         /* Failure */
745         return (1);
746 }
747
748
749 /*
750  * Helper function for "process_pref_file()"
751  *
752  * Input:
753  *   v: output buffer array
754  *   f: final character
755  *
756  * Output:
757  *   result
758  */
759 static cptr process_pref_file_expr(char **sp, char *fp)
760 {
761         cptr v;
762
763         char *b;
764         char *s;
765
766         char b1 = '[';
767         char b2 = ']';
768
769         char f = ' ';
770         static char tmp[8];
771
772         /* Initial */
773         s = (*sp);
774
775         /* Skip spaces */
776         while (isspace(*s)) s++;
777
778         /* Save start */
779         b = s;
780
781         /* Default */
782         v = "?o?o?";
783
784         /* Analyze */
785         if (*s == b1)
786         {
787                 const char *p;
788                 const char *t;
789
790                 /* Skip b1 */
791                 s++;
792
793                 /* First */
794                 t = process_pref_file_expr(&s, &f);
795
796                 /* Oops */
797                 if (!*t)
798                 {
799                         /* Nothing */
800                 }
801
802                 /* Function: IOR */
803                 else if (streq(t, "IOR"))
804                 {
805                         v = "0";
806                         while (*s && (f != b2))
807                         {
808                                 t = process_pref_file_expr(&s, &f);
809                                 if (*t && !streq(t, "0")) v = "1";
810                         }
811                 }
812
813                 /* Function: AND */
814                 else if (streq(t, "AND"))
815                 {
816                         v = "1";
817                         while (*s && (f != b2))
818                         {
819                                 t = process_pref_file_expr(&s, &f);
820                                 if (*t && streq(t, "0")) v = "0";
821                         }
822                 }
823
824                 /* Function: NOT */
825                 else if (streq(t, "NOT"))
826                 {
827                         v = "1";
828                         while (*s && (f != b2))
829                         {
830                                 t = process_pref_file_expr(&s, &f);
831                                 if (*t && streq(t, "1")) v = "0";
832                         }
833                 }
834
835                 /* Function: EQU */
836                 else if (streq(t, "EQU"))
837                 {
838                         v = "1";
839                         if (*s && (f != b2))
840                         {
841                                 t = process_pref_file_expr(&s, &f);
842                         }
843                         while (*s && (f != b2))
844                         {
845                                 p = t;
846                                 t = process_pref_file_expr(&s, &f);
847                                 if (*t && !streq(p, t)) v = "0";
848                         }
849                 }
850
851                 /* Function: LEQ */
852                 else if (streq(t, "LEQ"))
853                 {
854                         v = "1";
855                         if (*s && (f != b2))
856                         {
857                                 t = process_pref_file_expr(&s, &f);
858                         }
859                         while (*s && (f != b2))
860                         {
861                                 p = t;
862                                 t = process_pref_file_expr(&s, &f);
863                                 if (*t && (strcmp(p, t) > 0)) v = "0";
864                         }
865                 }
866
867                 /* Function: GEQ */
868                 else if (streq(t, "GEQ"))
869                 {
870                         v = "1";
871                         if (*s && (f != b2))
872                         {
873                                 t = process_pref_file_expr(&s, &f);
874                         }
875                         while (*s && (f != b2))
876                         {
877                                 p = t;
878                                 t = process_pref_file_expr(&s, &f);
879                                 if (*t && (strcmp(p, t) < 0)) v = "0";
880                         }
881                 }
882
883                 /* Oops */
884                 else
885                 {
886                         while (*s && (f != b2))
887                         {
888                                 t = process_pref_file_expr(&s, &f);
889                         }
890                 }
891
892                 /* Verify ending */
893                 if (f != b2) v = "?x?x?";
894
895                 /* Extract final and Terminate */
896                 if ((f = *s) != '\0') *s++ = '\0';
897         }
898
899         /* Other */
900         else
901         {
902                 /* Accept all printables except spaces and brackets */
903                 while (isprint(*s) && !strchr(" []", *s)) ++s;
904
905                 /* Extract final and Terminate */
906                 if ((f = *s) != '\0') *s++ = '\0';
907
908                 /* Variable */
909                 if (*b == '$')
910                 {
911                         /* System */
912                         if (streq(b+1, "SYS"))
913                         {
914                                 v = ANGBAND_SYS;
915                         }
916
917                         else if (streq(b+1, "KEYBOARD"))
918                         {
919                                 v = ANGBAND_KEYBOARD;
920                         }
921
922                         /* Graphics */
923                         else if (streq(b+1, "GRAF"))
924                         {
925                                 v = ANGBAND_GRAF;
926                         }
927
928                         /* Monochrome mode */
929                         else if (streq(b+1, "MONOCHROME"))
930                         {
931                                 if (arg_monochrome)
932                                         v = "ON";
933                                 else
934                                         v = "OFF";
935                         }
936
937                         /* Race */
938                         else if (streq(b+1, "RACE"))
939                         {
940 #ifdef JP
941                                 v = rp_ptr->E_title;
942 #else
943                                 v = rp_ptr->title;
944 #endif
945                         }
946
947                         /* Class */
948                         else if (streq(b+1, "CLASS"))
949                         {
950 #ifdef JP
951                                 v = cp_ptr->E_title;
952 #else
953                                 v = cp_ptr->title;
954 #endif
955                         }
956
957                         /* Player */
958                         else if (streq(b+1, "PLAYER"))
959                         {
960                                 v = player_base;
961                         }
962
963                         /* First realm */
964                         else if (streq(b+1, "REALM1"))
965                         {
966 #ifdef JP
967                                 v = E_realm_names[p_ptr->realm1];
968 #else
969                                 v = realm_names[p_ptr->realm1];
970 #endif
971                         }
972
973                         /* Second realm */
974                         else if (streq(b+1, "REALM2"))
975                         {
976 #ifdef JP
977                                 v = E_realm_names[p_ptr->realm2];
978 #else
979                                 v = realm_names[p_ptr->realm2];
980 #endif
981                         }
982
983                         /* Level */
984                         else if (streq(b+1, "LEVEL"))
985                         {
986                                 sprintf(tmp, "%02d", p_ptr->lev);
987                                 v = tmp;
988                         }
989                 }
990
991                 /* Constant */
992                 else
993                 {
994                         v = b;
995                 }
996         }
997
998         /* Save */
999         (*fp) = f;
1000
1001         /* Save */
1002         (*sp) = s;
1003
1004         /* Result */
1005         return (v);
1006 }
1007
1008
1009
1010 /*
1011  *  Process line for auto picker/destroyer.
1012  */
1013 static errr process_pickpref_file_line(char *buf)
1014 {
1015         char *s, *s2;
1016         int i;
1017         byte act = 0;
1018
1019         /* Nuke illegal char */
1020         for(i = 0; buf[i]; i++)
1021         {
1022 #ifdef JP
1023                 if (iskanji(buf[i]))
1024                 {
1025                         i++;
1026                         continue;
1027                 }
1028 #endif
1029                 if (isspace(buf[i]) && buf[i] != ' ')
1030                         break;
1031         }
1032         buf[i] = 0;
1033         
1034         s = buf;
1035
1036         act = DO_AUTOPICK | DO_DISPLAY;
1037         while (1)
1038         {
1039                 if (*s == '!')
1040                 {
1041                         act &= ~DO_AUTOPICK;
1042                         act |= DO_AUTODESTROY;
1043                         s++;
1044                 }
1045                 else if (*s == '~')
1046                 {
1047                         act &= ~DO_AUTOPICK;
1048                         act |= DONT_AUTOPICK;
1049                         s++;
1050                 }
1051                 else if (*s == '(')
1052                 {
1053                         act &= ~DO_DISPLAY;
1054                         s++;
1055                 }
1056                 else
1057                         break;
1058         }
1059
1060         /* don't mind upper or lower case */
1061         s2 = NULL;
1062         for (i = 0; s[i]; i++)
1063         {
1064 #ifdef JP
1065                 if (iskanji(s[i]))
1066                 {
1067                         i++;
1068                         continue;
1069                 }
1070 #endif
1071                 if (isupper(s[i]))
1072                         s[i] = tolower(s[i]);
1073
1074                 /* Auto-inscription? */
1075                 if (s[i] == '#')
1076                 {
1077                         s[i] = '\0';
1078                         s2 = s + i + 1;
1079                         break;
1080                 }
1081         }
1082         
1083         /* Skip empty line */
1084         if (*s == 0)
1085                 return 0;
1086         if (max_autopick == MAX_AUTOPICK)
1087                 return 1;
1088         
1089         /* Already has the same entry? */ 
1090         for(i = 0; i < max_autopick; i++)
1091                 if(!strcmp(s, autopick_name[i]))
1092                         return 0;
1093
1094         autopick_name[max_autopick] = string_make(s);
1095         autopick_action[max_autopick] = act;
1096
1097         autopick_insc[max_autopick] = string_make(s2);
1098         max_autopick++;
1099         return 0;
1100 }
1101
1102
1103
1104 /*
1105  * Open the "user pref file" and parse it.
1106  */
1107 static errr process_pref_file_aux(cptr name, bool read_pickpref)
1108 {
1109         FILE *fp;
1110
1111         char buf[1024];
1112
1113         char old[1024];
1114
1115         int line = -1;
1116
1117         errr err = 0;
1118
1119         bool bypass = FALSE;
1120
1121
1122         /* Open the file */
1123         fp = my_fopen(name, "r");
1124
1125         /* No such file */
1126         if (!fp) return (-1);
1127
1128         /* Process the file */
1129         while (0 == my_fgets(fp, buf, 1024))
1130         {
1131                 /* Count lines */
1132                 line++;
1133
1134                 /* Skip "empty" lines */
1135                 if (!buf[0]) continue;
1136
1137                 /* Skip "blank" lines */
1138 #ifdef JP
1139                 if (!iskanji(buf[0]))
1140 #endif
1141                 if (isspace(buf[0])) continue;
1142
1143                 /* Skip comments */
1144                 if (buf[0] == '#') continue;
1145
1146
1147                 /* Save a copy */
1148                 strcpy(old, buf);
1149
1150
1151                 /* Process "?:<expr>" */
1152                 if ((buf[0] == '?') && (buf[1] == ':'))
1153                 {
1154                         char f;
1155                         cptr v;
1156                         char *s;
1157
1158                         /* Start */
1159                         s = buf + 2;
1160
1161                         /* Parse the expr */
1162                         v = process_pref_file_expr(&s, &f);
1163
1164                         /* Set flag */
1165                         bypass = (streq(v, "0") ? TRUE : FALSE);
1166
1167                         /* Continue */
1168                         continue;
1169                 }
1170
1171                 /* Apply conditionals */
1172                 if (bypass) continue;
1173
1174
1175                 /* Process "%:<file>" */
1176                 if (buf[0] == '%')
1177                 {
1178                         /* Process that file if allowed */
1179                         if (read_pickpref)
1180                                 (void)process_pickpref_file(buf + 2);
1181                         else
1182                                 (void)process_pref_file(buf + 2);
1183
1184                         /* Continue */
1185                         continue;
1186                 }
1187
1188
1189                 /* Process the line */
1190                 err = process_pref_file_command(buf);
1191
1192                 /* This is not original pref line... */
1193                 if (err)
1194                 {
1195                         if (!read_pickpref)
1196                                 break;
1197                         err = process_pickpref_file_line(buf);
1198                 }
1199         }
1200
1201
1202         /* Error */
1203         if (err)
1204         {
1205                 /* Print error message */
1206                 /* ToDo: Add better error messages */
1207 #ifdef JP
1208               msg_format("¥Õ¥¡¥¤¥ë'%s'¤Î%d¹Ô¤Ç¥¨¥é¡¼ÈÖ¹æ%d¤Î¥¨¥é¡¼¡£", name, line, err);
1209               msg_format("('%s'¤ò²òÀÏÃæ)", old);
1210 #else
1211                 msg_format("Error %d in line %d of file '%s'.", err, line, name);
1212                 msg_format("Parsing '%s'", old);
1213 #endif
1214                 msg_print(NULL);
1215         }
1216
1217         /* Close the file */
1218         my_fclose(fp);
1219
1220         /* Result */
1221         return (err);
1222 }
1223
1224
1225
1226 /*
1227  * Process the "user pref file" with the given name
1228  *
1229  * See the functions above for a list of legal "commands".
1230  *
1231  * We also accept the special "?" and "%" directives, which
1232  * allow conditional evaluation and filename inclusion.
1233  */
1234 errr process_pref_file(cptr name)
1235 {
1236         char buf[1024];
1237
1238         errr err = 0;
1239
1240         /* Build the filename */
1241         path_build(buf, 1024, ANGBAND_DIR_PREF, name);
1242
1243         /* Process the pref file */
1244         err = process_pref_file_aux(buf, FALSE);
1245
1246         /* Stop at parser errors, but not at non-existing file */
1247         if (err < 1)
1248         {
1249                 /* Build the filename */
1250                 path_build(buf, 1024, ANGBAND_DIR_USER, name);
1251
1252                 /* Process the pref file */
1253                 err = process_pref_file_aux(buf, FALSE);
1254         }
1255
1256         /* Result */
1257         return (err);
1258 }
1259
1260
1261
1262 #ifdef CHECK_TIME
1263
1264 /*
1265  * Operating hours for ANGBAND (defaults to non-work hours)
1266  */
1267 static char days[7][29] =
1268 {
1269         "SUN:XXXXXXXXXXXXXXXXXXXXXXXX",
1270         "MON:XXXXXXXX.........XXXXXXX",
1271         "TUE:XXXXXXXX.........XXXXXXX",
1272         "WED:XXXXXXXX.........XXXXXXX",
1273         "THU:XXXXXXXX.........XXXXXXX",
1274         "FRI:XXXXXXXX.........XXXXXXX",
1275         "SAT:XXXXXXXXXXXXXXXXXXXXXXXX"
1276 };
1277
1278 /*
1279  * Restict usage (defaults to no restrictions)
1280  */
1281 static bool check_time_flag = FALSE;
1282
1283 #endif
1284
1285
1286 /*
1287  * Handle CHECK_TIME
1288  */
1289 errr check_time(void)
1290 {
1291
1292 #ifdef CHECK_TIME
1293
1294         time_t      c;
1295         struct tm   *tp;
1296
1297         /* No restrictions */
1298         if (!check_time_flag) return (0);
1299
1300         /* Check for time violation */
1301         c = time((time_t *)0);
1302         tp = localtime(&c);
1303
1304         /* Violation */
1305         if (days[tp->tm_wday][tp->tm_hour + 4] != 'X') return (1);
1306
1307 #endif
1308
1309         /* Success */
1310         return (0);
1311 }
1312
1313
1314
1315 /*
1316  * Initialize CHECK_TIME
1317  */
1318 errr check_time_init(void)
1319 {
1320
1321 #ifdef CHECK_TIME
1322
1323         FILE        *fp;
1324
1325         char    buf[1024];
1326
1327
1328         /* Build the filename */
1329         path_build(buf, 1024, ANGBAND_DIR_FILE, "time.txt");
1330
1331         /* Open the file */
1332         fp = my_fopen(buf, "r");
1333
1334         /* No file, no restrictions */
1335         if (!fp) return (0);
1336
1337         /* Assume restrictions */
1338         check_time_flag = TRUE;
1339
1340         /* Parse the file */
1341         while (0 == my_fgets(fp, buf, 80))
1342         {
1343                 /* Skip comments and blank lines */
1344                 if (!buf[0] || (buf[0] == '#')) continue;
1345
1346                 /* Chop the buffer */
1347                 buf[29] = '\0';
1348
1349                 /* Extract the info */
1350                 if (prefix(buf, "SUN:")) strcpy(days[0], buf);
1351                 if (prefix(buf, "MON:")) strcpy(days[1], buf);
1352                 if (prefix(buf, "TUE:")) strcpy(days[2], buf);
1353                 if (prefix(buf, "WED:")) strcpy(days[3], buf);
1354                 if (prefix(buf, "THU:")) strcpy(days[4], buf);
1355                 if (prefix(buf, "FRI:")) strcpy(days[5], buf);
1356                 if (prefix(buf, "SAT:")) strcpy(days[6], buf);
1357         }
1358
1359         /* Close it */
1360         my_fclose(fp);
1361
1362 #endif
1363
1364         /* Success */
1365         return (0);
1366 }
1367
1368
1369
1370 #ifdef CHECK_LOAD
1371
1372 #ifndef MAXHOSTNAMELEN
1373 # define MAXHOSTNAMELEN  64
1374 #endif
1375
1376 typedef struct statstime statstime;
1377
1378 struct statstime
1379 {
1380         int                 cp_time[4];
1381         int                 dk_xfer[4];
1382         unsigned int        v_pgpgin;
1383         unsigned int        v_pgpgout;
1384         unsigned int        v_pswpin;
1385         unsigned int        v_pswpout;
1386         unsigned int        v_intr;
1387         int                 if_ipackets;
1388         int                 if_ierrors;
1389         int                 if_opackets;
1390         int                 if_oerrors;
1391         int                 if_collisions;
1392         unsigned int        v_swtch;
1393         long                avenrun[3];
1394         struct timeval      boottime;
1395         struct timeval      curtime;
1396 };
1397
1398 /*
1399  * Maximal load (if any).
1400  */
1401 static int check_load_value = 0;
1402
1403 #endif
1404
1405
1406 /*
1407  * Handle CHECK_LOAD
1408  */
1409 errr check_load(void)
1410 {
1411
1412 #ifdef CHECK_LOAD
1413
1414         struct statstime    st;
1415
1416         /* Success if not checking */
1417         if (!check_load_value) return (0);
1418
1419         /* Check the load */
1420         if (0 == rstat("localhost", &st))
1421         {
1422                 long val1 = (long)(st.avenrun[2]);
1423                 long val2 = (long)(check_load_value) * FSCALE;
1424
1425                 /* Check for violation */
1426                 if (val1 >= val2) return (1);
1427         }
1428
1429 #endif
1430
1431         /* Success */
1432         return (0);
1433 }
1434
1435
1436 /*
1437  * Initialize CHECK_LOAD
1438  */
1439 errr check_load_init(void)
1440 {
1441
1442 #ifdef CHECK_LOAD
1443
1444         FILE        *fp;
1445
1446         char    buf[1024];
1447
1448         char    temphost[MAXHOSTNAMELEN+1];
1449         char    thishost[MAXHOSTNAMELEN+1];
1450
1451
1452         /* Build the filename */
1453         path_build(buf, 1024, ANGBAND_DIR_FILE, "load.txt");
1454
1455         /* Open the "load" file */
1456         fp = my_fopen(buf, "r");
1457
1458         /* No file, no restrictions */
1459         if (!fp) return (0);
1460
1461         /* Default load */
1462         check_load_value = 100;
1463
1464         /* Get the host name */
1465         (void)gethostname(thishost, (sizeof thishost) - 1);
1466
1467         /* Parse it */
1468         while (0 == my_fgets(fp, buf, 1024))
1469         {
1470                 int value;
1471
1472                 /* Skip comments and blank lines */
1473                 if (!buf[0] || (buf[0] == '#')) continue;
1474
1475                 /* Parse, or ignore */
1476                 if (sscanf(buf, "%s%d", temphost, &value) != 2) continue;
1477
1478                 /* Skip other hosts */
1479                 if (!streq(temphost, thishost) &&
1480                     !streq(temphost, "localhost")) continue;
1481
1482                 /* Use that value */
1483                 check_load_value = value;
1484
1485                 /* Done */
1486                 break;
1487         }
1488
1489         /* Close the file */
1490         my_fclose(fp);
1491
1492 #endif
1493
1494         /* Success */
1495         return (0);
1496 }
1497
1498
1499 /*
1500  * Print long number with header at given row, column
1501  * Use the color for the number, not the header
1502  */
1503 static void prt_lnum(cptr header, s32b num, int row, int col, byte color)
1504 {
1505         int len = strlen(header);
1506         char out_val[32];
1507         put_str(header, row, col);
1508         (void)sprintf(out_val, "%9ld", (long)num);
1509         c_put_str(color, out_val, row, col + len);
1510 }
1511
1512
1513 /*
1514  * Print number with header at given row, column
1515  */
1516 static void prt_num(cptr header, int num, int row, int col, byte color)
1517 {
1518         int len = strlen(header);
1519         char out_val[32];
1520         put_str(header, row, col);
1521         put_str("   ", row, col + len);
1522         (void)sprintf(out_val, "%6ld", (long)num);
1523         c_put_str(color, out_val, row, col + len + 3);
1524 }
1525
1526
1527 #ifdef JP
1528 /*    ÆüËܸìÈdzÈÄ¥
1529  *         £È£Ð / ºÇÂ砤Τ褦¤Êɽ¼¨
1530  *        xxxxx / yyyyy
1531  */
1532 static void prt_num_max( int num, int max , int row, int col, byte color1, byte color2 )
1533 {
1534         char out_val[32];
1535         (void)sprintf(out_val, "%5ld", (long)num);
1536         c_put_str(color1, out_val, row, col );
1537         put_str("/",row, col+6);
1538         (void)sprintf(out_val, "%5ld", (long)max);
1539         c_put_str(color2, out_val, row, col+8 );
1540 }
1541
1542 /*    ÆüËܸìÈdzÈÄ¥
1543  *    xx ºÐ  ¤È¤« xx kg ¤Ê¤É¤Îɽ¼¨ÍÑ cptr tailer ¤Ëñ°Ì¤¬Æþ¤ë¡£
1544  */
1545 static void prt_num2(cptr header, cptr tailer, int num, int row, int col, byte color)
1546 {
1547         int len = strlen(header);
1548         char out_val[32];
1549         put_str(header, row, col);
1550         put_str("   ", row, col + len);
1551         (void)sprintf(out_val, "%6ld", (long)num);
1552         c_put_str(color, out_val, row, col + len + 3);
1553         put_str(tailer, row, col + len + 3+6);
1554 }
1555 #endif
1556
1557 #define ENTRY_BARE_HAND 0
1558 #define ENTRY_TWO_HANDS 1
1559 #define ENTRY_RIGHT_HAND1 2
1560 #define ENTRY_LEFT_HAND1 3
1561 #define ENTRY_LEFT_HAND2 4
1562 #define ENTRY_RIGHT_HAND2 5
1563 #define ENTRY_POSTURE 6
1564 #define ENTRY_SHOOT_HIT_DAM 7
1565 #define ENTRY_SHOOT_POWER 8
1566 #define ENTRY_SPEED 9
1567 #define ENTRY_BASE_AC 10
1568 #define ENTRY_LEVEL 11
1569 #define ENTRY_CUR_EXP 12
1570 #define ENTRY_MAX_EXP 13
1571 #define ENTRY_EXP_TO_ADV 14
1572 #define ENTRY_GOLD 15
1573 #define ENTRY_DAY 16
1574 #define ENTRY_HP 17
1575 #define ENTRY_SP 18
1576 #define ENTRY_PLAY_TIME 19
1577 #define ENTRY_SKILL_FIGHT 20
1578 #define ENTRY_SKILL_SHOOT 21
1579 #define ENTRY_SKILL_SAVING 22
1580 #define ENTRY_SKILL_STEALTH 23
1581 #define ENTRY_SKILL_PERCEP 24
1582 #define ENTRY_SKILL_SEARCH 25
1583 #define ENTRY_SKILL_DISARM 26
1584 #define ENTRY_SKILL_DEVICE 27
1585 #define ENTRY_BLOWS 28
1586 #define ENTRY_SHOTS 29
1587 #define ENTRY_AVG_DMG 30
1588 #define ENTRY_INFRA 31
1589
1590 #define ENTRY_NAME 32
1591 #define ENTRY_SEX 33
1592 #define ENTRY_RACE 34
1593 #define ENTRY_CLASS 35
1594 #define ENTRY_REALM 36
1595 #define ENTRY_PATRON 37
1596 #define ENTRY_AGE 38
1597 #define ENTRY_HEIGHT 39
1598 #define ENTRY_WEIGHT 40
1599 #define ENTRY_SOCIAL 41
1600 #define ENTRY_ALIGN 42
1601
1602
1603 static struct
1604 {
1605         int col;
1606         int row;
1607         int len;
1608         char header[20];
1609 } disp_player_line[]
1610 #ifdef JP
1611 = {
1612         { 1, 10, 25, "ÂǷ⽤Àµ(³ÊÆ®)"},
1613         { 1, 10, 25, "ÂǷ⽤Àµ(ξ¼ê)"},
1614         { 1, 10, 25, "ÂǷ⽤Àµ(±¦¼ê)"},
1615         { 1, 10, 25, "ÂǷ⽤Àµ(º¸¼ê)"},
1616         { 1, 11, 25, "ÂǷ⽤Àµ(º¸¼ê)"},
1617         { 1, 11, 25, "ÂǷ⽤Àµ(±¦¼ê)"},
1618         { 1, 11, 25, ""},
1619         { 1, 15, 25, "¼Í·â¹¶·â½¤Àµ"},
1620         { 1, 16, 25, "¼Í·âÉð´ïÇÜΨ"},
1621         {01, 20, 25, "²Ã®"},
1622         { 1, 19, 25, "£Á£Ã"},
1623         {29, 13, 21, "¥ì¥Ù¥ë"},
1624         {29, 14, 21, "·Ð¸³ÃÍ"},
1625         {29, 15, 21, "ºÇÂç·Ð¸³"},
1626         {29, 16, 21, "¼¡¥ì¥Ù¥ë"},
1627         {29, 17, 21, "½ê»ý¶â"},
1628         {29, 19, 21, "ÆüÉÕ"},
1629         {29, 10, 21, "£È£Ð"},
1630         {29, 11, 21, "£Í£Ð"},
1631         {29, 20, 21, "¥×¥ì¥¤»þ´Ö"},
1632         {54, 10, -1, "ÂǷ⹶·â  :"},
1633         {54, 11, -1, "¼Í·â¹¶·â  :"},
1634         {54, 12, -1, "ËâË¡Ëɸ栠:"},
1635         {54, 13, -1, "±£Ì©¹ÔÆ°  :"},
1636         {54, 15, -1, "ÃγР     :"},
1637         {54, 16, -1, "õº÷      :"},
1638         {54, 17, -1, "²ò½ü      :"},
1639         {54, 18, -1, "ËâË¡Æ»¶ñ  :"},
1640         {01, 12, 25, "ÂÇ·â²ó¿ô"},
1641         {01, 17, 25, "¼Í·â²ó¿ô"},
1642         {01, 13, 25, "Ê¿¶Ñ¥À¥á¡¼¥¸"},
1643         {54, 20, -1, "ÀÖ³°Àþ»ëÎÏ:"},
1644         {26,  1, -1, "̾Á°  : "},
1645         { 1,  3, -1, "À­ÊÌ     : "},
1646         { 1,  4, -1, "¼ï²     : "},
1647         { 1,  5, -1, "¿¦¶È     : "},
1648         { 1,  6, -1, "ËâË¡     : "},
1649         { 1,  7, -1, "¼é¸îËâ¿À : "},
1650         {29,  3, 21, "ǯÎð"},
1651         {29,  4, 21, "¿ÈĹ"},
1652         {29,  5, 21, "ÂνÅ"},
1653         {29,  6, 21, "¼Ò²ñŪÃÏ°Ì"},
1654         {29,  7, 21, "°À­"},
1655 };
1656 #else
1657 = {
1658         { 1, 10, 25, "Bare hand"},
1659         { 1, 10, 25, "Two hands"},
1660         { 1, 10, 25, "Right hand"},
1661         { 1, 10, 25, "Left hand"},
1662         { 1, 11, 25, "Left hand"},
1663         { 1, 11, 25, "Right hand"},
1664         { 1, 11, 25, "Posture"},
1665         { 1, 15, 25, "Shooting"},
1666         { 1, 16, 25, "Multiplier"},
1667         {01, 20, 25, "Speed"},
1668         { 1, 19, 25, "AC"},
1669         {29, 13, 21, "Level"},
1670         {29, 14, 21, "Experience"},
1671         {29, 15, 21, "Max Exp"},
1672         {29, 16, 21, "Exp to Adv"},
1673         {29, 17, 21, "Gold"},
1674         {29, 19, 21, "Time"},
1675         {29, 10, 21, "Hit point"},
1676         {29, 11, 21, "SP (Mana)"},
1677         {29, 20, 21, "Play time"},
1678         {54, 10, -1, "Fighting    : "},
1679         {54, 11, -1, "Bows/Throw  : "},
1680         {54, 12, -1, "Saving Throw: "},
1681         {54, 13, -1, "Stealth     : "},
1682         {54, 15, -1, "Perception  : "},
1683         {54, 16, -1, "Searching   : "},
1684         {54, 17, -1, "Disarming   : "},
1685         {54, 18, -1, "Magic Device: "},
1686         {01, 12, 25, "Blows/Round"},
1687         {01, 17, 25, "Shots/Round"},
1688         {01, 13, 25, "AverageDmg/Rnd"},
1689         {54, 20, -1, "Infra-Vision: "},
1690         {26,  1, -1, "Name  : "},
1691         { 1,  3, -1, "Sex      : "},
1692         { 1,  4, -1, "Race     : "},
1693         { 1,  5, -1, "Class    : "},
1694         { 1,  6, -1, "Magic    : "},
1695         { 1,  7, -1, "Patron   : "},
1696         {29,  3, 21, "Age"},
1697         {29,  4, 21, "Height"},
1698         {29,  5, 21, "Weight"},
1699         {29,  6, 21, "Social Class"},
1700         {29,  7, 21, "Align"},
1701 };
1702 #endif
1703
1704 static void display_player_one_line(int entry, cptr val, byte attr)
1705 {
1706         char buf[40];
1707
1708         int row = disp_player_line[entry].row;
1709         int col = disp_player_line[entry].col;
1710         int len = disp_player_line[entry].len;
1711         cptr head = disp_player_line[entry].header;
1712
1713         int head_len = strlen(head);
1714
1715         Term_putstr(col, row, -1, TERM_WHITE, head);
1716
1717         if (!val)
1718                 return;
1719
1720         if (len > 0)
1721         {
1722                 int val_len = len - head_len;
1723                 sprintf(buf, "%*.*s", val_len, val_len, val);
1724                 Term_putstr(col + head_len, row, -1, attr, buf);
1725         }
1726         else
1727         {
1728                 Term_putstr(col + head_len, row, -1, attr, val);
1729         }
1730
1731         return;
1732 }
1733
1734
1735 /*
1736  * Prints the following information on the screen.
1737  *
1738  * For this to look right, the following should be spaced the
1739  * same as in the prt_lnum code... -CFT
1740  */
1741 static void display_player_middle(void)
1742 {
1743         char buf[160];
1744         int show_tohit, show_todam;
1745         object_type *o_ptr;
1746         int tmul = 0;
1747
1748         if(p_ptr->migite)
1749         {
1750                 show_tohit = p_ptr->dis_to_h[0];
1751                 show_todam = p_ptr->dis_to_d[0];
1752
1753                 o_ptr = &inventory[INVEN_RARM];
1754
1755                 /* Hack -- add in weapon info if known */
1756                 if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1757                 if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1758
1759                 /* Melee attacks */
1760                 sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);
1761
1762                 /* Dump the bonuses to hit/dam */
1763                 if(!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
1764                         display_player_one_line(ENTRY_BARE_HAND, buf, TERM_L_BLUE);
1765                 else if(p_ptr->ryoute)
1766                         display_player_one_line(ENTRY_TWO_HANDS, buf, TERM_L_BLUE);
1767                 else if (left_hander)
1768                         display_player_one_line(ENTRY_LEFT_HAND1, buf, TERM_L_BLUE);
1769                 else
1770                         display_player_one_line(ENTRY_RIGHT_HAND1, buf, TERM_L_BLUE);
1771         }
1772
1773         if(p_ptr->hidarite)
1774         {
1775                 show_tohit = p_ptr->dis_to_h[1];
1776                 show_todam = p_ptr->dis_to_d[1];
1777
1778                 o_ptr = &inventory[INVEN_LARM];
1779
1780                 /* Hack -- add in weapon info if known */
1781                 if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1782                 if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1783
1784                 /* Melee attacks */
1785                 sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);
1786
1787                 /* Dump the bonuses to hit/dam */
1788                 if (left_hander)
1789                         display_player_one_line(ENTRY_RIGHT_HAND2, buf, TERM_L_BLUE);
1790                 else
1791                         display_player_one_line(ENTRY_LEFT_HAND2, buf, TERM_L_BLUE);
1792         }
1793         else if ((p_ptr->pclass == CLASS_MONK) && (empty_hands(TRUE) > 1))
1794         {
1795                 int i;
1796                 if (p_ptr->special_defense & KAMAE_MASK)
1797                 {
1798                         for (i = 0; i < MAX_KAMAE; i++)
1799                         {
1800                                 if ((p_ptr->special_defense >> i) & KAMAE_GENBU) break;
1801                         }
1802                         if (i < MAX_KAMAE)
1803 #ifdef JP
1804                                 display_player_one_line(ENTRY_POSTURE, format("%s¤Î¹½¤¨", kamae_shurui[i].desc), TERM_YELLOW);
1805 #else
1806                                 display_player_one_line(ENTRY_POSTURE, format("%s form", kamae_shurui[i].desc), TERM_YELLOW);
1807 #endif
1808                 }
1809                 else
1810 #ifdef JP
1811                                 display_player_one_line(ENTRY_POSTURE, "¹½¤¨¤Ê¤·", TERM_YELLOW);
1812 #else
1813                                 display_player_one_line(ENTRY_POSTURE, "none", TERM_YELLOW);
1814 #endif
1815         }
1816
1817         /* Range weapon */
1818         o_ptr = &inventory[INVEN_BOW];
1819
1820         /* Base skill */
1821         show_tohit = p_ptr->dis_to_h_b;
1822         show_todam = 0;
1823
1824         /* Apply weapon bonuses */
1825         if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1826         if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1827
1828         show_tohit += (weapon_exp[0][o_ptr->sval]-4000)/200;
1829
1830         /* Range attacks */
1831         display_player_one_line(ENTRY_SHOOT_HIT_DAM, format("(%+d,%+d)", show_tohit, show_todam), TERM_L_BLUE);
1832         
1833         if (inventory[INVEN_BOW].k_idx)
1834         {
1835                 tmul = bow_tmul(inventory[INVEN_BOW].sval);
1836
1837                 /* Get extra "power" from "extra might" */
1838                 if (p_ptr->xtra_might) tmul++;
1839
1840                 tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
1841         }
1842
1843         /* shoot power */
1844         display_player_one_line(ENTRY_SHOOT_POWER, format("x%d.%02d", tmul/100, tmul%100), TERM_L_BLUE);
1845
1846         /* Dump the armor class */
1847         display_player_one_line(ENTRY_BASE_AC, format("[%d,%+d]", p_ptr->dis_ac, p_ptr->dis_to_a), TERM_L_BLUE);
1848
1849         /* Dump speed */
1850         {
1851                 bool is_fast = (p_ptr->fast || music_singing(MUSIC_SPEED) || music_singing(MUSIC_SHERO));
1852                 int tmp_speed = 0;
1853                 byte attr;
1854                 int i;
1855
1856                 i = p_ptr->pspeed-110;
1857
1858                 /* Hack -- Visually "undo" the Search Mode Slowdown */
1859                 if (p_ptr->action == ACTION_SEARCH) i += 10;
1860
1861                 if (i > 0)
1862                         attr = TERM_L_GREEN;
1863                 else if (i == 0)
1864                         attr = TERM_L_BLUE;
1865                 else
1866                         attr = TERM_L_UMBER;
1867
1868                 if (is_fast) tmp_speed += 10;
1869                 if (p_ptr->slow) tmp_speed -= 10;
1870                 if (p_ptr->lightspeed) tmp_speed = 99;
1871
1872                 if (tmp_speed)
1873                 {
1874                         sprintf(buf, "(%+d%+d)", i-tmp_speed, tmp_speed);
1875                         if (tmp_speed > 0)
1876                                 attr = TERM_YELLOW;
1877                         else
1878                                 attr = TERM_VIOLET;
1879                 }
1880                 else
1881                 {
1882                         sprintf(buf, "(%+d)", i);
1883                 }
1884         
1885                 display_player_one_line(ENTRY_SPEED, buf, attr);
1886         }
1887
1888         /* Dump character level */
1889         display_player_one_line(ENTRY_LEVEL, format("%d", p_ptr->lev), TERM_L_GREEN);
1890
1891         /* Dump experience */
1892         if (p_ptr->prace == RACE_ANDROID)
1893                 display_player_one_line(ENTRY_CUR_EXP, "*****", TERM_L_GREEN);
1894         else if (p_ptr->exp >= p_ptr->max_exp)
1895                 display_player_one_line(ENTRY_CUR_EXP, format("%ld", p_ptr->exp), TERM_L_GREEN);
1896         else
1897                 display_player_one_line(ENTRY_CUR_EXP, format("%ld", p_ptr->exp), TERM_YELLOW);
1898
1899         /* Dump max experience */
1900         if (p_ptr->prace == RACE_ANDROID)
1901                 display_player_one_line(ENTRY_MAX_EXP, "*****", TERM_L_GREEN);
1902         else
1903                 display_player_one_line(ENTRY_MAX_EXP, format("%ld", p_ptr->max_exp), TERM_L_GREEN);
1904
1905         /* Dump exp to advance */
1906         if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->prace == RACE_ANDROID))
1907                 display_player_one_line(ENTRY_EXP_TO_ADV, "*****", TERM_L_GREEN);
1908         else
1909                 display_player_one_line(ENTRY_EXP_TO_ADV, format("%ld", (s32b)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L)), TERM_L_GREEN);
1910
1911         /* Dump gold */
1912         display_player_one_line(ENTRY_GOLD, format("%ld", p_ptr->au), TERM_L_GREEN);
1913
1914         /* Dump Day */
1915         {
1916                 s32b len = 20L * TOWN_DAWN;
1917                 s32b tick = turn % len + len / 4;
1918
1919                 sprintf(buf, 
1920 #ifdef JP
1921                         "%2ldÆüÌÜ  %ld:%02ld", 
1922 #else
1923                         "Day %ld  %ld:%02ld", 
1924 #endif
1925                         ((p_ptr->prace == RACE_VAMPIRE) ||
1926                          (p_ptr->prace == RACE_SKELETON) ||
1927                          (p_ptr->prace == RACE_ZOMBIE) ||
1928                          (p_ptr->prace == RACE_SPECTRE))
1929                         ? (turn - (15L * TOWN_DAWN)) / len + 1
1930                         : (turn + (5L * TOWN_DAWN))/ len + 1,
1931                         (24 * tick / len) % 24,
1932                         (1440 * tick / len) % 60);
1933         }
1934         display_player_one_line(ENTRY_DAY, buf, TERM_L_GREEN);
1935
1936         /* Dump hit point */
1937         if (p_ptr->chp >= p_ptr->mhp) 
1938                 display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_L_GREEN);
1939         else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) 
1940                 display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_YELLOW);
1941         else
1942                 display_player_one_line(ENTRY_HP, format("%4d/%4d", p_ptr->chp , p_ptr->mhp), TERM_RED);
1943
1944         /* Dump mana power */
1945         if (p_ptr->csp >= p_ptr->msp) 
1946                 display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_L_GREEN);
1947         else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10) 
1948                 display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_YELLOW);
1949         else
1950                 display_player_one_line(ENTRY_SP, format("%4d/%4d", p_ptr->csp , p_ptr->msp), TERM_RED);
1951
1952         /* Dump play time */
1953         display_player_one_line(ENTRY_PLAY_TIME, format("%.2lu:%.2lu:%.2lu", playtime/(60*60), (playtime/60)%60, playtime%60), TERM_L_GREEN);
1954 }
1955
1956
1957 /*
1958  * Hack -- pass color info around this file
1959  */
1960 static byte likert_color = TERM_WHITE;
1961
1962
1963 /*
1964  * Returns a "rating" of x depending on y
1965  */
1966 static cptr likert(int x, int y)
1967 {
1968         static char dummy[20] = "";
1969
1970         /* Paranoia */
1971         if (y <= 0) y = 1;
1972
1973         /* Negative value */
1974         if (x < 0)
1975         {
1976                 likert_color = TERM_L_DARK;
1977 #ifdef JP
1978 return ("ºÇÄã");
1979 #else
1980                 return ("Very Bad");
1981 #endif
1982
1983         }
1984
1985         /* Analyze the value */
1986         switch ((x / y))
1987         {
1988                 case 0:
1989                 case 1:
1990                 {
1991                         likert_color = TERM_RED;
1992 #ifdef JP
1993 return ("°­¤¤");
1994 #else
1995                         return ("Bad");
1996 #endif
1997
1998                 }
1999                 case 2:
2000                 {
2001                         likert_color = TERM_L_RED;
2002 #ifdef JP
2003 return ("Îô¤ë");
2004 #else
2005                         return ("Poor");
2006 #endif
2007
2008                 }
2009                 case 3:
2010                 case 4:
2011                 {
2012                         likert_color = TERM_ORANGE;
2013 #ifdef JP
2014 return ("ÉáÄÌ");
2015 #else
2016                         return ("Fair");
2017 #endif
2018
2019                 }
2020                 case 5:
2021                 {
2022                         likert_color = TERM_YELLOW;
2023 #ifdef JP
2024 return ("Îɤ¤");
2025 #else
2026                         return ("Good");
2027 #endif
2028
2029                 }
2030                 case 6:
2031                 {
2032                         likert_color = TERM_YELLOW;
2033 #ifdef JP
2034 return ("ÂçÊÑÎɤ¤");
2035 #else
2036                         return ("Very Good");
2037 #endif
2038
2039                 }
2040                 case 7:
2041                 case 8:
2042                 {
2043                         likert_color = TERM_L_GREEN;
2044 #ifdef JP
2045 return ("Âî±Û");
2046 #else
2047                         return ("Excellent");
2048 #endif
2049
2050                 }
2051                 case 9:
2052                 case 10:
2053                 case 11:
2054                 case 12:
2055                 case 13:
2056                 {
2057                         likert_color = TERM_GREEN;
2058 #ifdef JP
2059 return ("Ķ±Û");
2060 #else
2061                         return ("Superb");
2062 #endif
2063
2064                 }
2065                 case 14:
2066                 case 15:
2067                 case 16:
2068                 case 17:
2069                 {
2070                         likert_color = TERM_BLUE;
2071 #ifdef JP
2072 return ("¥«¥ª¥¹¥é¥ó¥¯");
2073 #else
2074                         return ("Chaos Rank");
2075 #endif
2076
2077                 }
2078                 default:
2079                 {
2080                         likert_color = TERM_VIOLET;
2081 #ifdef JP
2082 sprintf(dummy,"¥¢¥ó¥Ð¡¼ [%d]", (int) ((((x/y)-17)*5)/2));
2083 #else
2084                         sprintf(dummy,"Amber [%d]", (int) ((((x/y)-17)*5)/2));
2085 #endif
2086
2087                         return dummy;
2088                 }
2089         }
2090 }
2091
2092
2093 /*
2094  * Prints ratings on certain abilities
2095  *
2096  * This code is "imitated" elsewhere to "dump" a character sheet.
2097  */
2098 static void display_player_various(void)
2099 {
2100         int         tmp, damage[2], blows1, blows2, i, basedam;
2101         int                     xthn, xthb, xfos, xsrh;
2102         int                     xdis, xdev, xsav, xstl;
2103         cptr            desc;
2104         int         muta_att = 0;
2105         u32b        f1, f2, f3;
2106         int             shots, shot_frac;
2107
2108         object_type             *o_ptr;
2109
2110         if (p_ptr->muta2 & MUT2_HORNS)     muta_att++;
2111         if (p_ptr->muta2 & MUT2_SCOR_TAIL) muta_att++;
2112         if (p_ptr->muta2 & MUT2_BEAK)      muta_att++;
2113         if (p_ptr->muta2 & MUT2_TRUNK)     muta_att++;
2114         if (p_ptr->muta2 & MUT2_TENTACLES) muta_att++;
2115
2116         xthn = p_ptr->skill_thn + (p_ptr->to_h_m * BTH_PLUS_ADJ);
2117
2118         /* Shooting Skill (with current bow and normal missile) */
2119         o_ptr = &inventory[INVEN_BOW];
2120         tmp = p_ptr->to_h_b + o_ptr->to_h;
2121         xthb = p_ptr->skill_thb + (tmp * BTH_PLUS_ADJ);
2122
2123         /* If the player is wielding one? */
2124         if (o_ptr->k_idx)
2125         {
2126                 s16b energy_fire = bow_energy(o_ptr->sval);
2127
2128                 /* Calculate shots per round */
2129                 shots = p_ptr->num_fire * 100;
2130                 shot_frac = (shots * 100 / energy_fire) % 100;
2131                 shots = shots / energy_fire;
2132                 if (o_ptr->name1 == ART_CRIMSON)
2133                 {
2134                         shots = 1;
2135                         shot_frac = 0;
2136                         if (p_ptr->pclass == CLASS_ARCHER)
2137                         {
2138                                 /* Extra shot at level 10 */
2139                                 if (p_ptr->lev >= 10) shots++;
2140
2141                                 /* Extra shot at level 30 */
2142                                 if (p_ptr->lev >= 30) shots++;
2143
2144                                 /* Extra shot at level 45 */
2145                                 if (p_ptr->lev >= 45) shots++;
2146                         }
2147                 }
2148         }
2149         else
2150         {
2151                 shots = 0;
2152                 shot_frac = 0;
2153         }
2154
2155         for(i = 0; i< 2; i++)
2156         {
2157                 damage[i] = p_ptr->dis_to_d[i]*100;
2158                 if (((p_ptr->pclass == CLASS_MONK) || (p_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(TRUE) > 1))
2159                 {
2160                         int level = p_ptr->lev;
2161                         if (i)
2162                         {
2163                                 damage[i] = 0;
2164                                 break;
2165                         }
2166                         if (p_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
2167                         if (p_ptr->special_defense & KAMAE_BYAKKO)
2168                                 basedam = monk_ave_damage[level][1];
2169                         else if (p_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
2170                                 basedam = monk_ave_damage[level][2];
2171                         else
2172                                 basedam = monk_ave_damage[level][0];
2173                 }
2174                 else
2175                 {
2176                         /* Average damage per round */
2177                         o_ptr = &inventory[INVEN_RARM+i];
2178                         if (object_known_p(o_ptr)) damage[i] += o_ptr->to_d*100;
2179                         basedam = (o_ptr->dd * (o_ptr->ds + 1))*50;
2180                         object_flags(o_ptr, &f1, &f2, &f3);
2181                         if ((o_ptr->ident & IDENT_MENTAL) && (o_ptr->name1 == ART_VORPAL_BLADE))
2182                         {
2183                                 /* vorpal blade */
2184                                 basedam *= 5;
2185                                 basedam /= 3;
2186                         }
2187                         else if (object_known_p(o_ptr) && (f1 & TR1_VORPAL))
2188                         {
2189                                 /* vorpal flag only */
2190                                 basedam *= 11;
2191                                 basedam /= 9;
2192                         }
2193                         if (object_known_p(o_ptr) && (p_ptr->pclass != CLASS_SAMURAI) && (f1 & TR1_FORCE_WEPON) && (p_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
2194                                 basedam = basedam * 7 / 2;
2195                         if (p_ptr->riding && (o_ptr->tval == TV_POLEARM) && ((o_ptr->sval == SV_LANCE) || (o_ptr->sval == SV_HEAVY_LANCE)))
2196                                 basedam = basedam*(o_ptr->dd+2)/o_ptr->dd;
2197                 }
2198                 damage[i] += basedam;
2199                 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DOKUBARI)) damage[i] = 1;
2200                 if (damage[i] < 0) damage[i] = 0;
2201         }
2202         blows1 = p_ptr->migite ? p_ptr->num_blow[0]: 0;
2203         blows2 = p_ptr->hidarite ? p_ptr->num_blow[1] : 0;
2204
2205         /* Basic abilities */
2206
2207         xdis = p_ptr->skill_dis;
2208         xdev = p_ptr->skill_dev;
2209         xsav = p_ptr->skill_sav;
2210         xstl = p_ptr->skill_stl;
2211         xsrh = p_ptr->skill_srh;
2212         xfos = p_ptr->skill_fos;
2213
2214
2215         desc = likert(xthn, 12);
2216         display_player_one_line(ENTRY_SKILL_FIGHT, desc, likert_color);
2217
2218         desc = likert(xthb, 12);
2219         display_player_one_line(ENTRY_SKILL_SHOOT, desc, likert_color);
2220
2221         desc = likert(xsav, 7);
2222         display_player_one_line(ENTRY_SKILL_SAVING, desc, likert_color);
2223
2224         desc = likert(xstl, 1);
2225         display_player_one_line(ENTRY_SKILL_STEALTH, desc, likert_color);
2226
2227         desc = likert(xfos, 6);
2228         display_player_one_line(ENTRY_SKILL_PERCEP, desc, likert_color);
2229
2230         desc = likert(xsrh, 6);
2231         display_player_one_line(ENTRY_SKILL_SEARCH, desc, likert_color);
2232
2233         desc = likert(xdis, 8);
2234         display_player_one_line(ENTRY_SKILL_DISARM, desc, likert_color);
2235
2236         desc = likert(xdev, 6);
2237         display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);
2238
2239         if (!muta_att)
2240                 display_player_one_line(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
2241         else
2242                 display_player_one_line(ENTRY_BLOWS, format("%d+%d+%d", blows1, blows2, muta_att), TERM_L_BLUE);
2243
2244         display_player_one_line(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);
2245
2246
2247         if ((damage[0]+damage[1]) == 0)
2248                 desc = "nil!";
2249         else
2250                 desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
2251
2252         display_player_one_line(ENTRY_AVG_DMG, desc, TERM_L_BLUE);
2253
2254         display_player_one_line(ENTRY_INFRA, format("%d feet", p_ptr->see_infra * 10), TERM_WHITE);
2255 }
2256
2257
2258
2259 /*
2260  * Obtain the "flags" for the player as if he was an item
2261  */
2262 static void player_flags(u32b *f1, u32b *f2, u32b *f3)
2263 {
2264         /* Clear */
2265         (*f1) = (*f2) = (*f3) = 0L;
2266
2267         /* Classes */
2268         switch (p_ptr->pclass)
2269         {
2270         case CLASS_WARRIOR:
2271                 if (p_ptr->lev > 44)
2272                         (*f3) |= (TR3_REGEN);
2273         case CLASS_SAMURAI:
2274                 if (p_ptr->lev > 29)
2275                         (*f2) |= (TR2_RES_FEAR);
2276                 break;
2277         case CLASS_PALADIN:
2278                 if (p_ptr->lev > 39)
2279                         (*f2) |= (TR2_RES_FEAR);
2280                 break;
2281         case CLASS_CHAOS_WARRIOR:
2282                 if (p_ptr->lev > 29)
2283                         (*f2) |= (TR2_RES_CHAOS);
2284                 if (p_ptr->lev > 39)
2285                         (*f2) |= (TR2_RES_FEAR);
2286                 break;
2287         case CLASS_MONK:
2288         case CLASS_FORCETRAINER:
2289                 if ((p_ptr->lev > 9) && !heavy_armor())
2290                         (*f1) |= TR1_SPEED;
2291                 if ((p_ptr->lev>24) && !heavy_armor())
2292                         (*f2) |= (TR2_FREE_ACT);
2293                 break;
2294         case CLASS_NINJA:
2295                 if (heavy_armor())
2296                         (*f1) |= TR1_SPEED;
2297                 else
2298                 {
2299                         if (!inventory[INVEN_LARM].tval || p_ptr->hidarite)
2300                                 (*f1) |= TR1_SPEED;
2301                         if (p_ptr->lev>24)
2302                                 (*f2) |= (TR2_FREE_ACT);
2303                 }
2304                 (*f3) |= TR3_SLOW_DIGEST;
2305                 (*f2) |= TR2_RES_FEAR;
2306                 if (p_ptr->lev > 19) (*f2) |= TR2_RES_POIS;
2307                 if (p_ptr->lev > 24) (*f2) |= TR2_SUST_DEX;
2308                 if (p_ptr->lev > 29) (*f3) |= TR3_SEE_INVIS;
2309                 break;
2310         case CLASS_MINDCRAFTER:
2311                 if (p_ptr->lev > 9)
2312                         (*f2) |= (TR2_RES_FEAR);
2313                 if (p_ptr->lev > 19)
2314                         (*f2) |= (TR2_SUST_WIS);
2315                 if (p_ptr->lev > 29)
2316                         (*f2) |= (TR2_RES_CONF);
2317                 if (p_ptr->lev > 39)
2318                         (*f3) |= (TR3_TELEPATHY);
2319                 break;
2320         case CLASS_BARD:
2321                 (*f2) |= (TR2_RES_SOUND);
2322                 break;
2323         case CLASS_BERSERKER:
2324                 (*f2) |= (TR2_SUST_STR);
2325                 (*f2) |= (TR2_SUST_DEX);
2326                 (*f2) |= (TR2_SUST_CON);
2327                 (*f3) |= (TR3_REGEN);
2328                 (*f2) |= (TR2_FREE_ACT);
2329                 (*f1) |= (TR1_SPEED);
2330                 if (p_ptr->lev > 39) (*f2) |= (TR2_REFLECT);
2331                 break;
2332         case CLASS_MIRROR_MASTER:
2333                 if(p_ptr->lev > 39)(*f2) |= (TR2_REFLECT);
2334                 break;
2335         default:
2336                 break; /* Do nothing */
2337         }
2338
2339         /* Races */
2340         if (p_ptr->mimic_form)
2341         {
2342                 switch(p_ptr->mimic_form)
2343                 {
2344                 case MIMIC_DEMON:
2345                         (*f2) |= (TR2_HOLD_LIFE);
2346                         (*f2) |= (TR2_RES_CHAOS);
2347                         (*f2) |= (TR2_RES_NETHER);
2348                         (*f2) |= (TR2_RES_FIRE);
2349                         (*f3) |= (TR3_SEE_INVIS);
2350                         (*f1) |= (TR1_SPEED);
2351                         break;
2352                 case MIMIC_DEMON_LORD:
2353                         (*f2) |= (TR2_HOLD_LIFE);
2354                         (*f2) |= (TR2_RES_CHAOS);
2355                         (*f2) |= (TR2_RES_NETHER);
2356                         (*f2) |= (TR2_RES_FIRE);
2357                         (*f2) |= (TR2_RES_COLD);
2358                         (*f2) |= (TR2_RES_ELEC);
2359                         (*f2) |= (TR2_RES_ACID);
2360                         (*f2) |= (TR2_RES_POIS);
2361                         (*f2) |= (TR2_RES_CONF);
2362                         (*f2) |= (TR2_RES_DISEN);
2363                         (*f2) |= (TR2_RES_NEXUS);
2364                         (*f2) |= (TR2_RES_FEAR);
2365                         (*f2) |= (TR2_IM_FIRE);
2366                         (*f3) |= (TR3_SH_FIRE);
2367                         (*f3) |= (TR3_SEE_INVIS);
2368                         (*f3) |= (TR3_TELEPATHY);
2369                         (*f3) |= (TR3_FEATHER);
2370                         (*f1) |= (TR1_SPEED);
2371                         break;
2372                 case MIMIC_VAMPIRE:
2373                         (*f2) |= (TR2_HOLD_LIFE);
2374                         (*f2) |= (TR2_RES_DARK);
2375                         (*f2) |= (TR2_RES_NETHER);
2376                         if (p_ptr->pclass != CLASS_NINJA) (*f3) |= (TR3_LITE);
2377                         (*f2) |= (TR2_RES_POIS);
2378                         (*f2) |= (TR2_RES_COLD);
2379                         (*f3) |= (TR3_SEE_INVIS);
2380                         (*f1) |= (TR1_SPEED);
2381                         break;
2382                 }
2383         }
2384         else
2385         {
2386         switch (p_ptr->prace)
2387         {
2388         case RACE_ELF:
2389                 (*f2) |= (TR2_RES_LITE);
2390                 break;
2391         case RACE_HOBBIT:
2392                 (*f2) |= (TR2_SUST_DEX);
2393                 break;
2394         case RACE_GNOME:
2395                 (*f2) |= (TR2_FREE_ACT);
2396                 break;
2397         case RACE_DWARF:
2398                 (*f2) |= (TR2_RES_BLIND);
2399                 break;
2400         case RACE_HALF_ORC:
2401                 (*f2) |= (TR2_RES_DARK);
2402                 break;
2403         case RACE_HALF_TROLL:
2404                 (*f2) |= (TR2_SUST_STR);
2405                 if (p_ptr->lev > 14)
2406                 {
2407                         (*f3) |= (TR3_REGEN);
2408                         if (p_ptr->pclass == CLASS_WARRIOR)
2409                         {
2410                                 (*f3) |= (TR3_SLOW_DIGEST);
2411                                 /*
2412                                  * Let's not make Regeneration a disadvantage
2413                                  * for the poor warriors who can never learn
2414                                  * a spell that satisfies hunger (actually
2415                                  * neither can rogues, but half-trolls are not
2416                                  * supposed to play rogues)
2417                                  */
2418                         }
2419                 }
2420                 break;
2421         case RACE_AMBERITE:
2422                 (*f2) |= (TR2_SUST_CON);
2423                 (*f3) |= (TR3_REGEN); /* Amberites heal fast */
2424                 break;
2425         case RACE_HIGH_ELF:
2426                 (*f2) |= (TR2_RES_LITE);
2427                 (*f3) |= (TR3_SEE_INVIS);
2428                 break;
2429         case RACE_BARBARIAN:
2430                 (*f2) |= (TR2_RES_FEAR);
2431                 break;
2432         case RACE_HALF_OGRE:
2433                 (*f2) |= (TR2_SUST_STR);
2434                 (*f2) |= (TR2_RES_DARK);
2435                 break;
2436         case RACE_HALF_GIANT:
2437                 (*f2) |= (TR2_RES_SHARDS);
2438                 (*f2) |= (TR2_SUST_STR);
2439                 break;
2440         case RACE_HALF_TITAN:
2441                 (*f2) |= (TR2_RES_CHAOS);
2442                 break;
2443         case RACE_CYCLOPS:
2444                 (*f2) |= (TR2_RES_SOUND);
2445                 break;
2446         case RACE_YEEK:
2447                 (*f2) |= (TR2_RES_ACID);
2448                 if (p_ptr->lev > 19)
2449                         (*f2) |= (TR2_IM_ACID);
2450                 break;
2451         case RACE_KLACKON:
2452                 (*f2) |= (TR2_RES_CONF);
2453                 (*f2) |= (TR2_RES_ACID);
2454                 if (p_ptr->lev > 9)
2455                         (*f1) |= TR1_SPEED;
2456                 break;
2457         case RACE_KOBOLD:
2458                 (*f2) |= (TR2_RES_POIS);
2459                 break;
2460         case RACE_NIBELUNG:
2461                 (*f2) |= (TR2_RES_DISEN);
2462                 (*f2) |= (TR2_RES_DARK);
2463                 break;
2464         case RACE_DARK_ELF:
2465                 (*f2) |= (TR2_RES_DARK);
2466                 if (p_ptr->lev > 19)
2467                         (*f3) |= (TR3_SEE_INVIS);
2468                 break;
2469         case RACE_DRACONIAN:
2470                 (*f3) |= TR3_FEATHER;
2471                 if (p_ptr->lev > 4)
2472                         (*f2) |= (TR2_RES_FIRE);
2473                 if (p_ptr->lev > 9)
2474                         (*f2) |= (TR2_RES_COLD);
2475                 if (p_ptr->lev > 14)
2476                         (*f2) |= (TR2_RES_ACID);
2477                 if (p_ptr->lev > 19)
2478                         (*f2) |= (TR2_RES_ELEC);
2479                 if (p_ptr->lev > 34)
2480                         (*f2) |= (TR2_RES_POIS);
2481                 break;
2482         case RACE_MIND_FLAYER:
2483                 (*f2) |= (TR2_SUST_INT);
2484                 (*f2) |= (TR2_SUST_WIS);
2485                 if (p_ptr->lev > 14)
2486                         (*f3) |= (TR3_SEE_INVIS);
2487                 if (p_ptr->lev > 29)
2488                         (*f3) |= (TR3_TELEPATHY);
2489                 break;
2490         case RACE_IMP:
2491                 (*f2) |= (TR2_RES_FIRE);
2492                 if (p_ptr->lev > 9)
2493                         (*f3) |= (TR3_SEE_INVIS);
2494                 break;
2495         case RACE_GOLEM:
2496                 (*f3) |= (TR3_SEE_INVIS);
2497                 (*f2) |= (TR2_FREE_ACT);
2498                 (*f2) |= (TR2_RES_POIS);
2499                 (*f3) |= (TR3_SLOW_DIGEST);
2500                 if (p_ptr->lev > 34)
2501                         (*f2) |= (TR2_HOLD_LIFE);
2502                 break;
2503         case RACE_SKELETON:
2504                 (*f3) |= (TR3_SEE_INVIS);
2505                 (*f2) |= (TR2_RES_SHARDS);
2506                 (*f2) |= (TR2_HOLD_LIFE);
2507                 (*f2) |= (TR2_RES_POIS);
2508                 if (p_ptr->lev > 9)
2509                         (*f2) |= (TR2_RES_COLD);
2510                 break;
2511         case RACE_ZOMBIE:
2512                 (*f3) |= (TR3_SEE_INVIS);
2513                 (*f2) |= (TR2_HOLD_LIFE);
2514                 (*f2) |= (TR2_RES_NETHER);
2515                 (*f2) |= (TR2_RES_POIS);
2516                 (*f3) |= (TR3_SLOW_DIGEST);
2517                 if (p_ptr->lev > 4)
2518                         (*f2) |= (TR2_RES_COLD);
2519                 break;
2520         case RACE_VAMPIRE:
2521                 (*f2) |= (TR2_HOLD_LIFE);
2522                 (*f2) |= (TR2_RES_DARK);
2523                 (*f2) |= (TR2_RES_NETHER);
2524                 if (p_ptr->pclass != CLASS_NINJA) (*f3) |= (TR3_LITE);
2525                 (*f2) |= (TR2_RES_POIS);
2526                 (*f2) |= (TR2_RES_COLD);
2527                 break;
2528         case RACE_SPECTRE:
2529                 (*f3) |= (TR3_FEATHER);
2530                 (*f2) |= (TR2_FREE_ACT);
2531                 (*f2) |= (TR2_RES_COLD);
2532                 (*f3) |= (TR3_SEE_INVIS);
2533                 (*f2) |= (TR2_HOLD_LIFE);
2534                 (*f2) |= (TR2_RES_NETHER);
2535                 (*f2) |= (TR2_RES_POIS);
2536                 (*f3) |= (TR3_SLOW_DIGEST);
2537                 /* XXX pass_wall */
2538                 if (p_ptr->lev > 34)
2539                         (*f3) |= TR3_TELEPATHY;
2540                 break;
2541         case RACE_SPRITE:
2542                 (*f2) |= (TR2_RES_LITE);
2543                 (*f3) |= (TR3_FEATHER);
2544                 if (p_ptr->lev > 9)
2545                         (*f1) |= (TR1_SPEED);
2546                 break;
2547         case RACE_BEASTMAN:
2548                 (*f2) |= (TR2_RES_SOUND);
2549                 (*f2) |= (TR2_RES_CONF);
2550                 break;
2551         case RACE_ANGEL:
2552                 (*f3) |= (TR3_FEATHER);
2553                 (*f3) |= (TR3_SEE_INVIS);
2554                 break;
2555         case RACE_DEMON:
2556                 (*f2) |= (TR2_RES_FIRE);
2557                 (*f2) |= (TR2_RES_NETHER);
2558                 (*f2) |= (TR2_HOLD_LIFE);
2559                 if (p_ptr->lev > 9)
2560                         (*f3) |= (TR3_SEE_INVIS);
2561                 break;
2562         case RACE_DUNADAN:
2563                 (*f2) |= (TR2_SUST_CON);
2564                 break;
2565         case RACE_S_FAIRY:
2566                 (*f3) |= (TR3_FEATHER);
2567                 break;
2568         case RACE_KUTA:
2569                 (*f2) |= (TR2_RES_CONF);
2570                 break;
2571         case RACE_ANDROID:
2572                 (*f2) |= (TR2_FREE_ACT);
2573                 (*f2) |= (TR2_RES_POIS);
2574                 (*f3) |= (TR3_SLOW_DIGEST);
2575                 (*f2) |= (TR2_HOLD_LIFE);
2576                 break;
2577         default:
2578                 ; /* Do nothing */
2579         }
2580         }
2581
2582         /* Mutations */
2583         if (p_ptr->muta3)
2584         {
2585                 if (p_ptr->muta3 & MUT3_FLESH_ROT)
2586                 {
2587                         (*f3) &= ~(TR3_REGEN);
2588                 }
2589
2590                 if ((p_ptr->muta3 & MUT3_XTRA_FAT) ||
2591                         (p_ptr->muta3 & MUT3_XTRA_LEGS) ||
2592                         (p_ptr->muta3 & MUT3_SHORT_LEG))
2593                 {
2594                         (*f1) |= TR1_SPEED;
2595                 }
2596
2597                 if (p_ptr->muta3  & MUT3_ELEC_TOUC)
2598                 {
2599                         (*f3) |= TR3_SH_ELEC;
2600                 }
2601
2602                 if (p_ptr->muta3 & MUT3_FIRE_BODY)
2603                 {
2604                         (*f3) |= TR3_SH_FIRE;
2605                         (*f3) |= TR3_LITE;
2606                 }
2607
2608                 if (p_ptr->muta3 & MUT3_WINGS)
2609                 {
2610                         (*f3) |= TR3_FEATHER;
2611                 }
2612
2613                 if (p_ptr->muta3 & MUT3_FEARLESS)
2614                 {
2615                         (*f2) |= (TR2_RES_FEAR);
2616                 }
2617
2618                 if (p_ptr->muta3 & MUT3_REGEN)
2619                 {
2620                         (*f3) |= TR3_REGEN;
2621                 }
2622
2623                 if (p_ptr->muta3 & MUT3_ESP)
2624                 {
2625                         (*f3) |= TR3_TELEPATHY;
2626                 }
2627
2628                 if (p_ptr->muta3 & MUT3_MOTION)
2629                 {
2630                         (*f2) |= TR2_FREE_ACT;
2631                 }
2632         }
2633
2634         if (p_ptr->pseikaku == SEIKAKU_SEXY)
2635                 (*f3) |= TR3_AGGRAVATE;
2636         if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN)
2637         {
2638                 (*f2) |= (TR2_RES_BLIND);
2639                 (*f2) |= (TR2_RES_CONF);
2640                 (*f2) |= (TR2_HOLD_LIFE);
2641                 (*f3) |= (TR3_LITE);
2642                 if (p_ptr->lev > 9)
2643                         (*f1) |= (TR1_SPEED);
2644         }
2645         if (p_ptr->special_defense & KATA_FUUJIN)
2646                 (*f2) |= TR2_REFLECT;
2647         if (p_ptr->special_defense & KAMAE_GENBU)
2648                 (*f2) |= TR2_REFLECT;
2649         if (p_ptr->special_defense & KAMAE_SUZAKU)
2650                 (*f3) |= TR3_FEATHER;
2651         if (p_ptr->special_defense & KAMAE_SEIRYU)
2652         {
2653                 (*f2) |= (TR2_RES_FIRE);
2654                 (*f2) |= (TR2_RES_COLD);
2655                 (*f2) |= (TR2_RES_ACID);
2656                 (*f2) |= (TR2_RES_ELEC);
2657                 (*f2) |= (TR2_RES_POIS);
2658                 (*f3) |= (TR3_FEATHER);
2659                 (*f3) |= (TR3_SH_FIRE);
2660                 (*f3) |= (TR3_SH_ELEC);
2661                 (*f3) |= (TR3_SH_COLD);
2662         }
2663         if (p_ptr->special_defense & KATA_MUSOU)
2664         {
2665                 (*f2) |= TR2_RES_FEAR;
2666                 (*f2) |= TR2_RES_LITE;
2667                 (*f2) |= TR2_RES_DARK;
2668                 (*f2) |= TR2_RES_BLIND;
2669                 (*f2) |= TR2_RES_CONF;
2670                 (*f2) |= TR2_RES_SOUND;
2671                 (*f2) |= TR2_RES_SHARDS;
2672                 (*f2) |= TR2_RES_NETHER;
2673                 (*f2) |= TR2_RES_NEXUS;
2674                 (*f2) |= TR2_RES_CHAOS;
2675                 (*f2) |= TR2_RES_DISEN;
2676                 (*f2) |= TR2_REFLECT;
2677                 (*f2) |= TR2_HOLD_LIFE;
2678                 (*f2) |= TR2_FREE_ACT;
2679                 (*f3) |= TR3_SH_FIRE;
2680                 (*f3) |= TR3_SH_ELEC;
2681                 (*f3) |= TR3_SH_COLD;
2682                 (*f3) |= TR3_FEATHER;
2683                 (*f3) |= TR3_LITE;
2684                 (*f3) |= TR3_SEE_INVIS;
2685                 (*f3) |= TR3_TELEPATHY;
2686                 (*f3) |= TR3_SLOW_DIGEST;
2687                 (*f3) |= TR3_REGEN;
2688                 (*f2) |= (TR2_SUST_STR);
2689                 (*f2) |= (TR2_SUST_INT);
2690                 (*f2) |= (TR2_SUST_WIS);
2691                 (*f2) |= (TR2_SUST_DEX);
2692                 (*f2) |= (TR2_SUST_CON);
2693                 (*f2) |= (TR2_SUST_CHR);
2694         }
2695 }
2696
2697
2698 static void tim_player_flags(u32b *f1, u32b *f2, u32b *f3, bool im_and_res)
2699 {
2700         /* Clear */
2701         (*f1) = (*f2) = (*f3) = 0L;
2702
2703         if (p_ptr->hero || p_ptr->shero || music_singing(MUSIC_HERO) || music_singing(MUSIC_SHERO))
2704                 (*f2) |= TR2_RES_FEAR;
2705         if (p_ptr->tim_invis)
2706                 (*f3) |= TR3_SEE_INVIS;
2707         if (p_ptr->tim_regen)
2708                 (*f3) |= TR3_REGEN;
2709         if (p_ptr->tim_esp || music_singing(MUSIC_MIND))
2710                 (*f3) |= TR3_TELEPATHY;
2711         if (p_ptr->fast || p_ptr->slow || music_singing(MUSIC_SPEED) || music_singing(MUSIC_SHERO))
2712                 (*f1) |= TR1_SPEED;
2713         if  ((p_ptr->special_defense & KATA_MUSOU) || music_singing(MUSIC_RESIST))
2714         {
2715                 (*f2) |= (TR2_RES_FIRE);
2716                 (*f2) |= (TR2_RES_COLD);
2717                 (*f2) |= (TR2_RES_ACID);
2718                 (*f2) |= (TR2_RES_ELEC);
2719                 (*f2) |= (TR2_RES_POIS);
2720         }
2721         if (im_and_res)
2722         {
2723                 if (p_ptr->oppose_acid && !(p_ptr->special_defense & DEFENSE_ACID) && !((prace_is_(RACE_YEEK)) && (p_ptr->lev > 19)))
2724                         (*f2) |= TR2_RES_ACID;
2725                 if (p_ptr->oppose_elec && !(p_ptr->special_defense & DEFENSE_ELEC))
2726                         (*f2) |= TR2_RES_ELEC;
2727                 if (p_ptr->oppose_fire && !(p_ptr->special_defense & DEFENSE_FIRE))
2728                         (*f2) |= TR2_RES_FIRE;
2729                 if (p_ptr->oppose_cold && !(p_ptr->special_defense & DEFENSE_COLD))
2730                         (*f2) |= TR2_RES_COLD;
2731         }
2732         else
2733         {
2734                 if (p_ptr->oppose_acid)
2735                         (*f2) |= TR2_RES_ACID;
2736                 if (p_ptr->oppose_elec)
2737                         (*f2) |= TR2_RES_ELEC;
2738                 if (p_ptr->oppose_fire)
2739                         (*f2) |= TR2_RES_FIRE;
2740                 if (p_ptr->oppose_cold)
2741                         (*f2) |= TR2_RES_COLD;
2742         }
2743         if (p_ptr->oppose_pois)
2744                 (*f2) |= TR2_RES_POIS;
2745         if (p_ptr->special_attack & ATTACK_ACID)
2746                 (*f1) |= TR1_BRAND_ACID;
2747         if (p_ptr->special_attack & ATTACK_ELEC)
2748                 (*f1) |= TR1_BRAND_ELEC;
2749         if (p_ptr->special_attack & ATTACK_FIRE)
2750                 (*f1) |= TR1_BRAND_FIRE;
2751         if (p_ptr->special_attack & ATTACK_COLD)
2752                 (*f1) |= TR1_BRAND_COLD;
2753         if (p_ptr->special_attack & ATTACK_POIS)
2754                 (*f1) |= TR1_BRAND_POIS;
2755         if (p_ptr->special_defense & DEFENSE_ACID)
2756                 (*f2) |= TR2_IM_ACID;
2757         if (p_ptr->special_defense & DEFENSE_ELEC)
2758                 (*f2) |= TR2_IM_ELEC;
2759         if (p_ptr->special_defense & DEFENSE_FIRE)
2760                 (*f2) |= TR2_IM_FIRE;
2761         if (p_ptr->special_defense & DEFENSE_COLD)
2762                 (*f2) |= TR2_IM_COLD;
2763         if (p_ptr->wraith_form)
2764                 (*f2) |= TR2_REFLECT;
2765         /* by henkma */
2766         if (p_ptr->tim_reflect){
2767                 (*f2) |= TR2_REFLECT;
2768         }
2769
2770         if (p_ptr->magicdef)
2771         {
2772                 (*f2) |= TR2_RES_BLIND;
2773                 (*f2) |= TR2_RES_CONF;
2774                 (*f2) |= TR2_REFLECT;
2775                 (*f2) |= TR2_FREE_ACT;
2776                 (*f3) |= TR3_FEATHER;
2777         }
2778         if (p_ptr->tim_res_nether)
2779         {
2780                 (*f2) |= TR2_RES_NETHER;
2781         }
2782         if (p_ptr->tim_sh_fire)
2783         {
2784                 (*f3) |= TR3_SH_FIRE;
2785         }
2786         if (p_ptr->ult_res)
2787         {
2788                 (*f2) |= TR2_RES_FEAR;
2789                 (*f2) |= TR2_RES_LITE;
2790                 (*f2) |= TR2_RES_DARK;
2791                 (*f2) |= TR2_RES_BLIND;
2792                 (*f2) |= TR2_RES_CONF;
2793                 (*f2) |= TR2_RES_SOUND;
2794                 (*f2) |= TR2_RES_SHARDS;
2795                 (*f2) |= TR2_RES_NETHER;
2796                 (*f2) |= TR2_RES_NEXUS;
2797                 (*f2) |= TR2_RES_CHAOS;
2798                 (*f2) |= TR2_RES_DISEN;
2799                 (*f2) |= TR2_REFLECT;
2800                 (*f2) |= TR2_HOLD_LIFE;
2801                 (*f2) |= TR2_FREE_ACT;
2802                 (*f3) |= TR3_SH_FIRE;
2803                 (*f3) |= TR3_SH_ELEC;
2804                 (*f3) |= TR3_SH_COLD;
2805                 (*f3) |= TR3_FEATHER;
2806                 (*f3) |= TR3_LITE;
2807                 (*f3) |= TR3_SEE_INVIS;
2808                 (*f3) |= TR3_TELEPATHY;
2809                 (*f3) |= TR3_SLOW_DIGEST;
2810                 (*f3) |= TR3_REGEN;
2811                 (*f2) |= (TR2_SUST_STR);
2812                 (*f2) |= (TR2_SUST_INT);
2813                 (*f2) |= (TR2_SUST_WIS);
2814                 (*f2) |= (TR2_SUST_DEX);
2815                 (*f2) |= (TR2_SUST_CON);
2816                 (*f2) |= (TR2_SUST_CHR);
2817         }
2818 }
2819
2820
2821 /*
2822  * Equippy chars
2823  */
2824 static void display_player_equippy(int y, int x)
2825 {
2826         int i;
2827
2828         byte a;
2829         char c;
2830
2831         object_type *o_ptr;
2832
2833
2834         /* Dump equippy chars */
2835         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2836         {
2837                 /* Object */
2838                 o_ptr = &inventory[i];
2839
2840                 a = object_attr(o_ptr);
2841                 c = object_char(o_ptr);
2842
2843                 /* Clear the part of the screen */
2844                 if (!equippy_chars || !o_ptr->k_idx)
2845                 {
2846                         c = ' ';
2847                         a = TERM_DARK;
2848                 }
2849
2850                 /* Dump */
2851                 Term_putch(x + i - INVEN_RARM, y, a, c);
2852         }
2853 }
2854
2855
2856 void print_equippy(void)
2857 {
2858         display_player_equippy(ROW_EQUIPPY, COL_EQUIPPY);
2859 }
2860
2861 /*
2862  *
2863  */
2864
2865 static void known_obj_immunity(u32b *f1, u32b *f2, u32b *f3)
2866 {
2867         int i;
2868
2869         /* Clear */
2870         (*f1) = (*f2) = (*f3) = 0L;
2871
2872         /* Check equipment */
2873         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2874         {
2875                 u32b    o_f1, o_f2, o_f3;
2876
2877                 object_type *o_ptr;
2878
2879                 /* Object */
2880                 o_ptr = &inventory[i];
2881
2882                 if (!o_ptr->k_idx) continue;
2883
2884                 /* Known flags */
2885                 object_flags_known(o_ptr, &o_f1, &o_f2, &o_f3);
2886
2887                 if (o_f2 & TR2_IM_ACID) (*f2) |= TR2_RES_ACID;
2888                 if (o_f2 & TR2_IM_ELEC) (*f2) |= TR2_RES_ELEC;
2889                 if (o_f2 & TR2_IM_FIRE) (*f2) |= TR2_RES_FIRE;
2890                 if (o_f2 & TR2_IM_COLD) (*f2) |= TR2_RES_COLD;
2891         }
2892 }
2893
2894 static void player_immunity(u32b *f1, u32b *f2, u32b *f3)
2895 {
2896         /* Clear */
2897         (*f1) = (*f2) = (*f3) = 0L;
2898
2899         if (prace_is_(RACE_SPECTRE))
2900                 (*f2) |= TR2_RES_NETHER;
2901         if (p_ptr->mimic_form == MIMIC_VAMPIRE || prace_is_(RACE_VAMPIRE))
2902                 (*f2) |= TR2_RES_DARK;
2903         if (p_ptr->mimic_form == MIMIC_DEMON_LORD)
2904                 (*f2) |= TR2_RES_FIRE;
2905         else if (prace_is_(RACE_YEEK) && p_ptr->lev > 19)
2906                 (*f2) |= TR2_RES_ACID;
2907 }
2908
2909 static void tim_player_immunity(u32b *f1, u32b *f2, u32b *f3)
2910 {
2911         /* Clear */
2912         (*f1) = (*f2) = (*f3) = 0L;
2913
2914         if (p_ptr->special_defense & DEFENSE_ACID)
2915                 (*f2) |= TR2_RES_ACID;
2916         if (p_ptr->special_defense & DEFENSE_ELEC)
2917                 (*f2) |= TR2_RES_ELEC;
2918         if (p_ptr->special_defense & DEFENSE_FIRE)
2919                 (*f2) |= TR2_RES_FIRE;
2920         if (p_ptr->special_defense & DEFENSE_COLD)
2921                 (*f2) |= TR2_RES_COLD;
2922         if (p_ptr->wraith_form)
2923                 (*f2) |= TR2_RES_DARK;
2924 }
2925
2926 static void player_vuln_flags(u32b *f1, u32b *f2, u32b *f3)
2927 {
2928         /* Clear */
2929         (*f1) = (*f2) = (*f3) = 0L;
2930
2931         if ((p_ptr->muta3 & MUT3_VULN_ELEM) || (p_ptr->special_defense & KATA_KOUKIJIN))
2932         {
2933                 (*f2) |= TR2_RES_ACID;
2934                 (*f2) |= TR2_RES_ELEC;
2935                 (*f2) |= TR2_RES_FIRE;
2936                 (*f2) |= TR2_RES_COLD;
2937         }
2938         if (prace_is_(RACE_ANDROID))
2939                 (*f2) |= TR2_RES_ELEC;
2940         if (prace_is_(RACE_ENT))
2941                 (*f2) |= TR2_RES_FIRE;
2942         if (prace_is_(RACE_VAMPIRE) || prace_is_(RACE_S_FAIRY) ||
2943             (p_ptr->mimic_form == MIMIC_VAMPIRE))
2944                 (*f2) |= TR2_RES_LITE;
2945 }
2946
2947 /*
2948  * Helper function, see below
2949  */
2950 static void display_player_flag_aux(int row, int col, char *header,
2951                                     int n, u32b flag1, u32b flag2,
2952                                     u32b im_f[], u32b vul_f)
2953 {
2954         int     i;
2955         u32b    f[3];
2956         bool    vuln = FALSE;
2957
2958         if ((vul_f & flag1) && !((im_f[0] | im_f[1] | im_f[2]) & flag1))
2959                 vuln = TRUE;
2960
2961         /* Header */
2962         c_put_str(TERM_WHITE, header, row, col);
2963
2964         /* Advance */
2965         col += strlen(header) + 1;
2966
2967         /* Check equipment */
2968         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2969         {
2970                 object_type *o_ptr;
2971                 f[0] = f[1] = f[2] = 0L;
2972
2973                 /* Object */
2974                 o_ptr = &inventory[i];
2975
2976                 /* Known flags */
2977                 object_flags_known(o_ptr, &f[0], &f[1], &f[2]);
2978
2979                 /* Default */
2980                 c_put_str((byte)(vuln ? TERM_RED : TERM_SLATE), ".", row, col);
2981
2982                 /* Check flags */
2983                 if (f[n - 1] & flag1) c_put_str((byte)(vuln ? TERM_L_RED : TERM_WHITE), "+", row, col);
2984                 if (f[n - 1] & flag2) c_put_str(TERM_WHITE, "*", row, col);
2985
2986                 /* Advance */
2987                 col++;
2988         }
2989
2990         /* Player flags */
2991         player_flags(&f[0], &f[1], &f[2]);
2992
2993         /* Default */
2994         c_put_str((byte)(vuln ? TERM_RED : TERM_SLATE), ".", row, col);
2995
2996         /* Check flags */
2997         if (f[n-1] & flag1) c_put_str((byte)(vuln ? TERM_L_RED : TERM_WHITE), "+", row, col);
2998
2999         /* Timed player flags */
3000         tim_player_flags(&f[0], &f[1], &f[2], TRUE);
3001
3002         /* Check flags */
3003         if (f[n-1] & flag1) c_put_str((byte)(vuln ? TERM_ORANGE : TERM_YELLOW), "#", row, col);
3004
3005         /* Immunity */
3006         if (im_f[2] & flag1) c_put_str(TERM_YELLOW, "*", row, col);
3007         if (im_f[1] & flag1) c_put_str(TERM_WHITE, "*", row, col);
3008
3009         /* Vulnerability */
3010         if (vuln) c_put_str(TERM_RED, "v", row, col + 1);
3011 }
3012
3013
3014 /*
3015  * Special display, part 1
3016  */
3017 static void display_player_flag_info(void)
3018 {
3019         int row;
3020         int col;
3021
3022         u32b im_f[3][3], vul_f[3];
3023
3024         known_obj_immunity(&im_f[0][0], &im_f[1][0], &im_f[2][0]);
3025         player_immunity(&im_f[0][1], &im_f[1][1], &im_f[2][1]);
3026         tim_player_immunity(&im_f[0][2], &im_f[1][2], &im_f[2][2]);
3027
3028         player_vuln_flags(&vul_f[0], &vul_f[1], &vul_f[2]);
3029
3030         /*** Set 1 ***/
3031
3032         row = 12;
3033         col = 1;
3034
3035         display_player_equippy(row-2, col+8);
3036         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
3037
3038 #ifdef JP
3039 display_player_flag_aux(row+0, col, "ÂÑ»À  :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
3040 display_player_flag_aux(row+1, col, "ÂÑÅÅ·â:", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
3041 display_player_flag_aux(row+2, col, "ÂѲбê:", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
3042 display_player_flag_aux(row+3, col, "ÂÑÎ䵤:", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
3043 display_player_flag_aux(row+4, col, "ÂÑÆÇ  :", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
3044 display_player_flag_aux(row+5, col, "ÂÑÁ®¸÷:", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
3045 display_player_flag_aux(row+6, col, "ÂѰŹõ:", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
3046 display_player_flag_aux(row+7, col, "ÂÑÇËÊÒ:", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
3047 display_player_flag_aux(row+8, col, "ÂÑÌÕÌÜ:", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
3048 display_player_flag_aux(row+9, col, "ÂѺ®Íð:", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
3049 #else
3050         display_player_flag_aux(row+0, col, "Acid  :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
3051         display_player_flag_aux(row+1, col, "Elec  :", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
3052         display_player_flag_aux(row+2, col, "Fire  :", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
3053         display_player_flag_aux(row+3, col, "Cold  :", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
3054         display_player_flag_aux(row+4, col, "Poison:", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
3055         display_player_flag_aux(row+5, col, "Light :", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
3056         display_player_flag_aux(row+6, col, "Dark  :", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
3057         display_player_flag_aux(row+7, col, "Shard :", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
3058         display_player_flag_aux(row+8, col, "Blind :", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
3059         display_player_flag_aux(row+9, col, "Conf  :", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
3060 #endif
3061
3062
3063         /*** Set 2 ***/
3064
3065         row = 12;
3066         col = 26;
3067
3068         display_player_equippy(row-2, col+8);
3069
3070         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
3071
3072 #ifdef JP
3073 display_player_flag_aux(row+0, col, "Âѹ첻:", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
3074 display_player_flag_aux(row+1, col, "ÂÑÃϹö:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
3075 display_player_flag_aux(row+2, col, "ÂÑ°øº®:", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
3076 display_player_flag_aux(row+3, col, "ÂÑ¥«¥ª:", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
3077 display_player_flag_aux(row+4, col, "ÂÑÎô²½:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
3078 display_player_flag_aux(row+5, col, "ÂѶ²ÉÝ:", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
3079 display_player_flag_aux(row+6, col, "È¿¼Í  :", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
3080 display_player_flag_aux(row+7, col, "²Ð±ê¥ª:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
3081 display_player_flag_aux(row+8, col, "Åŵ¤¥ª:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
3082 display_player_flag_aux(row+9, col, "Î䵤¥ª:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
3083 #else
3084         display_player_flag_aux(row+0, col, "Sound :", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
3085         display_player_flag_aux(row+1, col, "Nether:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
3086         display_player_flag_aux(row+2, col, "Nexus :", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
3087         display_player_flag_aux(row+3, col, "Chaos :", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
3088         display_player_flag_aux(row+4, col, "Disnch:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
3089         display_player_flag_aux(row+5, col, "Fear  :", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
3090         display_player_flag_aux(row+6, col, "Reflct:", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
3091         display_player_flag_aux(row+7, col, "AuFire:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
3092         display_player_flag_aux(row+8, col, "AuElec:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
3093         display_player_flag_aux(row+9, col, "AuCold:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
3094 #endif
3095
3096
3097         /*** Set 3 ***/
3098
3099         row = 12;
3100         col = 51;
3101
3102         display_player_equippy(row-2, col+12);
3103
3104         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+12);
3105
3106 #ifdef JP
3107 display_player_flag_aux(row+0, col, "²Ã®      :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
3108 display_player_flag_aux(row+1, col, "ÂÑËãáã    :", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
3109 display_player_flag_aux(row+2, col, "Æ©ÌÀÂλëǧ:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
3110 display_player_flag_aux(row+3, col, "·Ð¸³ÃÍÊÝ»ý:", 2, TR2_HOLD_LIFE, 0, im_f[2], vul_f[1]);
3111 display_player_flag_aux(row+4, col, "¥Æ¥ì¥Ñ¥·¡¼:", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
3112 display_player_flag_aux(row+5, col, "Ãپò½    :", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
3113 display_player_flag_aux(row+6, col, "µÞ²óÉü    :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
3114 display_player_flag_aux(row+7, col, "ÉâÍ·      :", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
3115 display_player_flag_aux(row+8, col, "±Ê±ó¸÷¸»  :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
3116 display_player_flag_aux(row+9, col, "¼ö¤¤      :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
3117 #else
3118         display_player_flag_aux(row+0, col, "Speed     :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
3119         display_player_flag_aux(row+1, col, "FreeAction:", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
3120         display_player_flag_aux(row+2, col, "SeeInvisi.:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
3121         display_player_flag_aux(row+3, col, "Hold Life :", 2, TR2_HOLD_LIFE, 0, im_f[1], vul_f[1]);
3122         display_player_flag_aux(row+4, col, "Telepathy :", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
3123         display_player_flag_aux(row+5, col, "SlowDigest:", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
3124         display_player_flag_aux(row+6, col, "Regene.   :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
3125         display_player_flag_aux(row+7, col, "Levitation:", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
3126         display_player_flag_aux(row+8, col, "Perm Lite :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
3127         display_player_flag_aux(row+9, col, "Cursed    :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
3128 #endif
3129
3130 }
3131
3132
3133 /*
3134  * Special display, part 2a
3135  */
3136 static void display_player_misc_info(void)
3137 {
3138         char    buf[80];
3139         char    tmp[80];
3140
3141         /* Display basics */
3142 #ifdef JP
3143 put_str("̾Á°  :", 1, 26);
3144 put_str("À­ÊÌ  :", 3, 1);
3145 put_str("¼ï²  :", 4, 1);
3146 put_str("¿¦¶È  :", 5, 1);
3147 #else
3148         put_str("Name  :", 1, 26);
3149         put_str("Sex   :", 3, 1);
3150         put_str("Race  :", 4, 1);
3151         put_str("Class :", 5, 1);
3152 #endif
3153
3154         strcpy(tmp,ap_ptr->title);
3155 #ifdef JP
3156         if(ap_ptr->no == 1)
3157                 strcat(tmp,"¤Î");
3158 #else
3159                 strcat(tmp," ");
3160 #endif
3161         strcat(tmp,player_name);
3162
3163         c_put_str(TERM_L_BLUE, tmp, 1, 34);
3164         c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
3165         c_put_str(TERM_L_BLUE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), 4, 9);
3166         c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 9);
3167
3168         /* Display extras */
3169 #ifdef JP
3170 put_str("¥ì¥Ù¥ë:", 6, 1);
3171 put_str("£È£Ð  :", 7, 1);
3172 put_str("£Í£Ð  :", 8, 1);
3173 #else
3174         put_str("Level :", 6, 1);
3175         put_str("Hits  :", 7, 1);
3176         put_str("Mana  :", 8, 1);
3177 #endif
3178
3179
3180         (void)sprintf(buf, "%d", (int)p_ptr->lev);
3181         c_put_str(TERM_L_BLUE, buf, 6, 9);
3182         (void)sprintf(buf, "%d/%d", (int)p_ptr->chp, (int)p_ptr->mhp);
3183         c_put_str(TERM_L_BLUE, buf, 7, 9);
3184         (void)sprintf(buf, "%d/%d", (int)p_ptr->csp, (int)p_ptr->msp);
3185         c_put_str(TERM_L_BLUE, buf, 8, 9);
3186 }
3187
3188
3189 /*
3190  * Special display, part 2b
3191  *
3192  * How to print out the modifications and sustains.
3193  * Positive mods with no sustain will be light green.
3194  * Positive mods with a sustain will be dark green.
3195  * Sustains (with no modification) will be a dark green 's'.
3196  * Negative mods (from a curse) will be red.
3197  * Huge mods (>9), like from MICoMorgoth, will be a '*'
3198  * No mod, no sustain, will be a slate '.'
3199  */
3200 static void display_player_stat_info(void)
3201 {
3202         int i, e_adj;
3203         int stat_col, stat;
3204         int row, col;
3205
3206         object_type *o_ptr;
3207         u32b f1, f2, f3;
3208         s16b k_idx;
3209
3210         byte a;
3211         char c;
3212
3213         char buf[80];
3214
3215
3216         /* Column */
3217         stat_col = 22;
3218
3219         /* Row */
3220         row = 3;
3221
3222         /* Print out the labels for the columns */
3223 #ifdef JP
3224 c_put_str(TERM_WHITE, "ǽÎÏ", row, stat_col+1);
3225 c_put_str(TERM_BLUE, "  ´ðËÜ", row, stat_col+7);
3226 c_put_str(TERM_L_BLUE, " ¼ï ¿¦ À­ Áõ ", row, stat_col+13);
3227 c_put_str(TERM_L_GREEN, "¹ç·×", row, stat_col+28);
3228 c_put_str(TERM_YELLOW, "¸½ºß", row, stat_col+33);
3229 #else
3230         c_put_str(TERM_WHITE, "Stat", row, stat_col+1);
3231         c_put_str(TERM_BLUE, "  Base", row, stat_col+7);
3232         c_put_str(TERM_L_BLUE, "RacClaPerMod", row, stat_col+13);
3233         c_put_str(TERM_L_GREEN, "Actual", row, stat_col+26);
3234         c_put_str(TERM_YELLOW, "Current", row, stat_col+32);
3235 #endif
3236
3237
3238         /* Display the stats */
3239         for (i = 0; i < 6; i++)
3240         {
3241                 int r_adj;
3242
3243                 if (p_ptr->mimic_form) r_adj = mimic_info[p_ptr->mimic_form].r_adj[i];
3244                 else r_adj = rp_ptr->r_adj[i];
3245
3246                 /* Calculate equipment adjustment */
3247                 e_adj = 0;
3248
3249                 /* Icky formula to deal with the 18 barrier */
3250                 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] > 18))
3251                         e_adj = (p_ptr->stat_top[i] - p_ptr->stat_max[i]) / 10;
3252                 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] <= 18))
3253                         e_adj = p_ptr->stat_top[i] - p_ptr->stat_max[i];
3254                 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] > 18))
3255                         e_adj = (p_ptr->stat_top[i] - 18) / 10 - p_ptr->stat_max[i] + 18;
3256
3257                 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] <= 18))
3258                         e_adj = p_ptr->stat_top[i] - (p_ptr->stat_max[i] - 19) / 10 - 19;
3259
3260                 if (prace_is_(RACE_ENT))
3261                 {
3262                         switch (i)
3263                         {
3264                                 case A_STR:
3265                                 case A_CON:
3266                                         if (p_ptr->lev > 25) r_adj++;
3267                                         if (p_ptr->lev > 40) r_adj++;
3268                                         if (p_ptr->lev > 45) r_adj++;
3269                                         break;
3270                                 case A_DEX:
3271                                         if (p_ptr->lev > 25) r_adj--;
3272                                         if (p_ptr->lev > 40) r_adj--;
3273                                         if (p_ptr->lev > 45) r_adj--;
3274                                         break;
3275                         }
3276                 }
3277
3278                 e_adj -= r_adj;
3279                 e_adj -= cp_ptr->c_adj[i];
3280                 e_adj -= ap_ptr->a_adj[i];
3281
3282                 /* Reduced name of stat */
3283 #ifdef JP
3284                 c_put_str(TERM_WHITE, stat_names[i], row + i+1, stat_col+1);
3285 #else
3286                 c_put_str(TERM_WHITE, stat_names_reduced[i], row + i+1, stat_col+1);
3287 #endif
3288
3289
3290                 /* Internal "natural" max value.  Maxes at 18/100 */
3291                 /* This is useful to see if you are maxed out */
3292                 cnv_stat(p_ptr->stat_max[i], buf);
3293                 if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
3294                 {
3295                         c_put_str(TERM_WHITE, "!", row + i+1, stat_col + 6);
3296                 }
3297                 c_put_str(TERM_BLUE, buf, row + i+1, stat_col + 13 - strlen(buf));
3298
3299                 /* Race, class, and equipment modifiers */
3300                 (void)sprintf(buf, "%3d", r_adj);
3301                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 13);
3302                 (void)sprintf(buf, "%3d", (int)cp_ptr->c_adj[i]);
3303                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 16);
3304                 (void)sprintf(buf, "%3d", (int)ap_ptr->a_adj[i]);
3305                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 19);
3306                 (void)sprintf(buf, "%3d", (int)e_adj);
3307                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 22);
3308
3309                 /* Actual maximal modified value */
3310                 cnv_stat(p_ptr->stat_top[i], buf);
3311                 c_put_str(TERM_L_GREEN, buf, row + i+1, stat_col + 26);
3312
3313                 /* Only display stat_use if not maximal */
3314                 if (p_ptr->stat_use[i] < p_ptr->stat_top[i])
3315                 {
3316                         cnv_stat(p_ptr->stat_use[i], buf);
3317                         c_put_str(TERM_YELLOW, buf, row + i+1, stat_col + 33);
3318                 }
3319         }
3320
3321         /* Column */
3322         col = stat_col + 41;
3323
3324         /* Header and Footer */
3325         c_put_str(TERM_WHITE, "abcdefghijkl@", row, col);
3326 #ifdef JP
3327 c_put_str(TERM_L_GREEN, "ǽÎϽ¤Àµ", row - 1, col);
3328 #else
3329         c_put_str(TERM_L_GREEN, "Modification", row - 1, col);
3330 #endif
3331
3332
3333         /* Process equipment */
3334         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3335         {
3336                 /* Access object */
3337                 o_ptr = &inventory[i];
3338
3339                 /* Object kind */
3340                 k_idx = o_ptr->k_idx;
3341
3342                 /* Acquire "known" flags */
3343                 object_flags_known(o_ptr, &f1, &f2, &f3);
3344
3345                 /* Initialize color based of sign of pval. */
3346                 for (stat = 0; stat < 6; stat++)
3347                 {
3348                         /* Default */
3349                         a = TERM_SLATE;
3350                         c = '.';
3351
3352                         /* Boost */
3353                         if (f1 & 1 << stat)
3354                         {
3355                                 /* Default */
3356                                 c = '*';
3357
3358                                 /* Good */
3359                                 if (o_ptr->pval > 0)
3360                                 {
3361                                         /* Good */
3362                                         a = TERM_L_GREEN;
3363
3364                                         /* Label boost */
3365                                         if (o_ptr->pval < 10) c = '0' + o_ptr->pval;
3366                                 }
3367
3368                                 if (f2 & 1 << stat)
3369                                 {
3370                                         /* Dark green for sustained stats */
3371                                         a = TERM_GREEN;
3372                                 }
3373
3374                                 /* Bad */
3375                                 if (o_ptr->pval < 0)
3376                                 {
3377                                         /* Bad */
3378                                         a = TERM_RED;
3379
3380                                         /* Label boost */
3381                                         if (o_ptr->pval < 10) c = '0' - o_ptr->pval;
3382                                 }
3383                         }
3384
3385                         /* Sustain */
3386                         else if (f2 & 1 << stat)
3387                         {
3388                                 /* Dark green "s" */
3389                                 a = TERM_GREEN;
3390                                 c = 's';
3391                         }
3392
3393                         /* Dump proper character */
3394                         Term_putch(col, row + stat+1, a, c);
3395                 }
3396
3397                 /* Advance */
3398                 col++;
3399         }
3400
3401         /* Player flags */
3402         player_flags(&f1, &f2, &f3);
3403
3404         /* Check stats */
3405         for (stat = 0; stat < 6; stat++)
3406         {
3407                 /* Default */
3408                 a = TERM_SLATE;
3409                 c = '.';
3410
3411                 /* Mutations ... */
3412                 if (p_ptr->muta3 || p_ptr->tsuyoshi)
3413                 {
3414                         int dummy = 0;
3415
3416                         if (stat == A_STR)
3417                         {
3418                                 if (p_ptr->muta3 & MUT3_HYPER_STR) dummy += 4;
3419                                 if (p_ptr->muta3 & MUT3_PUNY) dummy -= 4;
3420                                 if (p_ptr->tsuyoshi) dummy += 4;
3421                         }
3422                         else if (stat == A_WIS || stat == A_INT)
3423                         {
3424                                 if (p_ptr->muta3 & MUT3_HYPER_INT) dummy += 4;
3425                                 if (p_ptr->muta3 & MUT3_MORONIC) dummy -= 4;
3426                         }
3427                         else if (stat == A_DEX)
3428                         {
3429                                 if (p_ptr->muta3 & MUT3_IRON_SKIN) dummy -= 1;
3430                                 if (p_ptr->muta3 & MUT3_LIMBER) dummy += 3;
3431                                 if (p_ptr->muta3 & MUT3_ARTHRITIS) dummy -= 3;
3432                         }
3433                         else if (stat == A_CON)
3434                         {
3435                                 if (p_ptr->muta3 & MUT3_RESILIENT) dummy += 4;
3436                                 if (p_ptr->muta3 & MUT3_XTRA_FAT) dummy += 2;
3437                                 if (p_ptr->muta3 & MUT3_ALBINO) dummy -= 4;
3438                                 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 2;
3439                                 if (p_ptr->tsuyoshi) dummy += 4;
3440                         }
3441                         else if (stat == A_CHR)
3442                         {
3443                                 if (p_ptr->muta3 & MUT3_SILLY_VOI) dummy -= 4;
3444                                 if (p_ptr->muta3 & MUT3_BLANK_FAC) dummy -= 1;
3445                                 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 1;
3446                                 if (p_ptr->muta3 & MUT3_SCALES) dummy -= 1;
3447                                 if (p_ptr->muta3 & MUT3_WART_SKIN) dummy -= 2;
3448                                 if (p_ptr->muta3 & MUT3_ILL_NORM) dummy = 0;
3449                         }
3450
3451                         /* Boost */
3452                         if (dummy)
3453                         {
3454                                 /* Default */
3455                                 c = '*';
3456
3457                                 /* Good */
3458                                 if (dummy > 0)
3459                                 {
3460                                         /* Good */
3461                                         a = TERM_L_GREEN;
3462
3463                                         /* Label boost */
3464                                         if (dummy < 10) c = '0' + dummy;
3465                                 }
3466
3467                                 /* Bad */
3468                                 if (dummy < 0)
3469                                 {
3470                                         /* Bad */
3471                                         a = TERM_RED;
3472
3473                                         /* Label boost */
3474                                         if (dummy < 10) c = '0' - dummy;
3475                                 }
3476                         }
3477                 }
3478
3479
3480                 /* Sustain */
3481                 if (f2 & 1<<stat)
3482                 {
3483                         /* Dark green "s" */
3484                         a = TERM_GREEN;
3485                         c = 's';
3486                 }
3487
3488
3489                 /* Dump */
3490                 Term_putch(col, row + stat+1, a, c);
3491         }
3492 }
3493
3494
3495 /*
3496  * Object flag names
3497  */
3498 static cptr object_flag_names[96] =
3499 {
3500 #ifdef JP
3501 "+ÏÓÎÏ",
3502 "+ÃÎǽ",
3503 "+¸­¤µ",
3504 "+´ïÍÑ",
3505 "+Âѵ×",
3506 "+Ì¥ÎÏ",
3507 #else
3508         "Add Str",
3509         "Add Int",
3510         "Add Wis",
3511         "Add Dex",
3512         "Add Con",
3513         "Add Chr",
3514 #endif
3515
3516 #ifdef JP
3517         "ËâÆ»¶ñ",
3518
3519         "ÍýÎÏ",
3520 #else
3521         "M.Item-Mas",
3522
3523         "Force wep.",
3524 #endif
3525
3526 #ifdef JP
3527 "+±£Ì©¹ÔÆ°",
3528 "+õº÷",
3529 "+ÀÖ³°Àþ»ë",
3530 "+·¡ºï",
3531 "+¥¹¥Ô¡¼¥É",
3532 "+ÂÇ·â²ó¿ô",
3533 "¥«¥ª¥¹¸ú²Ì",
3534 "µÛ·ì",
3535 "ưʪ ÇÜÂÇ",
3536 "¼Ù°­ ÇÜÂÇ",
3537 "ÉÔ»à ÇÜÂÇ",
3538 "°­Ëâ ÇÜÂÇ",
3539 "¥ª¡¼¥¯ÇÜÂÇ",
3540 "¥È¥í¥ëÇÜÂÇ",
3541 "µð¿Í ÇÜÂÇ",
3542 "ζ ÇÜÂÇ",
3543 "ζ ÇÜÇÜÂÇ",
3544 "±Ô¿Ï",
3545 "ÃÏ¿ÌȯÀ¸",
3546 "ÆÇ°À­¹¶·â",
3547 "»À°À­¹¶·â",
3548 "ÅÅ°À­¹¶·â",
3549 "²Ð°À­¹¶·â",
3550 "Îä°À­¹¶·â",
3551 #else
3552         "Add Stea.",
3553         "Add Sear.",
3554         "Add Infra",
3555         "Add Tun..",
3556         "Add Speed",
3557         "Add Blows",
3558         "Chaotic",
3559         "Vampiric",
3560         "Slay Anim.",
3561         "Slay Evil",
3562         "Slay Und.",
3563         "Slay Demon",
3564         "Slay Orc",
3565         "Slay Troll",
3566         "Slay Giant",
3567         "Slay Drag.",
3568         "Kill Drag.",
3569         "Sharpness",
3570         "Impact",
3571         "Poison Brd",
3572         "Acid Brand",
3573         "Elec Brand",
3574         "Fire Brand",
3575         "Cold Brand",
3576 #endif
3577
3578
3579 #ifdef JP
3580 "ÏÓÎÏ ÊÝ»ý",
3581 "ÃÎǽ ÊÝ»ý",
3582 "¸­¤µ ÊÝ»ý",
3583 "´ïÍÑ ÊÝ»ý",
3584 "ÂѵנÊÝ»ý",
3585 "Ì¥ÎÏ ÊÝ»ý",
3586 #else
3587         "Sust Str",
3588         "Sust Int",
3589         "Sust Wis",
3590         "Sust Dex",
3591         "Sust Con",
3592         "Sust Chr",
3593 #endif
3594
3595         NULL,
3596         NULL,
3597 #ifdef JP
3598 "ĶÂÑ»À  ",
3599 "ĶÂÑÅÅ·â",
3600 "ĶÂѲбê",
3601 "ĶÂÑÎ䵤",
3602 #else
3603         "Imm Acid",
3604         "Imm Elec",
3605         "Imm Fire",
3606         "Imm Cold",
3607 #endif
3608
3609         NULL,
3610 #ifdef JP
3611 "È¿¼Í",
3612 "ÂÑËãáã",
3613 "·Ð¸³ÃÍÊÝ»ý",
3614 #else
3615         "Reflect",
3616         "Free Act",
3617         "Hold Life",
3618 #endif
3619
3620 #ifdef JP
3621 "ÂÑ»À  ",
3622 "ÂÑÅÅ·â",
3623 "ÂѲбê",
3624 "ÂÑÎ䵤",
3625 "ÂÑÆÇ  ",
3626 "ÂѶ²ÉÝ",
3627 "ÂÑÁ®¸÷",
3628 "ÂѰŹõ",
3629 "ÂÑÌÕÌÜ",
3630 "ÂѺ®Íð",
3631 "Âѹ첻",
3632 "ÂÑÇËÊÒ",
3633 "ÂÑÃϹö",
3634 "ÂÑ°øº®",
3635 "ÂÑ¥«¥ª",
3636 "ÂÑÎô²½",
3637 #else
3638         "Res Acid",
3639         "Res Elec",
3640         "Res Fire",
3641         "Res Cold",
3642         "Res Pois",
3643         "Res Fear",
3644         "Res Lite",
3645         "Res Dark",
3646         "Res Blind",
3647         "Res Conf",
3648         "Res Sound",
3649         "Res Shard",
3650         "Res Neth",
3651         "Res Nexus",
3652         "Res Chaos",
3653         "Res Disen",
3654 #endif
3655
3656
3657
3658
3659 #ifdef JP
3660         "²Ð±ê¥ª¡¼¥é",
3661
3662         "Åŵ¤¥ª¡¼¥é",
3663 #else
3664         "Aura Fire",
3665
3666         "Aura Elec",
3667 #endif
3668
3669         NULL,
3670 #ifdef JP
3671         "Î䵤¥ª¡¼¥é",
3672 #else
3673         "Aura Cold",
3674 #endif
3675 #ifdef JP
3676 "Ëɥƥì¥Ý",
3677 "È¿ËâË¡",
3678 "¸º¾ÃÈñËâÎÏ",
3679 "¼Ù°­¤Ê±åÇ°",
3680 NULL,
3681 "Hide Type",
3682 "Show Mods",
3683 "¾ï»þÅÁÀâʪ",
3684 "ÉâÍ·",
3685 "¸÷¸»",
3686 "Æ©ÌÀ»ëǧ",
3687 "¥Æ¥ì¥Ñ¥·¡¼",
3688 "Ãپò½",
3689 "µÞ²óÉü",
3690 "¶¯Îϼͷâ",
3691 "¹â®¼Í·â",
3692 "̵½ý »À",
3693 "̵½ý ÅÅ",
3694 "̵½ý ²Ð",
3695 "̵½ý Îä",
3696 "»ÏÆ°",
3697 "·Ð¸³µÛ¼ý",
3698 "¥Æ¥ì¥Ý¡¼¥È",
3699 "È¿´¶",
3700 "½ËÊ¡",
3701 "¼ö¤¤",
3702 "½Å¤¤¼ö¤¤",
3703 "±Ê±ó¤Î¼ö¤¤"
3704 #else
3705         "NoTeleport",
3706         "AntiMagic",
3707         "DecMana",
3708         "EvilCurse",
3709         NULL,
3710         "Hide Type",
3711         "Show Mods",
3712         "Insta Art",
3713         "Levitate",
3714         "Lite",
3715         "See Invis",
3716         "Telepathy",
3717         "Digestion",
3718         "Regen",
3719         "Xtra Might",
3720         "Xtra Shots",
3721         "Ign Acid",
3722         "Ign Elec",
3723         "Ign Fire",
3724         "Ign Cold",
3725         "Activate",
3726         "Drain Exp",
3727         "Teleport",
3728         "Aggravate",
3729         "Blessed",
3730         "Cursed",
3731         "Hvy Curse",
3732         "Prm Curse"
3733 #endif
3734
3735 };
3736
3737
3738 /*
3739  * Summarize resistances
3740  */
3741 static void display_player_ben(void)
3742 {
3743         int i, x, y;
3744
3745         object_type *o_ptr;
3746
3747         u32b f1, f2, f3;
3748
3749         u16b b[6];
3750         u16b color[6];
3751
3752
3753         /* Reset */
3754         for (i = 0; i < 6; i++) b[i] = 0;
3755
3756
3757         /* Scan equipment */
3758         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3759         {
3760                 /* Object */
3761                 o_ptr = &inventory[i];
3762
3763                 /* Known object flags */
3764                 object_flags_known(o_ptr, &f1, &f2, &f3);
3765
3766
3767                 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3768                 {
3769                         f3 &= ~(TR3_AGGRAVATE);
3770                         f1 |= TR1_STEALTH;
3771                 }
3772
3773                 /* Incorporate */
3774                 b[0] |= (f1 & 0xFFFF);
3775                 b[1] |= (f1 >> 16);
3776                 b[2] |= (f2 & 0xFFFF);
3777                 b[3] |= (f2 >> 16);
3778                 b[4] |= (f3 & 0xFFFF);
3779                 b[5] |= (f3 >> 16);
3780         }
3781
3782
3783         /* Player flags */
3784         player_flags(&f1, &f2, &f3);
3785
3786         /* Incorporate */
3787         b[0] |= (f1 & 0xFFFF);
3788         b[1] |= (f1 >> 16);
3789         b[2] |= (f2 & 0xFFFF);
3790         b[3] |= (f2 >> 16);
3791         b[4] |= (f3 & 0xFFFF);
3792         b[5] |= (f3 >> 16);
3793
3794         /* Player flags */
3795         tim_player_flags(&f1, &f2, &f3, FALSE);
3796
3797         /* Incorporate */
3798         b[0] |= (f1 & 0xFFFF);
3799         b[1] |= (f1 >> 16);
3800         b[2] |= (f2 & 0xFFFF);
3801         b[3] |= (f2 >> 16);
3802         b[4] |= (f3 & 0xFFFF);
3803         b[5] |= (f3 >> 16);
3804         color[0] = (u16b)(f1 & 0xFFFF);
3805         color[1] = (u16b)(f1 >> 16);
3806         color[2] = (u16b)(f2 & 0xFFFF);
3807         color[3] = (u16b)(f2 >> 16);
3808         color[4] = (u16b)(f3 & 0xFFFF);
3809         color[5] = (u16b)(f3 >> 16);
3810
3811         /* Scan cols */
3812         for (x = 0; x < 6; x++)
3813         {
3814                 /* Scan rows */
3815                 for (y = 0; y < 16; y++)
3816                 {
3817                         byte a = TERM_SLATE;
3818                         char c = '.';
3819
3820                         cptr name = object_flag_names[16*x+y];
3821
3822                         /* No name */
3823                         if (!name) continue;
3824
3825                         /* Dump name */
3826                         Term_putstr(x * 13, y + 4, -1, TERM_WHITE, name);
3827
3828                         /* Dump colon */
3829                         Term_putch(x * 13 + 10, y + 4, TERM_WHITE, ':');
3830
3831                         /* Check flag */
3832                         if (b[x] & (1<<y))
3833                         {
3834                                 if (color[x] & (1<<y))
3835                                 {
3836                                         a = TERM_YELLOW;
3837                                         c = '#';
3838                                 }
3839                                 else
3840                                 {
3841                                         a = TERM_WHITE;
3842                                         c = '+';
3843                                 }
3844                         }
3845
3846                         /* Dump flag */
3847                         Term_putch(x * 13 + 11, y + 4, a, c);
3848                 }
3849         }
3850 }
3851
3852
3853 /*
3854  * Summarize resistances
3855  */
3856 static void display_player_ben_one(int mode)
3857 {
3858         int i, n, x, y;
3859
3860         object_type *o_ptr;
3861
3862         u32b f1, f2, f3;
3863
3864         u16b b[13][6];
3865         u16b color[6];
3866
3867
3868         /* Scan equipment */
3869         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3870         {
3871                 /* Index */
3872                 n = (i - INVEN_RARM);
3873
3874                 /* Object */
3875                 o_ptr = &inventory[i];
3876
3877                 object_flags_known(o_ptr, &f1, &f2, &f3);
3878
3879                 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3880                 {
3881                         f3 &= ~(TR3_AGGRAVATE);
3882                         f1 |= TR1_STEALTH;
3883                 }
3884
3885                 /* Incorporate */
3886                 b[n][0] = (u16b)(f1 & 0xFFFF);
3887                 b[n][1] = (u16b)(f1 >> 16);
3888                 b[n][2] = (u16b)(f2 & 0xFFFF);
3889                 b[n][3] = (u16b)(f2 >> 16);
3890                 b[n][4] = (u16b)(f3 & 0xFFFF);
3891                 b[n][5] = (u16b)(f3 >> 16);
3892         }
3893
3894
3895         /* Index */
3896         n = 12;
3897
3898         /* Player flags */
3899         player_flags(&f1, &f2, &f3);
3900
3901         /* Incorporate */
3902         b[n][0] = (u16b)(f1 & 0xFFFF);
3903         b[n][1] = (u16b)(f1 >> 16);
3904         b[n][2] = (u16b)(f2 & 0xFFFF);
3905         b[n][3] = (u16b)(f2 >> 16);
3906         b[n][4] = (u16b)(f3 & 0xFFFF);
3907         b[n][5] = (u16b)(f3 >> 16);
3908
3909         /* Player flags */
3910         tim_player_flags(&f1, &f2, &f3, FALSE);
3911
3912         /* Incorporate */
3913         b[n][0] |= (f1 & 0xFFFF);
3914         b[n][1] |= (f1 >> 16);
3915         b[n][2] |= (f2 & 0xFFFF);
3916         b[n][3] |= (f2 >> 16);
3917         b[n][4] |= (f3 & 0xFFFF);
3918         b[n][5] |= (f3 >> 16);
3919         color[0] = (u16b)(f1 & 0xFFFF);
3920         color[1] = (u16b)(f1 >> 16);
3921         color[2] = (u16b)(f2 & 0xFFFF);
3922         color[3] = (u16b)(f2 >> 16);
3923         color[4] = (u16b)(f3 & 0xFFFF);
3924         color[5] = (u16b)(f3 >> 16);
3925
3926
3927         /* Scan cols */
3928         for (x = 0; x < 3; x++)
3929         {
3930                 /* Equippy */
3931                 display_player_equippy(2, x * 26 + 11);
3932
3933                 /* Label */
3934                 Term_putstr(x * 26 + 11, 3, -1, TERM_WHITE, "abcdefghijkl@");
3935
3936                 /* Scan rows */
3937                 for (y = 0; y < 16; y++)
3938                 {
3939                         cptr name = object_flag_names[48*mode+16*x+y];
3940
3941                         /* No name */
3942                         if (!name) continue;
3943
3944                         /* Dump name */
3945                         Term_putstr(x * 26, y + 4, -1, TERM_WHITE, name);
3946
3947                         /* Dump colon */
3948                         Term_putch(x * 26 + 10, y + 4, TERM_WHITE, ':');
3949
3950                         /* Check flags */
3951                         for (n = 0; n < 13; n++)
3952                         {
3953                                 byte a = TERM_SLATE;
3954                                 char c = '.';
3955
3956                                 /* Check flag */
3957                                 if (b[n][3*mode+x] & (1<<y))
3958                                 {
3959                                         if ((n == 12) && (color[3*mode+x] & (1<<y)))
3960                                         {
3961                                                 a = TERM_YELLOW;
3962                                                 c = '#';
3963                                         }
3964                                         else
3965                                         {
3966                                                 a = TERM_WHITE;
3967                                                 c = '+';
3968                                         }
3969                                 }
3970
3971                                 /* Dump flag */
3972                                 Term_putch(x * 26 + 11 + n, y + 4, a, c);
3973                         }
3974                 }
3975         }
3976 }
3977
3978
3979 /*
3980  * Display the character on the screen (various modes)
3981  *
3982  * The top two and bottom two lines are left blank.
3983  *
3984  * Mode 0 = standard display with skills
3985  * Mode 1 = standard display with history
3986  * Mode 2 = summary of various things
3987  * Mode 3 = current flags (combined)
3988  * Mode 4 = current flags (part 1)
3989  * Mode 5 = current flags (part 2)
3990  * Mode 6 = mutations
3991  */
3992 void display_player(int mode)
3993 {
3994         int i;
3995
3996         char    buf[80];
3997         char    tmp[64];
3998
3999
4000         /* XXX XXX XXX */
4001         if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && skip_mutations)
4002                 mode = (mode % 7);
4003         else
4004                 mode = (mode % 6);
4005
4006         /* Erase screen */
4007         clear_from(0);
4008
4009         /* Standard */
4010         if ((mode == 0) || (mode == 1))
4011         {
4012                 /* Name, Sex, Race, Class */
4013 #ifdef JP
4014                 sprintf(tmp, "%s%s%s", ap_ptr->title, ap_ptr->no == 1 ? "¤Î":"", player_name);
4015 #else
4016                 sprintf(tmp, "%s %s", ap_ptr->title, player_name);
4017 #endif
4018
4019                 display_player_one_line(ENTRY_NAME, tmp, TERM_L_BLUE);
4020                 display_player_one_line(ENTRY_SEX, sp_ptr->title, TERM_L_BLUE);
4021                 display_player_one_line(ENTRY_RACE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), TERM_L_BLUE);
4022                 display_player_one_line(ENTRY_CLASS, cp_ptr->title, TERM_L_BLUE);
4023
4024                 if (p_ptr->realm1)
4025                 {
4026                         if (p_ptr->realm2)
4027                                 sprintf(tmp, "%s, %s", realm_names[p_ptr->realm1], realm_names[p_ptr->realm2]);
4028                         else
4029                                 strcpy(tmp, realm_names[p_ptr->realm1]);
4030                         display_player_one_line(ENTRY_REALM, tmp, TERM_L_BLUE);
4031                 }
4032
4033                 if (p_ptr->pclass == CLASS_CHAOS_WARRIOR)
4034                         display_player_one_line(ENTRY_PATRON, chaos_patrons[p_ptr->chaos_patron], TERM_L_BLUE);
4035
4036                 /* Age, Height, Weight, Social */
4037                 /* ¿ÈĹ¤Ï¥»¥ó¥Á¥á¡¼¥È¥ë¤Ë¡¢ÂνŤϥ­¥í¥°¥é¥à¤ËÊѹ¹¤·¤Æ¤¢¤ê¤Þ¤¹ */
4038 #ifdef JP
4039                 display_player_one_line(ENTRY_AGE, format("%dºÍ" ,(int)p_ptr->age), TERM_L_BLUE);
4040                 display_player_one_line(ENTRY_HEIGHT, format("%dcm" ,(int)((p_ptr->ht*254)/100)), TERM_L_BLUE);
4041                 display_player_one_line(ENTRY_WEIGHT, format("%dkg" ,(int)((p_ptr->wt*4536)/10000)), TERM_L_BLUE);
4042                 display_player_one_line(ENTRY_SOCIAL, format("%d  " ,(int)p_ptr->sc), TERM_L_BLUE);
4043 #else
4044                 display_player_one_line(ENTRY_AGE, format("%d" ,(int)p_ptr->age), TERM_L_BLUE);
4045                 display_player_one_line(ENTRY_HEIGHT, format("%d" ,(int)p_ptr->ht), TERM_L_BLUE);
4046                 display_player_one_line(ENTRY_WEIGHT, format("%d" ,(int)p_ptr->wt), TERM_L_BLUE);
4047                 display_player_one_line(ENTRY_SOCIAL, format("%d" ,(int)p_ptr->sc), TERM_L_BLUE);
4048 #endif
4049                 display_player_one_line(ENTRY_ALIGN, format("%s" ,your_alignment()), TERM_L_BLUE);
4050
4051
4052                 /* Display the stats */
4053                 for (i = 0; i < 6; i++)
4054                 {
4055                         /* Special treatment of "injured" stats */
4056                         if (p_ptr->stat_cur[i] < p_ptr->stat_max[i])
4057                         {
4058                                 int value;
4059
4060                                 /* Use lowercase stat name */
4061                                 put_str(stat_names_reduced[i], 3 + i, 54);
4062
4063                                 /* Get the current stat */
4064                                 value = p_ptr->stat_use[i];
4065
4066                                 /* Obtain the current stat (modified) */
4067                                 cnv_stat(value, buf);
4068
4069                                 /* Display the current stat (modified) */
4070                                 c_put_str(TERM_YELLOW, buf, 3 + i, 61);
4071
4072                                 /* Acquire the max stat */
4073                                 value = p_ptr->stat_top[i];
4074
4075                                 /* Obtain the maximum stat (modified) */
4076                                 cnv_stat(value, buf);
4077
4078                                 /* Display the maximum stat (modified) */
4079                                 c_put_str(TERM_L_GREEN, buf, 3 + i, 68);
4080                         }
4081
4082                         /* Normal treatment of "normal" stats */
4083                         else
4084                         {
4085                                 /* Assume uppercase stat name */
4086                                 put_str(stat_names[i], 3 + i, 54);
4087
4088                                 /* Obtain the current stat (modified) */
4089                                 cnv_stat(p_ptr->stat_use[i], buf);
4090
4091                                 /* Display the current stat (modified) */
4092                                 c_put_str(TERM_L_GREEN, buf, 3 + i, 61);
4093                         }
4094
4095                         if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
4096                         {
4097                                 c_put_str(TERM_WHITE, "!", 2+i, 64);
4098                         }
4099                 }
4100
4101                 /* Display "history" info */
4102                 if (mode == 1)
4103                 {
4104 #ifdef JP
4105                         put_str("(¥­¥ã¥é¥¯¥¿¡¼¤ÎÀ¸¤¤Î©¤Á)", 11, 25);
4106 #else
4107                         put_str("(Character Background)", 11, 25);
4108 #endif
4109
4110                         for (i = 0; i < 4; i++)
4111                         {
4112                                 put_str(history[i], i + 12, 10);
4113                         }
4114
4115
4116                         if (death)
4117                         {
4118                                 if (dun_level)
4119 #ifdef JP
4120                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï %s ¤Î %d ³¬¤Ç»à¤ó¤À¡£", map_name(), dun_level), 5 + 12, 10);
4121 #else
4122                                         put_str(format("...You were dead at level %d of %s.", dun_level, map_name()), 5 + 12, 10);
4123 #endif
4124                                 else
4125 #ifdef JP
4126                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï %s ¤Ç»à¤ó¤À¡£", map_name()), 5 + 12, 10);
4127 #else
4128                                         put_str(format("...You were dead at %s.", map_name()), 5 + 12, 10);
4129 #endif
4130                         }
4131                         else
4132                         {
4133                                 if (dun_level)
4134 #ifdef JP
4135                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Î %d ³¬¤Çõº÷¤·¤Æ¤¤¤ë¡£", map_name(), dun_level), 5 + 12, 10);
4136 #else
4137                                         put_str(format("...Now, you are exploring at level %d of %s.", dun_level, map_name()), 5 + 12, 10);
4138 #endif
4139                                 else
4140 #ifdef JP
4141                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Ë¤¤¤ë¡£", map_name()), 5 + 12, 10);
4142 #else
4143                                         put_str(format("...Now, you are in %s.", map_name()), 5 + 12, 10);
4144 #endif
4145                         }
4146                 }
4147
4148                 /* Display "various" info */
4149                 else
4150                 {
4151                         display_player_middle();
4152                         display_player_various();
4153                 }
4154         }
4155
4156         /* Special */
4157         else if (mode == 2)
4158         {
4159                 /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */
4160
4161                 /* Dump the info */
4162                 display_player_misc_info();
4163                 display_player_stat_info();
4164                 display_player_flag_info();
4165         }
4166
4167         /* Special */
4168         else if (mode == 3)
4169         {
4170                 display_player_ben();
4171         }
4172
4173         else if (mode == 6)
4174         {
4175                 do_cmd_knowledge_mutations();
4176         }
4177
4178         /* Special */
4179         else
4180         {
4181                 display_player_ben_one(mode % 2);
4182         }
4183 }
4184
4185 errr make_character_dump(FILE *fff)
4186 {
4187         int             i, x, y;
4188         byte            a;
4189         char            c;
4190         cptr            paren = ")";
4191         store_type  *st_ptr;
4192         char            o_name[MAX_NLEN];
4193         char            buf[1024];
4194
4195
4196 #ifndef FAKE_VERSION
4197         /* Begin dump */
4198         fprintf(fff, "  [Angband %d.%d.%d Character Dump]\n\n",
4199                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
4200 #else
4201 #ifdef JP
4202         fprintf(fff, "  [ÊѶòÈÚÅÜ %d.%d.%d ¥­¥ã¥é¥¯¥¿¾ðÊó]\n\n",
4203                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4204 #else
4205         fprintf(fff, "  [Hengband %d.%d.%d Character Dump]\n\n",
4206                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4207 #endif
4208
4209 #endif
4210
4211         update_playtime();
4212
4213         /* Display player */
4214         display_player(0);
4215
4216         /* Dump part of the screen */
4217         for (y = 1; y < 22; y++)
4218         {
4219                 /* Dump each row */
4220                 for (x = 0; x < 79; x++)
4221                 {
4222                         /* Get the attr/char */
4223                         (void)(Term_what(x, y, &a, &c));
4224
4225                         /* Dump it */
4226                         buf[x] = c;
4227                 }
4228
4229                 /* End the string */
4230                 buf[x] = '\0';
4231
4232                 /* Kill trailing spaces */
4233                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4234
4235                 /* End the row */
4236 #ifdef JP
4237                         fprintf(fff, "%s\n", buf);
4238 #else
4239                 fprintf(fff, "%s\n", buf);
4240 #endif
4241
4242         }
4243
4244         /* Display history */
4245         display_player(1);
4246
4247         /* Dump part of the screen */
4248         for (y = 11; y < 18; y++)
4249         {
4250                 /* Dump each row */
4251                 for (x = 0; x < 79; x++)
4252                 {
4253                         /* Get the attr/char */
4254                         (void)(Term_what(x, y, &a, &c));
4255
4256                         /* Dump it */
4257                         buf[x] = c;
4258                 }
4259
4260                 /* End the string */
4261                 buf[x] = '\0';
4262
4263                 /* Kill trailing spaces */
4264                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4265
4266                 /* End the row */
4267                 fprintf(fff, "%s\n", buf);
4268         }
4269
4270         fprintf(fff, "\n");
4271         /* Display history */
4272         display_player(2);
4273
4274         /* Dump part of the screen */
4275         for (y = 2; y < 22; y++)
4276         {
4277                 /* Dump each row */
4278                 for (x = 0; x < 79; x++)
4279                 {
4280                         /* Get the attr/char */
4281                         (void)(Term_what(x, y, &a, &c));
4282
4283                         /* Dump it (Ignore equippy tile graphic) */
4284                         if (a < 128)
4285                                 buf[x] = c;
4286                         else
4287                                 buf[x] = ' ';
4288                 }
4289
4290                 /* End the string */
4291                 buf[x] = '\0';
4292
4293                 /* Kill trailing spaces */
4294                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4295
4296                 /* End the row */
4297                 fprintf(fff, "%s\n", buf);
4298         }
4299
4300         for (i = 0; i < p_ptr->count / 80; i++)
4301                 fprintf(fff, " ");
4302         fprintf(fff, "\n");
4303         for (i = 0; i < p_ptr->count % 80; i++)
4304                 fprintf(fff, " ");
4305         {
4306                 bool pet = FALSE;
4307
4308                 for (i = m_max - 1; i >= 1; i--)
4309                 {
4310                         monster_type *m_ptr = &m_list[i];
4311                         char pet_name[80];
4312
4313                         if (!m_ptr->r_idx) continue;
4314                         if (!is_pet(m_ptr)) continue;
4315                         if (!m_ptr->nickname && (p_ptr->riding != i)) continue;
4316                         if (!pet)
4317                         {
4318 #ifdef JP
4319                                 fprintf(fff, "\n  [¼ç¤Ê¥Ú¥Ã¥È]\n\n");
4320 #else
4321                                 fprintf(fff, "\n  [leading pets]\n\n");
4322 #endif
4323                                 pet = TRUE;
4324                         }
4325                         monster_desc(pet_name, m_ptr, 0x88);
4326                         fprintf(fff, "%s", pet_name);
4327                         if (p_ptr->riding == i)
4328 #ifdef JP
4329                                 fprintf(fff, " ¾èÇÏÃæ");
4330 #else
4331                                 fprintf(fff, " riding");
4332 #endif
4333                         fprintf(fff, "\n");
4334                 }
4335                 if (pet) fprintf(fff, "\n");
4336         }
4337
4338         if (death && !total_winner)
4339         {
4340 #ifdef JP
4341                 fprintf(fff, "\n  [»à¤ÌľÁ°¤Î¥á¥Ã¥»¡¼¥¸]\n\n");
4342 #else
4343                 fprintf(fff, "\n  [Last messages]\n\n");
4344 #endif
4345                 for (i = MIN(message_num(), 15); i >= 0; i--)
4346                 {
4347                         fprintf(fff,"> %s\n",message_str((s16b)i));
4348                 }
4349                 fprintf(fff, "\n");
4350         }
4351
4352 #ifdef JP
4353         fprintf(fff, "\n  [¤½¤Î¾¤Î¾ðÊó]        \n");
4354 #else
4355         fprintf(fff, "\n  [Miscellaneous information]\n");
4356 #endif
4357
4358 #ifdef JP
4359         fprintf(fff, "\n µ¢´Ô¾ì½ê:\n");
4360 #else
4361         fprintf(fff, "\n Recall Depth:\n");
4362 #endif
4363         for (y = 1; y < max_d_idx; y++)
4364         {
4365                 bool seiha = FALSE;
4366
4367                 if (!d_info[y].maxdepth) continue;
4368                 if (!max_dlv[y]) continue;
4369                 if (d_info[y].final_guardian)
4370                 {
4371                         if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
4372                 }
4373                 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
4374
4375 #ifdef JP
4376                 fprintf(fff, "   %c%-12s: %3d ³¬\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4377 #else
4378                 fprintf(fff, "   %c%-16s: level %3d\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4379 #endif
4380         }
4381
4382         if (preserve_mode)
4383 #ifdef JP
4384                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         ON");
4385 #else
4386                 fprintf(fff, "\n Preserve Mode:      ON");
4387 #endif
4388
4389         else
4390 #ifdef JP
4391                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         OFF");
4392 #else
4393                 fprintf(fff, "\n Preserve Mode:      OFF");
4394 #endif
4395
4396
4397         if (ironman_autoscum)
4398 #ifdef JP
4399                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ALWAYS");
4400 #else
4401                 fprintf(fff, "\n Autoscum:           ALWAYS");
4402 #endif
4403
4404         else if (auto_scum)
4405 #ifdef JP
4406                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ON");
4407 #else
4408                 fprintf(fff, "\n Autoscum:           ON");
4409 #endif
4410
4411         else
4412 #ifdef JP
4413                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     OFF");
4414 #else
4415                 fprintf(fff, "\n Autoscum:           OFF");
4416 #endif
4417
4418
4419         if (ironman_small_levels)
4420 #ifdef JP
4421                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ALWAYS");
4422 #else
4423                 fprintf(fff, "\n Small Levels:       ALWAYS");
4424 #endif
4425
4426         else if (always_small_levels)
4427 #ifdef JP
4428                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ON");
4429 #else
4430                 fprintf(fff, "\n Small Levels:       ON");
4431 #endif
4432
4433         else if (small_levels)
4434 #ifdef JP
4435                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ENABLED");
4436 #else
4437                 fprintf(fff, "\n Small Levels:       ENABLED");
4438 #endif
4439
4440         else
4441 #ifdef JP
4442                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   OFF");
4443 #else
4444                 fprintf(fff, "\n Small Levels:       OFF");
4445 #endif
4446
4447
4448         if (vanilla_town)
4449 #ifdef JP
4450                 fprintf(fff, "\n ¸µÁĤÎÄ®¤Î¤ß: ON");
4451 #else
4452                 fprintf(fff, "\n Vanilla Town:       ON");
4453 #endif
4454
4455         else if (lite_town)
4456 #ifdef JP
4457                 fprintf(fff, "\n ¾®µ¬ÌϤÊÄ®:         ON");
4458 #else
4459                 fprintf(fff, "\n Lite Town:          ON");
4460 #endif
4461
4462
4463         if (ironman_shops)
4464 #ifdef JP
4465                 fprintf(fff, "\n Å¹¤Ê¤·:             ON");
4466 #else
4467                 fprintf(fff, "\n No Shops:           ON");
4468 #endif
4469
4470
4471         if (ironman_downward)
4472 #ifdef JP
4473                 fprintf(fff, "\n ³¬Ãʤò¾å¤¬¤ì¤Ê¤¤:   ON");
4474 #else
4475                 fprintf(fff, "\n Diving only:        ON");
4476 #endif
4477
4478
4479         if (ironman_rooms)
4480 #ifdef JP
4481                 fprintf(fff, "\n ÉáÄ̤Ǥʤ¤Éô²°¤òÀ¸À®:         ON");
4482 #else
4483                 fprintf(fff, "\n Unusual rooms:      ON");
4484 #endif
4485
4486
4487         if (ironman_nightmare)
4488 #ifdef JP
4489                 fprintf(fff, "\n °­Ì´¥â¡¼¥É:         ON");
4490 #else
4491                 fprintf(fff, "\n Nightmare Mode:     ON");
4492 #endif
4493
4494
4495         if (ironman_empty_levels)
4496 #ifdef JP
4497                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ALWAYS");
4498 #else
4499                 fprintf(fff, "\n Arena Levels:       ALWAYS");
4500 #endif
4501
4502         else if (empty_levels)
4503 #ifdef JP
4504                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ON");
4505 #else
4506                 fprintf(fff, "\n Arena Levels:       ENABLED");
4507 #endif
4508
4509         else
4510 #ifdef JP
4511                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           OFF");
4512 #else
4513                 fprintf(fff, "\n Arena Levels:       OFF");
4514 #endif
4515
4516
4517 #ifdef JP
4518         fprintf(fff, "\n ¥é¥ó¥À¥à¥¯¥¨¥¹¥È¿ô: %d", number_of_quests());
4519 #else
4520         fprintf(fff, "\n Num. Random Quests: %d", number_of_quests());
4521 #endif
4522
4523         if (p_ptr->arena_number == 99)
4524         {
4525 #ifdef JP
4526                 fprintf(fff, "\n Æ®µ»¾ì: ÇÔËÌ\n");
4527 #else
4528                 fprintf(fff, "\n Arena: defeated\n");
4529 #endif
4530         }
4531         else if (p_ptr->arena_number > MAX_ARENA_MONS+2)
4532         {
4533 #ifdef JP
4534                 fprintf(fff, "\n Æ®µ»¾ì: ¿¿¤Î¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4535 #else
4536                 fprintf(fff, "\n Arena: True Champion\n");
4537 #endif
4538         }
4539         else if (p_ptr->arena_number > MAX_ARENA_MONS-1)
4540         {
4541 #ifdef JP
4542                 fprintf(fff, "\n Æ®µ»¾ì: ¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4543 #else
4544                 fprintf(fff, "\n Arena: Champion\n");
4545 #endif
4546         }
4547         else
4548         {
4549 #ifdef JP
4550                 fprintf(fff, "\n Æ®µ»¾ì:   %2d¾¡\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number));
4551 #else
4552                 fprintf(fff, "\n Arena:   %2d victor%s\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number), (p_ptr->arena_number>1) ? "ies" : "y");
4553 #endif
4554         }
4555
4556         if (noscore)
4557 #ifdef JP
4558 fprintf(fff, "\n ²¿¤«ÉÔÀµ¤Ê¤³¤È¤ò¤·¤Æ¤·¤Þ¤Ã¤Æ¤Þ¤¹¡£");
4559 #else
4560                 fprintf(fff, "\n You have done something illegal.");
4561 #endif
4562
4563
4564         if (stupid_monsters)
4565 #ifdef JP
4566 fprintf(fff, "\n Å¨¤Ï¶ò¤«¤Ê¹ÔÆ°¤ò¼è¤ê¤Þ¤¹¡£");
4567 #else
4568                 fprintf(fff, "\n Your opponents are behaving stupidly.");
4569 #endif
4570
4571
4572         if (munchkin_death)
4573 #ifdef JP
4574 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï»à¤ò²óÈò¤¹¤ë¥¤¥ó¥Á¥­¤ÊÎϤò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£");
4575 #else
4576                 fprintf(fff, "\n You possess munchkinish power over death.");
4577 #endif
4578
4579         fprintf(fff,"\n");
4580
4581         /* Monsters slain */
4582         {
4583                 int k;
4584                 s32b Total = 0;
4585
4586                 for (k = 1; k < max_r_idx; k++)
4587                 {
4588                         monster_race *r_ptr = &r_info[k];
4589
4590                         if (r_ptr->flags1 & RF1_UNIQUE)
4591                         {
4592                                 bool dead = (r_ptr->max_num == 0);
4593                                 if (dead)
4594                                 {
4595                                         Total++;
4596                                 }
4597                         }
4598                         else
4599                         {
4600                                 s16b This = r_ptr->r_pkills;
4601                                 if (This > 0)
4602                                 {
4603                                         Total += This;
4604                                 }
4605                         }
4606                 }
4607
4608                 if (Total < 1)
4609 #ifdef JP
4610 fprintf(fff,"\n ¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Þ¤»¤ó¡£\n");
4611 #else
4612                         fprintf(fff,"\n You have defeated no enemies yet.\n");
4613 #endif
4614
4615                 else if (Total == 1)
4616 #ifdef JP
4617 fprintf(fff,"\n °ìÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n");
4618 #else
4619                         fprintf(fff,"\n You have defeated one enemy.\n");
4620 #endif
4621
4622                 else
4623 #ifdef JP
4624 fprintf(fff,"\n %lu ÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n", Total);
4625 #else
4626                         fprintf(fff,"\n You have defeated %lu enemies.\n", Total);
4627 #endif
4628
4629         }
4630
4631
4632         if (p_ptr->old_race1 || p_ptr->old_race2)
4633         {
4634 #ifdef JP
4635                 fprintf(fff, "\n\n ¤¢¤Ê¤¿¤Ï%s¤È¤·¤ÆÀ¸¤Þ¤ì¤¿¡£", race_info[p_ptr->start_race].title);
4636 #else
4637                 fprintf(fff, "\n\n You were born as %s.", race_info[p_ptr->start_race].title);
4638 #endif
4639                 for (i = 0; i < MAX_RACES; i++)
4640                 {
4641                         if (p_ptr->start_race == i) continue;
4642                         if (i < 32)
4643                         {
4644                                 if (!(p_ptr->old_race1 & 1L << i)) continue;
4645                         }
4646                         else
4647                         {
4648                                 if (!(p_ptr->old_race2 & 1L << (i-32))) continue;
4649                         }
4650 #ifdef JP
4651                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%s¤À¤Ã¤¿¡£", race_info[i].title);
4652 #else
4653                         fprintf(fff, "\n You were a %s before.", race_info[i].title);
4654 #endif
4655                 }
4656         }
4657
4658         if (p_ptr->old_realm)
4659         {
4660                 for (i = 0; i < MAX_MAGIC; i++)
4661                 {
4662                         if (!(p_ptr->old_realm & 1L << i)) continue;
4663 #ifdef JP
4664                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%sËâË¡¤ò»È¤¨¤¿¡£", realm_names[i+1]);
4665 #else
4666                         fprintf(fff, "\n You were able to use %s magic before.", realm_names[i+1]);
4667 #endif
4668                 }
4669         }
4670
4671 #ifdef JP
4672 fprintf(fff, "\n\n  [¥×¥ì¥¤¥ä¡¼¤ÎÆÁ]\n\n");
4673 #else
4674         fprintf(fff, "\n\n  [Virtues]\n\n");
4675 #endif
4676
4677 #ifdef JP
4678         fprintf(fff, "°À­ : %s\n", your_alignment());
4679 #else
4680         fprintf(fff, "Your alighnment : %s\n", your_alignment());
4681 #endif
4682         fprintf(fff, "\n");
4683         dump_virtues(fff);
4684
4685         if (p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3)
4686         {
4687 #ifdef JP
4688 fprintf(fff, "\n\n  [ÆÍÁ³ÊÑ°Û]\n\n");
4689 #else
4690                 fprintf(fff, "\n\n  [Mutations]\n\n");
4691 #endif
4692
4693                 dump_mutations(fff);
4694         }
4695
4696
4697         /* Skip some lines */
4698         fprintf(fff, "\n\n");
4699
4700
4701         /* Dump the equipment */
4702         if (equip_cnt)
4703         {
4704 #ifdef JP
4705 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤ÎÁõÈ÷ ]\n\n");
4706 #else
4707                 fprintf(fff, "  [Character Equipment]\n\n");
4708 #endif
4709
4710                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4711                 {
4712                         object_desc(o_name, &inventory[i], TRUE, 3);
4713                         if ((i == INVEN_LARM) && p_ptr->ryoute)
4714 #ifdef JP
4715                                 strcpy(o_name, "(Éð´ï¤òξ¼ê»ý¤Á)");
4716 #else
4717                                 strcpy(o_name, "(wielding with two-hands)");
4718 #endif
4719                         fprintf(fff, "%c%s %s\n",
4720                                 index_to_label(i), paren, o_name);
4721                 }
4722                 fprintf(fff, "\n\n");
4723         }
4724
4725         /* Dump the inventory */
4726 #ifdef JP
4727 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤Î»ý¤Áʪ ]\n\n");
4728 #else
4729         fprintf(fff, "  [Character Inventory]\n\n");
4730 #endif
4731
4732         for (i = 0; i < INVEN_PACK; i++)
4733         {
4734                 /* Don't dump the empty slots */
4735                 if (!inventory[i].k_idx) break;
4736
4737                 /* Dump the inventory slots */
4738                 object_desc(o_name, &inventory[i], TRUE, 3);
4739                 fprintf(fff, "%c%s %s\n", index_to_label(i), paren, o_name);
4740         }
4741
4742         /* Add an empty line */
4743         fprintf(fff, "\n\n");
4744
4745         process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
4746
4747         /* Print all homes in the different towns */
4748         st_ptr = &town[1].store[STORE_HOME];
4749
4750         /* Home -- if anything there */
4751         if (st_ptr->stock_num)
4752         {
4753                 /* Header with name of the town */
4754 #ifdef JP
4755                 fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
4756 #else
4757                 fprintf(fff, "  [Home Inventory]\n");
4758 #endif
4759                 x=1;
4760
4761                 /* Dump all available items */
4762                 for (i = 0; i < st_ptr->stock_num; i++)
4763                 {
4764                         if ((i % 12) == 0)
4765 #ifdef JP
4766                                 fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4767 #else
4768                                 fprintf(fff, "\n ( page %d )\n", x++);
4769 #endif
4770                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4771                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4772                 }
4773
4774                 /* Add an empty line */
4775                 fprintf(fff, "\n\n");
4776         }
4777
4778
4779         /* Print all homes in the different towns */
4780         st_ptr = &town[1].store[STORE_MUSEUM];
4781
4782         /* Home -- if anything there */
4783         if (st_ptr->stock_num)
4784         {
4785                 /* Header with name of the town */
4786 #ifdef JP
4787                 fprintf(fff, "  [ Çîʪ´Û¤Î¥¢¥¤¥Æ¥à ]\n");
4788 #else
4789                 fprintf(fff, "  [Museum]\n");
4790 #endif
4791                 x=1;
4792
4793                 /* Dump all available items */
4794                 for (i = 0; i < st_ptr->stock_num; i++)
4795                 {
4796 #ifdef JP
4797                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4798                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4799                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4800 #else
4801                 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
4802                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4803                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4804 #endif
4805
4806                 }
4807
4808                 /* Add an empty line */
4809                 fprintf(fff, "\n\n");
4810         }
4811
4812         return 0;
4813 }
4814
4815 /*
4816  * Hack -- Dump a character description file
4817  *
4818  * XXX XXX XXX Allow the "full" flag to dump additional info,
4819  * and trigger its usage from various places in the code.
4820  */
4821 errr file_character(cptr name, bool full)
4822 {
4823         int             fd = -1;
4824         FILE            *fff = NULL;
4825         char            buf[1024];
4826
4827         /* Drop priv's */
4828         safe_setuid_drop();
4829
4830         /* Build the filename */
4831         path_build(buf, 1024, ANGBAND_DIR_USER, name);
4832
4833         /* File type is "TEXT" */
4834         FILE_TYPE(FILE_TYPE_TEXT);
4835
4836         /* Check for existing file */
4837         fd = fd_open(buf, O_RDONLY);
4838
4839         /* Existing file */
4840         if (fd >= 0)
4841         {
4842                 char out_val[160];
4843
4844                 /* Close the file */
4845                 (void)fd_close(fd);
4846
4847                 /* Build query */
4848 #ifdef JP
4849 (void)sprintf(out_val, "¸½Â¸¤¹¤ë¥Õ¥¡¥¤¥ë %s ¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«? ", buf);
4850 #else
4851                 (void)sprintf(out_val, "Replace existing file %s? ", buf);
4852 #endif
4853
4854
4855                 /* Ask */
4856                 if (get_check(out_val)) fd = -1;
4857         }
4858
4859         /* Open the non-existing file */
4860         if (fd < 0) fff = my_fopen(buf, "w");
4861
4862         /* Grab priv's */
4863         safe_setuid_grab();
4864
4865
4866         /* Invalid file */
4867         if (!fff)
4868         {
4869                 /* Message */
4870 #ifdef JP
4871 msg_format("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4872 #else
4873                 msg_format("Character dump failed!");
4874 #endif
4875
4876                 msg_print(NULL);
4877
4878                 /* Error */
4879                 return (-1);
4880         }
4881
4882         (void)make_character_dump(fff);
4883
4884         /* Close it */
4885         my_fclose(fff);
4886
4887
4888         /* Message */
4889 #ifdef JP
4890 msg_print("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤ËÀ®¸ù¤·¤Þ¤·¤¿¡£");
4891 #else
4892         msg_print("Character dump successful.");
4893 #endif
4894
4895         msg_print(NULL);
4896
4897         /* Success */
4898         return (0);
4899 }
4900
4901
4902 /*
4903  * Recursive file perusal.
4904  *
4905  * Return FALSE on 'Q', otherwise TRUE.
4906  *
4907  * Process various special text in the input file, including
4908  * the "menu" structures used by the "help file" system.
4909  *
4910  * XXX XXX XXX Consider using a temporary file.
4911  *
4912  * XXX XXX XXX Allow the user to "save" the current file.
4913  */
4914 bool show_file(bool show_version, cptr name, cptr what, int line, int mode)
4915 {
4916         int i, n, k;
4917
4918         /* Number of "real" lines passed by */
4919         int next = 0;
4920
4921         /* Number of "real" lines in the file */
4922         int size = 0;
4923
4924         /* Backup value for "line" */
4925         int back = 0;
4926
4927         /* Loop counter */
4928         int cnt;
4929
4930         /* This screen has sub-screens */
4931         bool menu = FALSE;
4932
4933         /* Current help file */
4934         FILE *fff = NULL;
4935
4936         /* Find this string (if any) */
4937         cptr find = NULL;
4938
4939         /* Jump to this tag */
4940         cptr tag = NULL;
4941
4942         /* Hold a string to find */
4943         char finder[81];
4944
4945         /* Hold a string to show */
4946         char shower[81];
4947
4948         /* Filename */
4949         char filename[1024];
4950
4951         /* Describe this thing */
4952         char caption[128];
4953
4954         /* Path buffer */
4955         char path[1024];
4956
4957         /* General buffer */
4958         char buf[1024];
4959
4960         /* Lower case version of the buffer, for searching */
4961         char lc_buf[1024];
4962
4963         /* Aux pointer for making lc_buf (and find!) lowercase */
4964         cptr lc_buf_ptr;
4965
4966         /* Sub-menu information */
4967         char hook[68][32];
4968
4969         /* Tags for in-file references */
4970         int tags[68];
4971
4972         bool reverse = (line < 0);
4973
4974         /* Wipe finder */
4975         strcpy(finder, "");
4976
4977         /* Wipe shower */
4978         strcpy(shower, "");
4979
4980         /* Wipe caption */
4981         strcpy(caption, "");
4982
4983         /* Wipe the hooks */
4984         for (i = 0; i < 68; i++)
4985         {
4986                 hook[i][0] = '\0';
4987         }
4988
4989         /* Copy the filename */
4990         strcpy(filename, name);
4991
4992         n = strlen(filename);
4993
4994         /* Extract the tag from the filename */
4995         for (i = 0; i < n; i++)
4996         {
4997                 if (filename[i] == '#')
4998                 {
4999                         filename[i] = '\0';
5000                         tag = filename + i + 1;
5001                         break;
5002                 }
5003         }
5004
5005         /* Redirect the name */
5006         name = filename;
5007
5008         /* Hack XXX XXX XXX */
5009         if (what)
5010         {
5011                 /* Caption */
5012                 strcpy(caption, what);
5013
5014                 /* Access the "file" */
5015                 strcpy(path, name);
5016
5017                 /* Open */
5018                 fff = my_fopen(path, "r");
5019         }
5020
5021         /* Look in "help" */
5022         if (!fff)
5023         {
5024                 /* Caption */
5025 #ifdef JP
5026 sprintf(caption, "¥Ø¥ë¥×¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5027 #else
5028                 sprintf(caption, "Help file '%s'", name);
5029 #endif
5030
5031
5032                 /* Build the filename */
5033                 path_build(path, 1024, ANGBAND_DIR_HELP, name);
5034
5035                 /* Open the file */
5036                 fff = my_fopen(path, "r");
5037         }
5038
5039         /* Look in "info" */
5040         if (!fff)
5041         {
5042                 /* Caption */
5043 #ifdef JP
5044 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5045 #else
5046                 sprintf(caption, "Info file '%s'", name);
5047 #endif
5048
5049
5050                 /* Build the filename */
5051                 path_build(path, 1024, ANGBAND_DIR_INFO, name);
5052
5053                 /* Open the file */
5054                 fff = my_fopen(path, "r");
5055         }
5056
5057         /* Look in "info" */
5058         if (!fff)
5059         {
5060                 /* Build the filename */
5061                 path_build(path, 1024, ANGBAND_DIR, name);
5062
5063                 for (i = 0; path[i]; i++)
5064                         if ('\\' == path[i])
5065                                 path[i] = PATH_SEP[0];
5066
5067                 /* Caption */
5068 #ifdef JP
5069 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5070 #else
5071                 sprintf(caption, "Info file '%s'", name);
5072 #endif
5073
5074                 /* Open the file */
5075                 fff = my_fopen(path, "r");
5076         }
5077
5078         /* Oops */
5079         if (!fff)
5080         {
5081                 /* Message */
5082 #ifdef JP
5083 msg_format("'%s'¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Þ¤»¤ó¡£", name);
5084 #else
5085                 msg_format("Cannot open '%s'.", name);
5086 #endif
5087
5088                 msg_print(NULL);
5089
5090                 /* Oops */
5091                 return (TRUE);
5092         }
5093
5094
5095         /* Pre-Parse the file */
5096         while (TRUE)
5097         {
5098                 /* Read a line or stop */
5099                 if (my_fgets(fff, buf, 1024)) break;
5100
5101                 /* XXX Parse "menu" items */
5102                 if (prefix(buf, "***** "))
5103                 {
5104                         /* Notice "menu" requests */
5105                         if ((buf[6] == '[') && (isdigit(buf[7]) || isalpha(buf[7])))
5106                         {
5107                                 /* This is a menu file */
5108                                 menu = TRUE;
5109
5110                                 /* Extract the menu item */
5111                                 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
5112
5113                                 if ((buf[8] == ']') && (buf[9] == ' '))
5114                                 {
5115                                         /* Extract the menu item */
5116                                         strcpy(hook[k], buf + 10);
5117                                 }
5118                         }
5119                         /* Notice "tag" requests */
5120                         else if ((buf[6] == '<') && (isdigit(buf[7]) || isalpha(buf[7])) &&
5121                             (buf[8] == '>'))
5122                         {
5123                                 /* Extract the menu item */
5124                                 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
5125
5126                                 /* Extract the menu item */
5127                                 tags[k] = next;
5128                         }
5129
5130                         /* Skip this */
5131                         continue;
5132                 }
5133
5134                 /* Count the "real" lines */
5135                 next++;
5136         }
5137
5138         /* Save the number of "real" lines */
5139         size = next;
5140
5141         if (line == -1) line = ((size-1)/20)*20;
5142
5143         /* Go to the tagged line */
5144         if (tag)
5145                 line = tags[isdigit(tag[0]) ? D2I(tag[0]) : tag[0] - 'A' + 10];
5146
5147         /* Display the file */
5148         while (TRUE)
5149         {
5150                 /* Clear screen */
5151                 Term_clear();
5152
5153                 /* Restart when necessary */
5154                 if (line >= size) line = 0;
5155
5156
5157                 /* Re-open the file if needed */
5158                 if (next > line)
5159                 {
5160                         /* Close it */
5161                         my_fclose(fff);
5162
5163                         /* Hack -- Re-Open the file */
5164                         fff = my_fopen(path, "r");
5165
5166                         /* Oops */
5167                         if (!fff) return (FALSE);
5168
5169                         /* File has been restarted */
5170                         next = 0;
5171                 }
5172
5173                 /* Goto the selected line */
5174                 while (next < line)
5175                 {
5176                         /* Get a line */
5177                         if (my_fgets(fff, buf, 1024)) break;
5178
5179                         /* Skip tags/links */
5180                         if (prefix(buf, "***** ")) continue;
5181
5182                         /* Count the lines */
5183                         next++;
5184                 }
5185
5186                 /* Dump the next 20 lines of the file */
5187                 for (i = 0; i < 20; )
5188                 {
5189                         /* Hack -- track the "first" line */
5190                         if (!i) line = next;
5191
5192                         /* Get a line of the file or stop */
5193                         if (my_fgets(fff, buf, 1024)) break;
5194
5195                         /* Hack -- skip "special" lines */
5196                         if (prefix(buf, "***** ")) continue;
5197
5198                         /* Count the "real" lines */
5199                         next++;
5200
5201                         /* Make a lower case version of buf for searching */
5202                         strcpy(lc_buf, buf);
5203
5204                         for (lc_buf_ptr = lc_buf; *lc_buf_ptr != 0; lc_buf_ptr++)
5205                         {
5206 #ifdef JP
5207                                 if (iskanji(*lc_buf_ptr))
5208                                         lc_buf_ptr++;
5209                                 else
5210 #endif
5211                                         lc_buf[lc_buf_ptr-lc_buf] = tolower(*lc_buf_ptr);
5212                         }
5213
5214                         /* Hack -- keep searching */
5215                         if (find && !i && !strstr(lc_buf, find)) continue;
5216
5217                         /* Hack -- stop searching */
5218                         find = NULL;
5219
5220                         /* Dump the line */
5221                         Term_putstr(0, i+2, -1, TERM_WHITE, buf);
5222
5223                         /* Hilite "shower" */
5224                         if (shower[0])
5225                         {
5226                                 cptr str = lc_buf;
5227
5228                                 /* Display matches */
5229                                 while ((str = strstr(str, shower)) != NULL)
5230                                 {
5231                                         int len = strlen(shower);
5232
5233                                         /* Display the match */
5234                                         Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]);
5235
5236                                         /* Advance */
5237                                         str += len;
5238                                 }
5239                         }
5240
5241                         /* Count the printed lines */
5242                         i++;
5243                 }
5244
5245                 /* Hack -- failed search */
5246                 if (find)
5247                 {
5248                         bell();
5249                         line = back;
5250                         find = NULL;
5251                         continue;
5252                 }
5253
5254
5255                 /* Show a general "title" */
5256                 if (show_version)
5257                 {
5258 #ifdef JP
5259 prt(format("[ÊѶòÈÚÅÜ %d.%d.%d, %s, %d/%d]",
5260 #else
5261                 prt(format("[Hengband %d.%d.%d, %s, Line %d/%d]",
5262 #endif
5263
5264                            FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH,
5265                            caption, line, size), 0, 0);
5266                 }
5267                 else
5268                 {
5269 #ifdef JP
5270 prt(format("[%s, %d/%d]",
5271 #else
5272                         prt(format("[%s, Line %d/%d]",
5273 #endif
5274                                    caption, line, size), 0, 0);
5275                 }
5276
5277                 /* Prompt -- menu screen */
5278                 if (menu)
5279                 {
5280                         /* Wait for it */
5281 #ifdef JP
5282 prt("[ ÈÖ¹æ¤òÆþÎϤ·¤Æ²¼¤µ¤¤( ESC¤Ç½ªÎ» ) ]", 23, 0);
5283 #else
5284                         prt("[Press a Number, or ESC to exit.]", 23, 0);
5285 #endif
5286
5287                 }
5288
5289                 /* Prompt -- small files */
5290                 else if (size <= 20)
5291                 {
5292                         /* Wait for it */
5293 #ifdef JP
5294 prt("[¥­¡¼:(?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5295 #else
5296                         prt("[Press ESC to exit.]", 23, 0);
5297 #endif
5298
5299                 }
5300
5301                 /* Prompt -- large files */
5302                 else
5303                 {
5304 #ifdef JP
5305                         if(reverse)
5306                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢¬ (-)¢­ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5307                         else
5308                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢­ (-)¢¬ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5309 #else
5310                         prt("[Press Return, Space, -, =, /, |, or ESC to exit.]", 23, 0);
5311 #endif
5312                 }
5313
5314                 /* Get a keypress */
5315                 k = inkey();
5316
5317                 /* Hack -- return to last screen */
5318                 if (k == '<') break;
5319
5320                 /* Show the help for the help */
5321                 if (k == '?')
5322                 {
5323                         /* Hack - prevent silly recursion */
5324 #ifdef JP
5325                         if (strcmp(name, "jhelpinfo.txt") != 0)
5326                                 show_file(TRUE, "jhelpinfo.txt", NULL, 0, mode);
5327 #else
5328                         if (strcmp(name, "helpinfo.txt") != 0)
5329                                 show_file(TRUE, "helpinfo.txt", NULL, 0, mode);
5330 #endif
5331                 }
5332
5333                 /* Hack -- try showing */
5334                 if (k == '=')
5335                 {
5336                         /* Get "shower" */
5337 #ifdef JP
5338 prt("¶¯Ä´: ", 23, 0);
5339 #else
5340                         prt("Show: ", 23, 0);
5341 #endif
5342
5343                         (void)askfor_aux(shower, 80);
5344                 }
5345
5346                 /* Hack -- try finding */
5347                 if (k == '/')
5348                 {
5349                         /* Get "finder" */
5350 #ifdef JP
5351 prt("¸¡º÷: ", 23, 0);
5352 #else
5353                         prt("Find: ", 23, 0);
5354 #endif
5355
5356
5357                         if (askfor_aux(finder, 80))
5358                         {
5359                                 /* Find it */
5360                                 find = finder;
5361                                 back = line;
5362                                 line = line + 1;
5363
5364                                 /* Make finder lowercase */
5365                                 for (cnt = 0; finder[cnt] != 0; cnt++)
5366                                 {
5367 #ifdef JP
5368                                         if (iskanji(finder[cnt]))
5369                                                 cnt++;
5370                                         else
5371 #endif
5372                                                 finder[cnt] = tolower(finder[cnt]);
5373                                 }
5374
5375                                 /* Show it */
5376                                 strcpy(shower, finder);
5377                         }
5378                 }
5379
5380                 /* Hack -- go to a specific line */
5381                 if (k == '#')
5382                 {
5383                         char tmp[81];
5384 #ifdef JP
5385 prt("¹Ô: ", 23, 0);
5386 #else
5387                         prt("Goto Line: ", 23, 0);
5388 #endif
5389
5390                         strcpy(tmp, "0");
5391
5392                         if (askfor_aux(tmp, 80))
5393                         {
5394                                 line = atoi(tmp);
5395                         }
5396                 }
5397
5398                 /* Hack -- go to a specific file */
5399                 if (k == '%')
5400                 {
5401                         char tmp[81];
5402 #ifdef JP
5403 prt("¥Õ¥¡¥¤¥ë¡¦¥Í¡¼¥à: ", 23, 0);
5404 strcpy(tmp, "jhelp.hlp");
5405 #else
5406                         prt("Goto File: ", 23, 0);
5407                         strcpy(tmp, "help.hlp");
5408 #endif
5409
5410
5411                         if (askfor_aux(tmp, 80))
5412                         {
5413                                 if (!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5414                         }
5415                 }
5416
5417                 /* Hack -- Allow backing up */
5418                 if (k == '-')
5419                 {
5420                         line = line + (reverse ? 20 : -20);
5421                         if (line < 0) line = ((size-1)/20)*20;
5422                 }
5423
5424                 /* Hack -- Advance a single line */
5425                 if ((k == '\n') || (k == '\r'))
5426                 {
5427                         line = line + (reverse ? -1 : 1);
5428                         if (line < 0) line = ((size-1)/20)*20;
5429                 }
5430
5431                 /* Advance one page */
5432                 if (k == ' ')
5433                 {
5434                         line = line + (reverse ? -20 : 20);
5435                         if (line < 0) line = ((size-1)/20)*20;
5436                 }
5437
5438 #ifdef JP_FALSE
5439                 /* ÆüËܸìÈǤÇÄɲ䵤줿¥Ø¥ë¥×¤Îɽ¼¨ */
5440                 /* ¤¢¤Þ¤ê¤è¤¤½èÍý¤Î»ÅÊý¤È¤Ï»×¤¨¤Ê¤¤¡¦¡¦¡¦¤¹¤Þ¤ó */
5441
5442                 /* ´Ê°×¥³¥Þ¥ó¥É°ìÍ÷ */
5443                 if (menu && (k == 'c' || k == 'C'))
5444                 {
5445                         char tmp[80];
5446                         switch (rogue_like_commands)
5447                         {
5448                                 case TRUE:
5449                                 {
5450                                         strcpy(tmp, "j_com_r.txt");
5451                                         if(!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5452                                         break;
5453                                 }
5454                                 case FALSE:
5455                                 {
5456                                         strcpy(tmp, "j_com_o.txt");
5457                                         if(!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5458                                         break;
5459                                 }
5460                         }
5461                 }
5462
5463 #endif
5464                 /* Recurse on numbers */
5465                 if (menu)
5466                 {
5467                         int key = -1;
5468
5469                         if (isdigit(k)) key = D2I(k);
5470                         else if (isalpha(k)) key = k - 'A' + 10;
5471
5472                         if ((key > -1) && hook[key][0])
5473                         {
5474                                 /* Recurse on that file */
5475                                 if (!show_file(TRUE, hook[key], NULL, 0, mode))
5476                                         k = 'q';
5477                         }
5478                 }
5479
5480                 /* Hack, dump to file */
5481                 if (k == '|')
5482                 {
5483                         FILE *ffp;
5484                         char buff[1024];
5485                         char xtmp[82];
5486
5487                         strcpy (xtmp, "");
5488
5489 #ifdef JP
5490 if (get_string("¥Õ¥¡¥¤¥ë̾: ", xtmp, 80))
5491 #else
5492                         if (get_string("File name: ", xtmp, 80))
5493 #endif
5494
5495                         {
5496                                 if (xtmp[0] && (xtmp[0] != ' '))
5497                                 {
5498                                 }
5499                         }
5500                         else
5501                         {
5502                                 continue;
5503                         }
5504
5505                         /* Build the filename */
5506                         path_build(buff, 1024, ANGBAND_DIR_USER, xtmp);
5507
5508                         /* Close it */
5509                         my_fclose(fff);
5510
5511                         /* Hack -- Re-Open the file */
5512                         fff = my_fopen(path, "r");
5513
5514                         ffp = my_fopen(buff, "w");
5515
5516                         /* Oops */
5517                         if (!(fff && ffp))
5518                         {
5519 #ifdef JP
5520 msg_print("¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£");
5521 #else
5522                                 msg_print("Failed to open file.");
5523 #endif
5524
5525                                 k = ESCAPE;
5526                                 break;
5527                         }
5528
5529                         sprintf(xtmp, "%s: %s", player_name, what);
5530                         my_fputs(ffp, xtmp, 80);
5531                         my_fputs(ffp, "\n", 80);
5532
5533                         while (!my_fgets(fff, buff, 80))
5534                                 my_fputs(ffp, buff, 80);
5535
5536                         /* Close it */
5537                         my_fclose(fff);
5538                         my_fclose(ffp);
5539
5540                         /* Hack -- Re-Open the file */
5541                         fff = my_fopen(path, "r");
5542                 }
5543
5544                 /* Exit on escape */
5545                 if (k == ESCAPE) break;
5546                 if (k == 'q') break;
5547         }
5548
5549         /* Close the file */
5550         my_fclose(fff);
5551
5552         /* Escape */
5553         if (k == 'q') return (FALSE);
5554
5555         /* Normal return */
5556         return (TRUE);
5557 }
5558
5559
5560 /*
5561  * Peruse the On-Line-Help
5562  */
5563 void do_cmd_help(void)
5564 {
5565         /* Save screen */
5566         screen_save();
5567
5568         /* Peruse the main help file */
5569 #ifdef JP
5570 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
5571 #else
5572         (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
5573 #endif
5574
5575
5576         /* Load screen */
5577         screen_load();
5578 }
5579
5580
5581 /*
5582  * Process the player name.
5583  * Extract a clean "base name".
5584  * Build the savefile name if needed.
5585  */
5586 void process_player_name(bool sf)
5587 {
5588         int i, k = 0;
5589
5590
5591         /* Cannot be too long */
5592 #if defined(MACINTOSH) || defined(MSDOS) || defined(USE_EMX) || defined(AMIGA) || defined(ACORN) || defined(VM)
5593 #ifdef MSDOS
5594         if (strlen(player_name) > 8)
5595 #else
5596         if (strlen(player_name) > 15)
5597 #endif
5598         {
5599                 /* Name too long */
5600 #ifdef JP
5601 quit_fmt("'%s'¤È¤¤¤¦Ì¾Á°¤ÏŤ¹¤®¤Þ¤¹¡ª", player_name);
5602 #else
5603                 quit_fmt("The name '%s' is too long!", player_name);
5604 #endif
5605
5606         }
5607 #endif
5608
5609         /* Cannot contain "icky" characters */
5610         for (i = 0; player_name[i]; i++)
5611         {
5612                 /* No control characters */
5613 #ifdef JP
5614                 if (iskanji(player_name[i])){i++;continue;}
5615                 if (iscntrl( (unsigned char)player_name[i]))
5616 #else
5617                 if (iscntrl(player_name[i]))
5618 #endif
5619
5620                 {
5621                         /* Illegal characters */
5622 #ifdef JP
5623 quit_fmt("'%s' ¤È¤¤¤¦Ì¾Á°¤ÏÉÔÀµ¤Ê¥³¥ó¥È¥í¡¼¥ë¥³¡¼¥É¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£", player_name);
5624 #else
5625                         quit_fmt("The name '%s' contains control chars!", player_name);
5626 #endif
5627
5628                 }
5629         }
5630
5631
5632 #ifdef MACINTOSH
5633
5634         /* Extract "useful" letters */
5635         for (i = 0; player_name[i]; i++)
5636         {
5637 #ifdef JP
5638                 unsigned char c = player_name[i];
5639 #else
5640                 char c = player_name[i];
5641 #endif
5642
5643
5644                 /* Convert "dot" to "underscore" */
5645                 if (c == '.') c = '_';
5646
5647                 /* Accept all the letters */
5648                 player_base[k++] = c;
5649         }
5650
5651 #else
5652
5653         /* Extract "useful" letters */
5654         for (i = 0; player_name[i]; i++)
5655         {
5656 #ifdef JP
5657                 unsigned char c = player_name[i];
5658 #else
5659                 char c = player_name[i];
5660 #endif
5661
5662                 /* Accept some letters */
5663 #ifdef JP
5664                 if(iskanji(c)){
5665                   if(k + 2 >= sizeof(player_base) || !player_name[i+1]) break;
5666                   player_base[k++] = c;
5667                   i++;
5668                   player_base[k++] = player_name[i];
5669                 }
5670 #ifdef SJIS
5671                 else if (iskana(c)) player_base[k++] = c;
5672 #endif
5673                 else
5674 #endif
5675                 /* Convert path separator to underscore */
5676                 if (!strncmp(PATH_SEP, player_name+i, strlen(PATH_SEP))){
5677                         player_base[k++] = '_';
5678                         i += strlen(PATH_SEP);
5679                 }
5680 #ifdef MSDOS
5681                 /* Convert space, dot, and underscore to underscore */
5682                 else if (strchr(". _", c)) player_base[k++] = '_';
5683 #endif
5684                 else if (isprint(c)) player_base[k++] = c;
5685         }
5686
5687 #endif
5688
5689
5690 #if defined(WINDOWS) || defined(MSDOS)
5691
5692         /* Hack -- max length */
5693         if (k > 8) k = 8;
5694
5695 #endif
5696
5697         /* Terminate */
5698         player_base[k] = '\0';
5699
5700         /* Require a "base" name */
5701         if (!player_base[0]) strcpy(player_base, "PLAYER");
5702
5703
5704 #ifdef SAVEFILE_MUTABLE
5705
5706         /* Accept */
5707         sf = TRUE;
5708
5709 #endif
5710         if (!savefile_base[0] && savefile[0])
5711         {
5712                 cptr s;
5713                 s = savefile;
5714                 while (1)
5715                 {
5716                         cptr t;
5717                         t = strstr(s, PATH_SEP);
5718                         if (!t)
5719                                 break;
5720                         s = t+1;
5721                 }
5722                 strcpy(savefile_base, s);
5723         }
5724
5725         if (!savefile_base[0] || !savefile[0])
5726                 sf = TRUE;
5727
5728         /* Change the savefile name */
5729         if (sf)
5730         {
5731                 char temp[128];
5732
5733                 strcpy(savefile_base, player_base);
5734
5735 #ifdef SAVEFILE_USE_UID
5736                 /* Rename the savefile, using the player_uid and player_base */
5737                 (void)sprintf(temp, "%d.%s", player_uid, player_base);
5738 #else
5739                 /* Rename the savefile, using the player_base */
5740                 (void)sprintf(temp, "%s", player_base);
5741 #endif
5742
5743 #ifdef VM
5744                 /* Hack -- support "flat directory" usage on VM/ESA */
5745                 (void)sprintf(temp, "%s.sv", player_base);
5746 #endif /* VM */
5747
5748                 /* Build the filename */
5749                 path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp);
5750         }
5751 }
5752
5753
5754 /*
5755  * Gets a name for the character, reacting to name changes.
5756  *
5757  * Assumes that "display_player(0)" has just been called
5758  *
5759  * Perhaps we should NOT ask for a name (at "birth()") on
5760  * Unix machines?  XXX XXX
5761  *
5762  * What a horrible name for a global function.  XXX XXX XXX
5763  */
5764 void get_name(void)
5765 {
5766         char tmp[64];
5767
5768         /* Save the player name */
5769         strcpy(tmp, player_name);
5770
5771         /* Prompt for a new name */
5772 #ifdef JP
5773         if (get_string("¥­¥ã¥é¥¯¥¿¡¼¤Î̾Á°¤òÆþÎϤ·¤Æ²¼¤µ¤¤: ", tmp, 15))
5774 #else
5775         if (get_string("Enter a name for your character: ", tmp, 15))
5776 #endif
5777         {
5778                 /* Use the name */
5779                 strcpy(player_name, tmp);
5780         }
5781         else if (0 == strlen(player_name))
5782         {
5783                 /* Use default name */
5784                 strcpy(player_name, "PLAYER");
5785         }
5786
5787         /* Process the player name */
5788         process_player_name(FALSE);
5789
5790         strcpy(tmp,ap_ptr->title);
5791 #ifdef JP
5792         if(ap_ptr->no == 1)
5793                 strcat(tmp,"¤Î");
5794 #else
5795         strcat(tmp, " ");
5796 #endif
5797         strcat(tmp,player_name);
5798
5799         /* Re-Draw the name (in light blue) */
5800         c_put_str(TERM_L_BLUE, tmp, 1, 34);
5801
5802         /* Erase the prompt, etc */
5803         clear_from(22);
5804 }
5805
5806
5807
5808 /*
5809  * Hack -- commit suicide
5810  */
5811 void do_cmd_suicide(void)
5812 {
5813         int i;
5814
5815         /* Flush input */
5816         flush();
5817
5818         /* Verify Retirement */
5819         if (total_winner)
5820         {
5821                 /* Verify */
5822 #ifdef JP
5823 if (!get_check("°úÂष¤Þ¤¹¤«? ")) return;
5824 #else
5825                 if (!get_check("Do you want to retire? ")) return;
5826 #endif
5827
5828         }
5829
5830         /* Verify Suicide */
5831         else
5832         {
5833                 /* Verify */
5834 #ifdef JP
5835 if (!get_check("ËÜÅö¤Ë¼«»¦¤·¤Þ¤¹¤«¡©")) return;
5836 #else
5837                 if (!get_check("Do you really want to commit suicide? ")) return;
5838 #endif
5839         }
5840
5841
5842         if (!noscore)
5843         {
5844                 /* Special Verification for suicide */
5845 #ifdef JP
5846 prt("³Îǧ¤Î¤¿¤á '@' ¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 0);
5847 #else
5848                 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
5849 #endif
5850
5851                 flush();
5852                 i = inkey();
5853                 prt("", 0, 0);
5854                 if (i != '@') return;
5855         }
5856
5857         /* Stop playing */
5858         alive = FALSE;
5859
5860         /* Kill the player */
5861         death = TRUE;
5862
5863         /* Leaving */
5864         p_ptr->leaving = TRUE;
5865
5866         if (!total_winner)
5867         {
5868 #ifdef JP
5869                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤ËÀä˾¤·¤Æ¼«»¦¤·¤¿¡£");
5870                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
5871 #else
5872                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "give up all hope to commit suicide.");
5873                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "--------   Game  Over   --------");
5874 #endif
5875                 do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
5876         }
5877
5878         /* Cause of death */
5879 #ifdef JP
5880 (void)strcpy(died_from, "ÅÓÃ潪λ");
5881 #else
5882         (void)strcpy(died_from, "Quitting");
5883 #endif
5884
5885 }
5886
5887
5888
5889 /*
5890  * Save the game
5891  */
5892 void do_cmd_save_game(int is_autosave)
5893 {
5894         /* Autosaves do not disturb */
5895         if (is_autosave)
5896         {
5897 #ifdef JP
5898 msg_print("¼«Æ°¥»¡¼¥ÖÃæ");
5899 #else
5900                 msg_print("Autosaving the game...");
5901 #endif
5902
5903         }
5904         else
5905         {
5906                 /* Disturb the player */
5907                 disturb(1, 0);
5908         }
5909
5910         /* Clear messages */
5911         msg_print(NULL);
5912
5913         /* Handle stuff */
5914         handle_stuff();
5915
5916         /* Message */
5917 #ifdef JP
5918 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹...", 0, 0);
5919 #else
5920         prt("Saving game...", 0, 0);
5921 #endif
5922
5923
5924         /* Refresh */
5925         Term_fresh();
5926
5927         /* The player is not dead */
5928 #ifdef JP
5929 (void)strcpy(died_from, "(¥»¡¼¥Ö)");
5930 #else
5931         (void)strcpy(died_from, "(saved)");
5932 #endif
5933
5934
5935         /* Forbid suspend */
5936         signals_ignore_tstp();
5937
5938         /* Save the player */
5939         if (save_player())
5940         {
5941 #ifdef JP
5942 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ½ªÎ»", 0, 0);
5943 #else
5944                 prt("Saving game... done.", 0, 0);
5945 #endif
5946
5947         }
5948
5949         /* Save failed (oops) */
5950         else
5951         {
5952 #ifdef JP
5953 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ¼ºÇÔ¡ª", 0, 0);
5954 #else
5955                 prt("Saving game... failed!", 0, 0);
5956 #endif
5957
5958         }
5959
5960         /* Allow suspend again */
5961         signals_handle_tstp();
5962
5963         /* Refresh */
5964         Term_fresh();
5965
5966         /* Note that the player is not dead */
5967 #ifdef JP
5968 (void)strcpy(died_from, "(¸µµ¤¤ËÀ¸¤­¤Æ¤¤¤ë)");
5969 #else
5970         (void)strcpy(died_from, "(alive and well)");
5971 #endif
5972
5973 }
5974
5975
5976 /*
5977  * Save the game and exit
5978  */
5979 void do_cmd_save_and_exit(void)
5980 {
5981         alive = FALSE;
5982
5983         /* Leaving */
5984         p_ptr->leaving = TRUE;
5985 #ifdef JP
5986         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "----¥²¡¼¥àÃæÃÇ----");
5987 #else
5988         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "---- Save and Exit Game ----");
5989 #endif
5990 }
5991
5992
5993 /*
5994  * Hack -- Calculates the total number of points earned         -JWT-
5995  */
5996 long total_points(void)
5997 {
5998         int i, mult = 100;
5999         s16b max_dl = 0;
6000         u32b point, point_h, point_l;
6001         int arena_win = MIN(p_ptr->arena_number, MAX_ARENA_MONS);
6002
6003         if (stupid_monsters) mult -= 70;
6004         if (!preserve_mode) mult += 10;
6005         if (!autoroller) mult += 10;
6006         if (!smart_learn) mult -= 20;
6007         if (!terrain_streams) mult -= 20;
6008         if (smart_cheat) mult += 30;
6009         if (ironman_shops) mult += 50;
6010         if (ironman_small_levels) mult += 10;
6011         if (ironman_empty_levels) mult += 20;
6012         if (!powerup_home) mult += 50;
6013         if (ironman_rooms) mult += 100;
6014         if (ironman_nightmare) mult += 100;
6015
6016         if (mult < 5) mult = 5;
6017
6018         for (i = 0; i < max_d_idx; i++)
6019                 if(max_dlv[i] > max_dl)
6020                         max_dl = max_dlv[i];
6021
6022         point_l = (p_ptr->max_exp + (100 * max_dl));
6023         point_h = point_l / 0x10000L;
6024         point_l = point_l % 0x10000L;
6025         point_h *= mult;
6026         point_l *= mult;
6027         point_h += point_l / 0x10000L;
6028         point_l %= 0x10000L;
6029
6030         point_l += ((point_h % 100) << 16);
6031         point_h /= 100;
6032         point_l /= 100;
6033
6034         point = (point_h << 16) + (point_l);
6035         if (p_ptr->arena_number < 99)
6036                 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
6037
6038         if (ironman_downward) point *= 2;
6039         if (p_ptr->pclass == CLASS_BERSERKER)
6040         {
6041                 if ((p_ptr->prace == RACE_SPECTRE) || (p_ptr->prace == RACE_AMBERITE))
6042                         point = point / 5;
6043         }
6044
6045         if ((p_ptr->pseikaku == SEIKAKU_MUNCHKIN) && point)
6046         {
6047                 point = 1;
6048                 if (total_winner) point = 2;
6049         }
6050         if (easy_band) point = (0 - point);
6051
6052         return point;
6053 }
6054
6055
6056
6057 /*
6058  * Centers a string within a 31 character string                -JWT-
6059  */
6060 static void center_string(char *buf, cptr str)
6061 {
6062         int i, j;
6063
6064         /* Total length */
6065         i = strlen(str);
6066
6067         /* Necessary border */
6068         j = 15 - i / 2;
6069
6070         /* Mega-Hack */
6071         (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, "");
6072 }
6073
6074
6075 #if 0
6076 /*
6077  * Save a "bones" file for a dead character
6078  *
6079  * Note that we will not use these files until Angband 2.8.0, and
6080  * then we will only use the name and level on which death occured.
6081  *
6082  * Should probably attempt some form of locking...
6083  */
6084 static void make_bones(void)
6085 {
6086         FILE                *fp;
6087
6088         char                str[1024];
6089
6090
6091         /* Ignore wizards and borgs */
6092         if (!(noscore & 0x00FF))
6093         {
6094                 /* Ignore people who die in town */
6095                 if (dun_level)
6096                 {
6097                         char tmp[128];
6098
6099                         /* XXX XXX XXX "Bones" name */
6100                         sprintf(tmp, "bone.%03d", dun_level);
6101
6102                         /* Build the filename */
6103                         path_build(str, 1024, ANGBAND_DIR_BONE, tmp);
6104
6105                         /* Attempt to open the bones file */
6106                         fp = my_fopen(str, "r");
6107
6108                         /* Close it right away */
6109                         if (fp) my_fclose(fp);
6110
6111                         /* Do not over-write a previous ghost */
6112                         if (fp) return;
6113
6114                         /* File type is "TEXT" */
6115                         FILE_TYPE(FILE_TYPE_TEXT);
6116
6117                         /* Try to write a new "Bones File" */
6118                         fp = my_fopen(str, "w");
6119
6120                         /* Not allowed to write it?  Weird. */
6121                         if (!fp) return;
6122
6123                         /* Save the info */
6124                         fprintf(fp, "%s\n", player_name);
6125                         fprintf(fp, "%d\n", p_ptr->mhp);
6126                         fprintf(fp, "%d\n", p_ptr->prace);
6127                         fprintf(fp, "%d\n", p_ptr->pclass);
6128
6129                         /* Close and save the Bones file */
6130                         my_fclose(fp);
6131                 }
6132         }
6133 }
6134 #endif
6135
6136
6137 /*
6138  * Redefinable "print_tombstone" action
6139  */
6140 bool (*tombstone_aux)(void) = NULL;
6141
6142
6143 /*
6144  * Display a "tomb-stone"
6145  */
6146 static void print_tomb(void)
6147 {
6148         bool done = FALSE;
6149
6150         /* Do we use a special tombstone ? */
6151         if (tombstone_aux)
6152         {
6153                 /* Use tombstone hook */
6154                 done = (*tombstone_aux)();
6155         }
6156
6157         /* Print the text-tombstone */
6158         if (!done)
6159         {
6160                 cptr    p;
6161
6162                 char    tmp[160];
6163
6164                 char    buf[1024];
6165 #ifndef JP
6166                 char    dummy[80];
6167 #endif
6168
6169                 FILE        *fp;
6170
6171                 time_t  ct = time((time_t)0);
6172
6173
6174                 /* Clear screen */
6175                 Term_clear();
6176
6177                 /* Build the filename */
6178 #ifdef JP
6179                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead_j.txt");
6180 #else
6181                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt");
6182 #endif
6183
6184
6185                 /* Open the News file */
6186                 fp = my_fopen(buf, "r");
6187
6188                 /* Dump */
6189                 if (fp)
6190                 {
6191                         int i = 0;
6192
6193                         /* Dump the file to the screen */
6194                         while (0 == my_fgets(fp, buf, 1024))
6195                         {
6196                                 /* Display and advance */
6197                                 put_str(buf, i++, 0);
6198                         }
6199
6200                         /* Close */
6201                         my_fclose(fp);
6202                 }
6203
6204
6205                 /* King or Queen */
6206                 if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
6207                 {
6208 #ifdef JP
6209                 /* ±ÑÆüÀÚ¤êÂؤ¨ */
6210                   p= "°ÎÂç¤Ê¤ë¼Ô";
6211 #else
6212                         p = "Magnificent";
6213 #endif
6214
6215                 }
6216
6217                 /* Normal */
6218                 else
6219                 {
6220                         p =  player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
6221                 }
6222
6223                 center_string(buf, player_name);
6224                 put_str(buf, 6, 11);
6225
6226 #ifndef JP
6227                 center_string(buf, "the");
6228                 put_str(buf, 7, 11);
6229 #endif
6230
6231                 center_string(buf, p);
6232                 put_str(buf, 8, 11);
6233
6234
6235                 center_string(buf, cp_ptr->title);
6236
6237                 put_str(buf, 10, 11);
6238
6239 #ifdef JP
6240 (void)sprintf(tmp, "¥ì¥Ù¥ë: %d", (int)p_ptr->lev);
6241 #else
6242                 (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
6243 #endif
6244
6245                 center_string(buf, tmp);
6246                 put_str(buf, 11, 11);
6247
6248 #ifdef JP
6249 (void)sprintf(tmp, "·Ð¸³ÃÍ: %ld", (long)p_ptr->exp);
6250 #else
6251                 (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp);
6252 #endif
6253
6254                 center_string(buf, tmp);
6255                 put_str(buf, 12, 11);
6256
6257 #ifdef JP
6258 (void)sprintf(tmp, "½ê»ý¶â: %ld", (long)p_ptr->au);
6259 #else
6260                 (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au);
6261 #endif
6262
6263                 center_string(buf, tmp);
6264                 put_str(buf, 13, 11);
6265
6266 #ifdef JP
6267         /* Êè¤Ë¹ï¤à¸ÀÍÕ¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
6268         if (streq(died_from, "ÅÓÃ潪λ"))
6269         {
6270                 strcpy(tmp, "<¼«»¦>");
6271         }
6272         else
6273         {
6274                 if (streq(died_from, "ripe"))
6275                 {
6276                         strcpy(tmp, "°úÂà¸å¤ËÅ·¼÷¤òÁ´¤¦");
6277                 }
6278                 else if (streq(died_from, "Seppuku"))
6279                 {
6280                         strcpy(tmp, "¾¡Íø¤Î¸å¡¢ÀÚÊ¢");
6281                 }
6282                 else
6283                 {
6284                         strcpy(tmp, died_from);
6285                 }
6286         }
6287         center_string(buf, tmp);
6288         put_str(buf, 14, 11);
6289
6290         if(!streq(died_from, "ripe") && !streq(died_from, "Seppuku"))
6291         {
6292                 if( dun_level == 0 )
6293                 {
6294                         cptr town = (p_ptr->town_num ? "³¹" : "¹ÓÌî");
6295                         if(streq(died_from, "ÅÓÃ潪λ"))
6296                         {
6297                                 sprintf(tmp, "%s¤Ç»à¤ó¤À", town);
6298                         }
6299                         else
6300                         {
6301                                 sprintf(tmp, "¤Ë%s¤Ç»¦¤µ¤ì¤¿", town);
6302                         }
6303                 }
6304                 else
6305                 {
6306                         if(streq(died_from, "ÅÓÃ潪λ"))
6307                         {
6308                                 sprintf(tmp, "Ãϲ¼ %d ³¬¤Ç»à¤ó¤À", dun_level);
6309                         }
6310                         else
6311                         {
6312                                 sprintf(tmp, "¤ËÃϲ¼ %d ³¬¤Ç»¦¤µ¤ì¤¿", dun_level);
6313                         }
6314                 }
6315                 center_string(buf, tmp);
6316                 put_str(buf, 15, 11);
6317         }
6318 #else
6319                 (void)sprintf(tmp, "Killed on Level %d", dun_level);
6320                 center_string(buf, tmp);
6321                 put_str(buf, 14, 11);
6322
6323
6324                 if (strlen(died_from) > 24)
6325                 {
6326                         strncpy(dummy, died_from, 24);
6327                         dummy[24] = '\0';
6328                         (void)sprintf(tmp, "by %s.", dummy);
6329                 }
6330                 else
6331                         (void)sprintf(tmp, "by %s.", died_from);
6332
6333                 center_string(buf, tmp);
6334                 put_str(buf, 15, 11);
6335 #endif
6336
6337
6338
6339                 (void)sprintf(tmp, "%-.24s", ctime(&ct));
6340                 center_string(buf, tmp);
6341                 put_str(buf, 17, 11);
6342
6343 #ifdef JP
6344 msg_format("¤µ¤è¤¦¤Ê¤é¡¢%s!", player_name);
6345 #else
6346                 msg_format("Goodbye, %s!", player_name);
6347 #endif
6348
6349         }
6350 }
6351
6352
6353 /*
6354  * Display some character info
6355  */
6356 static void show_info(void)
6357 {
6358         int             i, j, k, l;
6359         object_type             *o_ptr;
6360         store_type              *st_ptr;
6361
6362         /* Hack -- Know everything in the inven/equip */
6363         for (i = 0; i < INVEN_TOTAL; i++)
6364         {
6365                 o_ptr = &inventory[i];
6366
6367                 /* Skip non-objects */
6368                 if (!o_ptr->k_idx) continue;
6369
6370                 /* Aware and Known */
6371                 object_aware(o_ptr);
6372                 object_known(o_ptr);
6373         }
6374
6375         for (i = 1; i < max_towns; i++)
6376         {
6377                 st_ptr = &town[i].store[STORE_HOME];
6378
6379                 /* Hack -- Know everything in the home */
6380                 for (j = 0; j < st_ptr->stock_num; j++)
6381                 {
6382                         o_ptr = &st_ptr->stock[j];
6383
6384                         /* Skip non-objects */
6385                         if (!o_ptr->k_idx) continue;
6386
6387                         /* Aware and Known */
6388                         object_aware(o_ptr);
6389                         object_known(o_ptr);
6390                 }
6391         }
6392
6393         /* Hack -- Recalculate bonuses */
6394         p_ptr->update |= (PU_BONUS);
6395
6396         /* Handle stuff */
6397         handle_stuff();
6398
6399         /* Flush all input keys */
6400         flush();
6401
6402         /* Flush messages */
6403         msg_print(NULL);
6404
6405
6406         /* Describe options */
6407 #ifdef JP
6408 prt("¥­¥ã¥é¥¯¥¿¡¼¤Îµ­Ï¿¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£", 21, 0);
6409 prt("¥ê¥¿¡¼¥ó¥­¡¼¤Ç¥­¥ã¥é¥¯¥¿¡¼¤ò¸«¤Þ¤¹¡£ESC¤ÇÃæÃǤ·¤Þ¤¹¡£", 22, 0);
6410 #else
6411         prt("You may now dump a character record to one or more files.", 21, 0);
6412         prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
6413 #endif
6414
6415
6416         /* Dump character records as requested */
6417         while (TRUE)
6418         {
6419                 char out_val[160];
6420
6421                 /* Prompt */
6422 #ifdef JP
6423 put_str("¥Õ¥¡¥¤¥ë¥Í¡¼¥à: ", 23, 0);
6424 #else
6425                 put_str("Filename: ", 23, 0);
6426 #endif
6427
6428
6429                 /* Default */
6430                 strcpy(out_val, "");
6431
6432                 /* Ask for filename (or abort) */
6433                 if (!askfor_aux(out_val, 60)) return;
6434
6435                 /* Return means "show on screen" */
6436                 if (!out_val[0]) break;
6437
6438                 /* Save screen */
6439                 screen_save();
6440
6441                 /* Dump a character file */
6442                 (void)file_character(out_val, TRUE);
6443
6444                 /* Load screen */
6445                 screen_load();
6446         }
6447
6448         update_playtime();
6449
6450         /* Display player */
6451         display_player(0);
6452
6453         /* Prompt for inventory */
6454 #ifdef JP
6455 prt("²¿¤«¥­¡¼¤ò²¡¤¹¤È¤µ¤é¤Ë¾ðÊó¤¬Â³¤­¤Þ¤¹ (ESC¤ÇÃæÃÇ): ", 23, 0);
6456 #else
6457         prt("Hit any key to see more information (ESC to abort): ", 23, 0);
6458 #endif
6459
6460
6461         /* Allow abort at this point */
6462         if (inkey() == ESCAPE) return;
6463
6464
6465         /* Show equipment and inventory */
6466
6467         /* Equipment -- if any */
6468         if (equip_cnt)
6469         {
6470                 Term_clear();
6471                 item_tester_full = TRUE;
6472                 (void)show_equip(0);
6473 #ifdef JP
6474 prt("ÁõÈ÷¤·¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6475 #else
6476                 prt("You are using: -more-", 0, 0);
6477 #endif
6478
6479                 if (inkey() == ESCAPE) return;
6480         }
6481
6482         /* Inventory -- if any */
6483         if (inven_cnt)
6484         {
6485                 Term_clear();
6486                 item_tester_full = TRUE;
6487                 (void)show_inven(0);
6488 #ifdef JP
6489 prt("»ý¤Ã¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6490 #else
6491                 prt("You are carrying: -more-", 0, 0);
6492 #endif
6493
6494                 if (inkey() == ESCAPE) return;
6495         }
6496
6497         /* Homes in the different towns */
6498         for (l = 1; l < max_towns; l++)
6499         {
6500                 st_ptr = &town[l].store[STORE_HOME];
6501
6502                 /* Home -- if anything there */
6503                 if (st_ptr->stock_num)
6504                 {
6505                         /* Display contents of the home */
6506                         for (k = 0, i = 0; i < st_ptr->stock_num; k++)
6507                         {
6508                                 /* Clear screen */
6509                                 Term_clear();
6510
6511                                 /* Show 12 items */
6512                                 for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++)
6513                                 {
6514                                         char o_name[MAX_NLEN];
6515                                         char tmp_val[80];
6516
6517                                         /* Acquire item */
6518                                         o_ptr = &st_ptr->stock[i];
6519
6520                                         /* Print header, clear line */
6521                                         sprintf(tmp_val, "%c) ", I2A(j));
6522                                         prt(tmp_val, j+2, 4);
6523
6524                                         /* Display object description */
6525                                         object_desc(o_name, o_ptr, TRUE, 3);
6526                                         c_put_str(tval_to_attr[o_ptr->tval], o_name, j+2, 7);
6527                                 }
6528
6529                                 /* Caption */
6530 #ifdef JP
6531 prt(format("²æ¤¬²È¤ËÃÖ¤¤¤Æ¤¢¤Ã¤¿¥¢¥¤¥Æ¥à ( %d ¥Ú¡¼¥¸): -³¤¯-", k+1), 0, 0);
6532 #else
6533                                 prt(format("Your home contains (page %d): -more-", k+1), 0, 0);
6534 #endif
6535
6536
6537                                 /* Wait for it */
6538                                 if (inkey() == ESCAPE) return;
6539                         }
6540                 }
6541         }
6542 }
6543
6544
6545 static bool check_score(void)
6546 {
6547         /* Clear screen */
6548         Term_clear();
6549
6550         /* No score file */
6551         if (highscore_fd < 0)
6552         {
6553 #ifdef JP
6554 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
6555 #else
6556                 msg_print("Score file unavailable.");
6557 #endif
6558
6559                 msg_print(NULL);
6560                 return FALSE;
6561         }
6562
6563 #ifndef SCORE_WIZARDS
6564         /* Wizard-mode pre-empts scoring */
6565         if (noscore & 0x000F)
6566         {
6567 #ifdef JP
6568 msg_print("¥¦¥£¥¶¡¼¥É¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6569 #else
6570                 msg_print("Score not registered for wizards.");
6571 #endif
6572
6573                 msg_print(NULL);
6574                 return FALSE;
6575         }
6576 #endif
6577
6578 #ifndef SCORE_BORGS
6579         /* Borg-mode pre-empts scoring */
6580         if (noscore & 0x00F0)
6581         {
6582 #ifdef JP
6583 msg_print("¥Ü¡¼¥°¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6584 #else
6585                 msg_print("Score not registered for borgs.");
6586 #endif
6587
6588                 msg_print(NULL);
6589                 return FALSE;
6590         }
6591 #endif
6592
6593 #ifndef SCORE_CHEATERS
6594         /* Cheaters are not scored */
6595         if (noscore & 0xFF00)
6596         {
6597 #ifdef JP
6598 msg_print("º¾µ½¤ò¤ä¤Ã¤¿¿Í¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6599 #else
6600                 msg_print("Score not registered for cheaters.");
6601 #endif
6602
6603                 msg_print(NULL);
6604                 return FALSE;
6605         }
6606 #endif
6607
6608         /* Interupted */
6609 #ifdef JP
6610 if (!total_winner && streq(died_from, "¶¯À©½ªÎ»"))
6611 #else
6612         if (!total_winner && streq(died_from, "Interrupting"))
6613 #endif
6614
6615         {
6616 #ifdef JP
6617 msg_print("¶¯À©½ªÎ»¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6618 #else
6619                 msg_print("Score not registered due to interruption.");
6620 #endif
6621
6622                 msg_print(NULL);
6623                 return FALSE;
6624         }
6625
6626         /* Quitter */
6627 #ifdef JP
6628 if (!total_winner && streq(died_from, "ÅÓÃ潪λ"))
6629 #else
6630         if (!total_winner && streq(died_from, "Quitting"))
6631 #endif
6632
6633         {
6634 #ifdef JP
6635 msg_print("ÅÓÃ潪λ¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6636 #else
6637                 msg_print("Score not registered due to quitting.");
6638 #endif
6639
6640                 msg_print(NULL);
6641                 return FALSE;
6642         }
6643         return TRUE;
6644 }
6645
6646 /*
6647  * Close up the current game (player may or may not be dead)
6648  *
6649  * This function is called only from "main.c" and "signals.c".
6650  */
6651 void close_game(void)
6652 {
6653         char buf[1024];
6654         bool do_send = TRUE;
6655
6656 /*      cptr p = "[i:¥­¥ã¥é¥¯¥¿¤Î¾ðÊó, f:¥Õ¥¡¥¤¥ë½ñ¤­½Ð¤·, t:¥¹¥³¥¢, x:*´ÕÄê*, ESC:¥²¡¼¥à½ªÎ»]"; */
6657
6658         /* Handle stuff */
6659         handle_stuff();
6660
6661         /* Flush the messages */
6662         msg_print(NULL);
6663
6664         /* Flush the input */
6665         flush();
6666
6667
6668         /* No suspending now */
6669         signals_ignore_tstp();
6670
6671
6672         /* Hack -- Character is now "icky" */
6673         character_icky = TRUE;
6674
6675
6676         /* Build the filename */
6677         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
6678
6679         /* Open the high score file, for reading/writing */
6680         highscore_fd = fd_open(buf, O_RDWR);
6681
6682
6683         /* Handle death */
6684         if (death)
6685         {
6686                 /* Handle retirement */
6687                 if (total_winner) kingly();
6688
6689                 /* Save memories */
6690 #ifdef JP
6691                 if (!munchkin_death || get_check("»à¤ó¤À¥Ç¡¼¥¿¤ò¥»¡¼¥Ö¤·¤Þ¤¹¤«¡© "))
6692 #else
6693                 if (!munchkin_death || get_check("Save death? "))
6694 #endif
6695                 {
6696
6697 #ifdef JP
6698 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6699 #else
6700                         if (!save_player()) msg_print("death save failed!");
6701 #endif
6702                 }
6703                 else do_send = FALSE;
6704
6705                 /* You are dead */
6706                 print_tomb();
6707
6708                 flush();
6709
6710                 /* Show more info */
6711                 show_info();
6712
6713                 /* Clear screen */
6714                 Term_clear();
6715
6716                 if (check_score())
6717                 {
6718                         if ((!send_world_score(do_send)))
6719                         {
6720 #ifdef JP
6721                                 if (get_check("¸å¤Ç¥¹¥³¥¢¤òÅÐÏ¿¤¹¤ë¤¿¤á¤ËÂÔµ¡¤·¤Þ¤¹¤«¡©"))
6722 #else
6723                                 if (get_check("Stand by for later score registration? "))
6724 #endif
6725                                 {
6726                                         wait_report_score = TRUE;
6727                                         death = FALSE;
6728 #ifdef JP
6729                                         if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6730 #else
6731                                         if (!save_player()) msg_print("death save failed!");
6732 #endif
6733                                 }
6734                         }
6735                         if (!wait_report_score)
6736                                 (void)top_twenty();
6737                 }
6738                 else if (highscore_fd >= 0)
6739                 {
6740                         display_scores_aux(0, 10, -1, NULL);
6741                 }
6742 #if 0
6743                 /* Dump bones file */
6744                 make_bones();
6745 #endif
6746         }
6747
6748         /* Still alive */
6749         else
6750         {
6751                 /* Save the game */
6752                 do_cmd_save_game(FALSE);
6753
6754                 /* Prompt for scores XXX XXX XXX */
6755 #ifdef JP
6756 prt("¥ê¥¿¡¼¥ó¥­¡¼¤« ESC ¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 40);
6757 #else
6758                 prt("Press Return (or Escape).", 0, 40);
6759 #endif
6760
6761
6762                 /* Predict score (or ESCAPE) */
6763                 if (inkey() != ESCAPE) predict_score();
6764         }
6765
6766
6767         /* Shut the high score file */
6768         (void)fd_close(highscore_fd);
6769
6770         /* Forget the high score fd */
6771         highscore_fd = -1;
6772
6773
6774         /* Allow suspending now */
6775         signals_handle_tstp();
6776 }
6777
6778
6779 /*
6780  * Handle abrupt death of the visual system
6781  *
6782  * This routine is called only in very rare situations, and only
6783  * by certain visual systems, when they experience fatal errors.
6784  *
6785  * XXX XXX Hack -- clear the death flag when creating a HANGUP
6786  * save file so that player can see tombstone when restart.
6787  */
6788 void exit_game_panic(void)
6789 {
6790         /* If nothing important has happened, just quit */
6791 #ifdef JP
6792 if (!character_generated || character_saved) quit("¶ÛµÞ»öÂÖ");
6793 #else
6794         if (!character_generated || character_saved) quit("panic");
6795 #endif
6796
6797
6798         /* Mega-Hack -- see "msg_print()" */
6799         msg_flag = FALSE;
6800
6801         /* Clear the top line */
6802         prt("", 0, 0);
6803
6804         /* Hack -- turn off some things */
6805         disturb(1, 0);
6806
6807         /* Mega-Hack -- Delay death */
6808         if (p_ptr->chp < 0) death = FALSE;
6809
6810         /* Hardcode panic save */
6811         panic_save = 1;
6812
6813         /* Forbid suspend */
6814         signals_ignore_tstp();
6815
6816         /* Indicate panic save */
6817 #ifdef JP
6818 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
6819 #else
6820         (void)strcpy(died_from, "(panic save)");
6821 #endif
6822
6823
6824         /* Panic save, or get worried */
6825 #ifdef JP
6826 if (!save_player()) quit("¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
6827 #else
6828         if (!save_player()) quit("panic save failed!");
6829 #endif
6830
6831
6832         /* Successful panic save */
6833 #ifdef JP
6834 quit("¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
6835 #else
6836         quit("panic save succeeded!");
6837 #endif
6838
6839 }
6840
6841
6842 /*
6843  * Get a random line from a file
6844  * Based on the monster speech patch by Matt Graham,
6845  */
6846 errr get_rnd_line(cptr file_name, int entry, char *output)
6847 {
6848         FILE    *fp;
6849         char    buf[1024];
6850         int     line, counter, test, numentries;
6851         int     line_num = 0;
6852         bool    found = FALSE;
6853
6854
6855         /* Build the filename */
6856         path_build(buf, 1024, ANGBAND_DIR_FILE, file_name);
6857
6858         /* Open the file */
6859         fp = my_fopen(buf, "r");
6860
6861         /* Failed */
6862         if (!fp) return (-1);
6863
6864         /* Find the entry of the monster */
6865         while (TRUE)
6866         {
6867                 /* Get a line from the file */
6868                 if (my_fgets(fp, buf, 1024) == 0)
6869                 {
6870                         /* Count the lines */
6871                         line_num++;
6872
6873                         /* Look for lines starting with 'N:' */
6874                         if ((buf[0] == 'N') && (buf[1] == ':'))
6875                         {
6876                                 /* Allow default lines */
6877                                 if (buf[2] == '*')
6878                                 {
6879                                         /* Default lines */
6880                                         found = TRUE;
6881                                         break;
6882                                 }
6883                                 else if (buf[2] == 'M')
6884                                 {
6885                                         if (r_info[entry].flags1 & RF1_MALE)
6886                                         {
6887                                                 found = TRUE;
6888                                                 break;
6889                                         }
6890                                 }
6891                                 else if (buf[2] == 'F')
6892                                 {
6893                                         if (r_info[entry].flags1 & RF1_FEMALE)
6894                                         {
6895                                                 found = TRUE;
6896                                                 break;
6897                                         }
6898                                 }
6899                                 /* Get the monster number */
6900                                 else if (sscanf(&(buf[2]), "%d", &test) != EOF)
6901                                 {
6902                                         /* Is it the right monster? */
6903                                         if (test == entry)
6904                                         {
6905                                                 found = TRUE;
6906                                                 break;
6907                                         }
6908                                 }
6909                                 else
6910                                 {
6911                                         /* Error while converting the monster number */
6912                                         msg_format("Error in line %d of %s!",
6913                                                   line_num, file_name);
6914                                         my_fclose(fp);
6915                                         return (-1);
6916                                 }
6917                         }
6918                 }
6919                 else
6920                 {
6921                         /* Reached end of file */
6922                         my_fclose(fp);
6923                         return (-1);
6924                 }
6925
6926         }
6927         
6928         /* Get the number of entries */
6929         while (TRUE)
6930         {
6931                 /* Get the line */
6932                 if (my_fgets(fp, buf, 1024) == 0)
6933                 {
6934                         /* Count the lines */
6935                         line_num++;
6936
6937                         /* Look for the number of entries */
6938                         if (isdigit(buf[0]))
6939                         {
6940                                 /* Get the number of entries */
6941                                 numentries = atoi(buf);
6942                                 break;
6943                         }
6944                 }
6945                 else
6946                 {
6947                         /* Count the lines */
6948                         line_num++;
6949
6950                         /* Reached end of file without finding the number */
6951                         msg_format("Error in line %d of %s!",
6952                                   line_num, file_name);
6953
6954                         my_fclose(fp);
6955                         return (-1);
6956                 }
6957         }
6958
6959         if (numentries > 0)
6960         {
6961                 /* Grab an appropriate line number */
6962                 line = rand_int(numentries);
6963
6964                 /* Get the random line */
6965                 for (counter = 0; counter <= line; counter++)
6966                 {
6967                         /* Count the lines */
6968                         line_num++;
6969
6970                         while(TRUE)
6971                         {
6972                                 test = my_fgets(fp, buf, 1024);
6973                                 if(test || buf[0] != '#')
6974                                         break;
6975                         }
6976
6977                         if (test==0)
6978                         {
6979                                 /* Found the line */
6980                                 if (counter == line) break;
6981                         }
6982                         else
6983                         {
6984                                 /* Error - End of file */
6985                                 msg_format("Error in line %d of %s!",
6986                                           line_num, file_name);
6987
6988                                 my_fclose(fp);
6989                                 return (-1);
6990                         }
6991                 }
6992
6993                 /* Copy the line */
6994                 strcpy(output, buf);
6995         }
6996         else
6997         {
6998                 return (-1);
6999         }
7000
7001         /* Close the file */
7002         my_fclose(fp);
7003
7004         /* Success */
7005         return (0);
7006 }
7007
7008
7009 #ifdef JP
7010 errr get_rnd_line_jonly(cptr file_name, int entry, char *output, int count)
7011 {
7012   int i,j,kanji;
7013   errr result=1;
7014   for (i=0;i<count;i++){
7015     result=get_rnd_line(file_name, entry, output);
7016     if(result)break;
7017     kanji=0;
7018     for(j=0; output[j]; j++) kanji |= iskanji(output[j]);
7019     if(kanji)break;
7020   }
7021   return(result);
7022 }
7023 #endif
7024
7025 /*
7026  * Process file for auto picker/destroyer.
7027  */
7028 errr process_pickpref_file(cptr name)
7029 {
7030         char buf[1024];
7031
7032         errr err = 0;
7033
7034         /* Build the filename */
7035         path_build(buf, 1024, ANGBAND_DIR_USER, name);
7036
7037         err = process_pref_file_aux(buf, TRUE);
7038
7039         /* Result */
7040         return (err);
7041 }
7042
7043 static errr counts_seek(int fd, u32b where, bool flag)
7044 {
7045         huge seekpoint;
7046         char temp1[128], temp2[128];
7047         u32b zero_header[3] = {0L, 0L, 0L};
7048         int i;
7049
7050 #ifdef SAVEFILE_USE_UID
7051         (void)sprintf(temp1, "%d.%s.%d%d%d", player_uid, savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7052 #else
7053         (void)sprintf(temp1, "%s.%d%d%d", savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7054 #endif
7055         for (i = 0; temp1[i]; i++)
7056                 temp1[i] ^= (i+1) * 63;
7057
7058         seekpoint = 0;
7059         while (1)
7060         {
7061                 if (fd_seek(fd, seekpoint + 3 * sizeof(u32b)))
7062                         return 1;
7063                 if (fd_read(fd, (char*)(temp2), sizeof(temp2)))
7064                 {
7065                         if (!flag)
7066                                 return 1;
7067                         /* add new name */
7068                         fd_seek(fd, seekpoint);
7069                         fd_write(fd, (char*)zero_header, 3*sizeof(u32b));
7070                         fd_write(fd, (char*)(temp1), sizeof(temp1));
7071                         break;
7072                 }
7073
7074                 if (strcmp(temp1, temp2) == 0)
7075                         break;
7076
7077                 seekpoint += 128 + 3 * sizeof(u32b);
7078         }
7079
7080         return fd_seek(fd, seekpoint + where * sizeof(u32b));
7081 }
7082
7083 u32b counts_read(int where)
7084 {
7085         int fd;
7086         u32b count = 0;
7087         char buf[1024];
7088
7089 #ifdef JP
7090         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7091 #else
7092         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7093 #endif
7094         fd = fd_open(buf, O_RDONLY);
7095
7096         if (counts_seek(fd, where, FALSE) ||
7097             fd_read(fd, (char*)(&count), sizeof(u32b)))
7098                 count = 0;
7099
7100         (void)fd_close(fd);
7101
7102         return count;
7103 }
7104
7105 errr counts_write(int where, u32b count)
7106 {
7107         int fd;
7108         char buf[1024];
7109
7110 #ifdef JP
7111         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7112 #else
7113         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7114 #endif
7115         fd = fd_open(buf, O_RDWR);
7116         if (fd < 0)
7117         {
7118                 /* File type is "DATA" */
7119                 FILE_TYPE(FILE_TYPE_DATA);
7120
7121                 /* Create a new high score file */
7122                 fd = fd_make(buf, 0644);
7123         }
7124
7125         if (fd_lock(fd, F_WRLCK)) return 1;
7126
7127         counts_seek(fd, where, TRUE);
7128         fd_write(fd, (char*)(&count), sizeof(u32b));
7129
7130         if (fd_lock(fd, F_UNLCK)) return 1;
7131
7132         (void)fd_close(fd);
7133
7134         return 0;
7135 }
7136
7137
7138 #ifdef HANDLE_SIGNALS
7139
7140
7141 #include <signal.h>
7142
7143
7144 /*
7145  * Handle signals -- suspend
7146  *
7147  * Actually suspend the game, and then resume cleanly
7148  */
7149 static void handle_signal_suspend(int sig)
7150 {
7151         /* Disable handler */
7152         (void)signal(sig, SIG_IGN);
7153
7154 #ifdef SIGSTOP
7155
7156         /* Flush output */
7157         Term_fresh();
7158
7159         /* Suspend the "Term" */
7160         Term_xtra(TERM_XTRA_ALIVE, 0);
7161
7162         /* Suspend ourself */
7163         (void)kill(0, SIGSTOP);
7164
7165         /* Resume the "Term" */
7166         Term_xtra(TERM_XTRA_ALIVE, 1);
7167
7168         /* Redraw the term */
7169         Term_redraw();
7170
7171         /* Flush the term */
7172         Term_fresh();
7173
7174 #endif
7175
7176         /* Restore handler */
7177         (void)signal(sig, handle_signal_suspend);
7178 }
7179
7180
7181 /*
7182  * Handle signals -- simple (interrupt and quit)
7183  *
7184  * This function was causing a *huge* number of problems, so it has
7185  * been simplified greatly.  We keep a global variable which counts
7186  * the number of times the user attempts to kill the process, and
7187  * we commit suicide if the user does this a certain number of times.
7188  *
7189  * We attempt to give "feedback" to the user as he approaches the
7190  * suicide thresh-hold, but without penalizing accidental keypresses.
7191  *
7192  * To prevent messy accidents, we should reset this global variable
7193  * whenever the user enters a keypress, or something like that.
7194  */
7195 static void handle_signal_simple(int sig)
7196 {
7197         /* Disable handler */
7198         (void)signal(sig, SIG_IGN);
7199
7200
7201         /* Nothing to save, just quit */
7202         if (!character_generated || character_saved) quit(NULL);
7203
7204
7205         /* Count the signals */
7206         signal_count++;
7207
7208
7209         /* Terminate dead characters */
7210         if (death)
7211         {
7212                 /* Mark the savefile */
7213 #ifdef JP
7214 (void)strcpy(died_from, "¶¯À©½ªÎ»");
7215 #else
7216                 (void)strcpy(died_from, "Abortion");
7217 #endif
7218
7219                 forget_lite();
7220                 forget_view();
7221                 clear_mon_lite();
7222
7223                 /* Close stuff */
7224                 close_game();
7225
7226                 /* Quit */
7227 #ifdef JP
7228 quit("¶¯À©½ªÎ»");
7229 #else
7230                 quit("interrupt");
7231 #endif
7232
7233         }
7234
7235         /* Allow suicide (after 5) */
7236         else if (signal_count >= 5)
7237         {
7238                 /* Cause of "death" */
7239 #ifdef JP
7240 (void)strcpy(died_from, "¶¯À©½ªÎ»Ãæ");
7241 #else
7242                 (void)strcpy(died_from, "Interrupting");
7243 #endif
7244
7245
7246                 forget_lite();
7247                 forget_view();
7248                 clear_mon_lite();
7249
7250                 /* Stop playing */
7251                 alive = FALSE;
7252
7253                 /* Suicide */
7254                 death = TRUE;
7255
7256                 /* Leaving */
7257                 p_ptr->leaving = TRUE;
7258
7259                 /* Close stuff */
7260                 close_game();
7261
7262                 /* Quit */
7263 #ifdef JP
7264 quit("¶¯À©½ªÎ»");
7265 #else
7266                 quit("interrupt");
7267 #endif
7268
7269         }
7270
7271         /* Give warning (after 4) */
7272         else if (signal_count >= 4)
7273         {
7274                 /* Make a noise */
7275                 Term_xtra(TERM_XTRA_NOISE, 0);
7276
7277                 /* Clear the top line */
7278                 Term_erase(0, 0, 255);
7279
7280                 /* Display the cause */
7281 #ifdef JP
7282 Term_putstr(0, 0, -1, TERM_WHITE, "½Ïθ¤Î¾å¤Î¼«»¦¡ª");
7283 #else
7284                 Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");
7285 #endif
7286
7287
7288                 /* Flush */
7289                 Term_fresh();
7290         }
7291
7292         /* Give warning (after 2) */
7293         else if (signal_count >= 2)
7294         {
7295                 /* Make a noise */
7296                 Term_xtra(TERM_XTRA_NOISE, 0);
7297         }
7298
7299         /* Restore handler */
7300         (void)signal(sig, handle_signal_simple);
7301 }
7302
7303
7304 /*
7305  * Handle signal -- abort, kill, etc
7306  */
7307 static void handle_signal_abort(int sig)
7308 {
7309         /* Disable handler */
7310         (void)signal(sig, SIG_IGN);
7311
7312
7313         /* Nothing to save, just quit */
7314         if (!character_generated || character_saved) quit(NULL);
7315
7316
7317         forget_lite();
7318         forget_view();
7319         clear_mon_lite();
7320
7321         /* Clear the bottom line */
7322         Term_erase(0, 23, 255);
7323
7324         /* Give a warning */
7325         Term_putstr(0, 23, -1, TERM_RED,
7326 #ifdef JP
7327 "¶²¤í¤·¤¤¥½¥Õ¥È¤Î¥Ð¥°¤¬Èô¤Ó¤«¤«¤Ã¤Æ¤­¤¿¡ª");
7328 #else
7329                     "A gruesome software bug LEAPS out at you!");
7330 #endif
7331
7332
7333         /* Message */
7334 #ifdef JP
7335 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö...");
7336 #else
7337         Term_putstr(45, 23, -1, TERM_RED, "Panic save...");
7338 #endif
7339
7340
7341         /* Flush output */
7342         Term_fresh();
7343
7344         /* Panic Save */
7345         panic_save = 1;
7346
7347         /* Panic save */
7348 #ifdef JP
7349 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
7350 #else
7351         (void)strcpy(died_from, "(panic save)");
7352 #endif
7353
7354
7355         /* Forbid suspend */
7356         signals_ignore_tstp();
7357
7358         /* Attempt to save */
7359         if (save_player())
7360         {
7361 #ifdef JP
7362 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
7363 #else
7364                 Term_putstr(45, 23, -1, TERM_RED, "Panic save succeeded!");
7365 #endif
7366
7367         }
7368
7369         /* Save failed */
7370         else
7371         {
7372 #ifdef JP
7373 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
7374 #else
7375                 Term_putstr(45, 23, -1, TERM_RED, "Panic save failed!");
7376 #endif
7377
7378         }
7379
7380         /* Flush output */
7381         Term_fresh();
7382
7383         /* Quit */
7384 #ifdef JP
7385 quit("¥½¥Õ¥È¤Î¥Ð¥°");
7386 #else
7387         quit("software bug");
7388 #endif
7389
7390 }
7391
7392
7393
7394
7395 /*
7396  * Ignore SIGTSTP signals (keyboard suspend)
7397  */
7398 void signals_ignore_tstp(void)
7399 {
7400
7401 #ifdef SIGTSTP
7402         (void)signal(SIGTSTP, SIG_IGN);
7403 #endif
7404
7405 }
7406
7407 /*
7408  * Handle SIGTSTP signals (keyboard suspend)
7409  */
7410 void signals_handle_tstp(void)
7411 {
7412
7413 #ifdef SIGTSTP
7414         (void)signal(SIGTSTP, handle_signal_suspend);
7415 #endif
7416
7417 }
7418
7419
7420 /*
7421  * Prepare to handle the relevant signals
7422  */
7423 void signals_init(void)
7424 {
7425
7426 #ifdef SIGHUP
7427         (void)signal(SIGHUP, SIG_IGN);
7428 #endif
7429
7430
7431 #ifdef SIGTSTP
7432         (void)signal(SIGTSTP, handle_signal_suspend);
7433 #endif
7434
7435
7436 #ifdef SIGINT
7437         (void)signal(SIGINT, handle_signal_simple);
7438 #endif
7439
7440 #ifdef SIGQUIT
7441         (void)signal(SIGQUIT, handle_signal_simple);
7442 #endif
7443
7444
7445 #ifdef SIGFPE
7446         (void)signal(SIGFPE, handle_signal_abort);
7447 #endif
7448
7449 #ifdef SIGILL
7450         (void)signal(SIGILL, handle_signal_abort);
7451 #endif
7452
7453 #ifdef SIGTRAP
7454         (void)signal(SIGTRAP, handle_signal_abort);
7455 #endif
7456
7457 #ifdef SIGIOT
7458         (void)signal(SIGIOT, handle_signal_abort);
7459 #endif
7460
7461 #ifdef SIGKILL
7462         (void)signal(SIGKILL, handle_signal_abort);
7463 #endif
7464
7465 #ifdef SIGBUS
7466         (void)signal(SIGBUS, handle_signal_abort);
7467 #endif
7468
7469 #ifdef SIGSEGV
7470         (void)signal(SIGSEGV, handle_signal_abort);
7471 #endif
7472
7473 #ifdef SIGTERM
7474         (void)signal(SIGTERM, handle_signal_abort);
7475 #endif
7476
7477 #ifdef SIGPIPE
7478         (void)signal(SIGPIPE, handle_signal_abort);
7479 #endif
7480
7481 #ifdef SIGEMT
7482         (void)signal(SIGEMT, handle_signal_abort);
7483 #endif
7484
7485 #ifdef SIGDANGER
7486         (void)signal(SIGDANGER, handle_signal_abort);
7487 #endif
7488
7489 #ifdef SIGSYS
7490         (void)signal(SIGSYS, handle_signal_abort);
7491 #endif
7492
7493 #ifdef SIGXCPU
7494         (void)signal(SIGXCPU, handle_signal_abort);
7495 #endif
7496
7497 #ifdef SIGPWR
7498         (void)signal(SIGPWR, handle_signal_abort);
7499 #endif
7500
7501 }
7502
7503
7504 #else   /* HANDLE_SIGNALS */
7505
7506
7507 /*
7508  * Do nothing
7509  */
7510 void signals_ignore_tstp(void)
7511 {
7512 }
7513
7514 /*
7515  * Do nothing
7516  */
7517 void signals_handle_tstp(void)
7518 {
7519 }
7520
7521 /*
7522  * Do nothing
7523  */
7524 void signals_init(void)
7525 {
7526 }
7527 #endif  /* HANDLE_SIGNALS */