OSDN Git Service

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