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                         char statmsg[1000];
4134
4135 #ifdef JP
4136                         put_str("(¥­¥ã¥é¥¯¥¿¡¼¤ÎÀ¸¤¤Î©¤Á)", 11, 25);
4137 #else
4138                         put_str("(Character Background)", 11, 25);
4139 #endif
4140
4141                         for (i = 0; i < 4; i++)
4142                         {
4143                                 put_str(history[i], i + 12, 10);
4144                         }
4145
4146                         *statmsg = '\0';
4147
4148                         if (death && total_winner)
4149                         {
4150 #ifdef JP
4151                                 strcpy(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¾¡Íø¤Î¸å°úÂष¤¿¡£");
4152 #else
4153                                 strcpy(statmsg, "...You retired from the adventure after the winning.");
4154 #endif
4155                         }
4156                         else if (death)
4157                         {
4158                                 if (dun_level)
4159                                 {
4160                                         if (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST))
4161                                         {
4162 #ifdef JP
4163                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¡¢¥¯¥¨¥¹¥È¡Ö%s¡×¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", quest[p_ptr->inside_quest].name, died_from);
4164 #else
4165                                                 sprintf(statmsg, "...You were killed by %s in the quest '%s'.", died_from, quest[p_ptr->inside_quest].name);
4166 #endif
4167                                         }
4168                                         else
4169                                         {                                       
4170 #ifdef JP
4171                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¡¢%s¤Î%d³¬¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", map_name(), dun_level, died_from);
4172 #else
4173                                                 sprintf(statmsg, "...You were killed by %s on level %d of %s.", died_from, dun_level, map_name());
4174 #endif
4175                                         }
4176                                 }
4177                                 else
4178 #ifdef JP
4179                                         sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï%s¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", map_name(), died_from);
4180 #else
4181                                         sprintf(statmsg, "...You were killed by %s in %s.", died_from, map_name());
4182 #endif
4183                         }
4184                         else if (character_dungeon)
4185                         {
4186                                 if (dun_level)
4187                                 {
4188                                         if (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST))
4189                                         {
4190 #ifdef JP
4191                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ ¥¯¥¨¥¹¥È¡Ö%s¡×¤ò¿ë¹ÔÃæ¤À¡£", quest[p_ptr->inside_quest].name);
4192 #else
4193                                                 sprintf(statmsg, "...Now, you are in the quest '%s'.", quest[p_ptr->inside_quest].name);
4194 #endif
4195                                         }                                                       
4196                                         else
4197                                         {
4198 #ifdef JP
4199                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Î %d ³¬¤Çõº÷¤·¤Æ¤¤¤ë¡£", map_name(), dun_level);
4200 #else
4201                                                 sprintf(statmsg, "...Now, you are exploring level %d of %s.", dun_level, map_name());
4202 #endif
4203                                         }
4204                                 }
4205                                 else
4206 #ifdef JP
4207                                         sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Ë¤¤¤ë¡£", map_name());
4208 #else
4209                                         sprintf(statmsg, "...Now, you are in %s.", map_name());
4210 #endif
4211                         }
4212
4213                         if (*statmsg)
4214                         {
4215                                 char temp[64*2], *t;
4216                                 roff_to_buf(statmsg, 60, temp);
4217                                 t = temp;
4218                                 for(i=0 ; i<2 ; i++)
4219                                 {
4220                                         if(t[0]==0)
4221                                                 break; 
4222                                         else
4223                                         {
4224                                                 put_str(t, i + 5 + 12, 10);
4225                                                 t += strlen(t)+1;
4226                                         }
4227                                 }
4228                         }
4229
4230                 }
4231
4232                 /* Display "various" info */
4233                 else
4234                 {
4235                         display_player_middle();
4236                         display_player_various();
4237                 }
4238         }
4239
4240         /* Special */
4241         else if (mode == 2)
4242         {
4243                 /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */
4244
4245                 /* Dump the info */
4246                 display_player_misc_info();
4247                 display_player_stat_info();
4248                 display_player_flag_info();
4249         }
4250
4251         /* Special */
4252         else if (mode == 3)
4253         {
4254                 display_player_ben();
4255         }
4256
4257         else if (mode == 6)
4258         {
4259                 do_cmd_knowledge_mutations();
4260         }
4261
4262         /* Special */
4263         else
4264         {
4265                 display_player_ben_one(mode % 2);
4266         }
4267 }
4268
4269 errr make_character_dump(FILE *fff)
4270 {
4271         int             i, x, y;
4272         byte            a;
4273         char            c;
4274         cptr            paren = ")";
4275         store_type  *st_ptr;
4276         char            o_name[MAX_NLEN];
4277         char            buf[1024];
4278
4279
4280 #ifndef FAKE_VERSION
4281         /* Begin dump */
4282         fprintf(fff, "  [Angband %d.%d.%d Character Dump]\n\n",
4283                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
4284 #else
4285 #ifdef JP
4286         fprintf(fff, "  [ÊѶòÈÚÅÜ %d.%d.%d ¥­¥ã¥é¥¯¥¿¾ðÊó]\n\n",
4287                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4288 #else
4289         fprintf(fff, "  [Hengband %d.%d.%d Character Dump]\n\n",
4290                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4291 #endif
4292
4293 #endif
4294
4295         update_playtime();
4296
4297         /* Display player */
4298         display_player(0);
4299
4300         /* Dump part of the screen */
4301         for (y = 1; y < 22; y++)
4302         {
4303                 /* Dump each row */
4304                 for (x = 0; x < 79; x++)
4305                 {
4306                         /* Get the attr/char */
4307                         (void)(Term_what(x, y, &a, &c));
4308
4309                         /* Dump it */
4310                         buf[x] = c;
4311                 }
4312
4313                 /* End the string */
4314                 buf[x] = '\0';
4315
4316                 /* Kill trailing spaces */
4317                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4318
4319                 /* End the row */
4320 #ifdef JP
4321                         fprintf(fff, "%s\n", buf);
4322 #else
4323                 fprintf(fff, "%s\n", buf);
4324 #endif
4325
4326         }
4327
4328         /* Display history */
4329         display_player(1);
4330
4331         /* Dump part of the screen */
4332         for (y = 10; y < 19; y++)
4333         {
4334                 /* Dump each row */
4335                 for (x = 0; x < 79; x++)
4336                 {
4337                         /* Get the attr/char */
4338                         (void)(Term_what(x, y, &a, &c));
4339
4340                         /* Dump it */
4341                         buf[x] = c;
4342                 }
4343
4344                 /* End the string */
4345                 buf[x] = '\0';
4346
4347                 /* Kill trailing spaces */
4348                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4349
4350                 /* End the row */
4351                 fprintf(fff, "%s\n", buf);
4352         }
4353
4354         fprintf(fff, "\n");
4355         /* Display history */
4356         display_player(2);
4357
4358         /* Dump part of the screen */
4359         for (y = 2; y < 22; y++)
4360         {
4361                 /* Dump each row */
4362                 for (x = 0; x < 79; x++)
4363                 {
4364                         /* Get the attr/char */
4365                         (void)(Term_what(x, y, &a, &c));
4366
4367                         /* Dump it (Ignore equippy tile graphic) */
4368                         if (a < 128)
4369                                 buf[x] = c;
4370                         else
4371                                 buf[x] = ' ';
4372                 }
4373
4374                 /* End the string */
4375                 buf[x] = '\0';
4376
4377                 /* Kill trailing spaces */
4378                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4379
4380                 /* End the row */
4381                 fprintf(fff, "%s\n", buf);
4382         }
4383
4384         for (i = 0; i < p_ptr->count / 80; i++)
4385                 fprintf(fff, " ");
4386         fprintf(fff, "\n");
4387         for (i = 0; i < p_ptr->count % 80; i++)
4388                 fprintf(fff, " ");
4389
4390         {
4391                 bool pet = FALSE;
4392
4393                 for (i = m_max - 1; i >= 1; i--)
4394                 {
4395                         monster_type *m_ptr = &m_list[i];
4396                         char pet_name[80];
4397
4398                         if (!m_ptr->r_idx) continue;
4399                         if (!is_pet(m_ptr)) continue;
4400                         if (!m_ptr->nickname && (p_ptr->riding != i)) continue;
4401                         if (!pet)
4402                         {
4403 #ifdef JP
4404                                 fprintf(fff, "\n  [¼ç¤Ê¥Ú¥Ã¥È]\n\n");
4405 #else
4406                                 fprintf(fff, "\n  [leading pets]\n\n");
4407 #endif
4408                                 pet = TRUE;
4409                         }
4410                         monster_desc(pet_name, m_ptr, 0x88);
4411                         fprintf(fff, "%s", pet_name);
4412                         if (p_ptr->riding == i)
4413 #ifdef JP
4414                                 fprintf(fff, " ¾èÇÏÃæ");
4415 #else
4416                                 fprintf(fff, " (riding)");
4417 #endif
4418                         fprintf(fff, "\n");
4419                 }
4420                 if (pet) fprintf(fff, "\n");
4421         }
4422
4423         if (death && !total_winner)
4424         {
4425 #ifdef JP
4426                 fprintf(fff, "\n  [»à¤ÌľÁ°¤Î¥á¥Ã¥»¡¼¥¸]\n\n");
4427 #else
4428                 fprintf(fff, "\n  [Last messages]\n\n");
4429 #endif
4430                 for (i = MIN(message_num(), 30); i >= 0; i--)
4431                 {
4432                         fprintf(fff,"> %s\n",message_str((s16b)i));
4433                 }
4434                 fprintf(fff, "\n");
4435         }
4436
4437 #ifdef JP
4438         fprintf(fff, "\n  [¤½¤Î¾¤Î¾ðÊó]        \n");
4439 #else
4440         fprintf(fff, "\n  [Miscellaneous information]\n");
4441 #endif
4442
4443 #ifdef JP
4444         fprintf(fff, "\n µ¢´Ô¾ì½ê:\n");
4445 #else
4446         fprintf(fff, "\n Recall Depth:\n");
4447 #endif
4448         for (y = 1; y < max_d_idx; y++)
4449         {
4450                 bool seiha = FALSE;
4451
4452                 if (!d_info[y].maxdepth) continue;
4453                 if (!max_dlv[y]) continue;
4454                 if (d_info[y].final_guardian)
4455                 {
4456                         if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
4457                 }
4458                 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
4459
4460 #ifdef JP
4461                 fprintf(fff, "   %c%-12s: %3d ³¬\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4462 #else
4463                 fprintf(fff, "   %c%-16s: level %3d\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4464 #endif
4465         }
4466
4467         if (preserve_mode)
4468 #ifdef JP
4469                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         ON");
4470 #else
4471                 fprintf(fff, "\n Preserve Mode:      ON");
4472 #endif
4473
4474         else
4475 #ifdef JP
4476                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         OFF");
4477 #else
4478                 fprintf(fff, "\n Preserve Mode:      OFF");
4479 #endif
4480
4481
4482         if (ironman_autoscum)
4483 #ifdef JP
4484                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ALWAYS");
4485 #else
4486                 fprintf(fff, "\n Autoscum:           ALWAYS");
4487 #endif
4488
4489         else if (auto_scum)
4490 #ifdef JP
4491                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ON");
4492 #else
4493                 fprintf(fff, "\n Autoscum:           ON");
4494 #endif
4495
4496         else
4497 #ifdef JP
4498                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     OFF");
4499 #else
4500                 fprintf(fff, "\n Autoscum:           OFF");
4501 #endif
4502
4503
4504         if (ironman_small_levels)
4505 #ifdef JP
4506                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ALWAYS");
4507 #else
4508                 fprintf(fff, "\n Small Levels:       ALWAYS");
4509 #endif
4510
4511         else if (always_small_levels)
4512 #ifdef JP
4513                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ON");
4514 #else
4515                 fprintf(fff, "\n Small Levels:       ON");
4516 #endif
4517
4518         else if (small_levels)
4519 #ifdef JP
4520                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ENABLED");
4521 #else
4522                 fprintf(fff, "\n Small Levels:       ENABLED");
4523 #endif
4524
4525         else
4526 #ifdef JP
4527                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   OFF");
4528 #else
4529                 fprintf(fff, "\n Small Levels:       OFF");
4530 #endif
4531
4532
4533         if (vanilla_town)
4534 #ifdef JP
4535                 fprintf(fff, "\n ¸µÁĤÎÄ®¤Î¤ß: ON");
4536 #else
4537                 fprintf(fff, "\n Vanilla Town:       ON");
4538 #endif
4539
4540         else if (lite_town)
4541 #ifdef JP
4542                 fprintf(fff, "\n ¾®µ¬ÌϤÊÄ®:         ON");
4543 #else
4544                 fprintf(fff, "\n Lite Town:          ON");
4545 #endif
4546
4547
4548         if (ironman_shops)
4549 #ifdef JP
4550                 fprintf(fff, "\n Å¹¤Ê¤·:             ON");
4551 #else
4552                 fprintf(fff, "\n No Shops:           ON");
4553 #endif
4554
4555
4556         if (ironman_downward)
4557 #ifdef JP
4558                 fprintf(fff, "\n ³¬Ãʤò¾å¤¬¤ì¤Ê¤¤:   ON");
4559 #else
4560                 fprintf(fff, "\n Diving only:        ON");
4561 #endif
4562
4563
4564         if (ironman_rooms)
4565 #ifdef JP
4566                 fprintf(fff, "\n ÉáÄ̤Ǥʤ¤Éô²°¤òÀ¸À®:         ON");
4567 #else
4568                 fprintf(fff, "\n Unusual rooms:      ON");
4569 #endif
4570
4571
4572         if (ironman_nightmare)
4573 #ifdef JP
4574                 fprintf(fff, "\n °­Ì´¥â¡¼¥É:         ON");
4575 #else
4576                 fprintf(fff, "\n Nightmare Mode:     ON");
4577 #endif
4578
4579
4580         if (ironman_empty_levels)
4581 #ifdef JP
4582                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ALWAYS");
4583 #else
4584                 fprintf(fff, "\n Arena Levels:       ALWAYS");
4585 #endif
4586
4587         else if (empty_levels)
4588 #ifdef JP
4589                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ON");
4590 #else
4591                 fprintf(fff, "\n Arena Levels:       ENABLED");
4592 #endif
4593
4594         else
4595 #ifdef JP
4596                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           OFF");
4597 #else
4598                 fprintf(fff, "\n Arena Levels:       OFF");
4599 #endif
4600
4601
4602 #ifdef JP
4603         fprintf(fff, "\n ¥é¥ó¥À¥à¥¯¥¨¥¹¥È¿ô: %d", number_of_quests());
4604 #else
4605         fprintf(fff, "\n Num. Random Quests: %d", number_of_quests());
4606 #endif
4607
4608         if (p_ptr->arena_number == 99)
4609         {
4610 #ifdef JP
4611                 fprintf(fff, "\n Æ®µ»¾ì: ÇÔËÌ\n");
4612 #else
4613                 fprintf(fff, "\n Arena: defeated\n");
4614 #endif
4615         }
4616         else if (p_ptr->arena_number > MAX_ARENA_MONS+2)
4617         {
4618 #ifdef JP
4619                 fprintf(fff, "\n Æ®µ»¾ì: ¿¿¤Î¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4620 #else
4621                 fprintf(fff, "\n Arena: True Champion\n");
4622 #endif
4623         }
4624         else if (p_ptr->arena_number > MAX_ARENA_MONS-1)
4625         {
4626 #ifdef JP
4627                 fprintf(fff, "\n Æ®µ»¾ì: ¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4628 #else
4629                 fprintf(fff, "\n Arena: Champion\n");
4630 #endif
4631         }
4632         else
4633         {
4634 #ifdef JP
4635                 fprintf(fff, "\n Æ®µ»¾ì:   %2d¾¡\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number));
4636 #else
4637                 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");
4638 #endif
4639         }
4640
4641         if (noscore)
4642 #ifdef JP
4643 fprintf(fff, "\n ²¿¤«ÉÔÀµ¤Ê¤³¤È¤ò¤·¤Æ¤·¤Þ¤Ã¤Æ¤Þ¤¹¡£");
4644 #else
4645                 fprintf(fff, "\n You have done something illegal.");
4646 #endif
4647
4648
4649         if (stupid_monsters)
4650 #ifdef JP
4651 fprintf(fff, "\n Å¨¤Ï¶ò¤«¤Ê¹ÔÆ°¤ò¼è¤ê¤Þ¤¹¡£");
4652 #else
4653                 fprintf(fff, "\n Your opponents are behaving stupidly.");
4654 #endif
4655
4656
4657         if (munchkin_death)
4658 #ifdef JP
4659 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï»à¤ò²óÈò¤¹¤ë¥¤¥ó¥Á¥­¤ÊÎϤò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£");
4660 #else
4661                 fprintf(fff, "\n You possess munchkinish power over death.");
4662 #endif
4663
4664         fprintf(fff,"\n");
4665
4666         /* Monsters slain */
4667         {
4668                 int k;
4669                 s32b Total = 0;
4670
4671                 for (k = 1; k < max_r_idx; k++)
4672                 {
4673                         monster_race *r_ptr = &r_info[k];
4674
4675                         if (r_ptr->flags1 & RF1_UNIQUE)
4676                         {
4677                                 bool dead = (r_ptr->max_num == 0);
4678                                 if (dead)
4679                                 {
4680                                         Total++;
4681                                 }
4682                         }
4683                         else
4684                         {
4685                                 s16b This = r_ptr->r_pkills;
4686                                 if (This > 0)
4687                                 {
4688                                         Total += This;
4689                                 }
4690                         }
4691                 }
4692
4693                 if (Total < 1)
4694 #ifdef JP
4695 fprintf(fff,"\n ¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Þ¤»¤ó¡£\n");
4696 #else
4697                         fprintf(fff,"\n You have defeated no enemies yet.\n");
4698 #endif
4699
4700                 else if (Total == 1)
4701 #ifdef JP
4702 fprintf(fff,"\n °ìÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n");
4703 #else
4704                         fprintf(fff,"\n You have defeated one enemy.\n");
4705 #endif
4706
4707                 else
4708 #ifdef JP
4709 fprintf(fff,"\n %lu ÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n", Total);
4710 #else
4711                         fprintf(fff,"\n You have defeated %lu enemies.\n", Total);
4712 #endif
4713
4714         }
4715
4716
4717         if (p_ptr->old_race1 || p_ptr->old_race2)
4718         {
4719 #ifdef JP
4720                 fprintf(fff, "\n\n ¤¢¤Ê¤¿¤Ï%s¤È¤·¤ÆÀ¸¤Þ¤ì¤¿¡£", race_info[p_ptr->start_race].title);
4721 #else
4722                 fprintf(fff, "\n\n You were born as %s.", race_info[p_ptr->start_race].title);
4723 #endif
4724                 for (i = 0; i < MAX_RACES; i++)
4725                 {
4726                         if (p_ptr->start_race == i) continue;
4727                         if (i < 32)
4728                         {
4729                                 if (!(p_ptr->old_race1 & 1L << i)) continue;
4730                         }
4731                         else
4732                         {
4733                                 if (!(p_ptr->old_race2 & 1L << (i-32))) continue;
4734                         }
4735 #ifdef JP
4736                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%s¤À¤Ã¤¿¡£", race_info[i].title);
4737 #else
4738                         fprintf(fff, "\n You were a %s before.", race_info[i].title);
4739 #endif
4740                 }
4741         }
4742
4743         if (p_ptr->old_realm)
4744         {
4745                 for (i = 0; i < MAX_MAGIC; i++)
4746                 {
4747                         if (!(p_ptr->old_realm & 1L << i)) continue;
4748 #ifdef JP
4749                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%sËâË¡¤ò»È¤¨¤¿¡£", realm_names[i+1]);
4750 #else
4751                         fprintf(fff, "\n You were able to use %s magic before.", realm_names[i+1]);
4752 #endif
4753                 }
4754         }
4755
4756 #ifdef JP
4757 fprintf(fff, "\n\n  [¥×¥ì¥¤¥ä¡¼¤ÎÆÁ]\n\n");
4758 #else
4759         fprintf(fff, "\n\n  [Virtues]\n\n");
4760 #endif
4761
4762 #ifdef JP
4763         fprintf(fff, "°À­ : %s\n", your_alignment());
4764 #else
4765         fprintf(fff, "Your alighnment : %s\n", your_alignment());
4766 #endif
4767         fprintf(fff, "\n");
4768         dump_virtues(fff);
4769
4770         if (p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3)
4771         {
4772 #ifdef JP
4773 fprintf(fff, "\n\n  [ÆÍÁ³ÊÑ°Û]\n\n");
4774 #else
4775                 fprintf(fff, "\n\n  [Mutations]\n\n");
4776 #endif
4777
4778                 dump_mutations(fff);
4779         }
4780
4781
4782         /* Skip some lines */
4783         fprintf(fff, "\n\n");
4784
4785
4786         /* Dump the equipment */
4787         if (equip_cnt)
4788         {
4789 #ifdef JP
4790 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤ÎÁõÈ÷ ]\n\n");
4791 #else
4792                 fprintf(fff, "  [Character Equipment]\n\n");
4793 #endif
4794
4795                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4796                 {
4797                         object_desc(o_name, &inventory[i], TRUE, 3);
4798                         if ((i == INVEN_LARM) && p_ptr->ryoute)
4799 #ifdef JP
4800                                 strcpy(o_name, "(Éð´ï¤òξ¼ê»ý¤Á)");
4801 #else
4802                                 strcpy(o_name, "(wielding with two-hands)");
4803 #endif
4804                         fprintf(fff, "%c%s %s\n",
4805                                 index_to_label(i), paren, o_name);
4806                 }
4807                 fprintf(fff, "\n\n");
4808         }
4809
4810         /* Dump the inventory */
4811 #ifdef JP
4812 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤Î»ý¤Áʪ ]\n\n");
4813 #else
4814         fprintf(fff, "  [Character Inventory]\n\n");
4815 #endif
4816
4817         for (i = 0; i < INVEN_PACK; i++)
4818         {
4819                 /* Don't dump the empty slots */
4820                 if (!inventory[i].k_idx) break;
4821
4822                 /* Dump the inventory slots */
4823                 object_desc(o_name, &inventory[i], TRUE, 3);
4824                 fprintf(fff, "%c%s %s\n", index_to_label(i), paren, o_name);
4825         }
4826
4827         /* Add an empty line */
4828         fprintf(fff, "\n\n");
4829
4830         process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
4831
4832         /* Print all homes in the different towns */
4833         st_ptr = &town[1].store[STORE_HOME];
4834
4835         /* Home -- if anything there */
4836         if (st_ptr->stock_num)
4837         {
4838                 /* Header with name of the town */
4839 #ifdef JP
4840                 fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
4841 #else
4842                 fprintf(fff, "  [Home Inventory]\n");
4843 #endif
4844                 x=1;
4845
4846                 /* Dump all available items */
4847                 for (i = 0; i < st_ptr->stock_num; i++)
4848                 {
4849                         if ((i % 12) == 0)
4850 #ifdef JP
4851                                 fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4852 #else
4853                                 fprintf(fff, "\n ( page %d )\n", x++);
4854 #endif
4855                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4856                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4857                 }
4858
4859                 /* Add an empty line */
4860                 fprintf(fff, "\n\n");
4861         }
4862
4863
4864         /* Print all homes in the different towns */
4865         st_ptr = &town[1].store[STORE_MUSEUM];
4866
4867         /* Home -- if anything there */
4868         if (st_ptr->stock_num)
4869         {
4870                 /* Header with name of the town */
4871 #ifdef JP
4872                 fprintf(fff, "  [ Çîʪ´Û¤Î¥¢¥¤¥Æ¥à ]\n");
4873 #else
4874                 fprintf(fff, "  [Museum]\n");
4875 #endif
4876                 x=1;
4877
4878                 /* Dump all available items */
4879                 for (i = 0; i < st_ptr->stock_num; i++)
4880                 {
4881 #ifdef JP
4882                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4883                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4884                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4885 #else
4886                 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
4887                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4888                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4889 #endif
4890
4891                 }
4892
4893                 /* Add an empty line */
4894                 fprintf(fff, "\n\n");
4895         }
4896
4897         return 0;
4898 }
4899
4900 /*
4901  * Hack -- Dump a character description file
4902  *
4903  * XXX XXX XXX Allow the "full" flag to dump additional info,
4904  * and trigger its usage from various places in the code.
4905  */
4906 errr file_character(cptr name, bool full)
4907 {
4908         int             fd = -1;
4909         FILE            *fff = NULL;
4910         char            buf[1024];
4911
4912         /* Drop priv's */
4913         safe_setuid_drop();
4914
4915         /* Build the filename */
4916         path_build(buf, 1024, ANGBAND_DIR_USER, name);
4917
4918         /* File type is "TEXT" */
4919         FILE_TYPE(FILE_TYPE_TEXT);
4920
4921         /* Check for existing file */
4922         fd = fd_open(buf, O_RDONLY);
4923
4924         /* Existing file */
4925         if (fd >= 0)
4926         {
4927                 char out_val[160];
4928
4929                 /* Close the file */
4930                 (void)fd_close(fd);
4931
4932                 /* Build query */
4933 #ifdef JP
4934 (void)sprintf(out_val, "¸½Â¸¤¹¤ë¥Õ¥¡¥¤¥ë %s ¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«? ", buf);
4935 #else
4936                 (void)sprintf(out_val, "Replace existing file %s? ", buf);
4937 #endif
4938
4939
4940                 /* Ask */
4941                 if (get_check(out_val)) fd = -1;
4942         }
4943
4944         /* Open the non-existing file */
4945         if (fd < 0) fff = my_fopen(buf, "w");
4946
4947         /* Invalid file */
4948         if (!fff)
4949         {
4950                 /* Message */
4951 #ifdef JP
4952 msg_format("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4953 #else
4954                 msg_format("Character dump failed!");
4955 #endif
4956
4957                 msg_print(NULL);
4958
4959                 /* Error */
4960                 return (-1);
4961         }
4962
4963         (void)make_character_dump(fff);
4964
4965         /* Close it */
4966         my_fclose(fff);
4967
4968         /* Grab priv's */
4969         safe_setuid_grab();
4970
4971         /* Message */
4972 #ifdef JP
4973 msg_print("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤ËÀ®¸ù¤·¤Þ¤·¤¿¡£");
4974 #else
4975         msg_print("Character dump successful.");
4976 #endif
4977
4978         msg_print(NULL);
4979
4980         /* Success */
4981         return (0);
4982 }
4983
4984
4985 typedef struct file_tag
4986 {
4987         char name[32];
4988         int line_number;
4989 } file_tag;
4990
4991
4992 typedef struct file_tags
4993 {
4994         file_tag tags[64];
4995         int index;
4996 } file_tags;
4997
4998
4999 static void add_tag(file_tags *the_tags, cptr name, int line)
5000 {
5001         if (the_tags->index < 64)
5002         {
5003                 file_tag *tag = &(the_tags->tags[the_tags->index]);
5004
5005                 /* Set the name and end it with '\0' */
5006                 strncpy(tag->name, name, 31);
5007                 tag->name[31] = '\0';
5008
5009                 /* Set the line-number */
5010                 tag->line_number = line;
5011
5012                 /* Increase the number of tags */
5013                 the_tags->index++;
5014         }
5015 }
5016
5017
5018 static int get_line(file_tags *the_tags, cptr name)
5019 {
5020         int i;
5021
5022         /* Search for the tag */
5023         for (i = 0; i < the_tags->index; i++)
5024         {
5025                 if (streq(the_tags->tags[i].name, name))
5026                 {
5027                         return the_tags->tags[i].line_number;
5028                 }
5029         }
5030
5031         /* Not found */
5032         return 0;
5033 }
5034
5035
5036 /*
5037  * Recursive file perusal.
5038  *
5039  * Return FALSE on 'Q', otherwise TRUE.
5040  *
5041  * Process various special text in the input file, including
5042  * the "menu" structures used by the "help file" system.
5043  *
5044  * XXX XXX XXX Consider using a temporary file.
5045  *
5046  * XXX XXX XXX Allow the user to "save" the current file.
5047  */
5048 bool show_file(bool show_version, cptr name, cptr what, int line, int mode)
5049 {
5050         int i, n, k;
5051
5052         /* Number of "real" lines passed by */
5053         int next = 0;
5054
5055         /* Number of "real" lines in the file */
5056         int size = 0;
5057
5058         /* Backup value for "line" */
5059         int back = 0;
5060
5061         /* Loop counter */
5062         int cnt;
5063
5064         /* This screen has sub-screens */
5065         bool menu = FALSE;
5066
5067         /* Current help file */
5068         FILE *fff = NULL;
5069
5070         /* Find this string (if any) */
5071         cptr find = NULL;
5072
5073         /* Jump to this tag */
5074         cptr tag = NULL;
5075
5076         /* Hold a string to find */
5077         char finder[81];
5078
5079         /* Hold a string to show */
5080         char shower[81];
5081
5082         /* Filename */
5083         char filename[1024];
5084
5085         /* Describe this thing */
5086         char caption[128];
5087
5088         /* Path buffer */
5089         char path[1024];
5090
5091         /* General buffer */
5092         char buf[1024];
5093
5094         /* Lower case version of the buffer, for searching */
5095         char lc_buf[1024];
5096
5097         /* Aux pointer for making lc_buf (and find!) lowercase */
5098         cptr lc_buf_ptr;
5099
5100         /* Sub-menu information */
5101         char hook[68][32];
5102
5103         /* Tags for in-file references */
5104         file_tags tags;
5105
5106         bool reverse = (line < 0);
5107
5108         int wid, hgt, rows;
5109
5110         Term_get_size(&wid, &hgt);
5111         rows = hgt - 4;
5112
5113         /* Wipe finder */
5114         strcpy(finder, "");
5115
5116         /* Wipe shower */
5117         strcpy(shower, "");
5118
5119         /* Wipe caption */
5120         strcpy(caption, "");
5121
5122         /* Wipe the hooks */
5123         for (i = 0; i < 68; i++)
5124         {
5125                 hook[i][0] = '\0';
5126         }
5127
5128         /* No tags yet */
5129         tags.index = 0;
5130
5131         /* Copy the filename */
5132         strcpy(filename, name);
5133
5134         n = strlen(filename);
5135
5136         /* Extract the tag from the filename */
5137         for (i = 0; i < n; i++)
5138         {
5139                 if (filename[i] == '#')
5140                 {
5141                         filename[i] = '\0';
5142                         tag = filename + i + 1;
5143                         break;
5144                 }
5145         }
5146
5147         /* Redirect the name */
5148         name = filename;
5149
5150         /* Hack XXX XXX XXX */
5151         if (what)
5152         {
5153                 /* Caption */
5154                 strcpy(caption, what);
5155
5156                 /* Access the "file" */
5157                 strcpy(path, name);
5158
5159                 /* Open */
5160                 fff = my_fopen(path, "r");
5161         }
5162
5163         /* Look in "help" */
5164         if (!fff)
5165         {
5166                 /* Caption */
5167 #ifdef JP
5168 sprintf(caption, "¥Ø¥ë¥×¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5169 #else
5170                 sprintf(caption, "Help file '%s'", name);
5171 #endif
5172
5173
5174                 /* Build the filename */
5175                 path_build(path, 1024, ANGBAND_DIR_HELP, name);
5176
5177                 /* Open the file */
5178                 fff = my_fopen(path, "r");
5179         }
5180
5181         /* Look in "info" */
5182         if (!fff)
5183         {
5184                 /* Caption */
5185 #ifdef JP
5186 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5187 #else
5188                 sprintf(caption, "Info file '%s'", name);
5189 #endif
5190
5191
5192                 /* Build the filename */
5193                 path_build(path, 1024, ANGBAND_DIR_INFO, name);
5194
5195                 /* Open the file */
5196                 fff = my_fopen(path, "r");
5197         }
5198
5199         /* Look in "info" */
5200         if (!fff)
5201         {
5202                 /* Build the filename */
5203                 path_build(path, 1024, ANGBAND_DIR, name);
5204
5205                 for (i = 0; path[i]; i++)
5206                         if ('\\' == path[i])
5207                                 path[i] = PATH_SEP[0];
5208
5209                 /* Caption */
5210 #ifdef JP
5211 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5212 #else
5213                 sprintf(caption, "Info file '%s'", name);
5214 #endif
5215
5216                 /* Open the file */
5217                 fff = my_fopen(path, "r");
5218         }
5219
5220         /* Oops */
5221         if (!fff)
5222         {
5223                 /* Message */
5224 #ifdef JP
5225 msg_format("'%s'¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Þ¤»¤ó¡£", name);
5226 #else
5227                 msg_format("Cannot open '%s'.", name);
5228 #endif
5229
5230                 msg_print(NULL);
5231
5232                 /* Oops */
5233                 return (TRUE);
5234         }
5235
5236
5237         /* Pre-Parse the file */
5238         while (TRUE)
5239         {
5240                 /* Read a line or stop */
5241                 if (my_fgets(fff, buf, 1024)) break;
5242
5243                 /* XXX Parse "menu" items */
5244                 if (prefix(buf, "***** "))
5245                 {
5246                         /* Notice "menu" requests */
5247                         if ((buf[6] == '[') && (isdigit(buf[7]) || isalpha(buf[7])))
5248                         {
5249                                 /* This is a menu file */
5250                                 menu = TRUE;
5251
5252                                 /* Extract the menu item */
5253                                 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
5254
5255                                 if ((buf[8] == ']') && (buf[9] == ' '))
5256                                 {
5257                                         /* Extract the menu item */
5258                                         strncpy(hook[k], buf + 10, 31);
5259
5260                                         /* Make sure it's null-terminated */
5261                                         hook[k][31] = '\0';
5262                                 }
5263                         }
5264                         /* Notice "tag" requests */
5265                         else if (buf[6] == '<')
5266                         {
5267                                 buf[strlen(buf) - 1] = '\0';
5268                                 add_tag(&tags, buf + 7, next);
5269                         }
5270
5271                         /* Skip this */
5272                         continue;
5273                 }
5274
5275                 /* Count the "real" lines */
5276                 next++;
5277         }
5278
5279         /* Save the number of "real" lines */
5280         size = next;
5281
5282         /* start from bottom when reverse mode */
5283         if (line == -1) line = ((size-1)/rows)*rows;
5284
5285         /* Go to the tagged line */
5286         if (tag) line = get_line(&tags, tag);
5287
5288         /* Display the file */
5289         while (TRUE)
5290         {
5291                 /* Clear screen */
5292                 Term_clear();
5293
5294                 /* Restart when necessary */
5295                 if (line >= size) line = 0;
5296
5297
5298                 /* Re-open the file if needed */
5299                 if (next > line)
5300                 {
5301                         /* Close it */
5302                         my_fclose(fff);
5303
5304                         /* Hack -- Re-Open the file */
5305                         fff = my_fopen(path, "r");
5306
5307                         /* Oops */
5308                         if (!fff) return (FALSE);
5309
5310                         /* File has been restarted */
5311                         next = 0;
5312                 }
5313
5314                 /* Goto the selected line */
5315                 while (next < line)
5316                 {
5317                         /* Get a line */
5318                         if (my_fgets(fff, buf, 1024)) break;
5319
5320                         /* Skip tags/links */
5321                         if (prefix(buf, "***** ")) continue;
5322
5323                         /* Count the lines */
5324                         next++;
5325                 }
5326
5327                 /* Dump the next rows lines of the file */
5328                 for (i = 0; i < rows; )
5329                 {
5330                         /* Hack -- track the "first" line */
5331                         if (!i) line = next;
5332
5333                         /* Get a line of the file or stop */
5334                         if (my_fgets(fff, buf, 1024)) break;
5335
5336                         /* Hack -- skip "special" lines */
5337                         if (prefix(buf, "***** ")) continue;
5338
5339                         /* Count the "real" lines */
5340                         next++;
5341
5342                         /* Make a lower case version of buf for searching */
5343                         strcpy(lc_buf, buf);
5344
5345                         for (lc_buf_ptr = lc_buf; *lc_buf_ptr != 0; lc_buf_ptr++)
5346                         {
5347 #ifdef JP
5348                                 if (iskanji(*lc_buf_ptr))
5349                                         lc_buf_ptr++;
5350                                 else
5351 #endif
5352                                         lc_buf[lc_buf_ptr-lc_buf] = tolower(*lc_buf_ptr);
5353                         }
5354
5355                         /* Hack -- keep searching */
5356                         if (find && !i && !strstr(lc_buf, find)) continue;
5357
5358                         /* Hack -- stop searching */
5359                         find = NULL;
5360
5361                         /* Dump the line */
5362                         Term_putstr(0, i+2, -1, TERM_WHITE, buf);
5363
5364                         /* Hilite "shower" */
5365                         if (shower[0])
5366                         {
5367                                 cptr str = lc_buf;
5368
5369                                 /* Display matches */
5370                                 while ((str = strstr(str, shower)) != NULL)
5371                                 {
5372                                         int len = strlen(shower);
5373
5374                                         /* Display the match */
5375                                         Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]);
5376
5377                                         /* Advance */
5378                                         str += len;
5379                                 }
5380                         }
5381
5382                         /* Count the printed lines */
5383                         i++;
5384                 }
5385
5386                 /* Hack -- failed search */
5387                 if (find)
5388                 {
5389                         bell();
5390                         line = back;
5391                         find = NULL;
5392                         continue;
5393                 }
5394
5395
5396                 /* Show a general "title" */
5397                 if (show_version)
5398                 {
5399                         prt(format(
5400 #ifdef JP
5401                                 "[ÊѶòÈÚÅÜ %d.%d.%d, %s, %d/%d]",
5402 #else
5403                                 "[Hengband %d.%d.%d, %s, Line %d/%d]",
5404 #endif
5405
5406                            FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH,
5407                            caption, line, size), 0, 0);
5408                 }
5409                 else
5410                 {
5411                         prt(format(
5412 #ifdef JP
5413                                 "[%s, %d/%d]",
5414 #else
5415                                 "[%s, Line %d/%d]",
5416 #endif
5417                                 caption, line, size), 0, 0);
5418                 }
5419
5420                 /* Prompt -- menu screen */
5421                 if (menu)
5422                 {
5423                         /* Wait for it */
5424 #ifdef JP
5425 prt("[ ÈÖ¹æ¤òÆþÎϤ·¤Æ²¼¤µ¤¤( ESC¤Ç½ªÎ» ) ]", hgt - 1, 0);
5426 #else
5427                         prt("[Press a Number, or ESC to exit.]", hgt - 1, 0);
5428 #endif
5429
5430                 }
5431
5432                 /* Prompt -- small files */
5433                 else if (size <= rows)
5434                 {
5435                         /* Wait for it */
5436 #ifdef JP
5437 prt("[¥­¡¼:(?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5438 #else
5439                         prt("[Press ESC to exit.]", hgt - 1, 0);
5440 #endif
5441
5442                 }
5443
5444                 /* Prompt -- large files */
5445                 else
5446                 {
5447 #ifdef JP
5448                         if(reverse)
5449                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢¬ (-)¢­ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5450                         else
5451                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢­ (-)¢¬ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5452 #else
5453                         prt("[Press Return, Space, -, =, /, |, or ESC to exit.]", hgt - 1, 0);
5454 #endif
5455                 }
5456
5457                 /* Get a keypress */
5458                 k = inkey();
5459
5460                 /* Hack -- return to last screen */
5461                 if (k == '<') break;
5462
5463                 /* Show the help for the help */
5464                 if (k == '?')
5465                 {
5466                         /* Hack - prevent silly recursion */
5467 #ifdef JP
5468                         if (strcmp(name, "jhelpinfo.txt") != 0)
5469                                 show_file(TRUE, "jhelpinfo.txt", NULL, 0, mode);
5470 #else
5471                         if (strcmp(name, "helpinfo.txt") != 0)
5472                                 show_file(TRUE, "helpinfo.txt", NULL, 0, mode);
5473 #endif
5474                 }
5475
5476                 /* Hack -- try showing */
5477                 if (k == '=')
5478                 {
5479                         /* Get "shower" */
5480 #ifdef JP
5481 prt("¶¯Ä´: ", hgt - 1, 0);
5482 #else
5483                         prt("Show: ", hgt - 1, 0);
5484 #endif
5485
5486                         (void)askfor_aux(shower, 80);
5487                 }
5488
5489                 /* Hack -- try finding */
5490                 if (k == '/')
5491                 {
5492                         /* Get "finder" */
5493 #ifdef JP
5494 prt("¸¡º÷: ", hgt - 1, 0);
5495 #else
5496                         prt("Find: ", hgt - 1, 0);
5497 #endif
5498
5499
5500                         if (askfor_aux(finder, 80))
5501                         {
5502                                 /* Find it */
5503                                 find = finder;
5504                                 back = line;
5505                                 line = line + 1;
5506
5507                                 /* Make finder lowercase */
5508                                 for (cnt = 0; finder[cnt] != 0; cnt++)
5509                                 {
5510 #ifdef JP
5511                                         if (iskanji(finder[cnt]))
5512                                                 cnt++;
5513                                         else
5514 #endif
5515                                                 finder[cnt] = tolower(finder[cnt]);
5516                                 }
5517
5518                                 /* Show it */
5519                                 strcpy(shower, finder);
5520                         }
5521                 }
5522
5523                 /* Hack -- go to a specific line */
5524                 if (k == '#')
5525                 {
5526                         char tmp[81];
5527 #ifdef JP
5528 prt("¹Ô: ", hgt - 1, 0);
5529 #else
5530                         prt("Goto Line: ", hgt - 1, 0);
5531 #endif
5532
5533                         strcpy(tmp, "0");
5534
5535                         if (askfor_aux(tmp, 80))
5536                         {
5537                                 line = atoi(tmp);
5538                         }
5539                 }
5540
5541                 /* Hack -- go to a specific file */
5542                 if (k == '%')
5543                 {
5544                         char tmp[81];
5545 #ifdef JP
5546 prt("¥Õ¥¡¥¤¥ë¡¦¥Í¡¼¥à: ", hgt - 1, 0);
5547 strcpy(tmp, "jhelp.hlp");
5548 #else
5549                         prt("Goto File: ", hgt - 1, 0);
5550                         strcpy(tmp, "help.hlp");
5551 #endif
5552
5553
5554                         if (askfor_aux(tmp, 80))
5555                         {
5556                                 if (!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5557                         }
5558                 }
5559
5560                 /* Hack -- Allow backing up */
5561                 if (k == '-')
5562                 {
5563                         line = line + (reverse ? rows : -rows);
5564                         if (line < 0) line = ((size-1)/rows)*rows;
5565                 }
5566
5567                 /* Hack -- Advance a single line */
5568                 if ((k == '\n') || (k == '\r'))
5569                 {
5570                         line = line + (reverse ? -1 : 1);
5571                         if (line < 0) line = ((size-1)/rows)*rows;
5572                 }
5573
5574                 /* Advance one page */
5575                 if (k == ' ')
5576                 {
5577                         line = line + (reverse ? -rows : rows);
5578                         if (line < 0) line = ((size-1)/rows)*rows;
5579                 }
5580
5581                 /* Recurse on numbers */
5582                 if (menu)
5583                 {
5584                         int key = -1;
5585
5586                         if (isdigit(k)) key = D2I(k);
5587                         else if (isalpha(k)) key = k - 'A' + 10;
5588
5589                         if ((key > -1) && hook[key][0])
5590                         {
5591                                 /* Recurse on that file */
5592                                 if (!show_file(TRUE, hook[key], NULL, 0, mode))
5593                                         k = 'q';
5594                         }
5595                 }
5596
5597                 /* Hack, dump to file */
5598                 if (k == '|')
5599                 {
5600                         FILE *ffp;
5601                         char buff[1024];
5602                         char xtmp[82];
5603
5604                         strcpy (xtmp, "");
5605
5606 #ifdef JP
5607                         if (!get_string("¥Õ¥¡¥¤¥ë̾: ", xtmp, 80))
5608 #else
5609                         if (!get_string("File name: ", xtmp, 80))
5610 #endif
5611                         {
5612                                 continue;
5613                         }
5614  
5615                         /* Close it */
5616                         my_fclose(fff);
5617
5618                         /* Drop priv's */
5619                         safe_setuid_drop();
5620
5621                         /* Build the filename */
5622                         path_build(buff, 1024, ANGBAND_DIR_USER, xtmp);
5623
5624                         /* Hack -- Re-Open the file */
5625                         fff = my_fopen(path, "r");
5626
5627                         ffp = my_fopen(buff, "w");
5628
5629                         /* Oops */
5630                         if (!(fff && ffp))
5631                         {
5632 #ifdef JP
5633 msg_print("¥Õ¥¡¥¤¥ë¤¬³«¤±¤Þ¤»¤ó¡£");
5634 #else
5635                                 msg_print("Failed to open file.");
5636 #endif
5637
5638                                 k = ESCAPE;
5639                                 break;
5640                         }
5641
5642                         sprintf(xtmp, "%s: %s", player_name, what);
5643                         my_fputs(ffp, xtmp, 80);
5644                         my_fputs(ffp, "\n", 80);
5645
5646                         while (!my_fgets(fff, buff, 80))
5647                                 my_fputs(ffp, buff, 80);
5648
5649                         /* Close it */
5650                         my_fclose(fff);
5651                         my_fclose(ffp);
5652
5653                         /* Grab priv's */
5654                         safe_setuid_grab();
5655
5656                         /* Hack -- Re-Open the file */
5657                         fff = my_fopen(path, "r");
5658                 }
5659
5660                 /* Exit on escape */
5661                 if (k == ESCAPE) break;
5662                 if (k == 'q') break;
5663         }
5664
5665         /* Close the file */
5666         my_fclose(fff);
5667
5668         /* Escape */
5669         if (k == 'q') return (FALSE);
5670
5671         /* Normal return */
5672         return (TRUE);
5673 }
5674
5675
5676 /*
5677  * Peruse the On-Line-Help
5678  */
5679 void do_cmd_help(void)
5680 {
5681         /* Save screen */
5682         screen_save();
5683
5684         /* Peruse the main help file */
5685 #ifdef JP
5686 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
5687 #else
5688         (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
5689 #endif
5690
5691
5692         /* Load screen */
5693         screen_load();
5694 }
5695
5696
5697 /*
5698  * Process the player name.
5699  * Extract a clean "base name".
5700  * Build the savefile name if needed.
5701  */
5702 void process_player_name(bool sf)
5703 {
5704         int i, k = 0;
5705
5706
5707         /* Cannot be too long */
5708 #if defined(MACINTOSH) || defined(MSDOS) || defined(USE_EMX) || defined(AMIGA) || defined(ACORN) || defined(VM)
5709 #ifdef MSDOS
5710         if (strlen(player_name) > 8)
5711 #else
5712         if (strlen(player_name) > 15)
5713 #endif
5714         {
5715                 /* Name too long */
5716 #ifdef JP
5717 quit_fmt("'%s'¤È¤¤¤¦Ì¾Á°¤ÏŤ¹¤®¤Þ¤¹¡ª", player_name);
5718 #else
5719                 quit_fmt("The name '%s' is too long!", player_name);
5720 #endif
5721
5722         }
5723 #endif
5724
5725         /* Cannot contain "icky" characters */
5726         for (i = 0; player_name[i]; i++)
5727         {
5728                 /* No control characters */
5729 #ifdef JP
5730                 if (iskanji(player_name[i])){i++;continue;}
5731                 if (iscntrl( (unsigned char)player_name[i]))
5732 #else
5733                 if (iscntrl(player_name[i]))
5734 #endif
5735
5736                 {
5737                         /* Illegal characters */
5738 #ifdef JP
5739 quit_fmt("'%s' ¤È¤¤¤¦Ì¾Á°¤ÏÉÔÀµ¤Ê¥³¥ó¥È¥í¡¼¥ë¥³¡¼¥É¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£", player_name);
5740 #else
5741                         quit_fmt("The name '%s' contains control chars!", player_name);
5742 #endif
5743
5744                 }
5745         }
5746
5747
5748 #ifdef MACINTOSH
5749
5750         /* Extract "useful" letters */
5751         for (i = 0; player_name[i]; i++)
5752         {
5753 #ifdef JP
5754                 unsigned char c = player_name[i];
5755 #else
5756                 char c = player_name[i];
5757 #endif
5758
5759
5760                 /* Convert "dot" to "underscore" */
5761                 if (c == '.') c = '_';
5762
5763                 /* Accept all the letters */
5764                 player_base[k++] = c;
5765         }
5766
5767 #else
5768
5769         /* Extract "useful" letters */
5770         for (i = 0; player_name[i]; i++)
5771         {
5772 #ifdef JP
5773                 unsigned char c = player_name[i];
5774 #else
5775                 char c = player_name[i];
5776 #endif
5777
5778                 /* Accept some letters */
5779 #ifdef JP
5780                 if(iskanji(c)){
5781                   if(k + 2 >= sizeof(player_base) || !player_name[i+1]) break;
5782                   player_base[k++] = c;
5783                   i++;
5784                   player_base[k++] = player_name[i];
5785                 }
5786 #ifdef SJIS
5787                 else if (iskana(c)) player_base[k++] = c;
5788 #endif
5789                 else
5790 #endif
5791                 /* Convert path separator to underscore */
5792                 if (!strncmp(PATH_SEP, player_name+i, strlen(PATH_SEP))){
5793                         player_base[k++] = '_';
5794                         i += strlen(PATH_SEP);
5795                 }
5796 #ifdef MSDOS
5797                 /* Convert space, dot, and underscore to underscore */
5798                 else if (strchr(". _", c)) player_base[k++] = '_';
5799 #endif
5800                 else if (isprint(c)) player_base[k++] = c;
5801         }
5802
5803 #endif
5804
5805
5806 #if defined(MSDOS)
5807
5808         /* Hack -- max length */
5809         if (k > 8) k = 8;
5810
5811 #endif
5812
5813         /* Terminate */
5814         player_base[k] = '\0';
5815
5816         /* Require a "base" name */
5817         if (!player_base[0]) strcpy(player_base, "PLAYER");
5818
5819
5820 #ifdef SAVEFILE_MUTABLE
5821
5822         /* Accept */
5823         sf = TRUE;
5824
5825 #endif
5826         if (!savefile_base[0] && savefile[0])
5827         {
5828                 cptr s;
5829                 s = savefile;
5830                 while (1)
5831                 {
5832                         cptr t;
5833                         t = strstr(s, PATH_SEP);
5834                         if (!t)
5835                                 break;
5836                         s = t+1;
5837                 }
5838                 strcpy(savefile_base, s);
5839         }
5840
5841         if (!savefile_base[0] || !savefile[0])
5842                 sf = TRUE;
5843
5844         /* Change the savefile name */
5845         if (sf)
5846         {
5847                 char temp[128];
5848
5849                 strcpy(savefile_base, player_base);
5850
5851 #ifdef SAVEFILE_USE_UID
5852                 /* Rename the savefile, using the player_uid and player_base */
5853                 (void)sprintf(temp, "%d.%s", player_uid, player_base);
5854 #else
5855                 /* Rename the savefile, using the player_base */
5856                 (void)sprintf(temp, "%s", player_base);
5857 #endif
5858
5859 #ifdef VM
5860                 /* Hack -- support "flat directory" usage on VM/ESA */
5861                 (void)sprintf(temp, "%s.sv", player_base);
5862 #endif /* VM */
5863
5864                 /* Build the filename */
5865                 path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp);
5866         }
5867 }
5868
5869
5870 /*
5871  * Gets a name for the character, reacting to name changes.
5872  *
5873  * Assumes that "display_player(0)" has just been called
5874  *
5875  * Perhaps we should NOT ask for a name (at "birth()") on
5876  * Unix machines?  XXX XXX
5877  *
5878  * What a horrible name for a global function.  XXX XXX XXX
5879  */
5880 void get_name(void)
5881 {
5882         char tmp[64];
5883
5884         /* Save the player name */
5885         strcpy(tmp, player_name);
5886
5887         /* Prompt for a new name */
5888 #ifdef JP
5889         if (get_string("¥­¥ã¥é¥¯¥¿¡¼¤Î̾Á°¤òÆþÎϤ·¤Æ²¼¤µ¤¤: ", tmp, 15))
5890 #else
5891         if (get_string("Enter a name for your character: ", tmp, 15))
5892 #endif
5893         {
5894                 /* Use the name */
5895                 strcpy(player_name, tmp);
5896         }
5897         else if (0 == strlen(player_name))
5898         {
5899                 /* Use default name */
5900                 strcpy(player_name, "PLAYER");
5901         }
5902
5903         /* Process the player name */
5904         process_player_name(FALSE);
5905
5906         strcpy(tmp,ap_ptr->title);
5907 #ifdef JP
5908         if(ap_ptr->no == 1)
5909                 strcat(tmp,"¤Î");
5910 #else
5911         strcat(tmp, " ");
5912 #endif
5913         strcat(tmp,player_name);
5914
5915         /* Re-Draw the name (in light blue) */
5916         c_put_str(TERM_L_BLUE, tmp, 1, 34);
5917
5918         /* Erase the prompt, etc */
5919         clear_from(22);
5920 }
5921
5922
5923
5924 /*
5925  * Hack -- commit suicide
5926  */
5927 void do_cmd_suicide(void)
5928 {
5929         int i;
5930
5931         /* Flush input */
5932         flush();
5933
5934         /* Verify Retirement */
5935         if (total_winner)
5936         {
5937                 /* Verify */
5938 #ifdef JP
5939 if (!get_check("°úÂष¤Þ¤¹¤«? ")) return;
5940 #else
5941                 if (!get_check("Do you want to retire? ")) return;
5942 #endif
5943
5944         }
5945
5946         /* Verify Suicide */
5947         else
5948         {
5949                 /* Verify */
5950 #ifdef JP
5951 if (!get_check("ËÜÅö¤Ë¼«»¦¤·¤Þ¤¹¤«¡©")) return;
5952 #else
5953                 if (!get_check("Do you really want to commit suicide? ")) return;
5954 #endif
5955         }
5956
5957
5958         if (!noscore)
5959         {
5960                 /* Special Verification for suicide */
5961 #ifdef JP
5962 prt("³Îǧ¤Î¤¿¤á '@' ¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 0);
5963 #else
5964                 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
5965 #endif
5966
5967                 flush();
5968                 i = inkey();
5969                 prt("", 0, 0);
5970                 if (i != '@') return;
5971         }
5972
5973         /* Stop playing */
5974         alive = FALSE;
5975
5976         /* Kill the player */
5977         death = TRUE;
5978
5979         /* Leaving */
5980         p_ptr->leaving = TRUE;
5981
5982         if (!total_winner)
5983         {
5984 #ifdef JP
5985                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤ËÀä˾¤·¤Æ¼«»¦¤·¤¿¡£");
5986                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
5987 #else
5988                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "give up all hope to commit suicide.");
5989                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "--------   Game  Over   --------");
5990 #endif
5991                 do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
5992         }
5993
5994         /* Cause of death */
5995 #ifdef JP
5996 (void)strcpy(died_from, "ÅÓÃ潪λ");
5997 #else
5998         (void)strcpy(died_from, "Quitting");
5999 #endif
6000
6001 }
6002
6003
6004
6005 /*
6006  * Save the game
6007  */
6008 void do_cmd_save_game(int is_autosave)
6009 {
6010         /* Autosaves do not disturb */
6011         if (is_autosave)
6012         {
6013 #ifdef JP
6014 msg_print("¼«Æ°¥»¡¼¥ÖÃæ");
6015 #else
6016                 msg_print("Autosaving the game...");
6017 #endif
6018
6019         }
6020         else
6021         {
6022                 /* Disturb the player */
6023                 disturb(1, 0);
6024         }
6025
6026         /* Clear messages */
6027         msg_print(NULL);
6028
6029         /* Handle stuff */
6030         handle_stuff();
6031
6032         /* Message */
6033 #ifdef JP
6034 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹...", 0, 0);
6035 #else
6036         prt("Saving game...", 0, 0);
6037 #endif
6038
6039
6040         /* Refresh */
6041         Term_fresh();
6042
6043         /* The player is not dead */
6044 #ifdef JP
6045 (void)strcpy(died_from, "(¥»¡¼¥Ö)");
6046 #else
6047         (void)strcpy(died_from, "(saved)");
6048 #endif
6049
6050
6051         /* Forbid suspend */
6052         signals_ignore_tstp();
6053
6054         /* Save the player */
6055         if (save_player())
6056         {
6057 #ifdef JP
6058 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ½ªÎ»", 0, 0);
6059 #else
6060                 prt("Saving game... done.", 0, 0);
6061 #endif
6062
6063         }
6064
6065         /* Save failed (oops) */
6066         else
6067         {
6068 #ifdef JP
6069 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ¼ºÇÔ¡ª", 0, 0);
6070 #else
6071                 prt("Saving game... failed!", 0, 0);
6072 #endif
6073
6074         }
6075
6076         /* Allow suspend again */
6077         signals_handle_tstp();
6078
6079         /* Refresh */
6080         Term_fresh();
6081
6082         /* Note that the player is not dead */
6083 #ifdef JP
6084 (void)strcpy(died_from, "(¸µµ¤¤ËÀ¸¤­¤Æ¤¤¤ë)");
6085 #else
6086         (void)strcpy(died_from, "(alive and well)");
6087 #endif
6088
6089 }
6090
6091
6092 /*
6093  * Save the game and exit
6094  */
6095 void do_cmd_save_and_exit(void)
6096 {
6097         alive = FALSE;
6098
6099         /* Leaving */
6100         p_ptr->leaving = TRUE;
6101 #ifdef JP
6102         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "----¥²¡¼¥àÃæÃÇ----");
6103 #else
6104         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "---- Save and Exit Game ----");
6105 #endif
6106 }
6107
6108
6109 /*
6110  * Hack -- Calculates the total number of points earned         -JWT-
6111  */
6112 long total_points(void)
6113 {
6114         int i, mult = 100;
6115         s16b max_dl = 0;
6116         u32b point, point_h, point_l;
6117         int arena_win = MIN(p_ptr->arena_number, MAX_ARENA_MONS);
6118
6119         if (stupid_monsters) mult -= 70;
6120         if (!preserve_mode) mult += 10;
6121         if (!autoroller) mult += 10;
6122         if (!smart_learn) mult -= 20;
6123         if (!terrain_streams) mult -= 20;
6124         if (smart_cheat) mult += 30;
6125         if (ironman_shops) mult += 50;
6126         if (ironman_small_levels) mult += 10;
6127         if (ironman_empty_levels) mult += 20;
6128         if (!powerup_home) mult += 50;
6129         if (ironman_rooms) mult += 100;
6130         if (ironman_nightmare) mult += 100;
6131
6132         if (mult < 5) mult = 5;
6133
6134         for (i = 0; i < max_d_idx; i++)
6135                 if(max_dlv[i] > max_dl)
6136                         max_dl = max_dlv[i];
6137
6138         point_l = (p_ptr->max_exp + (100 * max_dl));
6139         point_h = point_l / 0x10000L;
6140         point_l = point_l % 0x10000L;
6141         point_h *= mult;
6142         point_l *= mult;
6143         point_h += point_l / 0x10000L;
6144         point_l %= 0x10000L;
6145
6146         point_l += ((point_h % 100) << 16);
6147         point_h /= 100;
6148         point_l /= 100;
6149
6150         point = (point_h << 16) + (point_l);
6151         if (p_ptr->arena_number < 99)
6152                 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
6153
6154         if (ironman_downward) point *= 2;
6155         if (p_ptr->pclass == CLASS_BERSERKER)
6156         {
6157                 if ((p_ptr->prace == RACE_SPECTRE) || (p_ptr->prace == RACE_AMBERITE))
6158                         point = point / 5;
6159         }
6160
6161         if ((p_ptr->pseikaku == SEIKAKU_MUNCHKIN) && point)
6162         {
6163                 point = 1;
6164                 if (total_winner) point = 2;
6165         }
6166         if (easy_band) point = (0 - point);
6167
6168         return point;
6169 }
6170
6171
6172
6173 /*
6174  * Centers a string within a 31 character string                -JWT-
6175  */
6176 static void center_string(char *buf, cptr str)
6177 {
6178         int i, j;
6179
6180         /* Total length */
6181         i = strlen(str);
6182
6183         /* Necessary border */
6184         j = 15 - i / 2;
6185
6186         /* Mega-Hack */
6187         (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, "");
6188 }
6189
6190
6191 #if 0
6192 /*
6193  * Save a "bones" file for a dead character
6194  *
6195  * Note that we will not use these files until Angband 2.8.0, and
6196  * then we will only use the name and level on which death occured.
6197  *
6198  * Should probably attempt some form of locking...
6199  */
6200 static void make_bones(void)
6201 {
6202         FILE                *fp;
6203
6204         char                str[1024];
6205
6206
6207         /* Ignore wizards and borgs */
6208         if (!(noscore & 0x00FF))
6209         {
6210                 /* Ignore people who die in town */
6211                 if (dun_level)
6212                 {
6213                         char tmp[128];
6214
6215                         /* XXX XXX XXX "Bones" name */
6216                         sprintf(tmp, "bone.%03d", dun_level);
6217
6218                         /* Build the filename */
6219                         path_build(str, 1024, ANGBAND_DIR_BONE, tmp);
6220
6221                         /* Attempt to open the bones file */
6222                         fp = my_fopen(str, "r");
6223
6224                         /* Close it right away */
6225                         if (fp) my_fclose(fp);
6226
6227                         /* Do not over-write a previous ghost */
6228                         if (fp) return;
6229
6230                         /* File type is "TEXT" */
6231                         FILE_TYPE(FILE_TYPE_TEXT);
6232
6233                         /* Try to write a new "Bones File" */
6234                         fp = my_fopen(str, "w");
6235
6236                         /* Not allowed to write it?  Weird. */
6237                         if (!fp) return;
6238
6239                         /* Save the info */
6240                         fprintf(fp, "%s\n", player_name);
6241                         fprintf(fp, "%d\n", p_ptr->mhp);
6242                         fprintf(fp, "%d\n", p_ptr->prace);
6243                         fprintf(fp, "%d\n", p_ptr->pclass);
6244
6245                         /* Close and save the Bones file */
6246                         my_fclose(fp);
6247                 }
6248         }
6249 }
6250 #endif
6251
6252
6253 /*
6254  * Redefinable "print_tombstone" action
6255  */
6256 bool (*tombstone_aux)(void) = NULL;
6257
6258
6259 /*
6260  * Display a "tomb-stone"
6261  */
6262 static void print_tomb(void)
6263 {
6264         bool done = FALSE;
6265
6266         /* Do we use a special tombstone ? */
6267         if (tombstone_aux)
6268         {
6269                 /* Use tombstone hook */
6270                 done = (*tombstone_aux)();
6271         }
6272
6273         /* Print the text-tombstone */
6274         if (!done)
6275         {
6276                 cptr    p;
6277
6278                 char    tmp[160];
6279
6280                 char    buf[1024];
6281 #ifndef JP
6282                 char    dummy[80];
6283 #endif
6284
6285                 FILE        *fp;
6286
6287                 time_t  ct = time((time_t)0);
6288
6289
6290                 /* Clear screen */
6291                 Term_clear();
6292
6293                 /* Build the filename */
6294 #ifdef JP
6295                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead_j.txt");
6296 #else
6297                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt");
6298 #endif
6299
6300
6301                 /* Open the News file */
6302                 fp = my_fopen(buf, "r");
6303
6304                 /* Dump */
6305                 if (fp)
6306                 {
6307                         int i = 0;
6308
6309                         /* Dump the file to the screen */
6310                         while (0 == my_fgets(fp, buf, 1024))
6311                         {
6312                                 /* Display and advance */
6313                                 put_str(buf, i++, 0);
6314                         }
6315
6316                         /* Close */
6317                         my_fclose(fp);
6318                 }
6319
6320
6321                 /* King or Queen */
6322                 if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
6323                 {
6324 #ifdef JP
6325                 /* ±ÑÆüÀÚ¤êÂؤ¨ */
6326                   p= "°ÎÂç¤Ê¤ë¼Ô";
6327 #else
6328                         p = "Magnificent";
6329 #endif
6330
6331                 }
6332
6333                 /* Normal */
6334                 else
6335                 {
6336                         p =  player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
6337                 }
6338
6339                 center_string(buf, player_name);
6340                 put_str(buf, 6, 11);
6341
6342 #ifndef JP
6343                 center_string(buf, "the");
6344                 put_str(buf, 7, 11);
6345 #endif
6346
6347                 center_string(buf, p);
6348                 put_str(buf, 8, 11);
6349
6350
6351                 center_string(buf, cp_ptr->title);
6352
6353                 put_str(buf, 10, 11);
6354
6355 #ifdef JP
6356 (void)sprintf(tmp, "¥ì¥Ù¥ë: %d", (int)p_ptr->lev);
6357 #else
6358                 (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
6359 #endif
6360
6361                 center_string(buf, tmp);
6362                 put_str(buf, 11, 11);
6363
6364 #ifdef JP
6365 (void)sprintf(tmp, "·Ð¸³ÃÍ: %ld", (long)p_ptr->exp);
6366 #else
6367                 (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp);
6368 #endif
6369
6370                 center_string(buf, tmp);
6371                 put_str(buf, 12, 11);
6372
6373 #ifdef JP
6374 (void)sprintf(tmp, "½ê»ý¶â: %ld", (long)p_ptr->au);
6375 #else
6376                 (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au);
6377 #endif
6378
6379                 center_string(buf, tmp);
6380                 put_str(buf, 13, 11);
6381
6382 #ifdef JP
6383         /* Êè¤Ë¹ï¤à¸ÀÍÕ¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
6384         if (streq(died_from, "ÅÓÃ潪λ"))
6385         {
6386                 strcpy(tmp, "<¼«»¦>");
6387         }
6388         else
6389         {
6390                 if (streq(died_from, "ripe"))
6391                 {
6392                         strcpy(tmp, "°úÂà¸å¤ËÅ·¼÷¤òÁ´¤¦");
6393                 }
6394                 else if (streq(died_from, "Seppuku"))
6395                 {
6396                         strcpy(tmp, "¾¡Íø¤Î¸å¡¢ÀÚÊ¢");
6397                 }
6398                 else
6399                 {
6400                         strcpy(tmp, died_from);
6401                 }
6402         }
6403         center_string(buf, tmp);
6404         put_str(buf, 14, 11);
6405
6406         if(!streq(died_from, "ripe") && !streq(died_from, "Seppuku"))
6407         {
6408                 if( dun_level == 0 )
6409                 {
6410                         cptr town = (p_ptr->town_num ? "³¹" : "¹ÓÌî");
6411                         if(streq(died_from, "ÅÓÃ潪λ"))
6412                         {
6413                                 sprintf(tmp, "%s¤Ç»à¤ó¤À", town);
6414                         }
6415                         else
6416                         {
6417                                 sprintf(tmp, "¤Ë%s¤Ç»¦¤µ¤ì¤¿", town);
6418                         }
6419                 }
6420                 else
6421                 {
6422                         if(streq(died_from, "ÅÓÃ潪λ"))
6423                         {
6424                                 sprintf(tmp, "Ãϲ¼ %d ³¬¤Ç»à¤ó¤À", dun_level);
6425                         }
6426                         else
6427                         {
6428                                 sprintf(tmp, "¤ËÃϲ¼ %d ³¬¤Ç»¦¤µ¤ì¤¿", dun_level);
6429                         }
6430                 }
6431                 center_string(buf, tmp);
6432                 put_str(buf, 15, 11);
6433         }
6434 #else
6435                 (void)sprintf(tmp, "Killed on Level %d", dun_level);
6436                 center_string(buf, tmp);
6437                 put_str(buf, 14, 11);
6438
6439
6440                 if (strlen(died_from) > 24)
6441                 {
6442                         strncpy(dummy, died_from, 24);
6443                         dummy[24] = '\0';
6444                         (void)sprintf(tmp, "by %s.", dummy);
6445                 }
6446                 else
6447                         (void)sprintf(tmp, "by %s.", died_from);
6448
6449                 center_string(buf, tmp);
6450                 put_str(buf, 15, 11);
6451 #endif
6452
6453
6454
6455                 (void)sprintf(tmp, "%-.24s", ctime(&ct));
6456                 center_string(buf, tmp);
6457                 put_str(buf, 17, 11);
6458
6459 #ifdef JP
6460 msg_format("¤µ¤è¤¦¤Ê¤é¡¢%s!", player_name);
6461 #else
6462                 msg_format("Goodbye, %s!", player_name);
6463 #endif
6464
6465         }
6466 }
6467
6468
6469 /*
6470  * Display some character info
6471  */
6472 static void show_info(void)
6473 {
6474         int             i, j, k, l;
6475         object_type             *o_ptr;
6476         store_type              *st_ptr;
6477
6478         /* Hack -- Know everything in the inven/equip */
6479         for (i = 0; i < INVEN_TOTAL; i++)
6480         {
6481                 o_ptr = &inventory[i];
6482
6483                 /* Skip non-objects */
6484                 if (!o_ptr->k_idx) continue;
6485
6486                 /* Aware and Known */
6487                 object_aware(o_ptr);
6488                 object_known(o_ptr);
6489         }
6490
6491         for (i = 1; i < max_towns; i++)
6492         {
6493                 st_ptr = &town[i].store[STORE_HOME];
6494
6495                 /* Hack -- Know everything in the home */
6496                 for (j = 0; j < st_ptr->stock_num; j++)
6497                 {
6498                         o_ptr = &st_ptr->stock[j];
6499
6500                         /* Skip non-objects */
6501                         if (!o_ptr->k_idx) continue;
6502
6503                         /* Aware and Known */
6504                         object_aware(o_ptr);
6505                         object_known(o_ptr);
6506                 }
6507         }
6508
6509         /* Hack -- Recalculate bonuses */
6510         p_ptr->update |= (PU_BONUS);
6511
6512         /* Handle stuff */
6513         handle_stuff();
6514
6515         /* Flush all input keys */
6516         flush();
6517
6518         /* Flush messages */
6519         msg_print(NULL);
6520
6521
6522         /* Describe options */
6523 #ifdef JP
6524 prt("¥­¥ã¥é¥¯¥¿¡¼¤Îµ­Ï¿¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£", 21, 0);
6525 prt("¥ê¥¿¡¼¥ó¥­¡¼¤Ç¥­¥ã¥é¥¯¥¿¡¼¤ò¸«¤Þ¤¹¡£ESC¤ÇÃæÃǤ·¤Þ¤¹¡£", 22, 0);
6526 #else
6527         prt("You may now dump a character record to one or more files.", 21, 0);
6528         prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
6529 #endif
6530
6531
6532         /* Dump character records as requested */
6533         while (TRUE)
6534         {
6535                 char out_val[160];
6536
6537                 /* Prompt */
6538 #ifdef JP
6539 put_str("¥Õ¥¡¥¤¥ë¥Í¡¼¥à: ", 23, 0);
6540 #else
6541                 put_str("Filename: ", 23, 0);
6542 #endif
6543
6544
6545                 /* Default */
6546                 strcpy(out_val, "");
6547
6548                 /* Ask for filename (or abort) */
6549                 if (!askfor_aux(out_val, 60)) return;
6550
6551                 /* Return means "show on screen" */
6552                 if (!out_val[0]) break;
6553
6554                 /* Save screen */
6555                 screen_save();
6556
6557                 /* Dump a character file */
6558                 (void)file_character(out_val, TRUE);
6559
6560                 /* Load screen */
6561                 screen_load();
6562         }
6563
6564         update_playtime();
6565
6566         /* Display player */
6567         display_player(0);
6568
6569         /* Prompt for inventory */
6570 #ifdef JP
6571 prt("²¿¤«¥­¡¼¤ò²¡¤¹¤È¤µ¤é¤Ë¾ðÊó¤¬Â³¤­¤Þ¤¹ (ESC¤ÇÃæÃÇ): ", 23, 0);
6572 #else
6573         prt("Hit any key to see more information (ESC to abort): ", 23, 0);
6574 #endif
6575
6576
6577         /* Allow abort at this point */
6578         if (inkey() == ESCAPE) return;
6579
6580
6581         /* Show equipment and inventory */
6582
6583         /* Equipment -- if any */
6584         if (equip_cnt)
6585         {
6586                 Term_clear();
6587                 item_tester_full = TRUE;
6588                 (void)show_equip(0);
6589 #ifdef JP
6590 prt("ÁõÈ÷¤·¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6591 #else
6592                 prt("You are using: -more-", 0, 0);
6593 #endif
6594
6595                 if (inkey() == ESCAPE) return;
6596         }
6597
6598         /* Inventory -- if any */
6599         if (inven_cnt)
6600         {
6601                 Term_clear();
6602                 item_tester_full = TRUE;
6603                 (void)show_inven(0);
6604 #ifdef JP
6605 prt("»ý¤Ã¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6606 #else
6607                 prt("You are carrying: -more-", 0, 0);
6608 #endif
6609
6610                 if (inkey() == ESCAPE) return;
6611         }
6612
6613         /* Homes in the different towns */
6614         for (l = 1; l < max_towns; l++)
6615         {
6616                 st_ptr = &town[l].store[STORE_HOME];
6617
6618                 /* Home -- if anything there */
6619                 if (st_ptr->stock_num)
6620                 {
6621                         /* Display contents of the home */
6622                         for (k = 0, i = 0; i < st_ptr->stock_num; k++)
6623                         {
6624                                 /* Clear screen */
6625                                 Term_clear();
6626
6627                                 /* Show 12 items */
6628                                 for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++)
6629                                 {
6630                                         char o_name[MAX_NLEN];
6631                                         char tmp_val[80];
6632
6633                                         /* Acquire item */
6634                                         o_ptr = &st_ptr->stock[i];
6635
6636                                         /* Print header, clear line */
6637                                         sprintf(tmp_val, "%c) ", I2A(j));
6638                                         prt(tmp_val, j+2, 4);
6639
6640                                         /* Display object description */
6641                                         object_desc(o_name, o_ptr, TRUE, 3);
6642                                         c_put_str(tval_to_attr[o_ptr->tval], o_name, j+2, 7);
6643                                 }
6644
6645                                 /* Caption */
6646 #ifdef JP
6647 prt(format("²æ¤¬²È¤ËÃÖ¤¤¤Æ¤¢¤Ã¤¿¥¢¥¤¥Æ¥à ( %d ¥Ú¡¼¥¸): -³¤¯-", k+1), 0, 0);
6648 #else
6649                                 prt(format("Your home contains (page %d): -more-", k+1), 0, 0);
6650 #endif
6651
6652
6653                                 /* Wait for it */
6654                                 if (inkey() == ESCAPE) return;
6655                         }
6656                 }
6657         }
6658 }
6659
6660
6661 static bool check_score(void)
6662 {
6663         /* Clear screen */
6664         Term_clear();
6665
6666         /* No score file */
6667         if (highscore_fd < 0)
6668         {
6669 #ifdef JP
6670 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
6671 #else
6672                 msg_print("Score file unavailable.");
6673 #endif
6674
6675                 msg_print(NULL);
6676                 return FALSE;
6677         }
6678
6679 #ifndef SCORE_WIZARDS
6680         /* Wizard-mode pre-empts scoring */
6681         if (noscore & 0x000F)
6682         {
6683 #ifdef JP
6684 msg_print("¥¦¥£¥¶¡¼¥É¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6685 #else
6686                 msg_print("Score not registered for wizards.");
6687 #endif
6688
6689                 msg_print(NULL);
6690                 return FALSE;
6691         }
6692 #endif
6693
6694 #ifndef SCORE_BORGS
6695         /* Borg-mode pre-empts scoring */
6696         if (noscore & 0x00F0)
6697         {
6698 #ifdef JP
6699 msg_print("¥Ü¡¼¥°¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6700 #else
6701                 msg_print("Score not registered for borgs.");
6702 #endif
6703
6704                 msg_print(NULL);
6705                 return FALSE;
6706         }
6707 #endif
6708
6709 #ifndef SCORE_CHEATERS
6710         /* Cheaters are not scored */
6711         if (noscore & 0xFF00)
6712         {
6713 #ifdef JP
6714 msg_print("º¾µ½¤ò¤ä¤Ã¤¿¿Í¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6715 #else
6716                 msg_print("Score not registered for cheaters.");
6717 #endif
6718
6719                 msg_print(NULL);
6720                 return FALSE;
6721         }
6722 #endif
6723
6724         /* Interupted */
6725 #ifdef JP
6726 if (!total_winner && streq(died_from, "¶¯À©½ªÎ»"))
6727 #else
6728         if (!total_winner && streq(died_from, "Interrupting"))
6729 #endif
6730
6731         {
6732 #ifdef JP
6733 msg_print("¶¯À©½ªÎ»¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6734 #else
6735                 msg_print("Score not registered due to interruption.");
6736 #endif
6737
6738                 msg_print(NULL);
6739                 return FALSE;
6740         }
6741
6742         /* Quitter */
6743 #ifdef JP
6744 if (!total_winner && streq(died_from, "ÅÓÃ潪λ"))
6745 #else
6746         if (!total_winner && streq(died_from, "Quitting"))
6747 #endif
6748
6749         {
6750 #ifdef JP
6751 msg_print("ÅÓÃ潪λ¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6752 #else
6753                 msg_print("Score not registered due to quitting.");
6754 #endif
6755
6756                 msg_print(NULL);
6757                 return FALSE;
6758         }
6759         return TRUE;
6760 }
6761
6762 /*
6763  * Close up the current game (player may or may not be dead)
6764  *
6765  * This function is called only from "main.c" and "signals.c".
6766  */
6767 void close_game(void)
6768 {
6769         char buf[1024];
6770         bool do_send = TRUE;
6771
6772 /*      cptr p = "[i:¥­¥ã¥é¥¯¥¿¤Î¾ðÊó, f:¥Õ¥¡¥¤¥ë½ñ¤­½Ð¤·, t:¥¹¥³¥¢, x:*´ÕÄê*, ESC:¥²¡¼¥à½ªÎ»]"; */
6773
6774         /* Handle stuff */
6775         handle_stuff();
6776
6777         /* Flush the messages */
6778         msg_print(NULL);
6779
6780         /* Flush the input */
6781         flush();
6782
6783
6784         /* No suspending now */
6785         signals_ignore_tstp();
6786
6787
6788         /* Hack -- Character is now "icky" */
6789         character_icky = TRUE;
6790
6791
6792         /* Build the filename */
6793         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
6794
6795         /* Open the high score file, for reading/writing */
6796         highscore_fd = fd_open(buf, O_RDWR);
6797
6798
6799         /* Handle death */
6800         if (death)
6801         {
6802                 /* Handle retirement */
6803                 if (total_winner) kingly();
6804
6805                 /* Save memories */
6806 #ifdef JP
6807                 if (!munchkin_death || get_check("»à¤ó¤À¥Ç¡¼¥¿¤ò¥»¡¼¥Ö¤·¤Þ¤¹¤«¡© "))
6808 #else
6809                 if (!munchkin_death || get_check("Save death? "))
6810 #endif
6811                 {
6812
6813 #ifdef JP
6814 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6815 #else
6816                         if (!save_player()) msg_print("death save failed!");
6817 #endif
6818                 }
6819                 else do_send = FALSE;
6820
6821                 /* You are dead */
6822                 print_tomb();
6823
6824                 flush();
6825
6826                 /* Show more info */
6827                 show_info();
6828
6829                 /* Clear screen */
6830                 Term_clear();
6831
6832                 if (check_score())
6833                 {
6834                         if ((!send_world_score(do_send)))
6835                         {
6836 #ifdef JP
6837                                 if (get_check("¸å¤Ç¥¹¥³¥¢¤òÅÐÏ¿¤¹¤ë¤¿¤á¤ËÂÔµ¡¤·¤Þ¤¹¤«¡©"))
6838 #else
6839                                 if (get_check("Stand by for later score registration? "))
6840 #endif
6841                                 {
6842                                         wait_report_score = TRUE;
6843                                         death = FALSE;
6844 #ifdef JP
6845                                         if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6846 #else
6847                                         if (!save_player()) msg_print("death save failed!");
6848 #endif
6849                                 }
6850                         }
6851                         if (!wait_report_score)
6852                                 (void)top_twenty();
6853                 }
6854                 else if (highscore_fd >= 0)
6855                 {
6856                         display_scores_aux(0, 10, -1, NULL);
6857                 }
6858 #if 0
6859                 /* Dump bones file */
6860                 make_bones();
6861 #endif
6862         }
6863
6864         /* Still alive */
6865         else
6866         {
6867                 /* Save the game */
6868                 do_cmd_save_game(FALSE);
6869
6870                 /* Prompt for scores XXX XXX XXX */
6871 #ifdef JP
6872 prt("¥ê¥¿¡¼¥ó¥­¡¼¤« ESC ¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 40);
6873 #else
6874                 prt("Press Return (or Escape).", 0, 40);
6875 #endif
6876
6877
6878                 /* Predict score (or ESCAPE) */
6879                 if (inkey() != ESCAPE) predict_score();
6880         }
6881
6882
6883         /* Shut the high score file */
6884         (void)fd_close(highscore_fd);
6885
6886         /* Forget the high score fd */
6887         highscore_fd = -1;
6888
6889
6890         /* Allow suspending now */
6891         signals_handle_tstp();
6892 }
6893
6894
6895 /*
6896  * Handle abrupt death of the visual system
6897  *
6898  * This routine is called only in very rare situations, and only
6899  * by certain visual systems, when they experience fatal errors.
6900  *
6901  * XXX XXX Hack -- clear the death flag when creating a HANGUP
6902  * save file so that player can see tombstone when restart.
6903  */
6904 void exit_game_panic(void)
6905 {
6906         /* If nothing important has happened, just quit */
6907 #ifdef JP
6908 if (!character_generated || character_saved) quit("¶ÛµÞ»öÂÖ");
6909 #else
6910         if (!character_generated || character_saved) quit("panic");
6911 #endif
6912
6913
6914         /* Mega-Hack -- see "msg_print()" */
6915         msg_flag = FALSE;
6916
6917         /* Clear the top line */
6918         prt("", 0, 0);
6919
6920         /* Hack -- turn off some things */
6921         disturb(1, 0);
6922
6923         /* Mega-Hack -- Delay death */
6924         if (p_ptr->chp < 0) death = FALSE;
6925
6926         /* Hardcode panic save */
6927         panic_save = 1;
6928
6929         /* Forbid suspend */
6930         signals_ignore_tstp();
6931
6932         /* Indicate panic save */
6933 #ifdef JP
6934 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
6935 #else
6936         (void)strcpy(died_from, "(panic save)");
6937 #endif
6938
6939
6940         /* Panic save, or get worried */
6941 #ifdef JP
6942 if (!save_player()) quit("¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
6943 #else
6944         if (!save_player()) quit("panic save failed!");
6945 #endif
6946
6947
6948         /* Successful panic save */
6949 #ifdef JP
6950 quit("¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
6951 #else
6952         quit("panic save succeeded!");
6953 #endif
6954
6955 }
6956
6957
6958 /*
6959  * Get a random line from a file
6960  * Based on the monster speech patch by Matt Graham,
6961  */
6962 errr get_rnd_line(cptr file_name, int entry, char *output)
6963 {
6964         FILE    *fp;
6965         char    buf[1024];
6966         int     line, counter, test, numentries;
6967         int     line_num = 0;
6968         bool    found = FALSE;
6969
6970
6971         /* Build the filename */
6972         path_build(buf, 1024, ANGBAND_DIR_FILE, file_name);
6973
6974         /* Open the file */
6975         fp = my_fopen(buf, "r");
6976
6977         /* Failed */
6978         if (!fp) return (-1);
6979
6980         /* Find the entry of the monster */
6981         while (TRUE)
6982         {
6983                 /* Get a line from the file */
6984                 if (my_fgets(fp, buf, 1024) == 0)
6985                 {
6986                         /* Count the lines */
6987                         line_num++;
6988
6989                         /* Look for lines starting with 'N:' */
6990                         if ((buf[0] == 'N') && (buf[1] == ':'))
6991                         {
6992                                 /* Allow default lines */
6993                                 if (buf[2] == '*')
6994                                 {
6995                                         /* Default lines */
6996                                         found = TRUE;
6997                                         break;
6998                                 }
6999                                 else if (buf[2] == 'M')
7000                                 {
7001                                         if (r_info[entry].flags1 & RF1_MALE)
7002                                         {
7003                                                 found = TRUE;
7004                                                 break;
7005                                         }
7006                                 }
7007                                 else if (buf[2] == 'F')
7008                                 {
7009                                         if (r_info[entry].flags1 & RF1_FEMALE)
7010                                         {
7011                                                 found = TRUE;
7012                                                 break;
7013                                         }
7014                                 }
7015                                 /* Get the monster number */
7016                                 else if (sscanf(&(buf[2]), "%d", &test) != EOF)
7017                                 {
7018                                         /* Is it the right monster? */
7019                                         if (test == entry)
7020                                         {
7021                                                 found = TRUE;
7022                                                 break;
7023                                         }
7024                                 }
7025                                 else
7026                                 {
7027                                         /* Error while converting the monster number */
7028                                         msg_format("Error in line %d of %s!",
7029                                                   line_num, file_name);
7030                                         my_fclose(fp);
7031                                         return (-1);
7032                                 }
7033                         }
7034                 }
7035                 else
7036                 {
7037                         /* Reached end of file */
7038                         my_fclose(fp);
7039                         return (-1);
7040                 }
7041
7042         }
7043         
7044         /* Get the number of entries */
7045         while (TRUE)
7046         {
7047                 /* Get the line */
7048                 if (my_fgets(fp, buf, 1024) == 0)
7049                 {
7050                         /* Count the lines */
7051                         line_num++;
7052
7053                         /* Look for the number of entries */
7054                         if (isdigit(buf[0]))
7055                         {
7056                                 /* Get the number of entries */
7057                                 numentries = atoi(buf);
7058                                 break;
7059                         }
7060                 }
7061                 else
7062                 {
7063                         /* Count the lines */
7064                         line_num++;
7065
7066                         /* Reached end of file without finding the number */
7067                         msg_format("Error in line %d of %s!",
7068                                   line_num, file_name);
7069
7070                         my_fclose(fp);
7071                         return (-1);
7072                 }
7073         }
7074
7075         if (numentries > 0)
7076         {
7077                 /* Grab an appropriate line number */
7078                 line = randint0(numentries);
7079
7080                 /* Get the random line */
7081                 for (counter = 0; counter <= line; counter++)
7082                 {
7083                         /* Count the lines */
7084                         line_num++;
7085
7086                         while(TRUE)
7087                         {
7088                                 test = my_fgets(fp, buf, 1024);
7089                                 if(test || buf[0] != '#')
7090                                         break;
7091                         }
7092
7093                         if (test==0)
7094                         {
7095                                 /* Found the line */
7096                                 if (counter == line) break;
7097                         }
7098                         else
7099                         {
7100                                 /* Error - End of file */
7101                                 msg_format("Error in line %d of %s!",
7102                                           line_num, file_name);
7103
7104                                 my_fclose(fp);
7105                                 return (-1);
7106                         }
7107                 }
7108
7109                 /* Copy the line */
7110                 strcpy(output, buf);
7111         }
7112         else
7113         {
7114                 return (-1);
7115         }
7116
7117         /* Close the file */
7118         my_fclose(fp);
7119
7120         /* Success */
7121         return (0);
7122 }
7123
7124
7125 #ifdef JP
7126 errr get_rnd_line_jonly(cptr file_name, int entry, char *output, int count)
7127 {
7128   int i,j,kanji;
7129   errr result=1;
7130   for (i=0;i<count;i++){
7131     result=get_rnd_line(file_name, entry, output);
7132     if(result)break;
7133     kanji=0;
7134     for(j=0; output[j]; j++) kanji |= iskanji(output[j]);
7135     if(kanji)break;
7136   }
7137   return(result);
7138 }
7139 #endif
7140
7141 /*
7142  * Process file for auto picker/destroyer.
7143  */
7144 errr process_pickpref_file(cptr name)
7145 {
7146         char buf[1024];
7147
7148         errr err = 0;
7149
7150         /* Drop priv's */
7151         safe_setuid_drop();
7152
7153         /* Build the filename */
7154         path_build(buf, 1024, ANGBAND_DIR_USER, name);
7155
7156         err = process_pref_file_aux(buf, TRUE);
7157
7158         /* Grab priv's */
7159         safe_setuid_grab();
7160
7161         /* Result */
7162         return (err);
7163 }
7164
7165 static errr counts_seek(int fd, u32b where, bool flag)
7166 {
7167         huge seekpoint;
7168         char temp1[128], temp2[128];
7169         u32b zero_header[3] = {0L, 0L, 0L};
7170         int i;
7171
7172 #ifdef SAVEFILE_USE_UID
7173         (void)sprintf(temp1, "%d.%s.%d%d%d", player_uid, savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7174 #else
7175         (void)sprintf(temp1, "%s.%d%d%d", savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7176 #endif
7177         for (i = 0; temp1[i]; i++)
7178                 temp1[i] ^= (i+1) * 63;
7179
7180         seekpoint = 0;
7181         while (1)
7182         {
7183                 if (fd_seek(fd, seekpoint + 3 * sizeof(u32b)))
7184                         return 1;
7185                 if (fd_read(fd, (char*)(temp2), sizeof(temp2)))
7186                 {
7187                         if (!flag)
7188                                 return 1;
7189                         /* add new name */
7190                         fd_seek(fd, seekpoint);
7191                         fd_write(fd, (char*)zero_header, 3*sizeof(u32b));
7192                         fd_write(fd, (char*)(temp1), sizeof(temp1));
7193                         break;
7194                 }
7195
7196                 if (strcmp(temp1, temp2) == 0)
7197                         break;
7198
7199                 seekpoint += 128 + 3 * sizeof(u32b);
7200         }
7201
7202         return fd_seek(fd, seekpoint + where * sizeof(u32b));
7203 }
7204
7205 u32b counts_read(int where)
7206 {
7207         int fd;
7208         u32b count = 0;
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_RDONLY);
7217
7218         if (counts_seek(fd, where, FALSE) ||
7219             fd_read(fd, (char*)(&count), sizeof(u32b)))
7220                 count = 0;
7221
7222         (void)fd_close(fd);
7223
7224         return count;
7225 }
7226
7227 errr counts_write(int where, u32b count)
7228 {
7229         int fd;
7230         char buf[1024];
7231
7232 #ifdef JP
7233         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7234 #else
7235         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7236 #endif
7237         fd = fd_open(buf, O_RDWR);
7238         if (fd < 0)
7239         {
7240                 /* File type is "DATA" */
7241                 FILE_TYPE(FILE_TYPE_DATA);
7242
7243                 /* Create a new high score file */
7244                 fd = fd_make(buf, 0644);
7245         }
7246
7247         if (fd_lock(fd, F_WRLCK)) return 1;
7248
7249         counts_seek(fd, where, TRUE);
7250         fd_write(fd, (char*)(&count), sizeof(u32b));
7251
7252         if (fd_lock(fd, F_UNLCK)) return 1;
7253
7254         (void)fd_close(fd);
7255
7256         return 0;
7257 }
7258
7259
7260 #ifdef HANDLE_SIGNALS
7261
7262
7263 #include <signal.h>
7264
7265
7266 /*
7267  * Handle signals -- suspend
7268  *
7269  * Actually suspend the game, and then resume cleanly
7270  */
7271 static void handle_signal_suspend(int sig)
7272 {
7273         /* Disable handler */
7274         (void)signal(sig, SIG_IGN);
7275
7276 #ifdef SIGSTOP
7277
7278         /* Flush output */
7279         Term_fresh();
7280
7281         /* Suspend the "Term" */
7282         Term_xtra(TERM_XTRA_ALIVE, 0);
7283
7284         /* Suspend ourself */
7285         (void)kill(0, SIGSTOP);
7286
7287         /* Resume the "Term" */
7288         Term_xtra(TERM_XTRA_ALIVE, 1);
7289
7290         /* Redraw the term */
7291         Term_redraw();
7292
7293         /* Flush the term */
7294         Term_fresh();
7295
7296 #endif
7297
7298         /* Restore handler */
7299         (void)signal(sig, handle_signal_suspend);
7300 }
7301
7302
7303 /*
7304  * Handle signals -- simple (interrupt and quit)
7305  *
7306  * This function was causing a *huge* number of problems, so it has
7307  * been simplified greatly.  We keep a global variable which counts
7308  * the number of times the user attempts to kill the process, and
7309  * we commit suicide if the user does this a certain number of times.
7310  *
7311  * We attempt to give "feedback" to the user as he approaches the
7312  * suicide thresh-hold, but without penalizing accidental keypresses.
7313  *
7314  * To prevent messy accidents, we should reset this global variable
7315  * whenever the user enters a keypress, or something like that.
7316  */
7317 static void handle_signal_simple(int sig)
7318 {
7319         /* Disable handler */
7320         (void)signal(sig, SIG_IGN);
7321
7322
7323         /* Nothing to save, just quit */
7324         if (!character_generated || character_saved) quit(NULL);
7325
7326
7327         /* Count the signals */
7328         signal_count++;
7329
7330
7331         /* Terminate dead characters */
7332         if (death)
7333         {
7334                 /* Mark the savefile */
7335 #ifdef JP
7336 (void)strcpy(died_from, "¶¯À©½ªÎ»");
7337 #else
7338                 (void)strcpy(died_from, "Abortion");
7339 #endif
7340
7341                 forget_lite();
7342                 forget_view();
7343                 clear_mon_lite();
7344
7345                 /* Close stuff */
7346                 close_game();
7347
7348                 /* Quit */
7349 #ifdef JP
7350 quit("¶¯À©½ªÎ»");
7351 #else
7352                 quit("interrupt");
7353 #endif
7354
7355         }
7356
7357         /* Allow suicide (after 5) */
7358         else if (signal_count >= 5)
7359         {
7360                 /* Cause of "death" */
7361 #ifdef JP
7362 (void)strcpy(died_from, "¶¯À©½ªÎ»Ãæ");
7363 #else
7364                 (void)strcpy(died_from, "Interrupting");
7365 #endif
7366
7367
7368                 forget_lite();
7369                 forget_view();
7370                 clear_mon_lite();
7371
7372                 /* Stop playing */
7373                 alive = FALSE;
7374
7375                 /* Suicide */
7376                 death = TRUE;
7377
7378                 /* Leaving */
7379                 p_ptr->leaving = TRUE;
7380
7381                 /* Close stuff */
7382                 close_game();
7383
7384                 /* Quit */
7385 #ifdef JP
7386 quit("¶¯À©½ªÎ»");
7387 #else
7388                 quit("interrupt");
7389 #endif
7390
7391         }
7392
7393         /* Give warning (after 4) */
7394         else if (signal_count >= 4)
7395         {
7396                 /* Make a noise */
7397                 Term_xtra(TERM_XTRA_NOISE, 0);
7398
7399                 /* Clear the top line */
7400                 Term_erase(0, 0, 255);
7401
7402                 /* Display the cause */
7403 #ifdef JP
7404 Term_putstr(0, 0, -1, TERM_WHITE, "½Ïθ¤Î¾å¤Î¼«»¦¡ª");
7405 #else
7406                 Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");
7407 #endif
7408
7409
7410                 /* Flush */
7411                 Term_fresh();
7412         }
7413
7414         /* Give warning (after 2) */
7415         else if (signal_count >= 2)
7416         {
7417                 /* Make a noise */
7418                 Term_xtra(TERM_XTRA_NOISE, 0);
7419         }
7420
7421         /* Restore handler */
7422         (void)signal(sig, handle_signal_simple);
7423 }
7424
7425
7426 /*
7427  * Handle signal -- abort, kill, etc
7428  */
7429 static void handle_signal_abort(int sig)
7430 {
7431         int wid, hgt, rows;
7432
7433         Term_get_size(&wid, &hgt);
7434         rows = hgt - 4;
7435
7436         /* Disable handler */
7437         (void)signal(sig, SIG_IGN);
7438
7439
7440         /* Nothing to save, just quit */
7441         if (!character_generated || character_saved) quit(NULL);
7442
7443
7444         forget_lite();
7445         forget_view();
7446         clear_mon_lite();
7447
7448         /* Clear the bottom line */
7449         Term_erase(0, hgt - 1, 255);
7450
7451         /* Give a warning */
7452         Term_putstr(0, hgt - 1, -1, TERM_RED,
7453 #ifdef JP
7454 "¶²¤í¤·¤¤¥½¥Õ¥È¤Î¥Ð¥°¤¬Èô¤Ó¤«¤«¤Ã¤Æ¤­¤¿¡ª");
7455 #else
7456                     "A gruesome software bug LEAPS out at you!");
7457 #endif
7458
7459
7460         /* Message */
7461 #ifdef JP
7462 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö...");
7463 #else
7464         Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save...");
7465 #endif
7466
7467
7468         /* Flush output */
7469         Term_fresh();
7470
7471         /* Panic Save */
7472         panic_save = 1;
7473
7474         /* Panic save */
7475 #ifdef JP
7476 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
7477 #else
7478         (void)strcpy(died_from, "(panic save)");
7479 #endif
7480
7481
7482         /* Forbid suspend */
7483         signals_ignore_tstp();
7484
7485         /* Attempt to save */
7486         if (save_player())
7487         {
7488 #ifdef JP
7489 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
7490 #else
7491                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save succeeded!");
7492 #endif
7493
7494         }
7495
7496         /* Save failed */
7497         else
7498         {
7499 #ifdef JP
7500 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
7501 #else
7502                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save failed!");
7503 #endif
7504
7505         }
7506
7507         /* Flush output */
7508         Term_fresh();
7509
7510         /* Quit */
7511 #ifdef JP
7512 quit("¥½¥Õ¥È¤Î¥Ð¥°");
7513 #else
7514         quit("software bug");
7515 #endif
7516
7517 }
7518
7519
7520
7521
7522 /*
7523  * Ignore SIGTSTP signals (keyboard suspend)
7524  */
7525 void signals_ignore_tstp(void)
7526 {
7527
7528 #ifdef SIGTSTP
7529         (void)signal(SIGTSTP, SIG_IGN);
7530 #endif
7531
7532 }
7533
7534 /*
7535  * Handle SIGTSTP signals (keyboard suspend)
7536  */
7537 void signals_handle_tstp(void)
7538 {
7539
7540 #ifdef SIGTSTP
7541         (void)signal(SIGTSTP, handle_signal_suspend);
7542 #endif
7543
7544 }
7545
7546
7547 /*
7548  * Prepare to handle the relevant signals
7549  */
7550 void signals_init(void)
7551 {
7552
7553 #ifdef SIGHUP
7554         (void)signal(SIGHUP, SIG_IGN);
7555 #endif
7556
7557
7558 #ifdef SIGTSTP
7559         (void)signal(SIGTSTP, handle_signal_suspend);
7560 #endif
7561
7562
7563 #ifdef SIGINT
7564         (void)signal(SIGINT, handle_signal_simple);
7565 #endif
7566
7567 #ifdef SIGQUIT
7568         (void)signal(SIGQUIT, handle_signal_simple);
7569 #endif
7570
7571
7572 #ifdef SIGFPE
7573         (void)signal(SIGFPE, handle_signal_abort);
7574 #endif
7575
7576 #ifdef SIGILL
7577         (void)signal(SIGILL, handle_signal_abort);
7578 #endif
7579
7580 #ifdef SIGTRAP
7581         (void)signal(SIGTRAP, handle_signal_abort);
7582 #endif
7583
7584 #ifdef SIGIOT
7585         (void)signal(SIGIOT, handle_signal_abort);
7586 #endif
7587
7588 #ifdef SIGKILL
7589         (void)signal(SIGKILL, handle_signal_abort);
7590 #endif
7591
7592 #ifdef SIGBUS
7593         (void)signal(SIGBUS, handle_signal_abort);
7594 #endif
7595
7596 #ifdef SIGSEGV
7597         (void)signal(SIGSEGV, handle_signal_abort);
7598 #endif
7599
7600 #ifdef SIGTERM
7601         (void)signal(SIGTERM, handle_signal_abort);
7602 #endif
7603
7604 #ifdef SIGPIPE
7605         (void)signal(SIGPIPE, handle_signal_abort);
7606 #endif
7607
7608 #ifdef SIGEMT
7609         (void)signal(SIGEMT, handle_signal_abort);
7610 #endif
7611
7612 #ifdef SIGDANGER
7613         (void)signal(SIGDANGER, handle_signal_abort);
7614 #endif
7615
7616 #ifdef SIGSYS
7617         (void)signal(SIGSYS, handle_signal_abort);
7618 #endif
7619
7620 #ifdef SIGXCPU
7621         (void)signal(SIGXCPU, handle_signal_abort);
7622 #endif
7623
7624 #ifdef SIGPWR
7625         (void)signal(SIGPWR, handle_signal_abort);
7626 #endif
7627
7628 }
7629
7630
7631 #else   /* HANDLE_SIGNALS */
7632
7633
7634 /*
7635  * Do nothing
7636  */
7637 void signals_ignore_tstp(void)
7638 {
7639 }
7640
7641 /*
7642  * Do nothing
7643  */
7644 void signals_handle_tstp(void)
7645 {
7646 }
7647
7648 /*
7649  * Do nothing
7650  */
7651 void signals_init(void)
7652 {
7653 }
7654 #endif  /* HANDLE_SIGNALS */