OSDN Git Service

branch-mogami-bigtile 、゙。シ・ク。」
[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[3];
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] = 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
2998                 /* Default */
2999                 c_put_str((byte)(vuln ? TERM_RED : TERM_SLATE), ".", row, col);
3000
3001                 /* Check flags */
3002                 if (f[n - 1] & flag1) c_put_str((byte)(vuln ? TERM_L_RED : TERM_WHITE), "+", row, col);
3003                 if (f[n - 1] & flag2) c_put_str(TERM_WHITE, "*", row, col);
3004
3005                 /* Advance */
3006                 col++;
3007         }
3008
3009         /* Player flags */
3010         player_flags(&f[0], &f[1], &f[2]);
3011
3012         /* Default */
3013         c_put_str((byte)(vuln ? TERM_RED : TERM_SLATE), ".", row, col);
3014
3015         /* Check flags */
3016         if (f[n-1] & flag1) c_put_str((byte)(vuln ? TERM_L_RED : TERM_WHITE), "+", row, col);
3017
3018         /* Timed player flags */
3019         tim_player_flags(&f[0], &f[1], &f[2], TRUE);
3020
3021         /* Check flags */
3022         if (f[n-1] & flag1) c_put_str((byte)(vuln ? TERM_ORANGE : TERM_YELLOW), "#", row, col);
3023
3024         /* Immunity */
3025         if (im_f[2] & flag1) c_put_str(TERM_YELLOW, "*", row, col);
3026         if (im_f[1] & flag1) c_put_str(TERM_WHITE, "*", row, col);
3027
3028         /* Vulnerability */
3029         if (vuln) c_put_str(TERM_RED, "v", row, col + 1);
3030 }
3031
3032
3033 /*
3034  * Special display, part 1
3035  */
3036 static void display_player_flag_info(void)
3037 {
3038         int row;
3039         int col;
3040
3041         u32b im_f[3][3], vul_f[3];
3042
3043         known_obj_immunity(&im_f[0][0], &im_f[1][0], &im_f[2][0]);
3044         player_immunity(&im_f[0][1], &im_f[1][1], &im_f[2][1]);
3045         tim_player_immunity(&im_f[0][2], &im_f[1][2], &im_f[2][2]);
3046
3047         player_vuln_flags(&vul_f[0], &vul_f[1], &vul_f[2]);
3048
3049         /*** Set 1 ***/
3050
3051         row = 12;
3052         col = 1;
3053
3054         display_player_equippy(row-2, col+8);
3055         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
3056
3057 #ifdef JP
3058 display_player_flag_aux(row+0, col, "ÂÑ»À  :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
3059 display_player_flag_aux(row+1, col, "ÂÑÅÅ·â:", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
3060 display_player_flag_aux(row+2, col, "ÂѲбê:", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
3061 display_player_flag_aux(row+3, col, "ÂÑÎ䵤:", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
3062 display_player_flag_aux(row+4, col, "ÂÑÆÇ  :", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
3063 display_player_flag_aux(row+5, col, "ÂÑÁ®¸÷:", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
3064 display_player_flag_aux(row+6, col, "ÂѰŹõ:", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
3065 display_player_flag_aux(row+7, col, "ÂÑÇËÊÒ:", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
3066 display_player_flag_aux(row+8, col, "ÂÑÌÕÌÜ:", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
3067 display_player_flag_aux(row+9, col, "ÂѺ®Íð:", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
3068 #else
3069         display_player_flag_aux(row+0, col, "Acid  :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
3070         display_player_flag_aux(row+1, col, "Elec  :", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
3071         display_player_flag_aux(row+2, col, "Fire  :", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
3072         display_player_flag_aux(row+3, col, "Cold  :", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
3073         display_player_flag_aux(row+4, col, "Poison:", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
3074         display_player_flag_aux(row+5, col, "Light :", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
3075         display_player_flag_aux(row+6, col, "Dark  :", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
3076         display_player_flag_aux(row+7, col, "Shard :", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
3077         display_player_flag_aux(row+8, col, "Blind :", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
3078         display_player_flag_aux(row+9, col, "Conf  :", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
3079 #endif
3080
3081
3082         /*** Set 2 ***/
3083
3084         row = 12;
3085         col = 26;
3086
3087         display_player_equippy(row-2, col+8);
3088
3089         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
3090
3091 #ifdef JP
3092 display_player_flag_aux(row+0, col, "Âѹ첻:", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
3093 display_player_flag_aux(row+1, col, "ÂÑÃϹö:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
3094 display_player_flag_aux(row+2, col, "ÂÑ°øº®:", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
3095 display_player_flag_aux(row+3, col, "ÂÑ¥«¥ª:", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
3096 display_player_flag_aux(row+4, col, "ÂÑÎô²½:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
3097 display_player_flag_aux(row+5, col, "ÂѶ²ÉÝ:", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
3098 display_player_flag_aux(row+6, col, "È¿¼Í  :", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
3099 display_player_flag_aux(row+7, col, "²Ð±ê¥ª:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
3100 display_player_flag_aux(row+8, col, "Åŵ¤¥ª:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
3101 display_player_flag_aux(row+9, col, "Î䵤¥ª:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
3102 #else
3103         display_player_flag_aux(row+0, col, "Sound :", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
3104         display_player_flag_aux(row+1, col, "Nether:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
3105         display_player_flag_aux(row+2, col, "Nexus :", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
3106         display_player_flag_aux(row+3, col, "Chaos :", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
3107         display_player_flag_aux(row+4, col, "Disnch:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
3108         display_player_flag_aux(row+5, col, "Fear  :", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
3109         display_player_flag_aux(row+6, col, "Reflct:", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
3110         display_player_flag_aux(row+7, col, "AuFire:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
3111         display_player_flag_aux(row+8, col, "AuElec:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
3112         display_player_flag_aux(row+9, col, "AuCold:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
3113 #endif
3114
3115
3116         /*** Set 3 ***/
3117
3118         row = 12;
3119         col = 51;
3120
3121         display_player_equippy(row-2, col+12);
3122
3123         c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+12);
3124
3125 #ifdef JP
3126 display_player_flag_aux(row+0, col, "²Ã®      :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
3127 display_player_flag_aux(row+1, col, "ÂÑËãáã    :", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
3128 display_player_flag_aux(row+2, col, "Æ©ÌÀÂλëǧ:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
3129 display_player_flag_aux(row+3, col, "·Ð¸³ÃÍÊÝ»ý:", 2, TR2_HOLD_LIFE, 0, im_f[2], vul_f[1]);
3130 display_player_flag_aux(row+4, col, "¥Æ¥ì¥Ñ¥·¡¼:", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
3131 display_player_flag_aux(row+5, col, "Ãپò½    :", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
3132 display_player_flag_aux(row+6, col, "µÞ²óÉü    :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
3133 display_player_flag_aux(row+7, col, "ÉâÍ·      :", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
3134 display_player_flag_aux(row+8, col, "±Ê±ó¸÷¸»  :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
3135 display_player_flag_aux(row+9, col, "¼ö¤¤      :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
3136 #else
3137         display_player_flag_aux(row+0, col, "Speed     :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
3138         display_player_flag_aux(row+1, col, "FreeAction:", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
3139         display_player_flag_aux(row+2, col, "SeeInvisi.:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
3140         display_player_flag_aux(row+3, col, "Hold Life :", 2, TR2_HOLD_LIFE, 0, im_f[1], vul_f[1]);
3141         display_player_flag_aux(row+4, col, "Telepathy :", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
3142         display_player_flag_aux(row+5, col, "SlowDigest:", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
3143         display_player_flag_aux(row+6, col, "Regene.   :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
3144         display_player_flag_aux(row+7, col, "Levitation:", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
3145         display_player_flag_aux(row+8, col, "Perm Lite :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
3146         display_player_flag_aux(row+9, col, "Cursed    :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
3147 #endif
3148
3149 }
3150
3151
3152 /*
3153  * Special display, part 2a
3154  */
3155 static void display_player_misc_info(void)
3156 {
3157         char    buf[80];
3158         char    tmp[80];
3159
3160         /* Display basics */
3161 #ifdef JP
3162 put_str("̾Á°  :", 1, 26);
3163 put_str("À­ÊÌ  :", 3, 1);
3164 put_str("¼ï²  :", 4, 1);
3165 put_str("¿¦¶È  :", 5, 1);
3166 #else
3167         put_str("Name  :", 1, 26);
3168         put_str("Sex   :", 3, 1);
3169         put_str("Race  :", 4, 1);
3170         put_str("Class :", 5, 1);
3171 #endif
3172
3173         strcpy(tmp,ap_ptr->title);
3174 #ifdef JP
3175         if(ap_ptr->no == 1)
3176                 strcat(tmp,"¤Î");
3177 #else
3178                 strcat(tmp," ");
3179 #endif
3180         strcat(tmp,player_name);
3181
3182         c_put_str(TERM_L_BLUE, tmp, 1, 34);
3183         c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
3184         c_put_str(TERM_L_BLUE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), 4, 9);
3185         c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 9);
3186
3187         /* Display extras */
3188 #ifdef JP
3189 put_str("¥ì¥Ù¥ë:", 6, 1);
3190 put_str("£È£Ð  :", 7, 1);
3191 put_str("£Í£Ð  :", 8, 1);
3192 #else
3193         put_str("Level :", 6, 1);
3194         put_str("Hits  :", 7, 1);
3195         put_str("Mana  :", 8, 1);
3196 #endif
3197
3198
3199         (void)sprintf(buf, "%d", (int)p_ptr->lev);
3200         c_put_str(TERM_L_BLUE, buf, 6, 9);
3201         (void)sprintf(buf, "%d/%d", (int)p_ptr->chp, (int)p_ptr->mhp);
3202         c_put_str(TERM_L_BLUE, buf, 7, 9);
3203         (void)sprintf(buf, "%d/%d", (int)p_ptr->csp, (int)p_ptr->msp);
3204         c_put_str(TERM_L_BLUE, buf, 8, 9);
3205 }
3206
3207
3208 /*
3209  * Special display, part 2b
3210  *
3211  * How to print out the modifications and sustains.
3212  * Positive mods with no sustain will be light green.
3213  * Positive mods with a sustain will be dark green.
3214  * Sustains (with no modification) will be a dark green 's'.
3215  * Negative mods (from a curse) will be red.
3216  * Huge mods (>9), like from MICoMorgoth, will be a '*'
3217  * No mod, no sustain, will be a slate '.'
3218  */
3219 static void display_player_stat_info(void)
3220 {
3221         int i, e_adj;
3222         int stat_col, stat;
3223         int row, col;
3224
3225         object_type *o_ptr;
3226         u32b f1, f2, f3;
3227         s16b k_idx;
3228
3229         byte a;
3230         char c;
3231
3232         char buf[80];
3233
3234
3235         /* Column */
3236         stat_col = 22;
3237
3238         /* Row */
3239         row = 3;
3240
3241         /* Print out the labels for the columns */
3242 #ifdef JP
3243 c_put_str(TERM_WHITE, "ǽÎÏ", row, stat_col+1);
3244 c_put_str(TERM_BLUE, "  ´ðËÜ", row, stat_col+7);
3245 c_put_str(TERM_L_BLUE, " ¼ï ¿¦ À­ Áõ ", row, stat_col+13);
3246 c_put_str(TERM_L_GREEN, "¹ç·×", row, stat_col+28);
3247 c_put_str(TERM_YELLOW, "¸½ºß", row, stat_col+35);
3248 #else
3249         c_put_str(TERM_WHITE, "Stat", row, stat_col+1);
3250         c_put_str(TERM_BLUE, "  Base", row, stat_col+7);
3251         c_put_str(TERM_L_BLUE, "RacClaPerMod", row, stat_col+13);
3252         c_put_str(TERM_L_GREEN, "Actual", row, stat_col+26);
3253         c_put_str(TERM_YELLOW, "Current", row, stat_col+32);
3254 #endif
3255
3256
3257         /* Display the stats */
3258         for (i = 0; i < 6; i++)
3259         {
3260                 int r_adj;
3261
3262                 if (p_ptr->mimic_form) r_adj = mimic_info[p_ptr->mimic_form].r_adj[i];
3263                 else r_adj = rp_ptr->r_adj[i];
3264
3265                 /* Calculate equipment adjustment */
3266                 e_adj = 0;
3267
3268                 /* Icky formula to deal with the 18 barrier */
3269                 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] > 18))
3270                         e_adj = (p_ptr->stat_top[i] - p_ptr->stat_max[i]) / 10;
3271                 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] <= 18))
3272                         e_adj = p_ptr->stat_top[i] - p_ptr->stat_max[i];
3273                 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] > 18))
3274                         e_adj = (p_ptr->stat_top[i] - 18) / 10 - p_ptr->stat_max[i] + 18;
3275
3276                 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] <= 18))
3277                         e_adj = p_ptr->stat_top[i] - (p_ptr->stat_max[i] - 19) / 10 - 19;
3278
3279                 if (prace_is_(RACE_ENT))
3280                 {
3281                         switch (i)
3282                         {
3283                                 case A_STR:
3284                                 case A_CON:
3285                                         if (p_ptr->lev > 25) r_adj++;
3286                                         if (p_ptr->lev > 40) r_adj++;
3287                                         if (p_ptr->lev > 45) r_adj++;
3288                                         break;
3289                                 case A_DEX:
3290                                         if (p_ptr->lev > 25) r_adj--;
3291                                         if (p_ptr->lev > 40) r_adj--;
3292                                         if (p_ptr->lev > 45) r_adj--;
3293                                         break;
3294                         }
3295                 }
3296
3297                 e_adj -= r_adj;
3298                 e_adj -= cp_ptr->c_adj[i];
3299                 e_adj -= ap_ptr->a_adj[i];
3300
3301                 if (p_ptr->stat_cur[i] < p_ptr->stat_max[i])
3302                         /* Reduced name of stat */
3303                         c_put_str(TERM_WHITE, stat_names_reduced[i], row + i+1, stat_col+1);
3304                 else
3305                         c_put_str(TERM_WHITE, stat_names[i], row + i+1, stat_col+1);
3306
3307
3308                 /* Internal "natural" max value.  Maxes at 18/100 */
3309                 /* This is useful to see if you are maxed out */
3310                 cnv_stat(p_ptr->stat_max[i], buf);
3311                 if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
3312                 {
3313 #ifdef JP
3314                         c_put_str(TERM_WHITE, "!", row + i+1, stat_col + 6);
3315 #else
3316                         c_put_str(TERM_WHITE, "!", row + i+1, stat_col + 4);
3317 #endif
3318                 }
3319                 c_put_str(TERM_BLUE, buf, row + i+1, stat_col + 13 - strlen(buf));
3320
3321                 /* Race, class, and equipment modifiers */
3322                 (void)sprintf(buf, "%3d", r_adj);
3323                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 13);
3324                 (void)sprintf(buf, "%3d", (int)cp_ptr->c_adj[i]);
3325                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 16);
3326                 (void)sprintf(buf, "%3d", (int)ap_ptr->a_adj[i]);
3327                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 19);
3328                 (void)sprintf(buf, "%3d", (int)e_adj);
3329                 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 22);
3330
3331                 /* Actual maximal modified value */
3332                 cnv_stat(p_ptr->stat_top[i], buf);
3333                 c_put_str(TERM_L_GREEN, buf, row + i+1, stat_col + 26);
3334
3335                 /* Only display stat_use if not maximal */
3336                 if (p_ptr->stat_use[i] < p_ptr->stat_top[i])
3337                 {
3338                         cnv_stat(p_ptr->stat_use[i], buf);
3339                         c_put_str(TERM_YELLOW, buf, row + i+1, stat_col + 33);
3340                 }
3341         }
3342
3343         /* Column */
3344         col = stat_col + 41;
3345
3346         /* Header and Footer */
3347         c_put_str(TERM_WHITE, "abcdefghijkl@", row, col);
3348 #ifdef JP
3349 c_put_str(TERM_L_GREEN, "ǽÎϽ¤Àµ", row - 1, col);
3350 #else
3351         c_put_str(TERM_L_GREEN, "Modification", row - 1, col);
3352 #endif
3353
3354
3355         /* Process equipment */
3356         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3357         {
3358                 /* Access object */
3359                 o_ptr = &inventory[i];
3360
3361                 /* Object kind */
3362                 k_idx = o_ptr->k_idx;
3363
3364                 /* Acquire "known" flags */
3365                 object_flags_known(o_ptr, &f1, &f2, &f3);
3366
3367                 /* Initialize color based of sign of pval. */
3368                 for (stat = 0; stat < 6; stat++)
3369                 {
3370                         /* Default */
3371                         a = TERM_SLATE;
3372                         c = '.';
3373
3374                         /* Boost */
3375                         if (f1 & 1 << stat)
3376                         {
3377                                 /* Default */
3378                                 c = '*';
3379
3380                                 /* Good */
3381                                 if (o_ptr->pval > 0)
3382                                 {
3383                                         /* Good */
3384                                         a = TERM_L_GREEN;
3385
3386                                         /* Label boost */
3387                                         if (o_ptr->pval < 10) c = '0' + o_ptr->pval;
3388                                 }
3389
3390                                 if (f2 & 1 << stat)
3391                                 {
3392                                         /* Dark green for sustained stats */
3393                                         a = TERM_GREEN;
3394                                 }
3395
3396                                 /* Bad */
3397                                 if (o_ptr->pval < 0)
3398                                 {
3399                                         /* Bad */
3400                                         a = TERM_RED;
3401
3402                                         /* Label boost */
3403                                         if (o_ptr->pval > -10) c = '0' - o_ptr->pval;
3404                                 }
3405                         }
3406
3407                         /* Sustain */
3408                         else if (f2 & 1 << stat)
3409                         {
3410                                 /* Dark green "s" */
3411                                 a = TERM_GREEN;
3412                                 c = 's';
3413                         }
3414
3415                         /* Dump proper character */
3416                         Term_putch(col, row + stat+1, a, c);
3417                 }
3418
3419                 /* Advance */
3420                 col++;
3421         }
3422
3423         /* Player flags */
3424         player_flags(&f1, &f2, &f3);
3425
3426         /* Check stats */
3427         for (stat = 0; stat < 6; stat++)
3428         {
3429                 /* Default */
3430                 a = TERM_SLATE;
3431                 c = '.';
3432
3433                 /* Mutations ... */
3434                 if (p_ptr->muta3 || p_ptr->tsuyoshi)
3435                 {
3436                         int dummy = 0;
3437
3438                         if (stat == A_STR)
3439                         {
3440                                 if (p_ptr->muta3 & MUT3_HYPER_STR) dummy += 4;
3441                                 if (p_ptr->muta3 & MUT3_PUNY) dummy -= 4;
3442                                 if (p_ptr->tsuyoshi) dummy += 4;
3443                         }
3444                         else if (stat == A_WIS || stat == A_INT)
3445                         {
3446                                 if (p_ptr->muta3 & MUT3_HYPER_INT) dummy += 4;
3447                                 if (p_ptr->muta3 & MUT3_MORONIC) dummy -= 4;
3448                         }
3449                         else if (stat == A_DEX)
3450                         {
3451                                 if (p_ptr->muta3 & MUT3_IRON_SKIN) dummy -= 1;
3452                                 if (p_ptr->muta3 & MUT3_LIMBER) dummy += 3;
3453                                 if (p_ptr->muta3 & MUT3_ARTHRITIS) dummy -= 3;
3454                         }
3455                         else if (stat == A_CON)
3456                         {
3457                                 if (p_ptr->muta3 & MUT3_RESILIENT) dummy += 4;
3458                                 if (p_ptr->muta3 & MUT3_XTRA_FAT) dummy += 2;
3459                                 if (p_ptr->muta3 & MUT3_ALBINO) dummy -= 4;
3460                                 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 2;
3461                                 if (p_ptr->tsuyoshi) dummy += 4;
3462                         }
3463                         else if (stat == A_CHR)
3464                         {
3465                                 if (p_ptr->muta3 & MUT3_SILLY_VOI) dummy -= 4;
3466                                 if (p_ptr->muta3 & MUT3_BLANK_FAC) dummy -= 1;
3467                                 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 1;
3468                                 if (p_ptr->muta3 & MUT3_SCALES) dummy -= 1;
3469                                 if (p_ptr->muta3 & MUT3_WART_SKIN) dummy -= 2;
3470                                 if (p_ptr->muta3 & MUT3_ILL_NORM) dummy = 0;
3471                         }
3472
3473                         /* Boost */
3474                         if (dummy)
3475                         {
3476                                 /* Default */
3477                                 c = '*';
3478
3479                                 /* Good */
3480                                 if (dummy > 0)
3481                                 {
3482                                         /* Good */
3483                                         a = TERM_L_GREEN;
3484
3485                                         /* Label boost */
3486                                         if (dummy < 10) c = '0' + dummy;
3487                                 }
3488
3489                                 /* Bad */
3490                                 if (dummy < 0)
3491                                 {
3492                                         /* Bad */
3493                                         a = TERM_RED;
3494
3495                                         /* Label boost */
3496                                         if (dummy > -10) c = '0' - dummy;
3497                                 }
3498                         }
3499                 }
3500
3501
3502                 /* Sustain */
3503                 if (f2 & 1<<stat)
3504                 {
3505                         /* Dark green "s" */
3506                         a = TERM_GREEN;
3507                         c = 's';
3508                 }
3509
3510
3511                 /* Dump */
3512                 Term_putch(col, row + stat+1, a, c);
3513         }
3514 }
3515
3516
3517 /*
3518  * Object flag names
3519  */
3520 static cptr object_flag_names[96] =
3521 {
3522 #ifdef JP
3523 "+ÏÓÎÏ",
3524 "+ÃÎǽ",
3525 "+¸­¤µ",
3526 "+´ïÍÑ",
3527 "+Âѵ×",
3528 "+Ì¥ÎÏ",
3529 #else
3530         "Add Str",
3531         "Add Int",
3532         "Add Wis",
3533         "Add Dex",
3534         "Add Con",
3535         "Add Chr",
3536 #endif
3537
3538 #ifdef JP
3539         "ËâÆ»¶ñ",
3540
3541         "ÍýÎÏ",
3542 #else
3543         "M.Item-Mas",
3544
3545         "Force wep.",
3546 #endif
3547
3548 #ifdef JP
3549 "+±£Ì©¹ÔÆ°",
3550 "+õº÷",
3551 "+ÀÖ³°Àþ»ë",
3552 "+·¡ºï",
3553 "+¥¹¥Ô¡¼¥É",
3554 "+ÂÇ·â²ó¿ô",
3555 "¥«¥ª¥¹¸ú²Ì",
3556 "µÛ·ì",
3557 "ưʪ ÇÜÂÇ",
3558 "¼Ù°­ ÇÜÂÇ",
3559 "ÉÔ»à ÇÜÂÇ",
3560 "°­Ëâ ÇÜÂÇ",
3561 "¥ª¡¼¥¯ÇÜÂÇ",
3562 "¥È¥í¥ëÇÜÂÇ",
3563 "µð¿Í ÇÜÂÇ",
3564 "ζ ÇÜÂÇ",
3565 "ζ ÇÜÇÜÂÇ",
3566 "±Ô¿Ï",
3567 "ÃÏ¿ÌȯÀ¸",
3568 "ÆÇ°À­¹¶·â",
3569 "»À°À­¹¶·â",
3570 "ÅÅ°À­¹¶·â",
3571 "²Ð°À­¹¶·â",
3572 "Îä°À­¹¶·â",
3573 #else
3574         "Add Stea.",
3575         "Add Sear.",
3576         "Add Infra",
3577         "Add Tun..",
3578         "Add Speed",
3579         "Add Blows",
3580         "Chaotic",
3581         "Vampiric",
3582         "Slay Anim.",
3583         "Slay Evil",
3584         "Slay Und.",
3585         "Slay Demon",
3586         "Slay Orc",
3587         "Slay Troll",
3588         "Slay Giant",
3589         "Slay Drag.",
3590         "Kill Drag.",
3591         "Sharpness",
3592         "Impact",
3593         "Poison Brd",
3594         "Acid Brand",
3595         "Elec Brand",
3596         "Fire Brand",
3597         "Cold Brand",
3598 #endif
3599
3600
3601 #ifdef JP
3602 "ÏÓÎÏ ÊÝ»ý",
3603 "ÃÎǽ ÊÝ»ý",
3604 "¸­¤µ ÊÝ»ý",
3605 "´ïÍÑ ÊÝ»ý",
3606 "ÂѵנÊÝ»ý",
3607 "Ì¥ÎÏ ÊÝ»ý",
3608 #else
3609         "Sust Str",
3610         "Sust Int",
3611         "Sust Wis",
3612         "Sust Dex",
3613         "Sust Con",
3614         "Sust Chr",
3615 #endif
3616
3617         NULL,
3618         NULL,
3619 #ifdef JP
3620 "ĶÂÑ»À  ",
3621 "ĶÂÑÅÅ·â",
3622 "ĶÂѲбê",
3623 "ĶÂÑÎ䵤",
3624 #else
3625         "Imm Acid",
3626         "Imm Elec",
3627         "Imm Fire",
3628         "Imm Cold",
3629 #endif
3630
3631         NULL,
3632 #ifdef JP
3633 "È¿¼Í",
3634 "ÂÑËãáã",
3635 "·Ð¸³ÃÍÊÝ»ý",
3636 #else
3637         "Reflect",
3638         "Free Act",
3639         "Hold Life",
3640 #endif
3641
3642 #ifdef JP
3643 "ÂÑ»À  ",
3644 "ÂÑÅÅ·â",
3645 "ÂѲбê",
3646 "ÂÑÎ䵤",
3647 "ÂÑÆÇ  ",
3648 "ÂѶ²ÉÝ",
3649 "ÂÑÁ®¸÷",
3650 "ÂѰŹõ",
3651 "ÂÑÌÕÌÜ",
3652 "ÂѺ®Íð",
3653 "Âѹ첻",
3654 "ÂÑÇËÊÒ",
3655 "ÂÑÃϹö",
3656 "ÂÑ°øº®",
3657 "ÂÑ¥«¥ª",
3658 "ÂÑÎô²½",
3659 #else
3660         "Res Acid",
3661         "Res Elec",
3662         "Res Fire",
3663         "Res Cold",
3664         "Res Pois",
3665         "Res Fear",
3666         "Res Lite",
3667         "Res Dark",
3668         "Res Blind",
3669         "Res Conf",
3670         "Res Sound",
3671         "Res Shard",
3672         "Res Neth",
3673         "Res Nexus",
3674         "Res Chaos",
3675         "Res Disen",
3676 #endif
3677
3678
3679
3680
3681 #ifdef JP
3682         "²Ð±ê¥ª¡¼¥é",
3683
3684         "Åŵ¤¥ª¡¼¥é",
3685 #else
3686         "Aura Fire",
3687
3688         "Aura Elec",
3689 #endif
3690
3691         NULL,
3692 #ifdef JP
3693         "Î䵤¥ª¡¼¥é",
3694 #else
3695         "Aura Cold",
3696 #endif
3697 #ifdef JP
3698 "Ëɥƥì¥Ý",
3699 "È¿ËâË¡",
3700 "¸º¾ÃÈñËâÎÏ",
3701 "¼Ù°­¤Ê±åÇ°",
3702 NULL,
3703 "Hide Type",
3704 "Show Mods",
3705 "¾ï»þÅÁÀâʪ",
3706 "ÉâÍ·",
3707 "¸÷¸»",
3708 "Æ©ÌÀ»ëǧ",
3709 "¥Æ¥ì¥Ñ¥·¡¼",
3710 "Ãپò½",
3711 "µÞ²óÉü",
3712 "¶¯Îϼͷâ",
3713 "¹â®¼Í·â",
3714 "̵½ý »À",
3715 "̵½ý ÅÅ",
3716 "̵½ý ²Ð",
3717 "̵½ý Îä",
3718 "»ÏÆ°",
3719 "·Ð¸³µÛ¼ý",
3720 "¥Æ¥ì¥Ý¡¼¥È",
3721 "È¿´¶",
3722 "½ËÊ¡",
3723 "¼ö¤¤",
3724 "½Å¤¤¼ö¤¤",
3725 "±Ê±ó¤Î¼ö¤¤"
3726 #else
3727         "NoTeleport",
3728         "AntiMagic",
3729         "DecMana",
3730         "EvilCurse",
3731         NULL,
3732         "Hide Type",
3733         "Show Mods",
3734         "Insta Art",
3735         "Levitate",
3736         "Lite",
3737         "See Invis",
3738         "Telepathy",
3739         "Digestion",
3740         "Regen",
3741         "Xtra Might",
3742         "Xtra Shots",
3743         "Ign Acid",
3744         "Ign Elec",
3745         "Ign Fire",
3746         "Ign Cold",
3747         "Activate",
3748         "Drain Exp",
3749         "Teleport",
3750         "Aggravate",
3751         "Blessed",
3752         "Cursed",
3753         "Hvy Curse",
3754         "Prm Curse"
3755 #endif
3756
3757 };
3758
3759
3760 /*
3761  * Summarize resistances
3762  */
3763 static void display_player_ben(void)
3764 {
3765         int i, x, y;
3766
3767         object_type *o_ptr;
3768
3769         u32b f1, f2, f3;
3770
3771         u16b b[6];
3772         u16b color[6];
3773
3774
3775         /* Reset */
3776         for (i = 0; i < 6; i++) b[i] = 0;
3777
3778
3779         /* Scan equipment */
3780         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3781         {
3782                 /* Object */
3783                 o_ptr = &inventory[i];
3784
3785                 /* Known object flags */
3786                 object_flags_known(o_ptr, &f1, &f2, &f3);
3787
3788
3789                 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3790                 {
3791                         f3 &= ~(TR3_AGGRAVATE);
3792                         f1 |= TR1_STEALTH;
3793                 }
3794
3795                 /* Incorporate */
3796                 b[0] |= (f1 & 0xFFFF);
3797                 b[1] |= (f1 >> 16);
3798                 b[2] |= (f2 & 0xFFFF);
3799                 b[3] |= (f2 >> 16);
3800                 b[4] |= (f3 & 0xFFFF);
3801                 b[5] |= (f3 >> 16);
3802         }
3803
3804
3805         /* Player flags */
3806         player_flags(&f1, &f2, &f3);
3807
3808         /* Incorporate */
3809         b[0] |= (f1 & 0xFFFF);
3810         b[1] |= (f1 >> 16);
3811         b[2] |= (f2 & 0xFFFF);
3812         b[3] |= (f2 >> 16);
3813         b[4] |= (f3 & 0xFFFF);
3814         b[5] |= (f3 >> 16);
3815
3816         /* Player flags */
3817         tim_player_flags(&f1, &f2, &f3, FALSE);
3818
3819         /* Incorporate */
3820         b[0] |= (f1 & 0xFFFF);
3821         b[1] |= (f1 >> 16);
3822         b[2] |= (f2 & 0xFFFF);
3823         b[3] |= (f2 >> 16);
3824         b[4] |= (f3 & 0xFFFF);
3825         b[5] |= (f3 >> 16);
3826         color[0] = (u16b)(f1 & 0xFFFF);
3827         color[1] = (u16b)(f1 >> 16);
3828         color[2] = (u16b)(f2 & 0xFFFF);
3829         color[3] = (u16b)(f2 >> 16);
3830         color[4] = (u16b)(f3 & 0xFFFF);
3831         color[5] = (u16b)(f3 >> 16);
3832
3833         /* Scan cols */
3834         for (x = 0; x < 6; x++)
3835         {
3836                 /* Scan rows */
3837                 for (y = 0; y < 16; y++)
3838                 {
3839                         byte a = TERM_SLATE;
3840                         char c = '.';
3841
3842                         cptr name = object_flag_names[16*x+y];
3843
3844                         /* No name */
3845                         if (!name) continue;
3846
3847                         /* Dump name */
3848                         Term_putstr(x * 13, y + 4, -1, TERM_WHITE, name);
3849
3850                         /* Dump colon */
3851                         Term_putch(x * 13 + 10, y + 4, TERM_WHITE, ':');
3852
3853                         /* Check flag */
3854                         if (b[x] & (1<<y))
3855                         {
3856                                 if (color[x] & (1<<y))
3857                                 {
3858                                         a = TERM_YELLOW;
3859                                         c = '#';
3860                                 }
3861                                 else
3862                                 {
3863                                         a = TERM_WHITE;
3864                                         c = '+';
3865                                 }
3866                         }
3867
3868                         /* Dump flag */
3869                         Term_putch(x * 13 + 11, y + 4, a, c);
3870                 }
3871         }
3872 }
3873
3874
3875 /*
3876  * Summarize resistances
3877  */
3878 static void display_player_ben_one(int mode)
3879 {
3880         int i, n, x, y;
3881
3882         object_type *o_ptr;
3883
3884         u32b f1, f2, f3;
3885
3886         u16b b[13][6];
3887         u16b color[6];
3888
3889
3890         /* Scan equipment */
3891         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3892         {
3893                 /* Index */
3894                 n = (i - INVEN_RARM);
3895
3896                 /* Object */
3897                 o_ptr = &inventory[i];
3898
3899                 object_flags_known(o_ptr, &f1, &f2, &f3);
3900
3901                 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3902                 {
3903                         f3 &= ~(TR3_AGGRAVATE);
3904                         f1 |= TR1_STEALTH;
3905                 }
3906
3907                 /* Incorporate */
3908                 b[n][0] = (u16b)(f1 & 0xFFFF);
3909                 b[n][1] = (u16b)(f1 >> 16);
3910                 b[n][2] = (u16b)(f2 & 0xFFFF);
3911                 b[n][3] = (u16b)(f2 >> 16);
3912                 b[n][4] = (u16b)(f3 & 0xFFFF);
3913                 b[n][5] = (u16b)(f3 >> 16);
3914         }
3915
3916
3917         /* Index */
3918         n = 12;
3919
3920         /* Player flags */
3921         player_flags(&f1, &f2, &f3);
3922
3923         /* Incorporate */
3924         b[n][0] = (u16b)(f1 & 0xFFFF);
3925         b[n][1] = (u16b)(f1 >> 16);
3926         b[n][2] = (u16b)(f2 & 0xFFFF);
3927         b[n][3] = (u16b)(f2 >> 16);
3928         b[n][4] = (u16b)(f3 & 0xFFFF);
3929         b[n][5] = (u16b)(f3 >> 16);
3930
3931         /* Player flags */
3932         tim_player_flags(&f1, &f2, &f3, FALSE);
3933
3934         /* Incorporate */
3935         b[n][0] |= (f1 & 0xFFFF);
3936         b[n][1] |= (f1 >> 16);
3937         b[n][2] |= (f2 & 0xFFFF);
3938         b[n][3] |= (f2 >> 16);
3939         b[n][4] |= (f3 & 0xFFFF);
3940         b[n][5] |= (f3 >> 16);
3941         color[0] = (u16b)(f1 & 0xFFFF);
3942         color[1] = (u16b)(f1 >> 16);
3943         color[2] = (u16b)(f2 & 0xFFFF);
3944         color[3] = (u16b)(f2 >> 16);
3945         color[4] = (u16b)(f3 & 0xFFFF);
3946         color[5] = (u16b)(f3 >> 16);
3947
3948
3949         /* Scan cols */
3950         for (x = 0; x < 3; x++)
3951         {
3952                 /* Equippy */
3953                 display_player_equippy(2, x * 26 + 11);
3954
3955                 /* Label */
3956                 Term_putstr(x * 26 + 11, 3, -1, TERM_WHITE, "abcdefghijkl@");
3957
3958                 /* Scan rows */
3959                 for (y = 0; y < 16; y++)
3960                 {
3961                         cptr name = object_flag_names[48*mode+16*x+y];
3962
3963                         /* No name */
3964                         if (!name) continue;
3965
3966                         /* Dump name */
3967                         Term_putstr(x * 26, y + 4, -1, TERM_WHITE, name);
3968
3969                         /* Dump colon */
3970                         Term_putch(x * 26 + 10, y + 4, TERM_WHITE, ':');
3971
3972                         /* Check flags */
3973                         for (n = 0; n < 13; n++)
3974                         {
3975                                 byte a = TERM_SLATE;
3976                                 char c = '.';
3977
3978                                 /* Check flag */
3979                                 if (b[n][3*mode+x] & (1<<y))
3980                                 {
3981                                         if ((n == 12) && (color[3*mode+x] & (1<<y)))
3982                                         {
3983                                                 a = TERM_YELLOW;
3984                                                 c = '#';
3985                                         }
3986                                         else
3987                                         {
3988                                                 a = TERM_WHITE;
3989                                                 c = '+';
3990                                         }
3991                                 }
3992
3993                                 /* Dump flag */
3994                                 Term_putch(x * 26 + 11 + n, y + 4, a, c);
3995                         }
3996                 }
3997         }
3998 }
3999
4000
4001 /*
4002  * Display the character on the screen (various modes)
4003  *
4004  * The top two and bottom two lines are left blank.
4005  *
4006  * Mode 0 = standard display with skills
4007  * Mode 1 = standard display with history
4008  * Mode 2 = summary of various things
4009  * Mode 3 = current flags (combined)
4010  * Mode 4 = current flags (part 1)
4011  * Mode 5 = current flags (part 2)
4012  * Mode 6 = mutations
4013  */
4014 void display_player(int mode)
4015 {
4016         int i;
4017
4018         char    buf[80];
4019         char    tmp[64];
4020
4021
4022         /* XXX XXX XXX */
4023         if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && skip_mutations)
4024                 mode = (mode % 7);
4025         else
4026                 mode = (mode % 6);
4027
4028         /* Erase screen */
4029         clear_from(0);
4030
4031         /* Standard */
4032         if ((mode == 0) || (mode == 1))
4033         {
4034                 /* Name, Sex, Race, Class */
4035 #ifdef JP
4036                 sprintf(tmp, "%s%s%s", ap_ptr->title, ap_ptr->no == 1 ? "¤Î":"", player_name);
4037 #else
4038                 sprintf(tmp, "%s %s", ap_ptr->title, player_name);
4039 #endif
4040
4041                 display_player_one_line(ENTRY_NAME, tmp, TERM_L_BLUE);
4042                 display_player_one_line(ENTRY_SEX, sp_ptr->title, TERM_L_BLUE);
4043                 display_player_one_line(ENTRY_RACE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), TERM_L_BLUE);
4044                 display_player_one_line(ENTRY_CLASS, cp_ptr->title, TERM_L_BLUE);
4045
4046                 if (p_ptr->realm1)
4047                 {
4048                         if (p_ptr->realm2)
4049                                 sprintf(tmp, "%s, %s", realm_names[p_ptr->realm1], realm_names[p_ptr->realm2]);
4050                         else
4051                                 strcpy(tmp, realm_names[p_ptr->realm1]);
4052                         display_player_one_line(ENTRY_REALM, tmp, TERM_L_BLUE);
4053                 }
4054
4055                 if (p_ptr->pclass == CLASS_CHAOS_WARRIOR)
4056                         display_player_one_line(ENTRY_PATRON, chaos_patrons[p_ptr->chaos_patron], TERM_L_BLUE);
4057
4058                 /* Age, Height, Weight, Social */
4059                 /* ¿ÈĹ¤Ï¥»¥ó¥Á¥á¡¼¥È¥ë¤Ë¡¢ÂνŤϥ­¥í¥°¥é¥à¤ËÊѹ¹¤·¤Æ¤¢¤ê¤Þ¤¹ */
4060 #ifdef JP
4061                 display_player_one_line(ENTRY_AGE, format("%dºÍ" ,(int)p_ptr->age), TERM_L_BLUE);
4062                 display_player_one_line(ENTRY_HEIGHT, format("%dcm" ,(int)((p_ptr->ht*254)/100)), TERM_L_BLUE);
4063                 display_player_one_line(ENTRY_WEIGHT, format("%dkg" ,(int)((p_ptr->wt*4536)/10000)), TERM_L_BLUE);
4064                 display_player_one_line(ENTRY_SOCIAL, format("%d  " ,(int)p_ptr->sc), TERM_L_BLUE);
4065 #else
4066                 display_player_one_line(ENTRY_AGE, format("%d" ,(int)p_ptr->age), TERM_L_BLUE);
4067                 display_player_one_line(ENTRY_HEIGHT, format("%d" ,(int)p_ptr->ht), TERM_L_BLUE);
4068                 display_player_one_line(ENTRY_WEIGHT, format("%d" ,(int)p_ptr->wt), TERM_L_BLUE);
4069                 display_player_one_line(ENTRY_SOCIAL, format("%d" ,(int)p_ptr->sc), TERM_L_BLUE);
4070 #endif
4071                 display_player_one_line(ENTRY_ALIGN, format("%s" ,your_alignment()), TERM_L_BLUE);
4072
4073
4074                 /* Display the stats */
4075                 for (i = 0; i < 6; i++)
4076                 {
4077                         /* Special treatment of "injured" stats */
4078                         if (p_ptr->stat_cur[i] < p_ptr->stat_max[i])
4079                         {
4080                                 int value;
4081
4082                                 /* Use lowercase stat name */
4083                                 put_str(stat_names_reduced[i], 3 + i, 54);
4084
4085                                 /* Get the current stat */
4086                                 value = p_ptr->stat_use[i];
4087
4088                                 /* Obtain the current stat (modified) */
4089                                 cnv_stat(value, buf);
4090
4091                                 /* Display the current stat (modified) */
4092                                 c_put_str(TERM_YELLOW, buf, 3 + i, 61);
4093
4094                                 /* Acquire the max stat */
4095                                 value = p_ptr->stat_top[i];
4096
4097                                 /* Obtain the maximum stat (modified) */
4098                                 cnv_stat(value, buf);
4099
4100                                 /* Display the maximum stat (modified) */
4101                                 c_put_str(TERM_L_GREEN, buf, 3 + i, 68);
4102                         }
4103
4104                         /* Normal treatment of "normal" stats */
4105                         else
4106                         {
4107                                 /* Assume uppercase stat name */
4108                                 put_str(stat_names[i], 3 + i, 54);
4109
4110                                 /* Obtain the current stat (modified) */
4111                                 cnv_stat(p_ptr->stat_use[i], buf);
4112
4113                                 /* Display the current stat (modified) */
4114                                 c_put_str(TERM_L_GREEN, buf, 3 + i, 61);
4115                         }
4116
4117                         if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
4118                         {
4119 #ifdef JP
4120                                 c_put_str(TERM_WHITE, "!", 3+i, 59);
4121 #else
4122                                 c_put_str(TERM_WHITE, "!", 3+i, 59-2);
4123 #endif
4124                         }
4125                 }
4126
4127                 /* Display "history" info */
4128                 if (mode == 1)
4129                 {
4130 #ifdef JP
4131                         put_str("(¥­¥ã¥é¥¯¥¿¡¼¤ÎÀ¸¤¤Î©¤Á)", 11, 25);
4132 #else
4133                         put_str("(Character Background)", 11, 25);
4134 #endif
4135
4136                         for (i = 0; i < 4; i++)
4137                         {
4138                                 put_str(history[i], i + 12, 10);
4139                         }
4140
4141
4142                         if (death && total_winner)
4143                         {
4144 #ifdef JP
4145                                 put_str("¡Ä¤¢¤Ê¤¿¤Ï¾¡Íø¤Î¸å°úÂष¤¿¡£", 5 + 12, 10);
4146 #else
4147                                 put_str("...You retired from the adventure after the winning.", 5 + 12, 10);
4148 #endif
4149                         }
4150                         else if (death)
4151                         {
4152                                 if (dun_level)
4153                                 {
4154                                         if (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST))
4155                                         {
4156 #ifdef JP
4157                                                 put_str(format("¡Ä¤¢¤Ê¤¿¤Ï ¥¯¥¨¥¹¥È¡Ö%s¡×¤Ç»à¤ó¤À¡£", quest[p_ptr->inside_quest].name), 5 + 12, 10);
4158 #else
4159                                                 put_str(format("...You died in the quest '%s'.", quest[p_ptr->inside_quest].name), 5 + 12, 10);
4160 #endif
4161                                         }
4162                                         else
4163                                         {                                       
4164 #ifdef JP
4165                                                 put_str(format("¡Ä¤¢¤Ê¤¿¤Ï %s ¤Î %d ³¬¤Ç»à¤ó¤À¡£", map_name(), dun_level), 5 + 12, 10);
4166 #else
4167                                                 put_str(format("...You died on level %d of %s.", dun_level, map_name()), 5 + 12, 10);
4168 #endif
4169                                         }
4170                                 }
4171                                 else
4172 #ifdef JP
4173                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï %s ¤Ç»à¤ó¤À¡£", map_name()), 5 + 12, 10);
4174 #else
4175                                         put_str(format("...You died in %s.", map_name()), 5 + 12, 10);
4176 #endif
4177                         }
4178                         else if (character_dungeon)
4179                         {
4180                                 if (dun_level)
4181                                 {
4182                                         if (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST))
4183                                         {
4184 #ifdef JP
4185                                                 put_str(format("¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ ¥¯¥¨¥¹¥È¡Ö%s¡×¤ò¿ë¹ÔÃæ¤À¡£", quest[p_ptr->inside_quest].name), 5 + 12, 10);
4186 #else
4187                                                 put_str(format("...Now, you are in the quest '%s'.", quest[p_ptr->inside_quest].name), 5 + 12, 10);
4188 #endif
4189                                         }                                                       
4190                                         else
4191                                         {
4192 #ifdef JP
4193                                                 put_str(format("¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Î %d ³¬¤Çõº÷¤·¤Æ¤¤¤ë¡£", map_name(), dun_level), 5 + 12, 10);
4194 #else
4195                                                 put_str(format("...Now, you are exploring level %d of %s.", dun_level, map_name()), 5 + 12, 10);
4196 #endif
4197                                         }
4198                                 }
4199                                 else
4200 #ifdef JP
4201                                         put_str(format("¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Ë¤¤¤ë¡£", map_name()), 5 + 12, 10);
4202 #else
4203                                         put_str(format("...Now, you are in %s.", map_name()), 5 + 12, 10);
4204 #endif
4205                         }
4206                 }
4207
4208                 /* Display "various" info */
4209                 else
4210                 {
4211                         display_player_middle();
4212                         display_player_various();
4213                 }
4214         }
4215
4216         /* Special */
4217         else if (mode == 2)
4218         {
4219                 /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */
4220
4221                 /* Dump the info */
4222                 display_player_misc_info();
4223                 display_player_stat_info();
4224                 display_player_flag_info();
4225         }
4226
4227         /* Special */
4228         else if (mode == 3)
4229         {
4230                 display_player_ben();
4231         }
4232
4233         else if (mode == 6)
4234         {
4235                 do_cmd_knowledge_mutations();
4236         }
4237
4238         /* Special */
4239         else
4240         {
4241                 display_player_ben_one(mode % 2);
4242         }
4243 }
4244
4245 errr make_character_dump(FILE *fff)
4246 {
4247         int             i, x, y;
4248         byte            a;
4249         char            c;
4250         cptr            paren = ")";
4251         store_type  *st_ptr;
4252         char            o_name[MAX_NLEN];
4253         char            buf[1024];
4254
4255
4256 #ifndef FAKE_VERSION
4257         /* Begin dump */
4258         fprintf(fff, "  [Angband %d.%d.%d Character Dump]\n\n",
4259                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
4260 #else
4261 #ifdef JP
4262         fprintf(fff, "  [ÊѶòÈÚÅÜ %d.%d.%d ¥­¥ã¥é¥¯¥¿¾ðÊó]\n\n",
4263                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4264 #else
4265         fprintf(fff, "  [Hengband %d.%d.%d Character Dump]\n\n",
4266                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4267 #endif
4268
4269 #endif
4270
4271         update_playtime();
4272
4273         /* Display player */
4274         display_player(0);
4275
4276         /* Dump part of the screen */
4277         for (y = 1; y < 22; y++)
4278         {
4279                 /* Dump each row */
4280                 for (x = 0; x < 79; x++)
4281                 {
4282                         /* Get the attr/char */
4283                         (void)(Term_what(x, y, &a, &c));
4284
4285                         /* Dump it */
4286                         buf[x] = c;
4287                 }
4288
4289                 /* End the string */
4290                 buf[x] = '\0';
4291
4292                 /* Kill trailing spaces */
4293                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4294
4295                 /* End the row */
4296 #ifdef JP
4297                         fprintf(fff, "%s\n", buf);
4298 #else
4299                 fprintf(fff, "%s\n", buf);
4300 #endif
4301
4302         }
4303
4304         /* Display history */
4305         display_player(1);
4306
4307         /* Dump part of the screen */
4308         for (y = 10; y < 18; y++)
4309         {
4310                 /* Dump each row */
4311                 for (x = 0; x < 79; x++)
4312                 {
4313                         /* Get the attr/char */
4314                         (void)(Term_what(x, y, &a, &c));
4315
4316                         /* Dump it */
4317                         buf[x] = c;
4318                 }
4319
4320                 /* End the string */
4321                 buf[x] = '\0';
4322
4323                 /* Kill trailing spaces */
4324                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4325
4326                 /* End the row */
4327                 fprintf(fff, "%s\n", buf);
4328         }
4329
4330         fprintf(fff, "\n");
4331         /* Display history */
4332         display_player(2);
4333
4334         /* Dump part of the screen */
4335         for (y = 2; y < 22; y++)
4336         {
4337                 /* Dump each row */
4338                 for (x = 0; x < 79; x++)
4339                 {
4340                         /* Get the attr/char */
4341                         (void)(Term_what(x, y, &a, &c));
4342
4343                         /* Dump it (Ignore equippy tile graphic) */
4344                         if (a < 128)
4345                                 buf[x] = c;
4346                         else
4347                                 buf[x] = ' ';
4348                 }
4349
4350                 /* End the string */
4351                 buf[x] = '\0';
4352
4353                 /* Kill trailing spaces */
4354                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4355
4356                 /* End the row */
4357                 fprintf(fff, "%s\n", buf);
4358         }
4359
4360         for (i = 0; i < p_ptr->count / 80; i++)
4361                 fprintf(fff, " ");
4362         fprintf(fff, "\n");
4363         for (i = 0; i < p_ptr->count % 80; i++)
4364                 fprintf(fff, " ");
4365
4366         {
4367                 bool pet = FALSE;
4368
4369                 for (i = m_max - 1; i >= 1; i--)
4370                 {
4371                         monster_type *m_ptr = &m_list[i];
4372                         char pet_name[80];
4373
4374                         if (!m_ptr->r_idx) continue;
4375                         if (!is_pet(m_ptr)) continue;
4376                         if (!m_ptr->nickname && (p_ptr->riding != i)) continue;
4377                         if (!pet)
4378                         {
4379 #ifdef JP
4380                                 fprintf(fff, "\n  [¼ç¤Ê¥Ú¥Ã¥È]\n\n");
4381 #else
4382                                 fprintf(fff, "\n  [leading pets]\n\n");
4383 #endif
4384                                 pet = TRUE;
4385                         }
4386                         monster_desc(pet_name, m_ptr, 0x88);
4387                         fprintf(fff, "%s", pet_name);
4388                         if (p_ptr->riding == i)
4389 #ifdef JP
4390                                 fprintf(fff, " ¾èÇÏÃæ");
4391 #else
4392                                 fprintf(fff, " (riding)");
4393 #endif
4394                         fprintf(fff, "\n");
4395                 }
4396                 if (pet) fprintf(fff, "\n");
4397         }
4398
4399         if (death && !total_winner)
4400         {
4401 #ifdef JP
4402                 fprintf(fff, "\n  [»à¤ÌľÁ°¤Î¥á¥Ã¥»¡¼¥¸]\n\n");
4403 #else
4404                 fprintf(fff, "\n  [Last messages]\n\n");
4405 #endif
4406                 for (i = MIN(message_num(), 30); i >= 0; i--)
4407                 {
4408                         fprintf(fff,"> %s\n",message_str((s16b)i));
4409                 }
4410                 fprintf(fff, "\n");
4411         }
4412
4413 #ifdef JP
4414         fprintf(fff, "\n  [¤½¤Î¾¤Î¾ðÊó]        \n");
4415 #else
4416         fprintf(fff, "\n  [Miscellaneous information]\n");
4417 #endif
4418
4419 #ifdef JP
4420         fprintf(fff, "\n µ¢´Ô¾ì½ê:\n");
4421 #else
4422         fprintf(fff, "\n Recall Depth:\n");
4423 #endif
4424         for (y = 1; y < max_d_idx; y++)
4425         {
4426                 bool seiha = FALSE;
4427
4428                 if (!d_info[y].maxdepth) continue;
4429                 if (!max_dlv[y]) continue;
4430                 if (d_info[y].final_guardian)
4431                 {
4432                         if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
4433                 }
4434                 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
4435
4436 #ifdef JP
4437                 fprintf(fff, "   %c%-12s: %3d ³¬\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4438 #else
4439                 fprintf(fff, "   %c%-16s: level %3d\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4440 #endif
4441         }
4442
4443         if (preserve_mode)
4444 #ifdef JP
4445                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         ON");
4446 #else
4447                 fprintf(fff, "\n Preserve Mode:      ON");
4448 #endif
4449
4450         else
4451 #ifdef JP
4452                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         OFF");
4453 #else
4454                 fprintf(fff, "\n Preserve Mode:      OFF");
4455 #endif
4456
4457
4458         if (ironman_autoscum)
4459 #ifdef JP
4460                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ALWAYS");
4461 #else
4462                 fprintf(fff, "\n Autoscum:           ALWAYS");
4463 #endif
4464
4465         else if (auto_scum)
4466 #ifdef JP
4467                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ON");
4468 #else
4469                 fprintf(fff, "\n Autoscum:           ON");
4470 #endif
4471
4472         else
4473 #ifdef JP
4474                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     OFF");
4475 #else
4476                 fprintf(fff, "\n Autoscum:           OFF");
4477 #endif
4478
4479
4480         if (ironman_small_levels)
4481 #ifdef JP
4482                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ALWAYS");
4483 #else
4484                 fprintf(fff, "\n Small Levels:       ALWAYS");
4485 #endif
4486
4487         else if (always_small_levels)
4488 #ifdef JP
4489                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ON");
4490 #else
4491                 fprintf(fff, "\n Small Levels:       ON");
4492 #endif
4493
4494         else if (small_levels)
4495 #ifdef JP
4496                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ENABLED");
4497 #else
4498                 fprintf(fff, "\n Small Levels:       ENABLED");
4499 #endif
4500
4501         else
4502 #ifdef JP
4503                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   OFF");
4504 #else
4505                 fprintf(fff, "\n Small Levels:       OFF");
4506 #endif
4507
4508
4509         if (vanilla_town)
4510 #ifdef JP
4511                 fprintf(fff, "\n ¸µÁĤÎÄ®¤Î¤ß: ON");
4512 #else
4513                 fprintf(fff, "\n Vanilla Town:       ON");
4514 #endif
4515
4516         else if (lite_town)
4517 #ifdef JP
4518                 fprintf(fff, "\n ¾®µ¬ÌϤÊÄ®:         ON");
4519 #else
4520                 fprintf(fff, "\n Lite Town:          ON");
4521 #endif
4522
4523
4524         if (ironman_shops)
4525 #ifdef JP
4526                 fprintf(fff, "\n Å¹¤Ê¤·:             ON");
4527 #else
4528                 fprintf(fff, "\n No Shops:           ON");
4529 #endif
4530
4531
4532         if (ironman_downward)
4533 #ifdef JP
4534                 fprintf(fff, "\n ³¬Ãʤò¾å¤¬¤ì¤Ê¤¤:   ON");
4535 #else
4536                 fprintf(fff, "\n Diving only:        ON");
4537 #endif
4538
4539
4540         if (ironman_rooms)
4541 #ifdef JP
4542                 fprintf(fff, "\n ÉáÄ̤Ǥʤ¤Éô²°¤òÀ¸À®:         ON");
4543 #else
4544                 fprintf(fff, "\n Unusual rooms:      ON");
4545 #endif
4546
4547
4548         if (ironman_nightmare)
4549 #ifdef JP
4550                 fprintf(fff, "\n °­Ì´¥â¡¼¥É:         ON");
4551 #else
4552                 fprintf(fff, "\n Nightmare Mode:     ON");
4553 #endif
4554
4555
4556         if (ironman_empty_levels)
4557 #ifdef JP
4558                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ALWAYS");
4559 #else
4560                 fprintf(fff, "\n Arena Levels:       ALWAYS");
4561 #endif
4562
4563         else if (empty_levels)
4564 #ifdef JP
4565                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ON");
4566 #else
4567                 fprintf(fff, "\n Arena Levels:       ENABLED");
4568 #endif
4569
4570         else
4571 #ifdef JP
4572                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           OFF");
4573 #else
4574                 fprintf(fff, "\n Arena Levels:       OFF");
4575 #endif
4576
4577
4578 #ifdef JP
4579         fprintf(fff, "\n ¥é¥ó¥À¥à¥¯¥¨¥¹¥È¿ô: %d", number_of_quests());
4580 #else
4581         fprintf(fff, "\n Num. Random Quests: %d", number_of_quests());
4582 #endif
4583
4584         if (p_ptr->arena_number == 99)
4585         {
4586 #ifdef JP
4587                 fprintf(fff, "\n Æ®µ»¾ì: ÇÔËÌ\n");
4588 #else
4589                 fprintf(fff, "\n Arena: defeated\n");
4590 #endif
4591         }
4592         else if (p_ptr->arena_number > MAX_ARENA_MONS+2)
4593         {
4594 #ifdef JP
4595                 fprintf(fff, "\n Æ®µ»¾ì: ¿¿¤Î¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4596 #else
4597                 fprintf(fff, "\n Arena: True Champion\n");
4598 #endif
4599         }
4600         else if (p_ptr->arena_number > MAX_ARENA_MONS-1)
4601         {
4602 #ifdef JP
4603                 fprintf(fff, "\n Æ®µ»¾ì: ¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4604 #else
4605                 fprintf(fff, "\n Arena: Champion\n");
4606 #endif
4607         }
4608         else
4609         {
4610 #ifdef JP
4611                 fprintf(fff, "\n Æ®µ»¾ì:   %2d¾¡\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number));
4612 #else
4613                 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");
4614 #endif
4615         }
4616
4617         if (noscore)
4618 #ifdef JP
4619 fprintf(fff, "\n ²¿¤«ÉÔÀµ¤Ê¤³¤È¤ò¤·¤Æ¤·¤Þ¤Ã¤Æ¤Þ¤¹¡£");
4620 #else
4621                 fprintf(fff, "\n You have done something illegal.");
4622 #endif
4623
4624
4625         if (stupid_monsters)
4626 #ifdef JP
4627 fprintf(fff, "\n Å¨¤Ï¶ò¤«¤Ê¹ÔÆ°¤ò¼è¤ê¤Þ¤¹¡£");
4628 #else
4629                 fprintf(fff, "\n Your opponents are behaving stupidly.");
4630 #endif
4631
4632
4633         if (munchkin_death)
4634 #ifdef JP
4635 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï»à¤ò²óÈò¤¹¤ë¥¤¥ó¥Á¥­¤ÊÎϤò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£");
4636 #else
4637                 fprintf(fff, "\n You possess munchkinish power over death.");
4638 #endif
4639
4640         fprintf(fff,"\n");
4641
4642         /* Monsters slain */
4643         {
4644                 int k;
4645                 s32b Total = 0;
4646
4647                 for (k = 1; k < max_r_idx; k++)
4648                 {
4649                         monster_race *r_ptr = &r_info[k];
4650
4651                         if (r_ptr->flags1 & RF1_UNIQUE)
4652                         {
4653                                 bool dead = (r_ptr->max_num == 0);
4654                                 if (dead)
4655                                 {
4656                                         Total++;
4657                                 }
4658                         }
4659                         else
4660                         {
4661                                 s16b This = r_ptr->r_pkills;
4662                                 if (This > 0)
4663                                 {
4664                                         Total += This;
4665                                 }
4666                         }
4667                 }
4668
4669                 if (Total < 1)
4670 #ifdef JP
4671 fprintf(fff,"\n ¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Þ¤»¤ó¡£\n");
4672 #else
4673                         fprintf(fff,"\n You have defeated no enemies yet.\n");
4674 #endif
4675
4676                 else if (Total == 1)
4677 #ifdef JP
4678 fprintf(fff,"\n °ìÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n");
4679 #else
4680                         fprintf(fff,"\n You have defeated one enemy.\n");
4681 #endif
4682
4683                 else
4684 #ifdef JP
4685 fprintf(fff,"\n %lu ÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n", Total);
4686 #else
4687                         fprintf(fff,"\n You have defeated %lu enemies.\n", Total);
4688 #endif
4689
4690         }
4691
4692
4693         if (p_ptr->old_race1 || p_ptr->old_race2)
4694         {
4695 #ifdef JP
4696                 fprintf(fff, "\n\n ¤¢¤Ê¤¿¤Ï%s¤È¤·¤ÆÀ¸¤Þ¤ì¤¿¡£", race_info[p_ptr->start_race].title);
4697 #else
4698                 fprintf(fff, "\n\n You were born as %s.", race_info[p_ptr->start_race].title);
4699 #endif
4700                 for (i = 0; i < MAX_RACES; i++)
4701                 {
4702                         if (p_ptr->start_race == i) continue;
4703                         if (i < 32)
4704                         {
4705                                 if (!(p_ptr->old_race1 & 1L << i)) continue;
4706                         }
4707                         else
4708                         {
4709                                 if (!(p_ptr->old_race2 & 1L << (i-32))) continue;
4710                         }
4711 #ifdef JP
4712                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%s¤À¤Ã¤¿¡£", race_info[i].title);
4713 #else
4714                         fprintf(fff, "\n You were a %s before.", race_info[i].title);
4715 #endif
4716                 }
4717         }
4718
4719         if (p_ptr->old_realm)
4720         {
4721                 for (i = 0; i < MAX_MAGIC; i++)
4722                 {
4723                         if (!(p_ptr->old_realm & 1L << i)) continue;
4724 #ifdef JP
4725                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%sËâË¡¤ò»È¤¨¤¿¡£", realm_names[i+1]);
4726 #else
4727                         fprintf(fff, "\n You were able to use %s magic before.", realm_names[i+1]);
4728 #endif
4729                 }
4730         }
4731
4732 #ifdef JP
4733 fprintf(fff, "\n\n  [¥×¥ì¥¤¥ä¡¼¤ÎÆÁ]\n\n");
4734 #else
4735         fprintf(fff, "\n\n  [Virtues]\n\n");
4736 #endif
4737
4738 #ifdef JP
4739         fprintf(fff, "°À­ : %s\n", your_alignment());
4740 #else
4741         fprintf(fff, "Your alighnment : %s\n", your_alignment());
4742 #endif
4743         fprintf(fff, "\n");
4744         dump_virtues(fff);
4745
4746         if (p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3)
4747         {
4748 #ifdef JP
4749 fprintf(fff, "\n\n  [ÆÍÁ³ÊÑ°Û]\n\n");
4750 #else
4751                 fprintf(fff, "\n\n  [Mutations]\n\n");
4752 #endif
4753
4754                 dump_mutations(fff);
4755         }
4756
4757
4758         /* Skip some lines */
4759         fprintf(fff, "\n\n");
4760
4761
4762         /* Dump the equipment */
4763         if (equip_cnt)
4764         {
4765 #ifdef JP
4766 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤ÎÁõÈ÷ ]\n\n");
4767 #else
4768                 fprintf(fff, "  [Character Equipment]\n\n");
4769 #endif
4770
4771                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4772                 {
4773                         object_desc(o_name, &inventory[i], TRUE, 3);
4774                         if ((i == INVEN_LARM) && p_ptr->ryoute)
4775 #ifdef JP
4776                                 strcpy(o_name, "(Éð´ï¤òξ¼ê»ý¤Á)");
4777 #else
4778                                 strcpy(o_name, "(wielding with two-hands)");
4779 #endif
4780                         fprintf(fff, "%c%s %s\n",
4781                                 index_to_label(i), paren, o_name);
4782                 }
4783                 fprintf(fff, "\n\n");
4784         }
4785
4786         /* Dump the inventory */
4787 #ifdef JP
4788 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤Î»ý¤Áʪ ]\n\n");
4789 #else
4790         fprintf(fff, "  [Character Inventory]\n\n");
4791 #endif
4792
4793         for (i = 0; i < INVEN_PACK; i++)
4794         {
4795                 /* Don't dump the empty slots */
4796                 if (!inventory[i].k_idx) break;
4797
4798                 /* Dump the inventory slots */
4799                 object_desc(o_name, &inventory[i], TRUE, 3);
4800                 fprintf(fff, "%c%s %s\n", index_to_label(i), paren, o_name);
4801         }
4802
4803         /* Add an empty line */
4804         fprintf(fff, "\n\n");
4805
4806         process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
4807
4808         /* Print all homes in the different towns */
4809         st_ptr = &town[1].store[STORE_HOME];
4810
4811         /* Home -- if anything there */
4812         if (st_ptr->stock_num)
4813         {
4814                 /* Header with name of the town */
4815 #ifdef JP
4816                 fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
4817 #else
4818                 fprintf(fff, "  [Home Inventory]\n");
4819 #endif
4820                 x=1;
4821
4822                 /* Dump all available items */
4823                 for (i = 0; i < st_ptr->stock_num; i++)
4824                 {
4825                         if ((i % 12) == 0)
4826 #ifdef JP
4827                                 fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4828 #else
4829                                 fprintf(fff, "\n ( page %d )\n", x++);
4830 #endif
4831                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4832                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4833                 }
4834
4835                 /* Add an empty line */
4836                 fprintf(fff, "\n\n");
4837         }
4838
4839
4840         /* Print all homes in the different towns */
4841         st_ptr = &town[1].store[STORE_MUSEUM];
4842
4843         /* Home -- if anything there */
4844         if (st_ptr->stock_num)
4845         {
4846                 /* Header with name of the town */
4847 #ifdef JP
4848                 fprintf(fff, "  [ Çîʪ´Û¤Î¥¢¥¤¥Æ¥à ]\n");
4849 #else
4850                 fprintf(fff, "  [Museum]\n");
4851 #endif
4852                 x=1;
4853
4854                 /* Dump all available items */
4855                 for (i = 0; i < st_ptr->stock_num; i++)
4856                 {
4857 #ifdef JP
4858                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4859                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4860                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4861 #else
4862                 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
4863                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4864                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4865 #endif
4866
4867                 }
4868
4869                 /* Add an empty line */
4870                 fprintf(fff, "\n\n");
4871         }
4872
4873         return 0;
4874 }
4875
4876 /*
4877  * Hack -- Dump a character description file
4878  *
4879  * XXX XXX XXX Allow the "full" flag to dump additional info,
4880  * and trigger its usage from various places in the code.
4881  */
4882 errr file_character(cptr name, bool full)
4883 {
4884         int             fd = -1;
4885         FILE            *fff = NULL;
4886         char            buf[1024];
4887
4888         /* Drop priv's */
4889         safe_setuid_drop();
4890
4891         /* Build the filename */
4892         path_build(buf, 1024, ANGBAND_DIR_USER, name);
4893
4894         /* File type is "TEXT" */
4895         FILE_TYPE(FILE_TYPE_TEXT);
4896
4897         /* Check for existing file */
4898         fd = fd_open(buf, O_RDONLY);
4899
4900         /* Existing file */
4901         if (fd >= 0)
4902         {
4903                 char out_val[160];
4904
4905                 /* Close the file */
4906                 (void)fd_close(fd);
4907
4908                 /* Build query */
4909 #ifdef JP
4910 (void)sprintf(out_val, "¸½Â¸¤¹¤ë¥Õ¥¡¥¤¥ë %s ¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«? ", buf);
4911 #else
4912                 (void)sprintf(out_val, "Replace existing file %s? ", buf);
4913 #endif
4914
4915
4916                 /* Ask */
4917                 if (get_check(out_val)) fd = -1;
4918         }
4919
4920         /* Open the non-existing file */
4921         if (fd < 0) fff = my_fopen(buf, "w");
4922
4923         /* Invalid file */
4924         if (!fff)
4925         {
4926                 /* Message */
4927 #ifdef JP
4928 msg_format("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4929 #else
4930                 msg_format("Character dump failed!");
4931 #endif
4932
4933                 msg_print(NULL);
4934
4935                 /* Error */
4936                 return (-1);
4937         }
4938
4939         (void)make_character_dump(fff);
4940
4941         /* Close it */
4942         my_fclose(fff);
4943
4944         /* Grab priv's */
4945         safe_setuid_grab();
4946
4947         /* Message */
4948 #ifdef JP
4949 msg_print("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤ËÀ®¸ù¤·¤Þ¤·¤¿¡£");
4950 #else
4951         msg_print("Character dump successful.");
4952 #endif
4953
4954         msg_print(NULL);
4955
4956         /* Success */
4957         return (0);
4958 }
4959
4960
4961 typedef struct file_tag
4962 {
4963         char name[32];
4964         int line_number;
4965 } file_tag;
4966
4967
4968 typedef struct file_tags
4969 {
4970         file_tag tags[64];
4971         int index;
4972 } file_tags;
4973
4974
4975 static void add_tag(file_tags *the_tags, cptr name, int line)
4976 {
4977         if (the_tags->index < 64)
4978         {
4979                 file_tag *tag = &(the_tags->tags[the_tags->index]);
4980
4981                 /* Set the name and end it with '\0' */
4982                 strncpy(tag->name, name, 31);
4983                 tag->name[31] = '\0';
4984
4985                 /* Set the line-number */
4986                 tag->line_number = line;
4987
4988                 /* Increase the number of tags */
4989                 the_tags->index++;
4990         }
4991 }
4992
4993
4994 static int get_line(file_tags *the_tags, cptr name)
4995 {
4996         int i;
4997
4998         /* Search for the tag */
4999         for (i = 0; i < the_tags->index; i++)
5000         {
5001                 if (streq(the_tags->tags[i].name, name))
5002                 {
5003                         return the_tags->tags[i].line_number;
5004                 }
5005         }
5006
5007         /* Not found */
5008         return 0;
5009 }
5010
5011
5012 /*
5013  * Recursive file perusal.
5014  *
5015  * Return FALSE on 'Q', otherwise TRUE.
5016  *
5017  * Process various special text in the input file, including
5018  * the "menu" structures used by the "help file" system.
5019  *
5020  * XXX XXX XXX Consider using a temporary file.
5021  *
5022  * XXX XXX XXX Allow the user to "save" the current file.
5023  */
5024 bool show_file(bool show_version, cptr name, cptr what, int line, int mode)
5025 {
5026         int i, n, k;
5027
5028         /* Number of "real" lines passed by */
5029         int next = 0;
5030
5031         /* Number of "real" lines in the file */
5032         int size = 0;
5033
5034         /* Backup value for "line" */
5035         int back = 0;
5036
5037         /* Loop counter */
5038         int cnt;
5039
5040         /* This screen has sub-screens */
5041         bool menu = FALSE;
5042
5043         /* Current help file */
5044         FILE *fff = NULL;
5045
5046         /* Find this string (if any) */
5047         cptr find = NULL;
5048
5049         /* Jump to this tag */
5050         cptr tag = NULL;
5051
5052         /* Hold a string to find */
5053         char finder[81];
5054
5055         /* Hold a string to show */
5056         char shower[81];
5057
5058         /* Filename */
5059         char filename[1024];
5060
5061         /* Describe this thing */
5062         char caption[128];
5063
5064         /* Path buffer */
5065         char path[1024];
5066
5067         /* General buffer */
5068         char buf[1024];
5069
5070         /* Lower case version of the buffer, for searching */
5071         char lc_buf[1024];
5072
5073         /* Aux pointer for making lc_buf (and find!) lowercase */
5074         cptr lc_buf_ptr;
5075
5076         /* Sub-menu information */
5077         char hook[68][32];
5078
5079         /* Tags for in-file references */
5080         file_tags tags;
5081
5082         bool reverse = (line < 0);
5083
5084         int wid, hgt, rows;
5085
5086         Term_get_size(&wid, &hgt);
5087         rows = hgt - 4;
5088
5089         /* Wipe finder */
5090         strcpy(finder, "");
5091
5092         /* Wipe shower */
5093         strcpy(shower, "");
5094
5095         /* Wipe caption */
5096         strcpy(caption, "");
5097
5098         /* Wipe the hooks */
5099         for (i = 0; i < 68; i++)
5100         {
5101                 hook[i][0] = '\0';
5102         }
5103
5104         /* No tags yet */
5105         tags.index = 0;
5106
5107         /* Copy the filename */
5108         strcpy(filename, name);
5109
5110         n = strlen(filename);
5111
5112         /* Extract the tag from the filename */
5113         for (i = 0; i < n; i++)
5114         {
5115                 if (filename[i] == '#')
5116                 {
5117                         filename[i] = '\0';
5118                         tag = filename + i + 1;
5119                         break;
5120                 }
5121         }
5122
5123         /* Redirect the name */
5124         name = filename;
5125
5126         /* Hack XXX XXX XXX */
5127         if (what)
5128         {
5129                 /* Caption */
5130                 strcpy(caption, what);
5131
5132                 /* Access the "file" */
5133                 strcpy(path, name);
5134
5135                 /* Open */
5136                 fff = my_fopen(path, "r");
5137         }
5138
5139         /* Look in "help" */
5140         if (!fff)
5141         {
5142                 /* Caption */
5143 #ifdef JP
5144 sprintf(caption, "¥Ø¥ë¥×¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5145 #else
5146                 sprintf(caption, "Help file '%s'", name);
5147 #endif
5148
5149
5150                 /* Build the filename */
5151                 path_build(path, 1024, ANGBAND_DIR_HELP, name);
5152
5153                 /* Open the file */
5154                 fff = my_fopen(path, "r");
5155         }
5156
5157         /* Look in "info" */
5158         if (!fff)
5159         {
5160                 /* Caption */
5161 #ifdef JP
5162 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5163 #else
5164                 sprintf(caption, "Info file '%s'", name);
5165 #endif
5166
5167
5168                 /* Build the filename */
5169                 path_build(path, 1024, ANGBAND_DIR_INFO, name);
5170
5171                 /* Open the file */
5172                 fff = my_fopen(path, "r");
5173         }
5174
5175         /* Look in "info" */
5176         if (!fff)
5177         {
5178                 /* Build the filename */
5179                 path_build(path, 1024, ANGBAND_DIR, name);
5180
5181                 for (i = 0; path[i]; i++)
5182                         if ('\\' == path[i])
5183                                 path[i] = PATH_SEP[0];
5184
5185                 /* Caption */
5186 #ifdef JP
5187 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5188 #else
5189                 sprintf(caption, "Info file '%s'", name);
5190 #endif
5191
5192                 /* Open the file */
5193                 fff = my_fopen(path, "r");
5194         }
5195
5196         /* Oops */
5197         if (!fff)
5198         {
5199                 /* Message */
5200 #ifdef JP
5201 msg_format("'%s'¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Þ¤»¤ó¡£", name);
5202 #else
5203                 msg_format("Cannot open '%s'.", name);
5204 #endif
5205
5206                 msg_print(NULL);
5207
5208                 /* Oops */
5209                 return (TRUE);
5210         }
5211
5212
5213         /* Pre-Parse the file */
5214         while (TRUE)
5215         {
5216                 /* Read a line or stop */
5217                 if (my_fgets(fff, buf, 1024)) break;
5218
5219                 /* XXX Parse "menu" items */
5220                 if (prefix(buf, "***** "))
5221                 {
5222                         /* Notice "menu" requests */
5223                         if ((buf[6] == '[') && (isdigit(buf[7]) || isalpha(buf[7])))
5224                         {
5225                                 /* This is a menu file */
5226                                 menu = TRUE;
5227
5228                                 /* Extract the menu item */
5229                                 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
5230
5231                                 if ((buf[8] == ']') && (buf[9] == ' '))
5232                                 {
5233                                         /* Extract the menu item */
5234                                         strncpy(hook[k], buf + 10, 31);
5235
5236                                         /* Make sure it's null-terminated */
5237                                         hook[k][31] = '\0';
5238                                 }
5239                         }
5240                         /* Notice "tag" requests */
5241                         else if (buf[6] == '<')
5242                         {
5243                                 buf[strlen(buf) - 1] = '\0';
5244                                 add_tag(&tags, buf + 7, next);
5245                         }
5246
5247                         /* Skip this */
5248                         continue;
5249                 }
5250
5251                 /* Count the "real" lines */
5252                 next++;
5253         }
5254
5255         /* Save the number of "real" lines */
5256         size = next;
5257
5258         /* start from bottom when reverse mode */
5259         if (line == -1) line = ((size-1)/rows)*rows;
5260
5261         /* Go to the tagged line */
5262         if (tag) line = get_line(&tags, tag);
5263
5264         /* Display the file */
5265         while (TRUE)
5266         {
5267                 /* Clear screen */
5268                 Term_clear();
5269
5270                 /* Restart when necessary */
5271                 if (line >= size) line = 0;
5272
5273
5274                 /* Re-open the file if needed */
5275                 if (next > line)
5276                 {
5277                         /* Close it */
5278                         my_fclose(fff);
5279
5280                         /* Hack -- Re-Open the file */
5281                         fff = my_fopen(path, "r");
5282
5283                         /* Oops */
5284                         if (!fff) return (FALSE);
5285
5286                         /* File has been restarted */
5287                         next = 0;
5288                 }
5289
5290                 /* Goto the selected line */
5291                 while (next < line)
5292                 {
5293                         /* Get a line */
5294                         if (my_fgets(fff, buf, 1024)) break;
5295
5296                         /* Skip tags/links */
5297                         if (prefix(buf, "***** ")) continue;
5298
5299                         /* Count the lines */
5300                         next++;
5301                 }
5302
5303                 /* Dump the next rows lines of the file */
5304                 for (i = 0; i < rows; )
5305                 {
5306                         /* Hack -- track the "first" line */
5307                         if (!i) line = next;
5308
5309                         /* Get a line of the file or stop */
5310                         if (my_fgets(fff, buf, 1024)) break;
5311
5312                         /* Hack -- skip "special" lines */
5313                         if (prefix(buf, "***** ")) continue;
5314
5315                         /* Count the "real" lines */
5316                         next++;
5317
5318                         /* Make a lower case version of buf for searching */
5319                         strcpy(lc_buf, buf);
5320
5321                         for (lc_buf_ptr = lc_buf; *lc_buf_ptr != 0; lc_buf_ptr++)
5322                         {
5323 #ifdef JP
5324                                 if (iskanji(*lc_buf_ptr))
5325                                         lc_buf_ptr++;
5326                                 else
5327 #endif
5328                                         lc_buf[lc_buf_ptr-lc_buf] = tolower(*lc_buf_ptr);
5329                         }
5330
5331                         /* Hack -- keep searching */
5332                         if (find && !i && !strstr(lc_buf, find)) continue;
5333
5334                         /* Hack -- stop searching */
5335                         find = NULL;
5336
5337                         /* Dump the line */
5338                         Term_putstr(0, i+2, -1, TERM_WHITE, buf);
5339
5340                         /* Hilite "shower" */
5341                         if (shower[0])
5342                         {
5343                                 cptr str = lc_buf;
5344
5345                                 /* Display matches */
5346                                 while ((str = strstr(str, shower)) != NULL)
5347                                 {
5348                                         int len = strlen(shower);
5349
5350                                         /* Display the match */
5351                                         Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]);
5352
5353                                         /* Advance */
5354                                         str += len;
5355                                 }
5356                         }
5357
5358                         /* Count the printed lines */
5359                         i++;
5360                 }
5361
5362                 /* Hack -- failed search */
5363                 if (find)
5364                 {
5365                         bell();
5366                         line = back;
5367                         find = NULL;
5368                         continue;
5369                 }
5370
5371
5372                 /* Show a general "title" */
5373                 if (show_version)
5374                 {
5375                         prt(format(
5376 #ifdef JP
5377                                 "[ÊѶòÈÚÅÜ %d.%d.%d, %s, %d/%d]",
5378 #else
5379                                 "[Hengband %d.%d.%d, %s, Line %d/%d]",
5380 #endif
5381
5382                            FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH,
5383                            caption, line, size), 0, 0);
5384                 }
5385                 else
5386                 {
5387                         prt(format(
5388 #ifdef JP
5389                                 "[%s, %d/%d]",
5390 #else
5391                                 "[%s, Line %d/%d]",
5392 #endif
5393                                 caption, line, size), 0, 0);
5394                 }
5395
5396                 /* Prompt -- menu screen */
5397                 if (menu)
5398                 {
5399                         /* Wait for it */
5400 #ifdef JP
5401 prt("[ ÈÖ¹æ¤òÆþÎϤ·¤Æ²¼¤µ¤¤( ESC¤Ç½ªÎ» ) ]", hgt - 1, 0);
5402 #else
5403                         prt("[Press a Number, or ESC to exit.]", hgt - 1, 0);
5404 #endif
5405
5406                 }
5407
5408                 /* Prompt -- small files */
5409                 else if (size <= rows)
5410                 {
5411                         /* Wait for it */
5412 #ifdef JP
5413 prt("[¥­¡¼:(?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5414 #else
5415                         prt("[Press ESC to exit.]", hgt - 1, 0);
5416 #endif
5417
5418                 }
5419
5420                 /* Prompt -- large files */
5421                 else
5422                 {
5423 #ifdef JP
5424                         if(reverse)
5425                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢¬ (-)¢­ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5426                         else
5427                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢­ (-)¢¬ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5428 #else
5429                         prt("[Press Return, Space, -, =, /, |, or ESC to exit.]", hgt - 1, 0);
5430 #endif
5431                 }
5432
5433                 /* Get a keypress */
5434                 k = inkey();
5435
5436                 /* Hack -- return to last screen */
5437                 if (k == '<') break;
5438
5439                 /* Show the help for the help */
5440                 if (k == '?')
5441                 {
5442                         /* Hack - prevent silly recursion */
5443 #ifdef JP
5444                         if (strcmp(name, "jhelpinfo.txt") != 0)
5445                                 show_file(TRUE, "jhelpinfo.txt", NULL, 0, mode);
5446 #else
5447                         if (strcmp(name, "helpinfo.txt") != 0)
5448                                 show_file(TRUE, "helpinfo.txt", NULL, 0, mode);
5449 #endif
5450                 }
5451
5452                 /* Hack -- try showing */
5453                 if (k == '=')
5454                 {
5455                         /* Get "shower" */
5456 #ifdef JP
5457 prt("¶¯Ä´: ", hgt - 1, 0);
5458 #else
5459                         prt("Show: ", hgt - 1, 0);
5460 #endif
5461
5462                         (void)askfor_aux(shower, 80);
5463                 }
5464
5465                 /* Hack -- try finding */
5466                 if (k == '/')
5467                 {
5468                         /* Get "finder" */
5469 #ifdef JP
5470 prt("¸¡º÷: ", hgt - 1, 0);
5471 #else
5472                         prt("Find: ", hgt - 1, 0);
5473 #endif
5474
5475
5476                         if (askfor_aux(finder, 80))
5477                         {
5478                                 /* Find it */
5479                                 find = finder;
5480                                 back = line;
5481                                 line = line + 1;
5482
5483                                 /* Make finder lowercase */
5484                                 for (cnt = 0; finder[cnt] != 0; cnt++)
5485                                 {
5486 #ifdef JP
5487                                         if (iskanji(finder[cnt]))
5488                                                 cnt++;
5489                                         else
5490 #endif
5491                                                 finder[cnt] = tolower(finder[cnt]);
5492                                 }
5493
5494                                 /* Show it */
5495                                 strcpy(shower, finder);
5496                         }
5497                 }
5498
5499                 /* Hack -- go to a specific line */
5500                 if (k == '#')
5501                 {
5502                         char tmp[81];
5503 #ifdef JP
5504 prt("¹Ô: ", hgt - 1, 0);
5505 #else
5506                         prt("Goto Line: ", hgt - 1, 0);
5507 #endif
5508
5509                         strcpy(tmp, "0");
5510
5511                         if (askfor_aux(tmp, 80))
5512                         {
5513                                 line = atoi(tmp);
5514                         }
5515                 }
5516
5517                 /* Hack -- go to a specific file */
5518                 if (k == '%')
5519                 {
5520                         char tmp[81];
5521 #ifdef JP
5522 prt("¥Õ¥¡¥¤¥ë¡¦¥Í¡¼¥à: ", hgt - 1, 0);
5523 strcpy(tmp, "jhelp.hlp");
5524 #else
5525                         prt("Goto File: ", hgt - 1, 0);
5526                         strcpy(tmp, "help.hlp");
5527 #endif
5528
5529
5530                         if (askfor_aux(tmp, 80))
5531                         {
5532                                 if (!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5533                         }
5534                 }
5535
5536                 /* Hack -- Allow backing up */
5537                 if (k == '-')
5538                 {
5539                         line = line + (reverse ? rows : -rows);
5540                         if (line < 0) line = ((size-1)/rows)*rows;
5541                 }
5542
5543                 /* Hack -- Advance a single line */
5544                 if ((k == '\n') || (k == '\r'))
5545                 {
5546                         line = line + (reverse ? -1 : 1);
5547                         if (line < 0) line = ((size-1)/rows)*rows;
5548                 }
5549
5550                 /* Advance one page */
5551                 if (k == ' ')
5552                 {
5553                         line = line + (reverse ? -rows : rows);
5554                         if (line < 0) line = ((size-1)/rows)*rows;
5555                 }
5556
5557                 /* Recurse on numbers */
5558                 if (menu)
5559                 {
5560                         int key = -1;
5561
5562                         if (isdigit(k)) key = D2I(k);
5563                         else if (isalpha(k)) key = k - 'A' + 10;
5564
5565                         if ((key > -1) && hook[key][0])
5566                         {
5567                                 /* Recurse on that file */
5568                                 if (!show_file(TRUE, hook[key], NULL, 0, mode))
5569                                         k = 'q';
5570                         }
5571                 }
5572
5573                 /* Hack, dump to file */
5574                 if (k == '|')
5575                 {
5576                         FILE *ffp;
5577                         char buff[1024];
5578                         char xtmp[82];
5579
5580                         strcpy (xtmp, "");
5581
5582 #ifdef JP
5583                         if (!get_string("¥Õ¥¡¥¤¥ë̾: ", xtmp, 80))
5584 #else
5585                         if (!get_string("File name: ", xtmp, 80))
5586 #endif
5587                         {
5588                                 continue;
5589                         }
5590  
5591                         /* Close it */
5592                         my_fclose(fff);
5593
5594                         /* Drop priv's */
5595                         safe_setuid_drop();
5596
5597                         /* Build the filename */
5598                         path_build(buff, 1024, ANGBAND_DIR_USER, xtmp);
5599
5600                         /* Hack -- Re-Open the file */
5601                         fff = my_fopen(path, "r");
5602
5603                         ffp = my_fopen(buff, "w");
5604
5605                         /* Oops */
5606                         if (!(fff && ffp))
5607                         {
5608 #ifdef JP
5609 msg_print("¥Õ¥¡¥¤¥ë¤¬³«¤±¤Þ¤»¤ó¡£");
5610 #else
5611                                 msg_print("Failed to open file.");
5612 #endif
5613
5614                                 k = ESCAPE;
5615                                 break;
5616                         }
5617
5618                         sprintf(xtmp, "%s: %s", player_name, what);
5619                         my_fputs(ffp, xtmp, 80);
5620                         my_fputs(ffp, "\n", 80);
5621
5622                         while (!my_fgets(fff, buff, 80))
5623                                 my_fputs(ffp, buff, 80);
5624
5625                         /* Close it */
5626                         my_fclose(fff);
5627                         my_fclose(ffp);
5628
5629                         /* Grab priv's */
5630                         safe_setuid_grab();
5631
5632                         /* Hack -- Re-Open the file */
5633                         fff = my_fopen(path, "r");
5634                 }
5635
5636                 /* Exit on escape */
5637                 if (k == ESCAPE) break;
5638                 if (k == 'q') break;
5639         }
5640
5641         /* Close the file */
5642         my_fclose(fff);
5643
5644         /* Escape */
5645         if (k == 'q') return (FALSE);
5646
5647         /* Normal return */
5648         return (TRUE);
5649 }
5650
5651
5652 /*
5653  * Peruse the On-Line-Help
5654  */
5655 void do_cmd_help(void)
5656 {
5657         /* Save screen */
5658         screen_save();
5659
5660         /* Peruse the main help file */
5661 #ifdef JP
5662 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
5663 #else
5664         (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
5665 #endif
5666
5667
5668         /* Load screen */
5669         screen_load();
5670 }
5671
5672
5673 /*
5674  * Process the player name.
5675  * Extract a clean "base name".
5676  * Build the savefile name if needed.
5677  */
5678 void process_player_name(bool sf)
5679 {
5680         int i, k = 0;
5681
5682
5683         /* Cannot be too long */
5684 #if defined(MACINTOSH) || defined(MSDOS) || defined(USE_EMX) || defined(AMIGA) || defined(ACORN) || defined(VM)
5685 #ifdef MSDOS
5686         if (strlen(player_name) > 8)
5687 #else
5688         if (strlen(player_name) > 15)
5689 #endif
5690         {
5691                 /* Name too long */
5692 #ifdef JP
5693 quit_fmt("'%s'¤È¤¤¤¦Ì¾Á°¤ÏŤ¹¤®¤Þ¤¹¡ª", player_name);
5694 #else
5695                 quit_fmt("The name '%s' is too long!", player_name);
5696 #endif
5697
5698         }
5699 #endif
5700
5701         /* Cannot contain "icky" characters */
5702         for (i = 0; player_name[i]; i++)
5703         {
5704                 /* No control characters */
5705 #ifdef JP
5706                 if (iskanji(player_name[i])){i++;continue;}
5707                 if (iscntrl( (unsigned char)player_name[i]))
5708 #else
5709                 if (iscntrl(player_name[i]))
5710 #endif
5711
5712                 {
5713                         /* Illegal characters */
5714 #ifdef JP
5715 quit_fmt("'%s' ¤È¤¤¤¦Ì¾Á°¤ÏÉÔÀµ¤Ê¥³¥ó¥È¥í¡¼¥ë¥³¡¼¥É¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£", player_name);
5716 #else
5717                         quit_fmt("The name '%s' contains control chars!", player_name);
5718 #endif
5719
5720                 }
5721         }
5722
5723
5724 #ifdef MACINTOSH
5725
5726         /* Extract "useful" letters */
5727         for (i = 0; player_name[i]; i++)
5728         {
5729 #ifdef JP
5730                 unsigned char c = player_name[i];
5731 #else
5732                 char c = player_name[i];
5733 #endif
5734
5735
5736                 /* Convert "dot" to "underscore" */
5737                 if (c == '.') c = '_';
5738
5739                 /* Accept all the letters */
5740                 player_base[k++] = c;
5741         }
5742
5743 #else
5744
5745         /* Extract "useful" letters */
5746         for (i = 0; player_name[i]; i++)
5747         {
5748 #ifdef JP
5749                 unsigned char c = player_name[i];
5750 #else
5751                 char c = player_name[i];
5752 #endif
5753
5754                 /* Accept some letters */
5755 #ifdef JP
5756                 if(iskanji(c)){
5757                   if(k + 2 >= sizeof(player_base) || !player_name[i+1]) break;
5758                   player_base[k++] = c;
5759                   i++;
5760                   player_base[k++] = player_name[i];
5761                 }
5762 #ifdef SJIS
5763                 else if (iskana(c)) player_base[k++] = c;
5764 #endif
5765                 else
5766 #endif
5767                 /* Convert path separator to underscore */
5768                 if (!strncmp(PATH_SEP, player_name+i, strlen(PATH_SEP))){
5769                         player_base[k++] = '_';
5770                         i += strlen(PATH_SEP);
5771                 }
5772 #ifdef MSDOS
5773                 /* Convert space, dot, and underscore to underscore */
5774                 else if (strchr(". _", c)) player_base[k++] = '_';
5775 #endif
5776                 else if (isprint(c)) player_base[k++] = c;
5777         }
5778
5779 #endif
5780
5781
5782 #if defined(MSDOS)
5783
5784         /* Hack -- max length */
5785         if (k > 8) k = 8;
5786
5787 #endif
5788
5789         /* Terminate */
5790         player_base[k] = '\0';
5791
5792         /* Require a "base" name */
5793         if (!player_base[0]) strcpy(player_base, "PLAYER");
5794
5795
5796 #ifdef SAVEFILE_MUTABLE
5797
5798         /* Accept */
5799         sf = TRUE;
5800
5801 #endif
5802         if (!savefile_base[0] && savefile[0])
5803         {
5804                 cptr s;
5805                 s = savefile;
5806                 while (1)
5807                 {
5808                         cptr t;
5809                         t = strstr(s, PATH_SEP);
5810                         if (!t)
5811                                 break;
5812                         s = t+1;
5813                 }
5814                 strcpy(savefile_base, s);
5815         }
5816
5817         if (!savefile_base[0] || !savefile[0])
5818                 sf = TRUE;
5819
5820         /* Change the savefile name */
5821         if (sf)
5822         {
5823                 char temp[128];
5824
5825                 strcpy(savefile_base, player_base);
5826
5827 #ifdef SAVEFILE_USE_UID
5828                 /* Rename the savefile, using the player_uid and player_base */
5829                 (void)sprintf(temp, "%d.%s", player_uid, player_base);
5830 #else
5831                 /* Rename the savefile, using the player_base */
5832                 (void)sprintf(temp, "%s", player_base);
5833 #endif
5834
5835 #ifdef VM
5836                 /* Hack -- support "flat directory" usage on VM/ESA */
5837                 (void)sprintf(temp, "%s.sv", player_base);
5838 #endif /* VM */
5839
5840                 /* Build the filename */
5841                 path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp);
5842         }
5843 }
5844
5845
5846 /*
5847  * Gets a name for the character, reacting to name changes.
5848  *
5849  * Assumes that "display_player(0)" has just been called
5850  *
5851  * Perhaps we should NOT ask for a name (at "birth()") on
5852  * Unix machines?  XXX XXX
5853  *
5854  * What a horrible name for a global function.  XXX XXX XXX
5855  */
5856 void get_name(void)
5857 {
5858         char tmp[64];
5859
5860         /* Save the player name */
5861         strcpy(tmp, player_name);
5862
5863         /* Prompt for a new name */
5864 #ifdef JP
5865         if (get_string("¥­¥ã¥é¥¯¥¿¡¼¤Î̾Á°¤òÆþÎϤ·¤Æ²¼¤µ¤¤: ", tmp, 15))
5866 #else
5867         if (get_string("Enter a name for your character: ", tmp, 15))
5868 #endif
5869         {
5870                 /* Use the name */
5871                 strcpy(player_name, tmp);
5872         }
5873         else if (0 == strlen(player_name))
5874         {
5875                 /* Use default name */
5876                 strcpy(player_name, "PLAYER");
5877         }
5878
5879         /* Process the player name */
5880         process_player_name(FALSE);
5881
5882         strcpy(tmp,ap_ptr->title);
5883 #ifdef JP
5884         if(ap_ptr->no == 1)
5885                 strcat(tmp,"¤Î");
5886 #else
5887         strcat(tmp, " ");
5888 #endif
5889         strcat(tmp,player_name);
5890
5891         /* Re-Draw the name (in light blue) */
5892         c_put_str(TERM_L_BLUE, tmp, 1, 34);
5893
5894         /* Erase the prompt, etc */
5895         clear_from(22);
5896 }
5897
5898
5899
5900 /*
5901  * Hack -- commit suicide
5902  */
5903 void do_cmd_suicide(void)
5904 {
5905         int i;
5906
5907         /* Flush input */
5908         flush();
5909
5910         /* Verify Retirement */
5911         if (total_winner)
5912         {
5913                 /* Verify */
5914 #ifdef JP
5915 if (!get_check("°úÂष¤Þ¤¹¤«? ")) return;
5916 #else
5917                 if (!get_check("Do you want to retire? ")) return;
5918 #endif
5919
5920         }
5921
5922         /* Verify Suicide */
5923         else
5924         {
5925                 /* Verify */
5926 #ifdef JP
5927 if (!get_check("ËÜÅö¤Ë¼«»¦¤·¤Þ¤¹¤«¡©")) return;
5928 #else
5929                 if (!get_check("Do you really want to commit suicide? ")) return;
5930 #endif
5931         }
5932
5933
5934         if (!noscore)
5935         {
5936                 /* Special Verification for suicide */
5937 #ifdef JP
5938 prt("³Îǧ¤Î¤¿¤á '@' ¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 0);
5939 #else
5940                 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
5941 #endif
5942
5943                 flush();
5944                 i = inkey();
5945                 prt("", 0, 0);
5946                 if (i != '@') return;
5947         }
5948
5949         /* Stop playing */
5950         alive = FALSE;
5951
5952         /* Kill the player */
5953         death = TRUE;
5954
5955         /* Leaving */
5956         p_ptr->leaving = TRUE;
5957
5958         if (!total_winner)
5959         {
5960 #ifdef JP
5961                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤ËÀä˾¤·¤Æ¼«»¦¤·¤¿¡£");
5962                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
5963 #else
5964                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "give up all hope to commit suicide.");
5965                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "--------   Game  Over   --------");
5966 #endif
5967                 do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
5968         }
5969
5970         /* Cause of death */
5971 #ifdef JP
5972 (void)strcpy(died_from, "ÅÓÃ潪λ");
5973 #else
5974         (void)strcpy(died_from, "Quitting");
5975 #endif
5976
5977 }
5978
5979
5980
5981 /*
5982  * Save the game
5983  */
5984 void do_cmd_save_game(int is_autosave)
5985 {
5986         /* Autosaves do not disturb */
5987         if (is_autosave)
5988         {
5989 #ifdef JP
5990 msg_print("¼«Æ°¥»¡¼¥ÖÃæ");
5991 #else
5992                 msg_print("Autosaving the game...");
5993 #endif
5994
5995         }
5996         else
5997         {
5998                 /* Disturb the player */
5999                 disturb(1, 0);
6000         }
6001
6002         /* Clear messages */
6003         msg_print(NULL);
6004
6005         /* Handle stuff */
6006         handle_stuff();
6007
6008         /* Message */
6009 #ifdef JP
6010 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹...", 0, 0);
6011 #else
6012         prt("Saving game...", 0, 0);
6013 #endif
6014
6015
6016         /* Refresh */
6017         Term_fresh();
6018
6019         /* The player is not dead */
6020 #ifdef JP
6021 (void)strcpy(died_from, "(¥»¡¼¥Ö)");
6022 #else
6023         (void)strcpy(died_from, "(saved)");
6024 #endif
6025
6026
6027         /* Forbid suspend */
6028         signals_ignore_tstp();
6029
6030         /* Save the player */
6031         if (save_player())
6032         {
6033 #ifdef JP
6034 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ½ªÎ»", 0, 0);
6035 #else
6036                 prt("Saving game... done.", 0, 0);
6037 #endif
6038
6039         }
6040
6041         /* Save failed (oops) */
6042         else
6043         {
6044 #ifdef JP
6045 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ¼ºÇÔ¡ª", 0, 0);
6046 #else
6047                 prt("Saving game... failed!", 0, 0);
6048 #endif
6049
6050         }
6051
6052         /* Allow suspend again */
6053         signals_handle_tstp();
6054
6055         /* Refresh */
6056         Term_fresh();
6057
6058         /* Note that the player is not dead */
6059 #ifdef JP
6060 (void)strcpy(died_from, "(¸µµ¤¤ËÀ¸¤­¤Æ¤¤¤ë)");
6061 #else
6062         (void)strcpy(died_from, "(alive and well)");
6063 #endif
6064
6065 }
6066
6067
6068 /*
6069  * Save the game and exit
6070  */
6071 void do_cmd_save_and_exit(void)
6072 {
6073         alive = FALSE;
6074
6075         /* Leaving */
6076         p_ptr->leaving = TRUE;
6077 #ifdef JP
6078         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "----¥²¡¼¥àÃæÃÇ----");
6079 #else
6080         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "---- Save and Exit Game ----");
6081 #endif
6082 }
6083
6084
6085 /*
6086  * Hack -- Calculates the total number of points earned         -JWT-
6087  */
6088 long total_points(void)
6089 {
6090         int i, mult = 100;
6091         s16b max_dl = 0;
6092         u32b point, point_h, point_l;
6093         int arena_win = MIN(p_ptr->arena_number, MAX_ARENA_MONS);
6094
6095         if (stupid_monsters) mult -= 70;
6096         if (!preserve_mode) mult += 10;
6097         if (!autoroller) mult += 10;
6098         if (!smart_learn) mult -= 20;
6099         if (!terrain_streams) mult -= 20;
6100         if (smart_cheat) mult += 30;
6101         if (ironman_shops) mult += 50;
6102         if (ironman_small_levels) mult += 10;
6103         if (ironman_empty_levels) mult += 20;
6104         if (!powerup_home) mult += 50;
6105         if (ironman_rooms) mult += 100;
6106         if (ironman_nightmare) mult += 100;
6107
6108         if (mult < 5) mult = 5;
6109
6110         for (i = 0; i < max_d_idx; i++)
6111                 if(max_dlv[i] > max_dl)
6112                         max_dl = max_dlv[i];
6113
6114         point_l = (p_ptr->max_exp + (100 * max_dl));
6115         point_h = point_l / 0x10000L;
6116         point_l = point_l % 0x10000L;
6117         point_h *= mult;
6118         point_l *= mult;
6119         point_h += point_l / 0x10000L;
6120         point_l %= 0x10000L;
6121
6122         point_l += ((point_h % 100) << 16);
6123         point_h /= 100;
6124         point_l /= 100;
6125
6126         point = (point_h << 16) + (point_l);
6127         if (p_ptr->arena_number < 99)
6128                 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
6129
6130         if (ironman_downward) point *= 2;
6131         if (p_ptr->pclass == CLASS_BERSERKER)
6132         {
6133                 if ((p_ptr->prace == RACE_SPECTRE) || (p_ptr->prace == RACE_AMBERITE))
6134                         point = point / 5;
6135         }
6136
6137         if ((p_ptr->pseikaku == SEIKAKU_MUNCHKIN) && point)
6138         {
6139                 point = 1;
6140                 if (total_winner) point = 2;
6141         }
6142         if (easy_band) point = (0 - point);
6143
6144         return point;
6145 }
6146
6147
6148
6149 /*
6150  * Centers a string within a 31 character string                -JWT-
6151  */
6152 static void center_string(char *buf, cptr str)
6153 {
6154         int i, j;
6155
6156         /* Total length */
6157         i = strlen(str);
6158
6159         /* Necessary border */
6160         j = 15 - i / 2;
6161
6162         /* Mega-Hack */
6163         (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, "");
6164 }
6165
6166
6167 #if 0
6168 /*
6169  * Save a "bones" file for a dead character
6170  *
6171  * Note that we will not use these files until Angband 2.8.0, and
6172  * then we will only use the name and level on which death occured.
6173  *
6174  * Should probably attempt some form of locking...
6175  */
6176 static void make_bones(void)
6177 {
6178         FILE                *fp;
6179
6180         char                str[1024];
6181
6182
6183         /* Ignore wizards and borgs */
6184         if (!(noscore & 0x00FF))
6185         {
6186                 /* Ignore people who die in town */
6187                 if (dun_level)
6188                 {
6189                         char tmp[128];
6190
6191                         /* XXX XXX XXX "Bones" name */
6192                         sprintf(tmp, "bone.%03d", dun_level);
6193
6194                         /* Build the filename */
6195                         path_build(str, 1024, ANGBAND_DIR_BONE, tmp);
6196
6197                         /* Attempt to open the bones file */
6198                         fp = my_fopen(str, "r");
6199
6200                         /* Close it right away */
6201                         if (fp) my_fclose(fp);
6202
6203                         /* Do not over-write a previous ghost */
6204                         if (fp) return;
6205
6206                         /* File type is "TEXT" */
6207                         FILE_TYPE(FILE_TYPE_TEXT);
6208
6209                         /* Try to write a new "Bones File" */
6210                         fp = my_fopen(str, "w");
6211
6212                         /* Not allowed to write it?  Weird. */
6213                         if (!fp) return;
6214
6215                         /* Save the info */
6216                         fprintf(fp, "%s\n", player_name);
6217                         fprintf(fp, "%d\n", p_ptr->mhp);
6218                         fprintf(fp, "%d\n", p_ptr->prace);
6219                         fprintf(fp, "%d\n", p_ptr->pclass);
6220
6221                         /* Close and save the Bones file */
6222                         my_fclose(fp);
6223                 }
6224         }
6225 }
6226 #endif
6227
6228
6229 /*
6230  * Redefinable "print_tombstone" action
6231  */
6232 bool (*tombstone_aux)(void) = NULL;
6233
6234
6235 /*
6236  * Display a "tomb-stone"
6237  */
6238 static void print_tomb(void)
6239 {
6240         bool done = FALSE;
6241
6242         /* Do we use a special tombstone ? */
6243         if (tombstone_aux)
6244         {
6245                 /* Use tombstone hook */
6246                 done = (*tombstone_aux)();
6247         }
6248
6249         /* Print the text-tombstone */
6250         if (!done)
6251         {
6252                 cptr    p;
6253
6254                 char    tmp[160];
6255
6256                 char    buf[1024];
6257 #ifndef JP
6258                 char    dummy[80];
6259 #endif
6260
6261                 FILE        *fp;
6262
6263                 time_t  ct = time((time_t)0);
6264
6265
6266                 /* Clear screen */
6267                 Term_clear();
6268
6269                 /* Build the filename */
6270 #ifdef JP
6271                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead_j.txt");
6272 #else
6273                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt");
6274 #endif
6275
6276
6277                 /* Open the News file */
6278                 fp = my_fopen(buf, "r");
6279
6280                 /* Dump */
6281                 if (fp)
6282                 {
6283                         int i = 0;
6284
6285                         /* Dump the file to the screen */
6286                         while (0 == my_fgets(fp, buf, 1024))
6287                         {
6288                                 /* Display and advance */
6289                                 put_str(buf, i++, 0);
6290                         }
6291
6292                         /* Close */
6293                         my_fclose(fp);
6294                 }
6295
6296
6297                 /* King or Queen */
6298                 if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
6299                 {
6300 #ifdef JP
6301                 /* ±ÑÆüÀÚ¤êÂؤ¨ */
6302                   p= "°ÎÂç¤Ê¤ë¼Ô";
6303 #else
6304                         p = "Magnificent";
6305 #endif
6306
6307                 }
6308
6309                 /* Normal */
6310                 else
6311                 {
6312                         p =  player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
6313                 }
6314
6315                 center_string(buf, player_name);
6316                 put_str(buf, 6, 11);
6317
6318 #ifndef JP
6319                 center_string(buf, "the");
6320                 put_str(buf, 7, 11);
6321 #endif
6322
6323                 center_string(buf, p);
6324                 put_str(buf, 8, 11);
6325
6326
6327                 center_string(buf, cp_ptr->title);
6328
6329                 put_str(buf, 10, 11);
6330
6331 #ifdef JP
6332 (void)sprintf(tmp, "¥ì¥Ù¥ë: %d", (int)p_ptr->lev);
6333 #else
6334                 (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
6335 #endif
6336
6337                 center_string(buf, tmp);
6338                 put_str(buf, 11, 11);
6339
6340 #ifdef JP
6341 (void)sprintf(tmp, "·Ð¸³ÃÍ: %ld", (long)p_ptr->exp);
6342 #else
6343                 (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp);
6344 #endif
6345
6346                 center_string(buf, tmp);
6347                 put_str(buf, 12, 11);
6348
6349 #ifdef JP
6350 (void)sprintf(tmp, "½ê»ý¶â: %ld", (long)p_ptr->au);
6351 #else
6352                 (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au);
6353 #endif
6354
6355                 center_string(buf, tmp);
6356                 put_str(buf, 13, 11);
6357
6358 #ifdef JP
6359         /* Êè¤Ë¹ï¤à¸ÀÍÕ¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
6360         if (streq(died_from, "ÅÓÃ潪λ"))
6361         {
6362                 strcpy(tmp, "<¼«»¦>");
6363         }
6364         else
6365         {
6366                 if (streq(died_from, "ripe"))
6367                 {
6368                         strcpy(tmp, "°úÂà¸å¤ËÅ·¼÷¤òÁ´¤¦");
6369                 }
6370                 else if (streq(died_from, "Seppuku"))
6371                 {
6372                         strcpy(tmp, "¾¡Íø¤Î¸å¡¢ÀÚÊ¢");
6373                 }
6374                 else
6375                 {
6376                         strcpy(tmp, died_from);
6377                 }
6378         }
6379         center_string(buf, tmp);
6380         put_str(buf, 14, 11);
6381
6382         if(!streq(died_from, "ripe") && !streq(died_from, "Seppuku"))
6383         {
6384                 if( dun_level == 0 )
6385                 {
6386                         cptr town = (p_ptr->town_num ? "³¹" : "¹ÓÌî");
6387                         if(streq(died_from, "ÅÓÃ潪λ"))
6388                         {
6389                                 sprintf(tmp, "%s¤Ç»à¤ó¤À", town);
6390                         }
6391                         else
6392                         {
6393                                 sprintf(tmp, "¤Ë%s¤Ç»¦¤µ¤ì¤¿", town);
6394                         }
6395                 }
6396                 else
6397                 {
6398                         if(streq(died_from, "ÅÓÃ潪λ"))
6399                         {
6400                                 sprintf(tmp, "Ãϲ¼ %d ³¬¤Ç»à¤ó¤À", dun_level);
6401                         }
6402                         else
6403                         {
6404                                 sprintf(tmp, "¤ËÃϲ¼ %d ³¬¤Ç»¦¤µ¤ì¤¿", dun_level);
6405                         }
6406                 }
6407                 center_string(buf, tmp);
6408                 put_str(buf, 15, 11);
6409         }
6410 #else
6411                 (void)sprintf(tmp, "Killed on Level %d", dun_level);
6412                 center_string(buf, tmp);
6413                 put_str(buf, 14, 11);
6414
6415
6416                 if (strlen(died_from) > 24)
6417                 {
6418                         strncpy(dummy, died_from, 24);
6419                         dummy[24] = '\0';
6420                         (void)sprintf(tmp, "by %s.", dummy);
6421                 }
6422                 else
6423                         (void)sprintf(tmp, "by %s.", died_from);
6424
6425                 center_string(buf, tmp);
6426                 put_str(buf, 15, 11);
6427 #endif
6428
6429
6430
6431                 (void)sprintf(tmp, "%-.24s", ctime(&ct));
6432                 center_string(buf, tmp);
6433                 put_str(buf, 17, 11);
6434
6435 #ifdef JP
6436 msg_format("¤µ¤è¤¦¤Ê¤é¡¢%s!", player_name);
6437 #else
6438                 msg_format("Goodbye, %s!", player_name);
6439 #endif
6440
6441         }
6442 }
6443
6444
6445 /*
6446  * Display some character info
6447  */
6448 static void show_info(void)
6449 {
6450         int             i, j, k, l;
6451         object_type             *o_ptr;
6452         store_type              *st_ptr;
6453
6454         /* Hack -- Know everything in the inven/equip */
6455         for (i = 0; i < INVEN_TOTAL; i++)
6456         {
6457                 o_ptr = &inventory[i];
6458
6459                 /* Skip non-objects */
6460                 if (!o_ptr->k_idx) continue;
6461
6462                 /* Aware and Known */
6463                 object_aware(o_ptr);
6464                 object_known(o_ptr);
6465         }
6466
6467         for (i = 1; i < max_towns; i++)
6468         {
6469                 st_ptr = &town[i].store[STORE_HOME];
6470
6471                 /* Hack -- Know everything in the home */
6472                 for (j = 0; j < st_ptr->stock_num; j++)
6473                 {
6474                         o_ptr = &st_ptr->stock[j];
6475
6476                         /* Skip non-objects */
6477                         if (!o_ptr->k_idx) continue;
6478
6479                         /* Aware and Known */
6480                         object_aware(o_ptr);
6481                         object_known(o_ptr);
6482                 }
6483         }
6484
6485         /* Hack -- Recalculate bonuses */
6486         p_ptr->update |= (PU_BONUS);
6487
6488         /* Handle stuff */
6489         handle_stuff();
6490
6491         /* Flush all input keys */
6492         flush();
6493
6494         /* Flush messages */
6495         msg_print(NULL);
6496
6497
6498         /* Describe options */
6499 #ifdef JP
6500 prt("¥­¥ã¥é¥¯¥¿¡¼¤Îµ­Ï¿¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£", 21, 0);
6501 prt("¥ê¥¿¡¼¥ó¥­¡¼¤Ç¥­¥ã¥é¥¯¥¿¡¼¤ò¸«¤Þ¤¹¡£ESC¤ÇÃæÃǤ·¤Þ¤¹¡£", 22, 0);
6502 #else
6503         prt("You may now dump a character record to one or more files.", 21, 0);
6504         prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
6505 #endif
6506
6507
6508         /* Dump character records as requested */
6509         while (TRUE)
6510         {
6511                 char out_val[160];
6512
6513                 /* Prompt */
6514 #ifdef JP
6515 put_str("¥Õ¥¡¥¤¥ë¥Í¡¼¥à: ", 23, 0);
6516 #else
6517                 put_str("Filename: ", 23, 0);
6518 #endif
6519
6520
6521                 /* Default */
6522                 strcpy(out_val, "");
6523
6524                 /* Ask for filename (or abort) */
6525                 if (!askfor_aux(out_val, 60)) return;
6526
6527                 /* Return means "show on screen" */
6528                 if (!out_val[0]) break;
6529
6530                 /* Save screen */
6531                 screen_save();
6532
6533                 /* Dump a character file */
6534                 (void)file_character(out_val, TRUE);
6535
6536                 /* Load screen */
6537                 screen_load();
6538         }
6539
6540         update_playtime();
6541
6542         /* Display player */
6543         display_player(0);
6544
6545         /* Prompt for inventory */
6546 #ifdef JP
6547 prt("²¿¤«¥­¡¼¤ò²¡¤¹¤È¤µ¤é¤Ë¾ðÊó¤¬Â³¤­¤Þ¤¹ (ESC¤ÇÃæÃÇ): ", 23, 0);
6548 #else
6549         prt("Hit any key to see more information (ESC to abort): ", 23, 0);
6550 #endif
6551
6552
6553         /* Allow abort at this point */
6554         if (inkey() == ESCAPE) return;
6555
6556
6557         /* Show equipment and inventory */
6558
6559         /* Equipment -- if any */
6560         if (equip_cnt)
6561         {
6562                 Term_clear();
6563                 item_tester_full = TRUE;
6564                 (void)show_equip(0);
6565 #ifdef JP
6566 prt("ÁõÈ÷¤·¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6567 #else
6568                 prt("You are using: -more-", 0, 0);
6569 #endif
6570
6571                 if (inkey() == ESCAPE) return;
6572         }
6573
6574         /* Inventory -- if any */
6575         if (inven_cnt)
6576         {
6577                 Term_clear();
6578                 item_tester_full = TRUE;
6579                 (void)show_inven(0);
6580 #ifdef JP
6581 prt("»ý¤Ã¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6582 #else
6583                 prt("You are carrying: -more-", 0, 0);
6584 #endif
6585
6586                 if (inkey() == ESCAPE) return;
6587         }
6588
6589         /* Homes in the different towns */
6590         for (l = 1; l < max_towns; l++)
6591         {
6592                 st_ptr = &town[l].store[STORE_HOME];
6593
6594                 /* Home -- if anything there */
6595                 if (st_ptr->stock_num)
6596                 {
6597                         /* Display contents of the home */
6598                         for (k = 0, i = 0; i < st_ptr->stock_num; k++)
6599                         {
6600                                 /* Clear screen */
6601                                 Term_clear();
6602
6603                                 /* Show 12 items */
6604                                 for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++)
6605                                 {
6606                                         char o_name[MAX_NLEN];
6607                                         char tmp_val[80];
6608
6609                                         /* Acquire item */
6610                                         o_ptr = &st_ptr->stock[i];
6611
6612                                         /* Print header, clear line */
6613                                         sprintf(tmp_val, "%c) ", I2A(j));
6614                                         prt(tmp_val, j+2, 4);
6615
6616                                         /* Display object description */
6617                                         object_desc(o_name, o_ptr, TRUE, 3);
6618                                         c_put_str(tval_to_attr[o_ptr->tval], o_name, j+2, 7);
6619                                 }
6620
6621                                 /* Caption */
6622 #ifdef JP
6623 prt(format("²æ¤¬²È¤ËÃÖ¤¤¤Æ¤¢¤Ã¤¿¥¢¥¤¥Æ¥à ( %d ¥Ú¡¼¥¸): -³¤¯-", k+1), 0, 0);
6624 #else
6625                                 prt(format("Your home contains (page %d): -more-", k+1), 0, 0);
6626 #endif
6627
6628
6629                                 /* Wait for it */
6630                                 if (inkey() == ESCAPE) return;
6631                         }
6632                 }
6633         }
6634 }
6635
6636
6637 static bool check_score(void)
6638 {
6639         /* Clear screen */
6640         Term_clear();
6641
6642         /* No score file */
6643         if (highscore_fd < 0)
6644         {
6645 #ifdef JP
6646 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
6647 #else
6648                 msg_print("Score file unavailable.");
6649 #endif
6650
6651                 msg_print(NULL);
6652                 return FALSE;
6653         }
6654
6655 #ifndef SCORE_WIZARDS
6656         /* Wizard-mode pre-empts scoring */
6657         if (noscore & 0x000F)
6658         {
6659 #ifdef JP
6660 msg_print("¥¦¥£¥¶¡¼¥É¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6661 #else
6662                 msg_print("Score not registered for wizards.");
6663 #endif
6664
6665                 msg_print(NULL);
6666                 return FALSE;
6667         }
6668 #endif
6669
6670 #ifndef SCORE_BORGS
6671         /* Borg-mode pre-empts scoring */
6672         if (noscore & 0x00F0)
6673         {
6674 #ifdef JP
6675 msg_print("¥Ü¡¼¥°¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6676 #else
6677                 msg_print("Score not registered for borgs.");
6678 #endif
6679
6680                 msg_print(NULL);
6681                 return FALSE;
6682         }
6683 #endif
6684
6685 #ifndef SCORE_CHEATERS
6686         /* Cheaters are not scored */
6687         if (noscore & 0xFF00)
6688         {
6689 #ifdef JP
6690 msg_print("º¾µ½¤ò¤ä¤Ã¤¿¿Í¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6691 #else
6692                 msg_print("Score not registered for cheaters.");
6693 #endif
6694
6695                 msg_print(NULL);
6696                 return FALSE;
6697         }
6698 #endif
6699
6700         /* Interupted */
6701 #ifdef JP
6702 if (!total_winner && streq(died_from, "¶¯À©½ªÎ»"))
6703 #else
6704         if (!total_winner && streq(died_from, "Interrupting"))
6705 #endif
6706
6707         {
6708 #ifdef JP
6709 msg_print("¶¯À©½ªÎ»¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6710 #else
6711                 msg_print("Score not registered due to interruption.");
6712 #endif
6713
6714                 msg_print(NULL);
6715                 return FALSE;
6716         }
6717
6718         /* Quitter */
6719 #ifdef JP
6720 if (!total_winner && streq(died_from, "ÅÓÃ潪λ"))
6721 #else
6722         if (!total_winner && streq(died_from, "Quitting"))
6723 #endif
6724
6725         {
6726 #ifdef JP
6727 msg_print("ÅÓÃ潪λ¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6728 #else
6729                 msg_print("Score not registered due to quitting.");
6730 #endif
6731
6732                 msg_print(NULL);
6733                 return FALSE;
6734         }
6735         return TRUE;
6736 }
6737
6738 /*
6739  * Close up the current game (player may or may not be dead)
6740  *
6741  * This function is called only from "main.c" and "signals.c".
6742  */
6743 void close_game(void)
6744 {
6745         char buf[1024];
6746         bool do_send = TRUE;
6747
6748 /*      cptr p = "[i:¥­¥ã¥é¥¯¥¿¤Î¾ðÊó, f:¥Õ¥¡¥¤¥ë½ñ¤­½Ð¤·, t:¥¹¥³¥¢, x:*´ÕÄê*, ESC:¥²¡¼¥à½ªÎ»]"; */
6749
6750         /* Handle stuff */
6751         handle_stuff();
6752
6753         /* Flush the messages */
6754         msg_print(NULL);
6755
6756         /* Flush the input */
6757         flush();
6758
6759
6760         /* No suspending now */
6761         signals_ignore_tstp();
6762
6763
6764         /* Hack -- Character is now "icky" */
6765         character_icky = TRUE;
6766
6767
6768         /* Build the filename */
6769         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
6770
6771         /* Open the high score file, for reading/writing */
6772         highscore_fd = fd_open(buf, O_RDWR);
6773
6774
6775         /* Handle death */
6776         if (death)
6777         {
6778                 /* Handle retirement */
6779                 if (total_winner) kingly();
6780
6781                 /* Save memories */
6782 #ifdef JP
6783                 if (!munchkin_death || get_check("»à¤ó¤À¥Ç¡¼¥¿¤ò¥»¡¼¥Ö¤·¤Þ¤¹¤«¡© "))
6784 #else
6785                 if (!munchkin_death || get_check("Save death? "))
6786 #endif
6787                 {
6788
6789 #ifdef JP
6790 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6791 #else
6792                         if (!save_player()) msg_print("death save failed!");
6793 #endif
6794                 }
6795                 else do_send = FALSE;
6796
6797                 /* You are dead */
6798                 print_tomb();
6799
6800                 flush();
6801
6802                 /* Show more info */
6803                 show_info();
6804
6805                 /* Clear screen */
6806                 Term_clear();
6807
6808                 if (check_score())
6809                 {
6810                         if ((!send_world_score(do_send)))
6811                         {
6812 #ifdef JP
6813                                 if (get_check("¸å¤Ç¥¹¥³¥¢¤òÅÐÏ¿¤¹¤ë¤¿¤á¤ËÂÔµ¡¤·¤Þ¤¹¤«¡©"))
6814 #else
6815                                 if (get_check("Stand by for later score registration? "))
6816 #endif
6817                                 {
6818                                         wait_report_score = TRUE;
6819                                         death = FALSE;
6820 #ifdef JP
6821                                         if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6822 #else
6823                                         if (!save_player()) msg_print("death save failed!");
6824 #endif
6825                                 }
6826                         }
6827                         if (!wait_report_score)
6828                                 (void)top_twenty();
6829                 }
6830                 else if (highscore_fd >= 0)
6831                 {
6832                         display_scores_aux(0, 10, -1, NULL);
6833                 }
6834 #if 0
6835                 /* Dump bones file */
6836                 make_bones();
6837 #endif
6838         }
6839
6840         /* Still alive */
6841         else
6842         {
6843                 /* Save the game */
6844                 do_cmd_save_game(FALSE);
6845
6846                 /* Prompt for scores XXX XXX XXX */
6847 #ifdef JP
6848 prt("¥ê¥¿¡¼¥ó¥­¡¼¤« ESC ¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 40);
6849 #else
6850                 prt("Press Return (or Escape).", 0, 40);
6851 #endif
6852
6853
6854                 /* Predict score (or ESCAPE) */
6855                 if (inkey() != ESCAPE) predict_score();
6856         }
6857
6858
6859         /* Shut the high score file */
6860         (void)fd_close(highscore_fd);
6861
6862         /* Forget the high score fd */
6863         highscore_fd = -1;
6864
6865
6866         /* Allow suspending now */
6867         signals_handle_tstp();
6868 }
6869
6870
6871 /*
6872  * Handle abrupt death of the visual system
6873  *
6874  * This routine is called only in very rare situations, and only
6875  * by certain visual systems, when they experience fatal errors.
6876  *
6877  * XXX XXX Hack -- clear the death flag when creating a HANGUP
6878  * save file so that player can see tombstone when restart.
6879  */
6880 void exit_game_panic(void)
6881 {
6882         /* If nothing important has happened, just quit */
6883 #ifdef JP
6884 if (!character_generated || character_saved) quit("¶ÛµÞ»öÂÖ");
6885 #else
6886         if (!character_generated || character_saved) quit("panic");
6887 #endif
6888
6889
6890         /* Mega-Hack -- see "msg_print()" */
6891         msg_flag = FALSE;
6892
6893         /* Clear the top line */
6894         prt("", 0, 0);
6895
6896         /* Hack -- turn off some things */
6897         disturb(1, 0);
6898
6899         /* Mega-Hack -- Delay death */
6900         if (p_ptr->chp < 0) death = FALSE;
6901
6902         /* Hardcode panic save */
6903         panic_save = 1;
6904
6905         /* Forbid suspend */
6906         signals_ignore_tstp();
6907
6908         /* Indicate panic save */
6909 #ifdef JP
6910 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
6911 #else
6912         (void)strcpy(died_from, "(panic save)");
6913 #endif
6914
6915
6916         /* Panic save, or get worried */
6917 #ifdef JP
6918 if (!save_player()) quit("¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
6919 #else
6920         if (!save_player()) quit("panic save failed!");
6921 #endif
6922
6923
6924         /* Successful panic save */
6925 #ifdef JP
6926 quit("¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
6927 #else
6928         quit("panic save succeeded!");
6929 #endif
6930
6931 }
6932
6933
6934 /*
6935  * Get a random line from a file
6936  * Based on the monster speech patch by Matt Graham,
6937  */
6938 errr get_rnd_line(cptr file_name, int entry, char *output)
6939 {
6940         FILE    *fp;
6941         char    buf[1024];
6942         int     line, counter, test, numentries;
6943         int     line_num = 0;
6944         bool    found = FALSE;
6945
6946
6947         /* Build the filename */
6948         path_build(buf, 1024, ANGBAND_DIR_FILE, file_name);
6949
6950         /* Open the file */
6951         fp = my_fopen(buf, "r");
6952
6953         /* Failed */
6954         if (!fp) return (-1);
6955
6956         /* Find the entry of the monster */
6957         while (TRUE)
6958         {
6959                 /* Get a line from the file */
6960                 if (my_fgets(fp, buf, 1024) == 0)
6961                 {
6962                         /* Count the lines */
6963                         line_num++;
6964
6965                         /* Look for lines starting with 'N:' */
6966                         if ((buf[0] == 'N') && (buf[1] == ':'))
6967                         {
6968                                 /* Allow default lines */
6969                                 if (buf[2] == '*')
6970                                 {
6971                                         /* Default lines */
6972                                         found = TRUE;
6973                                         break;
6974                                 }
6975                                 else if (buf[2] == 'M')
6976                                 {
6977                                         if (r_info[entry].flags1 & RF1_MALE)
6978                                         {
6979                                                 found = TRUE;
6980                                                 break;
6981                                         }
6982                                 }
6983                                 else if (buf[2] == 'F')
6984                                 {
6985                                         if (r_info[entry].flags1 & RF1_FEMALE)
6986                                         {
6987                                                 found = TRUE;
6988                                                 break;
6989                                         }
6990                                 }
6991                                 /* Get the monster number */
6992                                 else if (sscanf(&(buf[2]), "%d", &test) != EOF)
6993                                 {
6994                                         /* Is it the right monster? */
6995                                         if (test == entry)
6996                                         {
6997                                                 found = TRUE;
6998                                                 break;
6999                                         }
7000                                 }
7001                                 else
7002                                 {
7003                                         /* Error while converting the monster number */
7004                                         msg_format("Error in line %d of %s!",
7005                                                   line_num, file_name);
7006                                         my_fclose(fp);
7007                                         return (-1);
7008                                 }
7009                         }
7010                 }
7011                 else
7012                 {
7013                         /* Reached end of file */
7014                         my_fclose(fp);
7015                         return (-1);
7016                 }
7017
7018         }
7019         
7020         /* Get the number of entries */
7021         while (TRUE)
7022         {
7023                 /* Get the line */
7024                 if (my_fgets(fp, buf, 1024) == 0)
7025                 {
7026                         /* Count the lines */
7027                         line_num++;
7028
7029                         /* Look for the number of entries */
7030                         if (isdigit(buf[0]))
7031                         {
7032                                 /* Get the number of entries */
7033                                 numentries = atoi(buf);
7034                                 break;
7035                         }
7036                 }
7037                 else
7038                 {
7039                         /* Count the lines */
7040                         line_num++;
7041
7042                         /* Reached end of file without finding the number */
7043                         msg_format("Error in line %d of %s!",
7044                                   line_num, file_name);
7045
7046                         my_fclose(fp);
7047                         return (-1);
7048                 }
7049         }
7050
7051         if (numentries > 0)
7052         {
7053                 /* Grab an appropriate line number */
7054                 line = randint0(numentries);
7055
7056                 /* Get the random line */
7057                 for (counter = 0; counter <= line; counter++)
7058                 {
7059                         /* Count the lines */
7060                         line_num++;
7061
7062                         while(TRUE)
7063                         {
7064                                 test = my_fgets(fp, buf, 1024);
7065                                 if(test || buf[0] != '#')
7066                                         break;
7067                         }
7068
7069                         if (test==0)
7070                         {
7071                                 /* Found the line */
7072                                 if (counter == line) break;
7073                         }
7074                         else
7075                         {
7076                                 /* Error - End of file */
7077                                 msg_format("Error in line %d of %s!",
7078                                           line_num, file_name);
7079
7080                                 my_fclose(fp);
7081                                 return (-1);
7082                         }
7083                 }
7084
7085                 /* Copy the line */
7086                 strcpy(output, buf);
7087         }
7088         else
7089         {
7090                 return (-1);
7091         }
7092
7093         /* Close the file */
7094         my_fclose(fp);
7095
7096         /* Success */
7097         return (0);
7098 }
7099
7100
7101 #ifdef JP
7102 errr get_rnd_line_jonly(cptr file_name, int entry, char *output, int count)
7103 {
7104   int i,j,kanji;
7105   errr result=1;
7106   for (i=0;i<count;i++){
7107     result=get_rnd_line(file_name, entry, output);
7108     if(result)break;
7109     kanji=0;
7110     for(j=0; output[j]; j++) kanji |= iskanji(output[j]);
7111     if(kanji)break;
7112   }
7113   return(result);
7114 }
7115 #endif
7116
7117 /*
7118  * Process file for auto picker/destroyer.
7119  */
7120 errr process_pickpref_file(cptr name)
7121 {
7122         char buf[1024];
7123
7124         errr err = 0;
7125
7126         /* Drop priv's */
7127         safe_setuid_drop();
7128
7129         /* Build the filename */
7130         path_build(buf, 1024, ANGBAND_DIR_USER, name);
7131
7132         err = process_pref_file_aux(buf, TRUE);
7133
7134         /* Grab priv's */
7135         safe_setuid_grab();
7136
7137         /* Result */
7138         return (err);
7139 }
7140
7141 static errr counts_seek(int fd, u32b where, bool flag)
7142 {
7143         huge seekpoint;
7144         char temp1[128], temp2[128];
7145         u32b zero_header[3] = {0L, 0L, 0L};
7146         int i;
7147
7148 #ifdef SAVEFILE_USE_UID
7149         (void)sprintf(temp1, "%d.%s.%d%d%d", player_uid, savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7150 #else
7151         (void)sprintf(temp1, "%s.%d%d%d", savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7152 #endif
7153         for (i = 0; temp1[i]; i++)
7154                 temp1[i] ^= (i+1) * 63;
7155
7156         seekpoint = 0;
7157         while (1)
7158         {
7159                 if (fd_seek(fd, seekpoint + 3 * sizeof(u32b)))
7160                         return 1;
7161                 if (fd_read(fd, (char*)(temp2), sizeof(temp2)))
7162                 {
7163                         if (!flag)
7164                                 return 1;
7165                         /* add new name */
7166                         fd_seek(fd, seekpoint);
7167                         fd_write(fd, (char*)zero_header, 3*sizeof(u32b));
7168                         fd_write(fd, (char*)(temp1), sizeof(temp1));
7169                         break;
7170                 }
7171
7172                 if (strcmp(temp1, temp2) == 0)
7173                         break;
7174
7175                 seekpoint += 128 + 3 * sizeof(u32b);
7176         }
7177
7178         return fd_seek(fd, seekpoint + where * sizeof(u32b));
7179 }
7180
7181 u32b counts_read(int where)
7182 {
7183         int fd;
7184         u32b count = 0;
7185         char buf[1024];
7186
7187 #ifdef JP
7188         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7189 #else
7190         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7191 #endif
7192         fd = fd_open(buf, O_RDONLY);
7193
7194         if (counts_seek(fd, where, FALSE) ||
7195             fd_read(fd, (char*)(&count), sizeof(u32b)))
7196                 count = 0;
7197
7198         (void)fd_close(fd);
7199
7200         return count;
7201 }
7202
7203 errr counts_write(int where, u32b count)
7204 {
7205         int fd;
7206         char buf[1024];
7207
7208 #ifdef JP
7209         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7210 #else
7211         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7212 #endif
7213         fd = fd_open(buf, O_RDWR);
7214         if (fd < 0)
7215         {
7216                 /* File type is "DATA" */
7217                 FILE_TYPE(FILE_TYPE_DATA);
7218
7219                 /* Create a new high score file */
7220                 fd = fd_make(buf, 0644);
7221         }
7222
7223         if (fd_lock(fd, F_WRLCK)) return 1;
7224
7225         counts_seek(fd, where, TRUE);
7226         fd_write(fd, (char*)(&count), sizeof(u32b));
7227
7228         if (fd_lock(fd, F_UNLCK)) return 1;
7229
7230         (void)fd_close(fd);
7231
7232         return 0;
7233 }
7234
7235
7236 #ifdef HANDLE_SIGNALS
7237
7238
7239 #include <signal.h>
7240
7241
7242 /*
7243  * Handle signals -- suspend
7244  *
7245  * Actually suspend the game, and then resume cleanly
7246  */
7247 static void handle_signal_suspend(int sig)
7248 {
7249         /* Disable handler */
7250         (void)signal(sig, SIG_IGN);
7251
7252 #ifdef SIGSTOP
7253
7254         /* Flush output */
7255         Term_fresh();
7256
7257         /* Suspend the "Term" */
7258         Term_xtra(TERM_XTRA_ALIVE, 0);
7259
7260         /* Suspend ourself */
7261         (void)kill(0, SIGSTOP);
7262
7263         /* Resume the "Term" */
7264         Term_xtra(TERM_XTRA_ALIVE, 1);
7265
7266         /* Redraw the term */
7267         Term_redraw();
7268
7269         /* Flush the term */
7270         Term_fresh();
7271
7272 #endif
7273
7274         /* Restore handler */
7275         (void)signal(sig, handle_signal_suspend);
7276 }
7277
7278
7279 /*
7280  * Handle signals -- simple (interrupt and quit)
7281  *
7282  * This function was causing a *huge* number of problems, so it has
7283  * been simplified greatly.  We keep a global variable which counts
7284  * the number of times the user attempts to kill the process, and
7285  * we commit suicide if the user does this a certain number of times.
7286  *
7287  * We attempt to give "feedback" to the user as he approaches the
7288  * suicide thresh-hold, but without penalizing accidental keypresses.
7289  *
7290  * To prevent messy accidents, we should reset this global variable
7291  * whenever the user enters a keypress, or something like that.
7292  */
7293 static void handle_signal_simple(int sig)
7294 {
7295         /* Disable handler */
7296         (void)signal(sig, SIG_IGN);
7297
7298
7299         /* Nothing to save, just quit */
7300         if (!character_generated || character_saved) quit(NULL);
7301
7302
7303         /* Count the signals */
7304         signal_count++;
7305
7306
7307         /* Terminate dead characters */
7308         if (death)
7309         {
7310                 /* Mark the savefile */
7311 #ifdef JP
7312 (void)strcpy(died_from, "¶¯À©½ªÎ»");
7313 #else
7314                 (void)strcpy(died_from, "Abortion");
7315 #endif
7316
7317                 forget_lite();
7318                 forget_view();
7319                 clear_mon_lite();
7320
7321                 /* Close stuff */
7322                 close_game();
7323
7324                 /* Quit */
7325 #ifdef JP
7326 quit("¶¯À©½ªÎ»");
7327 #else
7328                 quit("interrupt");
7329 #endif
7330
7331         }
7332
7333         /* Allow suicide (after 5) */
7334         else if (signal_count >= 5)
7335         {
7336                 /* Cause of "death" */
7337 #ifdef JP
7338 (void)strcpy(died_from, "¶¯À©½ªÎ»Ãæ");
7339 #else
7340                 (void)strcpy(died_from, "Interrupting");
7341 #endif
7342
7343
7344                 forget_lite();
7345                 forget_view();
7346                 clear_mon_lite();
7347
7348                 /* Stop playing */
7349                 alive = FALSE;
7350
7351                 /* Suicide */
7352                 death = TRUE;
7353
7354                 /* Leaving */
7355                 p_ptr->leaving = TRUE;
7356
7357                 /* Close stuff */
7358                 close_game();
7359
7360                 /* Quit */
7361 #ifdef JP
7362 quit("¶¯À©½ªÎ»");
7363 #else
7364                 quit("interrupt");
7365 #endif
7366
7367         }
7368
7369         /* Give warning (after 4) */
7370         else if (signal_count >= 4)
7371         {
7372                 /* Make a noise */
7373                 Term_xtra(TERM_XTRA_NOISE, 0);
7374
7375                 /* Clear the top line */
7376                 Term_erase(0, 0, 255);
7377
7378                 /* Display the cause */
7379 #ifdef JP
7380 Term_putstr(0, 0, -1, TERM_WHITE, "½Ïθ¤Î¾å¤Î¼«»¦¡ª");
7381 #else
7382                 Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");
7383 #endif
7384
7385
7386                 /* Flush */
7387                 Term_fresh();
7388         }
7389
7390         /* Give warning (after 2) */
7391         else if (signal_count >= 2)
7392         {
7393                 /* Make a noise */
7394                 Term_xtra(TERM_XTRA_NOISE, 0);
7395         }
7396
7397         /* Restore handler */
7398         (void)signal(sig, handle_signal_simple);
7399 }
7400
7401
7402 /*
7403  * Handle signal -- abort, kill, etc
7404  */
7405 static void handle_signal_abort(int sig)
7406 {
7407         int wid, hgt, rows;
7408
7409         Term_get_size(&wid, &hgt);
7410         rows = hgt - 4;
7411
7412         /* Disable handler */
7413         (void)signal(sig, SIG_IGN);
7414
7415
7416         /* Nothing to save, just quit */
7417         if (!character_generated || character_saved) quit(NULL);
7418
7419
7420         forget_lite();
7421         forget_view();
7422         clear_mon_lite();
7423
7424         /* Clear the bottom line */
7425         Term_erase(0, hgt - 1, 255);
7426
7427         /* Give a warning */
7428         Term_putstr(0, hgt - 1, -1, TERM_RED,
7429 #ifdef JP
7430 "¶²¤í¤·¤¤¥½¥Õ¥È¤Î¥Ð¥°¤¬Èô¤Ó¤«¤«¤Ã¤Æ¤­¤¿¡ª");
7431 #else
7432                     "A gruesome software bug LEAPS out at you!");
7433 #endif
7434
7435
7436         /* Message */
7437 #ifdef JP
7438 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö...");
7439 #else
7440         Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save...");
7441 #endif
7442
7443
7444         /* Flush output */
7445         Term_fresh();
7446
7447         /* Panic Save */
7448         panic_save = 1;
7449
7450         /* Panic save */
7451 #ifdef JP
7452 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
7453 #else
7454         (void)strcpy(died_from, "(panic save)");
7455 #endif
7456
7457
7458         /* Forbid suspend */
7459         signals_ignore_tstp();
7460
7461         /* Attempt to save */
7462         if (save_player())
7463         {
7464 #ifdef JP
7465 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
7466 #else
7467                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save succeeded!");
7468 #endif
7469
7470         }
7471
7472         /* Save failed */
7473         else
7474         {
7475 #ifdef JP
7476 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
7477 #else
7478                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save failed!");
7479 #endif
7480
7481         }
7482
7483         /* Flush output */
7484         Term_fresh();
7485
7486         /* Quit */
7487 #ifdef JP
7488 quit("¥½¥Õ¥È¤Î¥Ð¥°");
7489 #else
7490         quit("software bug");
7491 #endif
7492
7493 }
7494
7495
7496
7497
7498 /*
7499  * Ignore SIGTSTP signals (keyboard suspend)
7500  */
7501 void signals_ignore_tstp(void)
7502 {
7503
7504 #ifdef SIGTSTP
7505         (void)signal(SIGTSTP, SIG_IGN);
7506 #endif
7507
7508 }
7509
7510 /*
7511  * Handle SIGTSTP signals (keyboard suspend)
7512  */
7513 void signals_handle_tstp(void)
7514 {
7515
7516 #ifdef SIGTSTP
7517         (void)signal(SIGTSTP, handle_signal_suspend);
7518 #endif
7519
7520 }
7521
7522
7523 /*
7524  * Prepare to handle the relevant signals
7525  */
7526 void signals_init(void)
7527 {
7528
7529 #ifdef SIGHUP
7530         (void)signal(SIGHUP, SIG_IGN);
7531 #endif
7532
7533
7534 #ifdef SIGTSTP
7535         (void)signal(SIGTSTP, handle_signal_suspend);
7536 #endif
7537
7538
7539 #ifdef SIGINT
7540         (void)signal(SIGINT, handle_signal_simple);
7541 #endif
7542
7543 #ifdef SIGQUIT
7544         (void)signal(SIGQUIT, handle_signal_simple);
7545 #endif
7546
7547
7548 #ifdef SIGFPE
7549         (void)signal(SIGFPE, handle_signal_abort);
7550 #endif
7551
7552 #ifdef SIGILL
7553         (void)signal(SIGILL, handle_signal_abort);
7554 #endif
7555
7556 #ifdef SIGTRAP
7557         (void)signal(SIGTRAP, handle_signal_abort);
7558 #endif
7559
7560 #ifdef SIGIOT
7561         (void)signal(SIGIOT, handle_signal_abort);
7562 #endif
7563
7564 #ifdef SIGKILL
7565         (void)signal(SIGKILL, handle_signal_abort);
7566 #endif
7567
7568 #ifdef SIGBUS
7569         (void)signal(SIGBUS, handle_signal_abort);
7570 #endif
7571
7572 #ifdef SIGSEGV
7573         (void)signal(SIGSEGV, handle_signal_abort);
7574 #endif
7575
7576 #ifdef SIGTERM
7577         (void)signal(SIGTERM, handle_signal_abort);
7578 #endif
7579
7580 #ifdef SIGPIPE
7581         (void)signal(SIGPIPE, handle_signal_abort);
7582 #endif
7583
7584 #ifdef SIGEMT
7585         (void)signal(SIGEMT, handle_signal_abort);
7586 #endif
7587
7588 #ifdef SIGDANGER
7589         (void)signal(SIGDANGER, handle_signal_abort);
7590 #endif
7591
7592 #ifdef SIGSYS
7593         (void)signal(SIGSYS, handle_signal_abort);
7594 #endif
7595
7596 #ifdef SIGXCPU
7597         (void)signal(SIGXCPU, handle_signal_abort);
7598 #endif
7599
7600 #ifdef SIGPWR
7601         (void)signal(SIGPWR, handle_signal_abort);
7602 #endif
7603
7604 }
7605
7606
7607 #else   /* HANDLE_SIGNALS */
7608
7609
7610 /*
7611  * Do nothing
7612  */
7613 void signals_ignore_tstp(void)
7614 {
7615 }
7616
7617 /*
7618  * Do nothing
7619  */
7620 void signals_handle_tstp(void)
7621 {
7622 }
7623
7624 /*
7625  * Do nothing
7626  */
7627 void signals_init(void)
7628 {
7629 }
7630 #endif  /* HANDLE_SIGNALS */