OSDN Git Service

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