OSDN Git Service

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