OSDN Git Service

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