OSDN Git Service

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