OSDN Git Service

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