OSDN Git Service

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