OSDN Git Service

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