OSDN Git Service

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