OSDN Git Service

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