OSDN Git Service

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