OSDN Git Service

ヌヒシル、ホ・ミ・ース、タオ&タクフソ、キ・ミ。シ・ク・逾ヒ。」
[hengband/hengband.git] / src / files.c
1 /* File: files.c */
2
3 /* Purpose: code dealing with files (and death) */
4
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12
13 #include "angband.h"
14
15
16 /*
17  * You may or may not want to use the following "#undef".
18  */
19 /* #undef _POSIX_SAVED_IDS */
20
21
22 /*
23  * Hack -- drop permissions
24  */
25 void safe_setuid_drop(void)
26 {
27
28 #ifdef SET_UID
29
30 # ifdef SAFE_SETUID
31
32 #  ifdef SAFE_SETUID_POSIX
33
34         if (setuid(getuid()) != 0)
35         {
36 #ifdef JP
37 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
38 #else
39                 quit("setuid(): cannot set permissions correctly!");
40 #endif
41
42         }
43         if (setgid(getgid()) != 0)
44         {
45 #ifdef JP
46 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
47 #else
48                 quit("setgid(): cannot set permissions correctly!");
49 #endif
50
51         }
52
53 #  else
54
55         if (setreuid(geteuid(), getuid()) != 0)
56         {
57 #ifdef JP
58 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
59 #else
60                 quit("setreuid(): cannot set permissions correctly!");
61 #endif
62
63         }
64         if (setregid(getegid(), getgid()) != 0)
65         {
66 #ifdef JP
67 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
68 #else
69                 quit("setregid(): cannot set permissions correctly!");
70 #endif
71
72         }
73
74 #  endif
75
76 # endif
77
78 #endif
79
80 }
81
82
83 /*
84  * Hack -- grab permissions
85  */
86 void safe_setuid_grab(void)
87 {
88
89 #ifdef SET_UID
90
91 # ifdef SAFE_SETUID
92
93 #  ifdef SAFE_SETUID_POSIX
94
95         if (setuid(player_euid) != 0)
96         {
97 #ifdef JP
98 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
99 #else
100                 quit("setuid(): cannot set permissions correctly!");
101 #endif
102
103         }
104         if (setgid(player_egid) != 0)
105         {
106 #ifdef JP
107 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
108 #else
109                 quit("setgid(): cannot set permissions correctly!");
110 #endif
111
112         }
113
114 #  else
115
116         if (setreuid(geteuid(), getuid()) != 0)
117         {
118 #ifdef JP
119 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
120 #else
121                 quit("setreuid(): cannot set permissions correctly!");
122 #endif
123
124         }
125         if (setregid(getegid(), getgid()) != 0)
126         {
127 #ifdef JP
128 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
129 #else
130                 quit("setregid(): cannot set permissions correctly!");
131 #endif
132
133         }
134
135 #  endif /* SAFE_SETUID_POSIX */
136
137 # endif /* SAFE_SETUID */
138
139 #endif /* SET_UID */
140
141 }
142
143
144 /*
145  * Extract the first few "tokens" from a buffer
146  *
147  * This function uses "colon" and "slash" as the delimeter characters.
148  *
149  * We never extract more than "num" tokens.  The "last" token may include
150  * "delimeter" characters, allowing the buffer to include a "string" token.
151  *
152  * We save pointers to the tokens in "tokens", and return the number found.
153  *
154  * Hack -- Attempt to handle the 'c' character formalism
155  *
156  * Hack -- An empty buffer, or a final delimeter, yields an "empty" token.
157  *
158  * Hack -- We will always extract at least one token
159  */
160 s16b tokenize(char *buf, s16b num, char **tokens, int mode)
161 {
162         int i = 0;
163
164         char *s = buf;
165
166
167         /* Process */
168         while (i < num - 1)
169         {
170                 char *t;
171
172                 /* Scan the string */
173                 for (t = s; *t; t++)
174                 {
175                         /* Found a delimiter */
176                         if ((*t == ':') || (*t == '/')) break;
177
178                         /* Handle single quotes */
179                         if ((mode & TOKENIZE_CHECKQUOTE) && (*t == '\''))
180                         {
181                                 /* Advance */
182                                 t++;
183
184                                 /* Handle backslash */
185                                 if (*t == '\\') t++;
186
187                                 /* Require a character */
188                                 if (!*t) break;
189
190                                 /* Advance */
191                                 t++;
192
193                                 /* Hack -- Require a close quote */
194                                 if (*t != '\'') *t = '\'';
195                         }
196
197                         /* Handle back-slash */
198                         if (*t == '\\') t++;
199                 }
200
201                 /* Nothing left */
202                 if (!*t) break;
203
204                 /* Nuke and advance */
205                 *t++ = '\0';
206
207                 /* Save the token */
208                 tokens[i++] = s;
209
210                 /* Advance */
211                 s = t;
212         }
213
214         /* Save the token */
215         tokens[i++] = s;
216
217         /* Number found */
218         return (i);
219 }
220
221
222 /* A number with a name */
223 typedef struct named_num named_num;
224
225 struct named_num
226 {
227         cptr name;              /* The name of this thing */
228         int num;                        /* A number associated with it */
229 };
230
231
232 /* Index of spell type names */
233 static named_num gf_desc[] =
234 {
235         {"GF_ELEC",                             GF_ELEC                         },
236         {"GF_POIS",                             GF_POIS                         },
237         {"GF_ACID",                             GF_ACID                         },
238         {"GF_COLD",                             GF_COLD                         },
239         {"GF_FIRE",                                     GF_FIRE                         },
240         {"GF_PSY_SPEAR",                        GF_PSY_SPEAR                    },
241         {"GF_MISSILE",                          GF_MISSILE                      },
242         {"GF_ARROW",                            GF_ARROW                                },
243         {"GF_PLASMA",                           GF_PLASMA                       },
244         {"GF_WATER",                            GF_WATER                                },
245         {"GF_LITE",                                     GF_LITE                         },
246         {"GF_DARK",                                     GF_DARK                         },
247         {"GF_LITE_WEAK",                        GF_LITE_WEAK            },
248         {"GF_DARK_WEAK",                        GF_DARK_WEAK            },
249         {"GF_SHARDS",                           GF_SHARDS                       },
250         {"GF_SOUND",                            GF_SOUND                                },
251         {"GF_CONFUSION",                        GF_CONFUSION            },
252         {"GF_FORCE",                            GF_FORCE                                },
253         {"GF_INERTIA",                          GF_INERTIA                      },
254         {"GF_MANA",                                     GF_MANA                         },
255         {"GF_METEOR",                           GF_METEOR                       },
256         {"GF_ICE",                                      GF_ICE                          },
257         {"GF_CHAOS",                            GF_CHAOS                                },
258         {"GF_NETHER",                           GF_NETHER                       },
259         {"GF_DISENCHANT",                       GF_DISENCHANT           },
260         {"GF_NEXUS",                            GF_NEXUS                                },
261         {"GF_TIME",                                     GF_TIME                         },
262         {"GF_GRAVITY",                          GF_GRAVITY                      },
263         {"GF_KILL_WALL",                        GF_KILL_WALL            },
264         {"GF_KILL_DOOR",                        GF_KILL_DOOR            },
265         {"GF_KILL_TRAP",                        GF_KILL_TRAP            },
266         {"GF_MAKE_WALL",                        GF_MAKE_WALL            },
267         {"GF_MAKE_DOOR",                        GF_MAKE_DOOR            },
268         {"GF_MAKE_TRAP",                        GF_MAKE_TRAP            },
269         {"GF_MAKE_TREE",                        GF_MAKE_TREE            },
270         {"GF_OLD_CLONE",                        GF_OLD_CLONE            },
271         {"GF_OLD_POLY",                 GF_OLD_POLY                     },
272         {"GF_OLD_HEAL",                 GF_OLD_HEAL                     },
273         {"GF_OLD_SPEED",                        GF_OLD_SPEED            },
274         {"GF_OLD_SLOW",                 GF_OLD_SLOW                     },
275         {"GF_OLD_CONF",                 GF_OLD_CONF                     },
276         {"GF_OLD_SLEEP",                        GF_OLD_SLEEP            },
277         {"GF_OLD_DRAIN",                        GF_OLD_DRAIN            },
278         {"GF_AWAY_UNDEAD",              GF_AWAY_UNDEAD          },
279         {"GF_AWAY_EVIL",                        GF_AWAY_EVIL            },
280         {"GF_AWAY_ALL",                 GF_AWAY_ALL                     },
281         {"GF_TURN_UNDEAD",              GF_TURN_UNDEAD          },
282         {"GF_TURN_EVIL",                        GF_TURN_EVIL            },
283         {"GF_TURN_ALL",                 GF_TURN_ALL                     },
284         {"GF_DISP_UNDEAD",              GF_DISP_UNDEAD          },
285         {"GF_DISP_EVIL",                        GF_DISP_EVIL            },
286         {"GF_DISP_ALL",                 GF_DISP_ALL                     },
287         {"GF_DISP_DEMON",                       GF_DISP_DEMON           },
288         {"GF_DISP_LIVING",              GF_DISP_LIVING          },
289         {"GF_ROCKET",                           GF_ROCKET                       },
290         {"GF_NUKE",                                     GF_NUKE                         },
291         {"GF_MAKE_GLYPH",                       GF_MAKE_GLYPH           },
292         {"GF_STASIS",                           GF_STASIS                       },
293         {"GF_STONE_WALL",                       GF_STONE_WALL           },
294         {"GF_DEATH_RAY",                        GF_DEATH_RAY            },
295         {"GF_STUN",                                     GF_STUN                         },
296         {"GF_HOLY_FIRE",                        GF_HOLY_FIRE            },
297         {"GF_HELL_FIRE",                        GF_HELL_FIRE            },
298         {"GF_DISINTEGRATE",             GF_DISINTEGRATE },
299         {"GF_CHARM",                            GF_CHARM                                },
300         {"GF_CONTROL_UNDEAD",   GF_CONTROL_UNDEAD       },
301         {"GF_CONTROL_ANIMAL",   GF_CONTROL_ANIMAL       },
302         {"GF_PSI",                                      GF_PSI                          },
303         {"GF_PSI_DRAIN",                        GF_PSI_DRAIN            },
304         {"GF_TELEKINESIS",              GF_TELEKINESIS          },
305         {"GF_JAM_DOOR",                 GF_JAM_DOOR                     },
306         {"GF_DOMINATION",                       GF_DOMINATION           },
307         {"GF_DISP_GOOD",                        GF_DISP_GOOD            },
308         {"GF_DRAIN_MANA",                       GF_DRAIN_MANA           },
309         {"GF_MIND_BLAST",                       GF_MIND_BLAST           },
310         {"GF_BRAIN_SMASH",                      GF_BRAIN_SMASH          },
311         {"GF_CAUSE_1",                  GF_CAUSE_1              },
312         {"GF_CAUSE_2",                  GF_CAUSE_2              },
313         {"GF_CAUSE_3",                  GF_CAUSE_3              },
314         {"GF_CAUSE_4",                  GF_CAUSE_4              },
315         {"GF_HAND_DOOM",                        GF_HAND_DOOM            },
316         {"GF_CAPTURE",                  GF_CAPTURE              },
317         {"GF_ANIM_DEAD",                        GF_ANIM_DEAD            },
318         {"GF_CONTROL_LIVING",           GF_CONTROL_LIVING       },
319         {"GF_IDENTIFY",                 GF_IDENTIFY     },
320         {"GF_ATTACK",                   GF_ATTACK       },
321         {"GF_ENGETSU",                  GF_ENGETSU      },
322         {"GF_GENOCIDE",                 GF_GENOCIDE     },
323         {"GF_PHOTO",                    GF_PHOTO        },
324         {"GF_CONTROL_DEMON",    GF_CONTROL_DEMON        },
325         {"GF_LAVA_FLOW",        GF_LAVA_FLOW    },
326         {"GF_BLOOD_CURSE",      GF_BLOOD_CURSE  },
327         {"GF_SEEKER",                   GF_SEEKER                       },
328         {"GF_SUPER_RAY",                GF_SUPER_RAY                    },
329         {"GF_STAR_HEAL",                GF_STAR_HEAL                    },
330         {"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, char *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 #ifdef JP
4106                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¡¢¥¯¥¨¥¹¥È¡Ö%s¡×¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", quest[p_ptr->inside_quest].name, died_from);
4107 #else
4108                                                 sprintf(statmsg, "...You were killed by %s in the quest '%s'.", died_from, quest[p_ptr->inside_quest].name);
4109 #endif
4110                                         }
4111                                         else
4112                                         {                                       
4113 #ifdef JP
4114                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¡¢%s¤Î%d³¬¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", map_name(), dun_level, died_from);
4115 #else
4116                                                 sprintf(statmsg, "...You were killed by %s on level %d of %s.", died_from, dun_level, map_name());
4117 #endif
4118                                         }
4119                                 }
4120                                 else
4121 #ifdef JP
4122                                         sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï%s¤Ç%s¤Ë»¦¤µ¤ì¤¿¡£", map_name(), died_from);
4123 #else
4124                                         sprintf(statmsg, "...You were killed by %s in %s.", died_from, map_name());
4125 #endif
4126                         }
4127                         else if (character_dungeon)
4128                         {
4129                                 if (dun_level)
4130                                 {
4131                                         if (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST))
4132                                         {
4133 #ifdef JP
4134                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ ¥¯¥¨¥¹¥È¡Ö%s¡×¤ò¿ë¹ÔÃæ¤À¡£", quest[p_ptr->inside_quest].name);
4135 #else
4136                                                 sprintf(statmsg, "...Now, you are in the quest '%s'.", quest[p_ptr->inside_quest].name);
4137 #endif
4138                                         }                                                       
4139                                         else
4140                                         {
4141 #ifdef JP
4142                                                 sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Î %d ³¬¤Çõº÷¤·¤Æ¤¤¤ë¡£", map_name(), dun_level);
4143 #else
4144                                                 sprintf(statmsg, "...Now, you are exploring level %d of %s.", dun_level, map_name());
4145 #endif
4146                                         }
4147                                 }
4148                                 else
4149 #ifdef JP
4150                                         sprintf(statmsg, "¡Ä¤¢¤Ê¤¿¤Ï¸½ºß¡¢ %s ¤Ë¤¤¤ë¡£", map_name());
4151 #else
4152                                         sprintf(statmsg, "...Now, you are in %s.", map_name());
4153 #endif
4154                         }
4155
4156                         if (*statmsg)
4157                         {
4158                                 char temp[64*2], *t;
4159                                 roff_to_buf(statmsg, 60, temp);
4160                                 t = temp;
4161                                 for(i=0 ; i<2 ; i++)
4162                                 {
4163                                         if(t[0]==0)
4164                                                 break; 
4165                                         else
4166                                         {
4167                                                 put_str(t, i + 5 + 12, 10);
4168                                                 t += strlen(t)+1;
4169                                         }
4170                                 }
4171                         }
4172
4173                 }
4174
4175                 /* Display "various" info */
4176                 else
4177                 {
4178                         display_player_middle();
4179                         display_player_various();
4180                 }
4181         }
4182
4183         /* Special */
4184         else if (mode == 2)
4185         {
4186                 /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */
4187
4188                 /* Dump the info */
4189                 display_player_misc_info();
4190                 display_player_stat_info();
4191                 display_player_flag_info();
4192         }
4193
4194         /* Special */
4195         else if (mode == 3)
4196         {
4197                 display_player_ben();
4198         }
4199
4200         else if (mode == 6)
4201         {
4202                 do_cmd_knowledge_mutations();
4203         }
4204
4205         /* Special */
4206         else
4207         {
4208                 display_player_ben_one(mode % 2);
4209         }
4210 }
4211
4212 errr make_character_dump(FILE *fff)
4213 {
4214         int             i, x, y;
4215         byte            a;
4216         char            c;
4217         cptr            paren = ")";
4218         store_type  *st_ptr;
4219         char            o_name[MAX_NLEN];
4220         char            buf[1024];
4221
4222
4223 #ifndef FAKE_VERSION
4224         /* Begin dump */
4225         fprintf(fff, "  [Angband %d.%d.%d Character Dump]\n\n",
4226                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
4227 #else
4228 #ifdef JP
4229         fprintf(fff, "  [ÊѶòÈÚÅÜ %d.%d.%d ¥­¥ã¥é¥¯¥¿¾ðÊó]\n\n",
4230                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4231 #else
4232         fprintf(fff, "  [Hengband %d.%d.%d Character Dump]\n\n",
4233                 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4234 #endif
4235
4236 #endif
4237
4238         update_playtime();
4239
4240         /* Display player */
4241         display_player(0);
4242
4243         /* Dump part of the screen */
4244         for (y = 1; y < 22; y++)
4245         {
4246                 /* Dump each row */
4247                 for (x = 0; x < 79; x++)
4248                 {
4249                         /* Get the attr/char */
4250                         (void)(Term_what(x, y, &a, &c));
4251
4252                         /* Dump it */
4253                         buf[x] = c;
4254                 }
4255
4256                 /* End the string */
4257                 buf[x] = '\0';
4258
4259                 /* Kill trailing spaces */
4260                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4261
4262                 /* End the row */
4263 #ifdef JP
4264                         fprintf(fff, "%s\n", buf);
4265 #else
4266                 fprintf(fff, "%s\n", buf);
4267 #endif
4268
4269         }
4270
4271         /* Display history */
4272         display_player(1);
4273
4274         /* Dump part of the screen */
4275         for (y = 10; y < 19; y++)
4276         {
4277                 /* Dump each row */
4278                 for (x = 0; x < 79; x++)
4279                 {
4280                         /* Get the attr/char */
4281                         (void)(Term_what(x, y, &a, &c));
4282
4283                         /* Dump it */
4284                         buf[x] = c;
4285                 }
4286
4287                 /* End the string */
4288                 buf[x] = '\0';
4289
4290                 /* Kill trailing spaces */
4291                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4292
4293                 /* End the row */
4294                 fprintf(fff, "%s\n", buf);
4295         }
4296
4297         fprintf(fff, "\n");
4298         /* Display history */
4299         display_player(2);
4300
4301         /* Dump part of the screen */
4302         for (y = 2; y < 22; y++)
4303         {
4304                 /* Dump each row */
4305                 for (x = 0; x < 79; x++)
4306                 {
4307                         /* Get the attr/char */
4308                         (void)(Term_what(x, y, &a, &c));
4309
4310                         /* Dump it (Ignore equippy tile graphic) */
4311                         if (a < 128)
4312                                 buf[x] = c;
4313                         else
4314                                 buf[x] = ' ';
4315                 }
4316
4317                 /* End the string */
4318                 buf[x] = '\0';
4319
4320                 /* Kill trailing spaces */
4321                 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4322
4323                 /* End the row */
4324                 fprintf(fff, "%s\n", buf);
4325         }
4326
4327         for (i = 0; (unsigned int) i < (p_ptr->count / 80); i++)
4328                 fprintf(fff, " ");
4329         fprintf(fff, "\n");
4330         for (i = 0; (unsigned int) i < (p_ptr->count % 80); i++)
4331                 fprintf(fff, " ");
4332
4333         {
4334                 bool pet = FALSE;
4335
4336                 for (i = m_max - 1; i >= 1; i--)
4337                 {
4338                         monster_type *m_ptr = &m_list[i];
4339                         char pet_name[80];
4340
4341                         if (!m_ptr->r_idx) continue;
4342                         if (!is_pet(m_ptr)) continue;
4343                         if (!m_ptr->nickname && (p_ptr->riding != i)) continue;
4344                         if (!pet)
4345                         {
4346 #ifdef JP
4347                                 fprintf(fff, "\n  [¼ç¤Ê¥Ú¥Ã¥È]\n\n");
4348 #else
4349                                 fprintf(fff, "\n  [leading pets]\n\n");
4350 #endif
4351                                 pet = TRUE;
4352                         }
4353                         monster_desc(pet_name, m_ptr, 0x88);
4354                         fprintf(fff, "%s", pet_name);
4355                         if (p_ptr->riding == i)
4356 #ifdef JP
4357                                 fprintf(fff, " ¾èÇÏÃæ");
4358 #else
4359                                 fprintf(fff, " (riding)");
4360 #endif
4361                         fprintf(fff, "\n");
4362                 }
4363                 if (pet) fprintf(fff, "\n");
4364         }
4365
4366         if (death && !total_winner)
4367         {
4368 #ifdef JP
4369                 fprintf(fff, "\n  [»à¤ÌľÁ°¤Î¥á¥Ã¥»¡¼¥¸]\n\n");
4370 #else
4371                 fprintf(fff, "\n  [Last messages]\n\n");
4372 #endif
4373                 for (i = MIN(message_num(), 30); i >= 0; i--)
4374                 {
4375                         fprintf(fff,"> %s\n",message_str((s16b)i));
4376                 }
4377                 fprintf(fff, "\n");
4378         }
4379
4380 #ifdef JP
4381         fprintf(fff, "\n  [¤½¤Î¾¤Î¾ðÊó]        \n");
4382 #else
4383         fprintf(fff, "\n  [Miscellaneous information]\n");
4384 #endif
4385
4386 #ifdef JP
4387         fprintf(fff, "\n µ¢´Ô¾ì½ê:\n");
4388 #else
4389         fprintf(fff, "\n Recall Depth:\n");
4390 #endif
4391         for (y = 1; y < max_d_idx; y++)
4392         {
4393                 bool seiha = FALSE;
4394
4395                 if (!d_info[y].maxdepth) continue;
4396                 if (!max_dlv[y]) continue;
4397                 if (d_info[y].final_guardian)
4398                 {
4399                         if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
4400                 }
4401                 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
4402
4403 #ifdef JP
4404                 fprintf(fff, "   %c%-12s: %3d ³¬\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4405 #else
4406                 fprintf(fff, "   %c%-16s: level %3d\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4407 #endif
4408         }
4409
4410         if (preserve_mode)
4411 #ifdef JP
4412                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         ON");
4413 #else
4414                 fprintf(fff, "\n Preserve Mode:      ON");
4415 #endif
4416
4417         else
4418 #ifdef JP
4419                 fprintf(fff, "\n Êݸ¥â¡¼¥É:         OFF");
4420 #else
4421                 fprintf(fff, "\n Preserve Mode:      OFF");
4422 #endif
4423
4424
4425         if (ironman_autoscum)
4426 #ifdef JP
4427                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ALWAYS");
4428 #else
4429                 fprintf(fff, "\n Autoscum:           ALWAYS");
4430 #endif
4431
4432         else if (auto_scum)
4433 #ifdef JP
4434                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     ON");
4435 #else
4436                 fprintf(fff, "\n Autoscum:           ON");
4437 #endif
4438
4439         else
4440 #ifdef JP
4441                 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß  :     OFF");
4442 #else
4443                 fprintf(fff, "\n Autoscum:           OFF");
4444 #endif
4445
4446
4447         if (ironman_small_levels)
4448 #ifdef JP
4449                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ALWAYS");
4450 #else
4451                 fprintf(fff, "\n Small Levels:       ALWAYS");
4452 #endif
4453
4454         else if (always_small_levels)
4455 #ifdef JP
4456                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ON");
4457 #else
4458                 fprintf(fff, "\n Small Levels:       ON");
4459 #endif
4460
4461         else if (small_levels)
4462 #ifdef JP
4463                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   ENABLED");
4464 #else
4465                 fprintf(fff, "\n Small Levels:       ENABLED");
4466 #endif
4467
4468         else
4469 #ifdef JP
4470                 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó:   OFF");
4471 #else
4472                 fprintf(fff, "\n Small Levels:       OFF");
4473 #endif
4474
4475
4476         if (vanilla_town)
4477 #ifdef JP
4478                 fprintf(fff, "\n ¸µÁĤÎÄ®¤Î¤ß: ON");
4479 #else
4480                 fprintf(fff, "\n Vanilla Town:       ON");
4481 #endif
4482
4483         else if (lite_town)
4484 #ifdef JP
4485                 fprintf(fff, "\n ¾®µ¬ÌϤÊÄ®:         ON");
4486 #else
4487                 fprintf(fff, "\n Lite Town:          ON");
4488 #endif
4489
4490
4491         if (ironman_shops)
4492 #ifdef JP
4493                 fprintf(fff, "\n Å¹¤Ê¤·:             ON");
4494 #else
4495                 fprintf(fff, "\n No Shops:           ON");
4496 #endif
4497
4498
4499         if (ironman_downward)
4500 #ifdef JP
4501                 fprintf(fff, "\n ³¬Ãʤò¾å¤¬¤ì¤Ê¤¤:   ON");
4502 #else
4503                 fprintf(fff, "\n Diving only:        ON");
4504 #endif
4505
4506
4507         if (ironman_rooms)
4508 #ifdef JP
4509                 fprintf(fff, "\n ÉáÄ̤Ǥʤ¤Éô²°¤òÀ¸À®:         ON");
4510 #else
4511                 fprintf(fff, "\n Unusual rooms:      ON");
4512 #endif
4513
4514
4515         if (ironman_nightmare)
4516 #ifdef JP
4517                 fprintf(fff, "\n °­Ì´¥â¡¼¥É:         ON");
4518 #else
4519                 fprintf(fff, "\n Nightmare Mode:     ON");
4520 #endif
4521
4522
4523         if (ironman_empty_levels)
4524 #ifdef JP
4525                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ALWAYS");
4526 #else
4527                 fprintf(fff, "\n Arena Levels:       ALWAYS");
4528 #endif
4529
4530         else if (empty_levels)
4531 #ifdef JP
4532                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           ON");
4533 #else
4534                 fprintf(fff, "\n Arena Levels:       ENABLED");
4535 #endif
4536
4537         else
4538 #ifdef JP
4539                 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê:           OFF");
4540 #else
4541                 fprintf(fff, "\n Arena Levels:       OFF");
4542 #endif
4543
4544
4545 #ifdef JP
4546         fprintf(fff, "\n ¥é¥ó¥À¥à¥¯¥¨¥¹¥È¿ô: %d", number_of_quests());
4547 #else
4548         fprintf(fff, "\n Num. Random Quests: %d", number_of_quests());
4549 #endif
4550
4551         if (p_ptr->arena_number == 99)
4552         {
4553 #ifdef JP
4554                 fprintf(fff, "\n Æ®µ»¾ì: ÇÔËÌ\n");
4555 #else
4556                 fprintf(fff, "\n Arena: defeated\n");
4557 #endif
4558         }
4559         else if (p_ptr->arena_number > MAX_ARENA_MONS+2)
4560         {
4561 #ifdef JP
4562                 fprintf(fff, "\n Æ®µ»¾ì: ¿¿¤Î¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4563 #else
4564                 fprintf(fff, "\n Arena: True Champion\n");
4565 #endif
4566         }
4567         else if (p_ptr->arena_number > MAX_ARENA_MONS-1)
4568         {
4569 #ifdef JP
4570                 fprintf(fff, "\n Æ®µ»¾ì: ¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4571 #else
4572                 fprintf(fff, "\n Arena: Champion\n");
4573 #endif
4574         }
4575         else
4576         {
4577 #ifdef JP
4578                 fprintf(fff, "\n Æ®µ»¾ì:   %2d¾¡\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number));
4579 #else
4580                 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");
4581 #endif
4582         }
4583
4584         if (noscore)
4585 #ifdef JP
4586 fprintf(fff, "\n ²¿¤«ÉÔÀµ¤Ê¤³¤È¤ò¤·¤Æ¤·¤Þ¤Ã¤Æ¤Þ¤¹¡£");
4587 #else
4588                 fprintf(fff, "\n You have done something illegal.");
4589 #endif
4590
4591
4592         if (stupid_monsters)
4593 #ifdef JP
4594 fprintf(fff, "\n Å¨¤Ï¶ò¤«¤Ê¹ÔÆ°¤ò¼è¤ê¤Þ¤¹¡£");
4595 #else
4596                 fprintf(fff, "\n Your opponents are behaving stupidly.");
4597 #endif
4598
4599
4600         if (munchkin_death)
4601 #ifdef JP
4602 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï»à¤ò²óÈò¤¹¤ë¥¤¥ó¥Á¥­¤ÊÎϤò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£");
4603 #else
4604                 fprintf(fff, "\n You possess munchkinish power over death.");
4605 #endif
4606
4607         fprintf(fff,"\n");
4608
4609         /* Monsters slain */
4610         {
4611                 int k;
4612                 s32b Total = 0;
4613
4614                 for (k = 1; k < max_r_idx; k++)
4615                 {
4616                         monster_race *r_ptr = &r_info[k];
4617
4618                         if (r_ptr->flags1 & RF1_UNIQUE)
4619                         {
4620                                 bool dead = (r_ptr->max_num == 0);
4621                                 if (dead)
4622                                 {
4623                                         Total++;
4624                                 }
4625                         }
4626                         else
4627                         {
4628                                 s16b This = r_ptr->r_pkills;
4629                                 if (This > 0)
4630                                 {
4631                                         Total += This;
4632                                 }
4633                         }
4634                 }
4635
4636                 if (Total < 1)
4637 #ifdef JP
4638 fprintf(fff,"\n ¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Þ¤»¤ó¡£\n");
4639 #else
4640                         fprintf(fff,"\n You have defeated no enemies yet.\n");
4641 #endif
4642
4643                 else if (Total == 1)
4644 #ifdef JP
4645 fprintf(fff,"\n °ìÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n");
4646 #else
4647                         fprintf(fff,"\n You have defeated one enemy.\n");
4648 #endif
4649
4650                 else
4651 #ifdef JP
4652 fprintf(fff,"\n %lu ÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n", Total);
4653 #else
4654                         fprintf(fff,"\n You have defeated %lu enemies.\n", Total);
4655 #endif
4656
4657         }
4658
4659
4660         if (p_ptr->old_race1 || p_ptr->old_race2)
4661         {
4662 #ifdef JP
4663                 fprintf(fff, "\n\n ¤¢¤Ê¤¿¤Ï%s¤È¤·¤ÆÀ¸¤Þ¤ì¤¿¡£", race_info[p_ptr->start_race].title);
4664 #else
4665                 fprintf(fff, "\n\n You were born as %s.", race_info[p_ptr->start_race].title);
4666 #endif
4667                 for (i = 0; i < MAX_RACES; i++)
4668                 {
4669                         if (p_ptr->start_race == i) continue;
4670                         if (i < 32)
4671                         {
4672                                 if (!(p_ptr->old_race1 & 1L << i)) continue;
4673                         }
4674                         else
4675                         {
4676                                 if (!(p_ptr->old_race2 & 1L << (i-32))) continue;
4677                         }
4678 #ifdef JP
4679                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%s¤À¤Ã¤¿¡£", race_info[i].title);
4680 #else
4681                         fprintf(fff, "\n You were a %s before.", race_info[i].title);
4682 #endif
4683                 }
4684         }
4685
4686         if (p_ptr->old_realm)
4687         {
4688                 for (i = 0; i < MAX_MAGIC; i++)
4689                 {
4690                         if (!(p_ptr->old_realm & 1L << i)) continue;
4691 #ifdef JP
4692                         fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%sËâË¡¤ò»È¤¨¤¿¡£", realm_names[i+1]);
4693 #else
4694                         fprintf(fff, "\n You were able to use %s magic before.", realm_names[i+1]);
4695 #endif
4696                 }
4697         }
4698
4699 #ifdef JP
4700 fprintf(fff, "\n\n  [¥×¥ì¥¤¥ä¡¼¤ÎÆÁ]\n\n");
4701 #else
4702         fprintf(fff, "\n\n  [Virtues]\n\n");
4703 #endif
4704
4705 #ifdef JP
4706         fprintf(fff, "°À­ : %s\n", your_alignment());
4707 #else
4708         fprintf(fff, "Your alighnment : %s\n", your_alignment());
4709 #endif
4710         fprintf(fff, "\n");
4711         dump_virtues(fff);
4712
4713         if (p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3)
4714         {
4715 #ifdef JP
4716 fprintf(fff, "\n\n  [ÆÍÁ³ÊÑ°Û]\n\n");
4717 #else
4718                 fprintf(fff, "\n\n  [Mutations]\n\n");
4719 #endif
4720
4721                 dump_mutations(fff);
4722         }
4723
4724
4725         /* Skip some lines */
4726         fprintf(fff, "\n\n");
4727
4728
4729         /* Dump the equipment */
4730         if (equip_cnt)
4731         {
4732 #ifdef JP
4733 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤ÎÁõÈ÷ ]\n\n");
4734 #else
4735                 fprintf(fff, "  [Character Equipment]\n\n");
4736 #endif
4737
4738                 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4739                 {
4740                         object_desc(o_name, &inventory[i], TRUE, 3);
4741                         if ((i == INVEN_LARM) && p_ptr->ryoute)
4742 #ifdef JP
4743                                 strcpy(o_name, "(Éð´ï¤òξ¼ê»ý¤Á)");
4744 #else
4745                                 strcpy(o_name, "(wielding with two-hands)");
4746 #endif
4747                         fprintf(fff, "%c%s %s\n",
4748                                 index_to_label(i), paren, o_name);
4749                 }
4750                 fprintf(fff, "\n\n");
4751         }
4752
4753         /* Dump the inventory */
4754 #ifdef JP
4755 fprintf(fff, "  [ ¥­¥ã¥é¥¯¥¿¤Î»ý¤Áʪ ]\n\n");
4756 #else
4757         fprintf(fff, "  [Character Inventory]\n\n");
4758 #endif
4759
4760         for (i = 0; i < INVEN_PACK; i++)
4761         {
4762                 /* Don't dump the empty slots */
4763                 if (!inventory[i].k_idx) break;
4764
4765                 /* Dump the inventory slots */
4766                 object_desc(o_name, &inventory[i], TRUE, 3);
4767                 fprintf(fff, "%c%s %s\n", index_to_label(i), paren, o_name);
4768         }
4769
4770         /* Add an empty line */
4771         fprintf(fff, "\n\n");
4772
4773         process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
4774
4775         /* Print all homes in the different towns */
4776         st_ptr = &town[1].store[STORE_HOME];
4777
4778         /* Home -- if anything there */
4779         if (st_ptr->stock_num)
4780         {
4781                 /* Header with name of the town */
4782 #ifdef JP
4783                 fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
4784 #else
4785                 fprintf(fff, "  [Home Inventory]\n");
4786 #endif
4787                 x=1;
4788
4789                 /* Dump all available items */
4790                 for (i = 0; i < st_ptr->stock_num; i++)
4791                 {
4792                         if ((i % 12) == 0)
4793 #ifdef JP
4794                                 fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4795 #else
4796                                 fprintf(fff, "\n ( page %d )\n", x++);
4797 #endif
4798                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4799                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4800                 }
4801
4802                 /* Add an empty line */
4803                 fprintf(fff, "\n\n");
4804         }
4805
4806
4807         /* Print all homes in the different towns */
4808         st_ptr = &town[1].store[STORE_MUSEUM];
4809
4810         /* Home -- if anything there */
4811         if (st_ptr->stock_num)
4812         {
4813                 /* Header with name of the town */
4814 #ifdef JP
4815                 fprintf(fff, "  [ Çîʪ´Û¤Î¥¢¥¤¥Æ¥à ]\n");
4816 #else
4817                 fprintf(fff, "  [Museum]\n");
4818 #endif
4819                 x=1;
4820
4821                 /* Dump all available items */
4822                 for (i = 0; i < st_ptr->stock_num; i++)
4823                 {
4824 #ifdef JP
4825                 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4826                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4827                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4828 #else
4829                 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
4830                         object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4831                         fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4832 #endif
4833
4834                 }
4835
4836                 /* Add an empty line */
4837                 fprintf(fff, "\n\n");
4838         }
4839
4840         return 0;
4841 }
4842
4843 /*
4844  * Hack -- Dump a character description file
4845  *
4846  * XXX XXX XXX Allow the "full" flag to dump additional info,
4847  * and trigger its usage from various places in the code.
4848  */
4849 errr file_character(cptr name, bool full)
4850 {
4851         int             fd = -1;
4852         FILE            *fff = NULL;
4853         char            buf[1024];
4854
4855         /* Drop priv's */
4856         safe_setuid_drop();
4857
4858         /* Build the filename */
4859         path_build(buf, 1024, ANGBAND_DIR_USER, name);
4860
4861         /* File type is "TEXT" */
4862         FILE_TYPE(FILE_TYPE_TEXT);
4863
4864         /* Check for existing file */
4865         fd = fd_open(buf, O_RDONLY);
4866
4867         /* Existing file */
4868         if (fd >= 0)
4869         {
4870                 char out_val[160];
4871
4872                 /* Close the file */
4873                 (void)fd_close(fd);
4874
4875                 /* Build query */
4876 #ifdef JP
4877 (void)sprintf(out_val, "¸½Â¸¤¹¤ë¥Õ¥¡¥¤¥ë %s ¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«? ", buf);
4878 #else
4879                 (void)sprintf(out_val, "Replace existing file %s? ", buf);
4880 #endif
4881
4882
4883                 /* Ask */
4884                 if (get_check(out_val)) fd = -1;
4885         }
4886
4887         /* Open the non-existing file */
4888         if (fd < 0) fff = my_fopen(buf, "w");
4889
4890         /* Invalid file */
4891         if (!fff)
4892         {
4893                 /* Message */
4894 #ifdef JP
4895 msg_format("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4896 #else
4897                 msg_format("Character dump failed!");
4898 #endif
4899
4900                 msg_print(NULL);
4901
4902                 /* Error */
4903                 return (-1);
4904         }
4905
4906         (void)make_character_dump(fff);
4907
4908         /* Close it */
4909         my_fclose(fff);
4910
4911         /* Grab priv's */
4912         safe_setuid_grab();
4913
4914         /* Message */
4915 #ifdef JP
4916 msg_print("¥­¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­½Ð¤·¤ËÀ®¸ù¤·¤Þ¤·¤¿¡£");
4917 #else
4918         msg_print("Character dump successful.");
4919 #endif
4920
4921         msg_print(NULL);
4922
4923         /* Success */
4924         return (0);
4925 }
4926
4927
4928 typedef struct file_tag
4929 {
4930         char name[32];
4931         int line_number;
4932 } file_tag;
4933
4934
4935 typedef struct file_tags
4936 {
4937         file_tag tags[64];
4938         int index;
4939 } file_tags;
4940
4941
4942 static void add_tag(file_tags *the_tags, cptr name, int line)
4943 {
4944         if (the_tags->index < 64)
4945         {
4946                 file_tag *tag = &(the_tags->tags[the_tags->index]);
4947
4948                 /* Set the name and end it with '\0' */
4949                 strncpy(tag->name, name, 31);
4950                 tag->name[31] = '\0';
4951
4952                 /* Set the line-number */
4953                 tag->line_number = line;
4954
4955                 /* Increase the number of tags */
4956                 the_tags->index++;
4957         }
4958 }
4959
4960
4961 static int get_line(file_tags *the_tags, cptr name)
4962 {
4963         int i;
4964
4965         /* Search for the tag */
4966         for (i = 0; i < the_tags->index; i++)
4967         {
4968                 if (streq(the_tags->tags[i].name, name))
4969                 {
4970                         return the_tags->tags[i].line_number;
4971                 }
4972         }
4973
4974         /* Not found */
4975         return 0;
4976 }
4977
4978
4979 /*
4980  * Recursive file perusal.
4981  *
4982  * Return FALSE on 'Q', otherwise TRUE.
4983  *
4984  * Process various special text in the input file, including
4985  * the "menu" structures used by the "help file" system.
4986  *
4987  * XXX XXX XXX Consider using a temporary file.
4988  *
4989  * XXX XXX XXX Allow the user to "save" the current file.
4990  */
4991 bool show_file(bool show_version, cptr name, cptr what, int line, int mode)
4992 {
4993         int i, n, k;
4994
4995         /* Number of "real" lines passed by */
4996         int next = 0;
4997
4998         /* Number of "real" lines in the file */
4999         int size = 0;
5000
5001         /* Backup value for "line" */
5002         int back = 0;
5003
5004         /* Color of the next line */
5005         byte color = TERM_WHITE;
5006
5007         /* Loop counter */
5008         int cnt;
5009
5010         /* This screen has sub-screens */
5011         bool menu = FALSE;
5012
5013         /* Current help file */
5014         FILE *fff = NULL;
5015
5016         /* Find this string (if any) */
5017         cptr find = NULL;
5018
5019         /* Jump to this tag */
5020         cptr tag = NULL;
5021
5022         /* Hold a string to find */
5023         char finder[81];
5024
5025         /* Hold a string to show */
5026         char shower[81];
5027
5028         /* Filename */
5029         char filename[1024];
5030
5031         /* Describe this thing */
5032         char caption[128];
5033
5034         /* Path buffer */
5035         char path[1024];
5036
5037         /* General buffer */
5038         char buf[1024];
5039
5040         /* Lower case version of the buffer, for searching */
5041         char lc_buf[1024];
5042
5043         /* Aux pointer for making lc_buf (and find!) lowercase */
5044         cptr lc_buf_ptr;
5045
5046         /* Sub-menu information */
5047         char hook[68][32];
5048
5049         /* Tags for in-file references */
5050         file_tags tags;
5051
5052         bool reverse = (line < 0);
5053
5054         int wid, hgt, rows;
5055
5056         Term_get_size(&wid, &hgt);
5057         rows = hgt - 4;
5058
5059         /* Wipe finder */
5060         strcpy(finder, "");
5061
5062         /* Wipe shower */
5063         strcpy(shower, "");
5064
5065         /* Wipe caption */
5066         strcpy(caption, "");
5067
5068         /* Wipe the hooks */
5069         for (i = 0; i < 68; i++)
5070         {
5071                 hook[i][0] = '\0';
5072         }
5073
5074         /* No tags yet */
5075         tags.index = 0;
5076
5077         /* Copy the filename */
5078         strcpy(filename, name);
5079
5080         n = strlen(filename);
5081
5082         /* Extract the tag from the filename */
5083         for (i = 0; i < n; i++)
5084         {
5085                 if (filename[i] == '#')
5086                 {
5087                         filename[i] = '\0';
5088                         tag = filename + i + 1;
5089                         break;
5090                 }
5091         }
5092
5093         /* Redirect the name */
5094         name = filename;
5095
5096         /* Hack XXX XXX XXX */
5097         if (what)
5098         {
5099                 /* Caption */
5100                 strcpy(caption, what);
5101
5102                 /* Access the "file" */
5103                 strcpy(path, name);
5104
5105                 /* Open */
5106                 fff = my_fopen(path, "r");
5107         }
5108
5109         /* Look in "help" */
5110         if (!fff)
5111         {
5112                 /* Caption */
5113 #ifdef JP
5114 sprintf(caption, "¥Ø¥ë¥×¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5115 #else
5116                 sprintf(caption, "Help file '%s'", name);
5117 #endif
5118
5119
5120                 /* Build the filename */
5121                 path_build(path, 1024, ANGBAND_DIR_HELP, name);
5122
5123                 /* Open the file */
5124                 fff = my_fopen(path, "r");
5125         }
5126
5127         /* Look in "info" */
5128         if (!fff)
5129         {
5130                 /* Caption */
5131 #ifdef JP
5132 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5133 #else
5134                 sprintf(caption, "Info file '%s'", name);
5135 #endif
5136
5137
5138                 /* Build the filename */
5139                 path_build(path, 1024, ANGBAND_DIR_INFO, name);
5140
5141                 /* Open the file */
5142                 fff = my_fopen(path, "r");
5143         }
5144
5145         /* Look in "info" */
5146         if (!fff)
5147         {
5148                 /* Build the filename */
5149                 path_build(path, 1024, ANGBAND_DIR, name);
5150
5151                 for (i = 0; path[i]; i++)
5152                         if ('\\' == path[i])
5153                                 path[i] = PATH_SEP[0];
5154
5155                 /* Caption */
5156 #ifdef JP
5157 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
5158 #else
5159                 sprintf(caption, "Info file '%s'", name);
5160 #endif
5161
5162                 /* Open the file */
5163                 fff = my_fopen(path, "r");
5164         }
5165
5166         /* Oops */
5167         if (!fff)
5168         {
5169                 /* Message */
5170 #ifdef JP
5171 msg_format("'%s'¤ò¥ª¡¼¥×¥ó¤Ç¤­¤Þ¤»¤ó¡£", name);
5172 #else
5173                 msg_format("Cannot open '%s'.", name);
5174 #endif
5175
5176                 msg_print(NULL);
5177
5178                 /* Oops */
5179                 return (TRUE);
5180         }
5181
5182
5183         /* Pre-Parse the file */
5184         while (TRUE)
5185         {
5186                 char *str;
5187
5188                 /* Read a line or stop */
5189                 if (my_fgets(fff, buf, 1024)) break;
5190
5191                 /* Get a color */
5192                 if (prefix(buf, "#####")) str = &buf[6];
5193                 else str = buf;
5194
5195                 /* XXX Parse "menu" items */
5196                 if (prefix(str, "***** "))
5197                 {
5198                         /* Notice "menu" requests */
5199                         if ((str[6] == '[') && isalpha(str[7]))
5200                         {
5201                                 /* This is a menu file */
5202                                 menu = TRUE;
5203
5204                                 /* Extract the menu item */
5205                                 k = str[7] - 'A';
5206
5207                                 if ((str[8] == ']') && (str[9] == ' '))
5208                                 {
5209                                         /* Extract the menu item */
5210                                         strncpy(hook[k], str + 10, 31);
5211
5212                                         /* Make sure it's null-terminated */
5213                                         hook[k][31] = '\0';
5214                                 }
5215                         }
5216                         /* Notice "tag" requests */
5217                         else if (str[6] == '<')
5218                         {
5219                                 str[strlen(str) - 1] = '\0';
5220                                 add_tag(&tags, str + 7, next);
5221                         }
5222
5223                         /* Skip this */
5224                         continue;
5225                 }
5226
5227                 /* Count the "real" lines */
5228                 next++;
5229         }
5230
5231         /* Save the number of "real" lines */
5232         size = next;
5233
5234         /* start from bottom when reverse mode */
5235         if (line == -1) line = ((size-1)/rows)*rows;
5236
5237         /* Go to the tagged line */
5238         if (tag) line = get_line(&tags, tag);
5239
5240         /* Display the file */
5241         while (TRUE)
5242         {
5243                 /* Clear screen */
5244                 Term_clear();
5245
5246                 /* Restart when necessary */
5247                 if (line >= size - rows) line = size - rows;
5248                 if (line < 0) line = 0;
5249
5250                 /* Re-open the file if needed */
5251                 if (next > line)
5252                 {
5253                         /* Close it */
5254                         my_fclose(fff);
5255
5256                         /* Hack -- Re-Open the file */
5257                         fff = my_fopen(path, "r");
5258
5259                         /* Oops */
5260                         if (!fff) return (FALSE);
5261
5262                         /* File has been restarted */
5263                         next = 0;
5264                 }
5265
5266                 /* Goto the selected line */
5267                 while (next < line)
5268                 {
5269                         /* Get a line */
5270                         if (my_fgets(fff, buf, 1024)) break;
5271
5272                         /* Skip tags/links */
5273                         if (prefix(buf, "***** ")) continue;
5274
5275                         /* Count the lines */
5276                         next++;
5277                 }
5278
5279                 /* Dump the next 20, or rows, lines of the file */
5280                 for (i = 0; i < rows; )
5281                 {
5282                         int print_x, x;
5283                         cptr str;
5284
5285                         /* Hack -- track the "first" line */
5286                         if (!i) line = next;
5287
5288                         /* Get a line of the file or stop */
5289                         if (my_fgets(fff, buf, 1024)) break;
5290
5291                         /* Hack -- skip "special" lines */
5292                         if (prefix(buf, "***** ")) continue;
5293
5294                         /* Get a color */
5295                         if (prefix(buf, "#####"))
5296                         {
5297                                 color = color_char_to_attr(buf[5]);
5298                                 str = &buf[6];
5299                         }
5300                         else
5301                         {
5302                                 color = TERM_WHITE;
5303                                 str = buf;
5304                         }
5305
5306                         /* Count the "real" lines */
5307                         next++;
5308
5309                         /* Make a lower case version of str for searching */
5310                         strcpy(lc_buf, str);
5311
5312                         for (lc_buf_ptr = lc_buf; *lc_buf_ptr != 0; lc_buf_ptr++)
5313                         {
5314 #ifdef JP
5315                                 if (iskanji(*lc_buf_ptr))
5316                                         lc_buf_ptr++;
5317                                 else
5318 #endif
5319                                         lc_buf[lc_buf_ptr-lc_buf] = tolower(*lc_buf_ptr);
5320                         }
5321
5322                         /* Hack -- keep searching */
5323                         if (find && !i && !strstr(lc_buf, find)) continue;
5324
5325                         /* Hack -- stop searching */
5326                         find = NULL;
5327
5328                         /* Dump the line */
5329                         x = 0;
5330                         print_x = 0;
5331                         while (str[x])
5332                         {
5333                                 /* Color ? */
5334                                 if (prefix(str + x, "[[[[["))
5335                                 {
5336                                         byte c = color_char_to_attr(str[x + 5]);
5337                                         x += 6;
5338
5339                                         /* Ok print the link name */
5340                                         while (str[x] != ']')
5341                                         {
5342                                                 Term_putch(print_x, i + 2, c, str[x]);
5343                                                 x++;
5344                                                 print_x++;
5345                                         }
5346                                 }
5347                                 else
5348                                 {
5349                                         Term_putch(print_x, i + 2, color, str[x]);
5350                                         print_x++;
5351                                 }
5352
5353                                 x++;
5354                         }
5355
5356                         /* Hilite "shower" */
5357                         if (shower[0])
5358                         {
5359                                 cptr s2 = lc_buf;
5360
5361                                 /* Display matches */
5362                                 while ((s2 = strstr(s2, shower)) != NULL)
5363                                 {
5364                                         int len = strlen(shower);
5365
5366                                         /* Display the match */
5367                                         Term_putstr(s2-lc_buf, i+2, len, TERM_YELLOW, &str[s2-lc_buf]);
5368
5369                                         /* Advance */
5370                                         s2 += len;
5371                                 }
5372                         }
5373
5374                         /* Count the printed lines */
5375                         i++;
5376                 }
5377
5378                 /* Hack -- failed search */
5379                 if (find)
5380                 {
5381                         bell();
5382                         line = back;
5383                         find = NULL;
5384                         continue;
5385                 }
5386
5387
5388                 /* Show a general "title" */
5389                 if (show_version)
5390                 {
5391                         prt(format(
5392 #ifdef JP
5393                                 "[ÊѶòÈÚÅÜ %d.%d.%d, %s, %d/%d]",
5394 #else
5395                                 "[Hengband %d.%d.%d, %s, Line %d/%d]",
5396 #endif
5397
5398                            FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH,
5399                            caption, line, size), 0, 0);
5400                 }
5401                 else
5402                 {
5403                         prt(format(
5404 #ifdef JP
5405                                 "[%s, %d/%d]",
5406 #else
5407                                 "[%s, Line %d/%d]",
5408 #endif
5409                                 caption, line, size), 0, 0);
5410                 }
5411
5412                 /* Prompt -- small files */
5413                 if (size <= rows)
5414                 {
5415                         /* Wait for it */
5416 #ifdef JP
5417 prt("[¥­¡¼:(?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5418 #else
5419                         prt("[Press ESC to exit.]", hgt - 1, 0);
5420 #endif
5421
5422                 }
5423
5424                 /* Prompt -- large files */
5425                 else
5426                 {
5427 #ifdef JP
5428                         if(reverse)
5429                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢¬ (-)¢­ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5430                         else
5431                                 prt("[¥­¡¼:(RET/¥¹¥Ú¡¼¥¹)¢­ (-)¢¬ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", hgt - 1, 0);
5432 #else
5433                         prt("[Press Return, Space, -, =, /, |, or ESC to exit.]", hgt - 1, 0);
5434 #endif
5435                 }
5436
5437                 /* Get a keypress */
5438                 k = inkey();
5439
5440                 /* Hack -- return to last screen */
5441                 if (k == '<') break;
5442
5443                 /* Show the help for the help */
5444                 if (k == '?')
5445                 {
5446                         /* Hack - prevent silly recursion */
5447 #ifdef JP
5448                         if (strcmp(name, "jhelpinfo.txt") != 0)
5449                                 show_file(TRUE, "jhelpinfo.txt", NULL, 0, mode);
5450 #else
5451                         if (strcmp(name, "helpinfo.txt") != 0)
5452                                 show_file(TRUE, "helpinfo.txt", NULL, 0, mode);
5453 #endif
5454                 }
5455
5456                 /* Hack -- try showing */
5457                 if (k == '=')
5458                 {
5459                         /* Get "shower" */
5460 #ifdef JP
5461 prt("¶¯Ä´: ", hgt - 1, 0);
5462 #else
5463                         prt("Show: ", hgt - 1, 0);
5464 #endif
5465
5466                         (void)askfor_aux(shower, 80);
5467                 }
5468
5469                 /* Hack -- try finding */
5470                 if (k == '/')
5471                 {
5472                         /* Get "finder" */
5473 #ifdef JP
5474 prt("¸¡º÷: ", hgt - 1, 0);
5475 #else
5476                         prt("Find: ", hgt - 1, 0);
5477 #endif
5478
5479
5480                         if (askfor_aux(finder, 80))
5481                         {
5482                                 /* Find it */
5483                                 find = finder;
5484                                 back = line;
5485                                 line = line + 1;
5486
5487                                 /* Make finder lowercase */
5488                                 for (cnt = 0; finder[cnt] != 0; cnt++)
5489                                 {
5490 #ifdef JP
5491                                         if (iskanji(finder[cnt]))
5492                                                 cnt++;
5493                                         else
5494 #endif
5495                                                 finder[cnt] = tolower(finder[cnt]);
5496                                 }
5497
5498                                 /* Show it */
5499                                 strcpy(shower, finder);
5500                         }
5501                 }
5502
5503                 /* Hack -- go to a specific line */
5504                 if (k == '#')
5505                 {
5506                         char tmp[81];
5507 #ifdef JP
5508 prt("¹Ô: ", hgt - 1, 0);
5509 #else
5510                         prt("Goto Line: ", hgt - 1, 0);
5511 #endif
5512
5513                         strcpy(tmp, "0");
5514
5515                         if (askfor_aux(tmp, 80))
5516                         {
5517                                 line = atoi(tmp);
5518                         }
5519                 }
5520
5521                 /* Hack -- go to a specific file */
5522                 if (k == '%')
5523                 {
5524                         char tmp[81];
5525 #ifdef JP
5526 prt("¥Õ¥¡¥¤¥ë¡¦¥Í¡¼¥à: ", hgt - 1, 0);
5527 strcpy(tmp, "jhelp.hlp");
5528 #else
5529                         prt("Goto File: ", hgt - 1, 0);
5530                         strcpy(tmp, "help.hlp");
5531 #endif
5532
5533
5534                         if (askfor_aux(tmp, 80))
5535                         {
5536                                 if (!show_file(TRUE, tmp, NULL, 0, mode)) k = 'q';
5537                         }
5538                 }
5539
5540                 /* Allow backing up */
5541                 if (k == '-')
5542                 {
5543                         line = line + (reverse ? rows : -rows);
5544                         if (line < 0) line = 0;
5545                 }
5546
5547                 /* Advance a single line */
5548                 if ((k == '\n') || (k == '\r'))
5549                 {
5550                         line = line + (reverse ? -1 : 1);
5551                         if (line < 0) line = 0;
5552                 }
5553
5554
5555                 /* Move up / down */
5556                 if (k == '8')
5557                 {
5558                         line--;
5559                         if (line < 0) line = 0;
5560                 }
5561
5562                 if (k == '2') line++;
5563
5564                 /* Advance one page */
5565                 if (k == ' ')
5566                 {
5567                         line = line + (reverse ? -rows : rows);
5568                         if (line < 0) line = ((size-1)/rows)*rows;
5569                 }
5570
5571                 /* Recurse on numbers */
5572                 if (menu)
5573                 {
5574                         int key = -1;
5575
5576                         if (isalpha(k))
5577                                 key = k - 'A';
5578
5579                         if ((key > -1) && hook[key][0])
5580                         {
5581                                 /* Recurse on that file */
5582                                 if (!show_file(TRUE, hook[key], NULL, 0, mode))
5583                                         k = 'q';
5584                         }
5585                 }
5586
5587                 /* Hack, dump to file */
5588                 if (k == '|')
5589                 {
5590                         FILE *ffp;
5591                         char buff[1024];
5592                         char xtmp[82];
5593
5594                         strcpy (xtmp, "");
5595
5596 #ifdef JP
5597                         if (!get_string("¥Õ¥¡¥¤¥ë̾: ", xtmp, 80))
5598 #else
5599                         if (!get_string("File name: ", xtmp, 80))
5600 #endif
5601                         {
5602                                 continue;
5603                         }
5604  
5605                         /* Close it */
5606                         my_fclose(fff);
5607
5608                         /* Drop priv's */
5609                         safe_setuid_drop();
5610
5611                         /* Build the filename */
5612                         path_build(buff, 1024, ANGBAND_DIR_USER, xtmp);
5613
5614                         /* Hack -- Re-Open the file */
5615                         fff = my_fopen(path, "r");
5616
5617                         ffp = my_fopen(buff, "w");
5618
5619                         /* Oops */
5620                         if (!(fff && ffp))
5621                         {
5622 #ifdef JP
5623 msg_print("¥Õ¥¡¥¤¥ë¤¬³«¤±¤Þ¤»¤ó¡£");
5624 #else
5625                                 msg_print("Failed to open file.");
5626 #endif
5627
5628                                 k = ESCAPE;
5629                                 break;
5630                         }
5631
5632                         sprintf(xtmp, "%s: %s", player_name, what);
5633                         my_fputs(ffp, xtmp, 80);
5634                         my_fputs(ffp, "\n", 80);
5635
5636                         while (!my_fgets(fff, buff, 80))
5637                                 my_fputs(ffp, buff, 80);
5638
5639                         /* Close it */
5640                         my_fclose(fff);
5641                         my_fclose(ffp);
5642
5643                         /* Grab priv's */
5644                         safe_setuid_grab();
5645
5646                         /* Hack -- Re-Open the file */
5647                         fff = my_fopen(path, "r");
5648                 }
5649
5650                 /* Exit on escape */
5651                 if (k == ESCAPE) break;
5652                 if (k == 'q') break;
5653         }
5654
5655         /* Close the file */
5656         my_fclose(fff);
5657
5658         /* Escape */
5659         if (k == 'q') return (FALSE);
5660
5661         /* Normal return */
5662         return (TRUE);
5663 }
5664
5665
5666 /*
5667  * Peruse the On-Line-Help
5668  */
5669 void do_cmd_help(void)
5670 {
5671         /* Save screen */
5672         screen_save();
5673
5674         /* Peruse the main help file */
5675 #ifdef JP
5676 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
5677 #else
5678         (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
5679 #endif
5680
5681
5682         /* Load screen */
5683         screen_load();
5684 }
5685
5686
5687 /*
5688  * Process the player name.
5689  * Extract a clean "base name".
5690  * Build the savefile name if needed.
5691  */
5692 void process_player_name(bool sf)
5693 {
5694         int i, k = 0;
5695
5696
5697         /* Cannot be too long */
5698 #if defined(MACINTOSH) || defined(MSDOS) || defined(USE_EMX) || defined(AMIGA) || defined(ACORN) || defined(VM)
5699 #ifdef MSDOS
5700         if (strlen(player_name) > 8)
5701 #else
5702         if (strlen(player_name) > 15)
5703 #endif
5704         {
5705                 /* Name too long */
5706 #ifdef JP
5707 quit_fmt("'%s'¤È¤¤¤¦Ì¾Á°¤ÏŤ¹¤®¤Þ¤¹¡ª", player_name);
5708 #else
5709                 quit_fmt("The name '%s' is too long!", player_name);
5710 #endif
5711
5712         }
5713 #endif
5714
5715         /* Cannot contain "icky" characters */
5716         for (i = 0; player_name[i]; i++)
5717         {
5718                 /* No control characters */
5719 #ifdef JP
5720                 if (iskanji(player_name[i])){i++;continue;}
5721                 if (iscntrl( (unsigned char)player_name[i]))
5722 #else
5723                 if (iscntrl(player_name[i]))
5724 #endif
5725
5726                 {
5727                         /* Illegal characters */
5728 #ifdef JP
5729 quit_fmt("'%s' ¤È¤¤¤¦Ì¾Á°¤ÏÉÔÀµ¤Ê¥³¥ó¥È¥í¡¼¥ë¥³¡¼¥É¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£", player_name);
5730 #else
5731                         quit_fmt("The name '%s' contains control chars!", player_name);
5732 #endif
5733
5734                 }
5735         }
5736
5737
5738 #ifdef MACINTOSH
5739
5740         /* Extract "useful" letters */
5741         for (i = 0; player_name[i]; i++)
5742         {
5743 #ifdef JP
5744                 unsigned char c = player_name[i];
5745 #else
5746                 char c = player_name[i];
5747 #endif
5748
5749
5750                 /* Convert "dot" to "underscore" */
5751                 if (c == '.') c = '_';
5752
5753                 /* Accept all the letters */
5754                 player_base[k++] = c;
5755         }
5756
5757 #else
5758
5759         /* Extract "useful" letters */
5760         for (i = 0; player_name[i]; i++)
5761         {
5762 #ifdef JP
5763                 unsigned char c = player_name[i];
5764 #else
5765                 char c = player_name[i];
5766 #endif
5767
5768                 /* Accept some letters */
5769 #ifdef JP
5770                 if(iskanji(c)){
5771                   if(k + 2 >= sizeof(player_base) || !player_name[i+1]) break;
5772                   player_base[k++] = c;
5773                   i++;
5774                   player_base[k++] = player_name[i];
5775                 }
5776 #ifdef SJIS
5777                 else if (iskana(c)) player_base[k++] = c;
5778 #endif
5779                 else
5780 #endif
5781                 /* Convert path separator to underscore */
5782                 if (!strncmp(PATH_SEP, player_name+i, strlen(PATH_SEP))){
5783                         player_base[k++] = '_';
5784                         i += strlen(PATH_SEP);
5785                 }
5786 #ifdef MSDOS
5787                 /* Convert space, dot, and underscore to underscore */
5788                 else if (strchr(". _", c)) player_base[k++] = '_';
5789 #endif
5790                 else if (isprint(c)) player_base[k++] = c;
5791         }
5792
5793 #endif
5794
5795
5796 #if defined(MSDOS)
5797
5798         /* Hack -- max length */
5799         if (k > 8) k = 8;
5800
5801 #endif
5802
5803         /* Terminate */
5804         player_base[k] = '\0';
5805
5806         /* Require a "base" name */
5807         if (!player_base[0]) strcpy(player_base, "PLAYER");
5808
5809
5810 #ifdef SAVEFILE_MUTABLE
5811
5812         /* Accept */
5813         sf = TRUE;
5814
5815 #endif
5816         if (!savefile_base[0] && savefile[0])
5817         {
5818                 cptr s;
5819                 s = savefile;
5820                 while (1)
5821                 {
5822                         cptr t;
5823                         t = strstr(s, PATH_SEP);
5824                         if (!t)
5825                                 break;
5826                         s = t+1;
5827                 }
5828                 strcpy(savefile_base, s);
5829         }
5830
5831         if (!savefile_base[0] || !savefile[0])
5832                 sf = TRUE;
5833
5834         /* Change the savefile name */
5835         if (sf)
5836         {
5837                 char temp[128];
5838
5839                 strcpy(savefile_base, player_base);
5840
5841 #ifdef SAVEFILE_USE_UID
5842                 /* Rename the savefile, using the player_uid and player_base */
5843                 (void)sprintf(temp, "%d.%s", player_uid, player_base);
5844 #else
5845                 /* Rename the savefile, using the player_base */
5846                 (void)sprintf(temp, "%s", player_base);
5847 #endif
5848
5849 #ifdef VM
5850                 /* Hack -- support "flat directory" usage on VM/ESA */
5851                 (void)sprintf(temp, "%s.sv", player_base);
5852 #endif /* VM */
5853
5854                 /* Build the filename */
5855                 path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp);
5856         }
5857 }
5858
5859
5860 /*
5861  * Gets a name for the character, reacting to name changes.
5862  *
5863  * Assumes that "display_player(0)" has just been called
5864  *
5865  * Perhaps we should NOT ask for a name (at "birth()") on
5866  * Unix machines?  XXX XXX
5867  *
5868  * What a horrible name for a global function.  XXX XXX XXX
5869  */
5870 void get_name(void)
5871 {
5872         char tmp[64];
5873
5874         /* Save the player name */
5875         strcpy(tmp, player_name);
5876
5877         /* Prompt for a new name */
5878 #ifdef JP
5879         if (get_string("¥­¥ã¥é¥¯¥¿¡¼¤Î̾Á°¤òÆþÎϤ·¤Æ²¼¤µ¤¤: ", tmp, 15))
5880 #else
5881         if (get_string("Enter a name for your character: ", tmp, 15))
5882 #endif
5883         {
5884                 /* Use the name */
5885                 strcpy(player_name, tmp);
5886         }
5887         else if (0 == strlen(player_name))
5888         {
5889                 /* Use default name */
5890                 strcpy(player_name, "PLAYER");
5891         }
5892
5893         /* Process the player name */
5894         process_player_name(FALSE);
5895
5896         strcpy(tmp,ap_ptr->title);
5897 #ifdef JP
5898         if(ap_ptr->no == 1)
5899                 strcat(tmp,"¤Î");
5900 #else
5901         strcat(tmp, " ");
5902 #endif
5903         strcat(tmp,player_name);
5904
5905         /* Re-Draw the name (in light blue) */
5906         Term_erase(34, 1, 255);
5907         c_put_str(TERM_L_BLUE, tmp, 1, 34);
5908
5909         /* Erase the prompt, etc */
5910         clear_from(22);
5911 }
5912
5913
5914
5915 /*
5916  * Hack -- commit suicide
5917  */
5918 void do_cmd_suicide(void)
5919 {
5920         int i;
5921
5922         /* Flush input */
5923         flush();
5924
5925         /* Verify Retirement */
5926         if (total_winner)
5927         {
5928                 /* Verify */
5929 #ifdef JP
5930 if (!get_check_strict("°úÂष¤Þ¤¹¤«? ", CHECK_NO_HISTORY)) return;
5931 #else
5932                 if (!get_check_strict("Do you want to retire? ", CHECK_NO_HISTORY)) return;
5933 #endif
5934
5935         }
5936
5937         /* Verify Suicide */
5938         else
5939         {
5940                 /* Verify */
5941 #ifdef JP
5942 if (!get_check("ËÜÅö¤Ë¼«»¦¤·¤Þ¤¹¤«¡©")) return;
5943 #else
5944                 if (!get_check("Do you really want to commit suicide? ")) return;
5945 #endif
5946         }
5947
5948
5949         if (!noscore)
5950         {
5951                 /* Special Verification for suicide */
5952 #ifdef JP
5953 prt("³Îǧ¤Î¤¿¤á '@' ¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 0);
5954 #else
5955                 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
5956 #endif
5957
5958                 flush();
5959                 i = inkey();
5960                 prt("", 0, 0);
5961                 if (i != '@') return;
5962         }
5963
5964         /* Stop playing */
5965         alive = FALSE;
5966
5967         /* Kill the player */
5968         death = TRUE;
5969
5970         /* Leaving */
5971         p_ptr->leaving = TRUE;
5972
5973         if (!total_winner)
5974         {
5975 #ifdef JP
5976                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤ËÀä˾¤·¤Æ¼«»¦¤·¤¿¡£");
5977                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
5978 #else
5979                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "give up all hope to commit suicide.");
5980                 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "--------   Game  Over   --------");
5981 #endif
5982                 do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
5983         }
5984
5985         /* Cause of death */
5986 #ifdef JP
5987 (void)strcpy(died_from, "ÅÓÃ潪λ");
5988 #else
5989         (void)strcpy(died_from, "Quitting");
5990 #endif
5991
5992 }
5993
5994
5995
5996 /*
5997  * Save the game
5998  */
5999 void do_cmd_save_game(int is_autosave)
6000 {
6001         /* Autosaves do not disturb */
6002         if (is_autosave)
6003         {
6004 #ifdef JP
6005 msg_print("¼«Æ°¥»¡¼¥ÖÃæ");
6006 #else
6007                 msg_print("Autosaving the game...");
6008 #endif
6009
6010         }
6011         else
6012         {
6013                 /* Disturb the player */
6014                 disturb(1, 0);
6015         }
6016
6017         /* Clear messages */
6018         msg_print(NULL);
6019
6020         /* Handle stuff */
6021         handle_stuff();
6022
6023         /* Message */
6024 #ifdef JP
6025 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹...", 0, 0);
6026 #else
6027         prt("Saving game...", 0, 0);
6028 #endif
6029
6030
6031         /* Refresh */
6032         Term_fresh();
6033
6034         /* The player is not dead */
6035 #ifdef JP
6036 (void)strcpy(died_from, "(¥»¡¼¥Ö)");
6037 #else
6038         (void)strcpy(died_from, "(saved)");
6039 #endif
6040
6041
6042         /* Forbid suspend */
6043         signals_ignore_tstp();
6044
6045         /* Save the player */
6046         if (save_player())
6047         {
6048 #ifdef JP
6049 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ½ªÎ»", 0, 0);
6050 #else
6051                 prt("Saving game... done.", 0, 0);
6052 #endif
6053
6054         }
6055
6056         /* Save failed (oops) */
6057         else
6058         {
6059 #ifdef JP
6060 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ¼ºÇÔ¡ª", 0, 0);
6061 #else
6062                 prt("Saving game... failed!", 0, 0);
6063 #endif
6064
6065         }
6066
6067         /* Allow suspend again */
6068         signals_handle_tstp();
6069
6070         /* Refresh */
6071         Term_fresh();
6072
6073         /* Note that the player is not dead */
6074 #ifdef JP
6075 (void)strcpy(died_from, "(¸µµ¤¤ËÀ¸¤­¤Æ¤¤¤ë)");
6076 #else
6077         (void)strcpy(died_from, "(alive and well)");
6078 #endif
6079
6080 }
6081
6082
6083 /*
6084  * Save the game and exit
6085  */
6086 void do_cmd_save_and_exit(void)
6087 {
6088         alive = FALSE;
6089
6090         /* Leaving */
6091         p_ptr->leaving = TRUE;
6092 #ifdef JP
6093         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "----¥²¡¼¥àÃæÃÇ----");
6094 #else
6095         do_cmd_write_nikki(NIKKI_GAMESTART, 0, "---- Save and Exit Game ----");
6096 #endif
6097 }
6098
6099
6100 /*
6101  * Hack -- Calculates the total number of points earned         -JWT-
6102  */
6103 long total_points(void)
6104 {
6105         int i, mult = 100;
6106         s16b max_dl = 0;
6107         u32b point, point_h, point_l;
6108         int arena_win = MIN(p_ptr->arena_number, MAX_ARENA_MONS);
6109
6110         if (stupid_monsters) mult -= 70;
6111         if (!preserve_mode) mult += 10;
6112         if (!autoroller) mult += 10;
6113         if (!smart_learn) mult -= 20;
6114         if (!terrain_streams) mult -= 20;
6115         if (smart_cheat) mult += 30;
6116         if (ironman_shops) mult += 50;
6117         if (ironman_small_levels) mult += 10;
6118         if (ironman_empty_levels) mult += 20;
6119         if (!powerup_home) mult += 50;
6120         if (ironman_rooms) mult += 100;
6121         if (ironman_nightmare) mult += 100;
6122
6123         if (mult < 5) mult = 5;
6124
6125         for (i = 0; i < max_d_idx; i++)
6126                 if(max_dlv[i] > max_dl)
6127                         max_dl = max_dlv[i];
6128
6129         point_l = (p_ptr->max_exp + (100 * max_dl));
6130         point_h = point_l / 0x10000L;
6131         point_l = point_l % 0x10000L;
6132         point_h *= mult;
6133         point_l *= mult;
6134         point_h += point_l / 0x10000L;
6135         point_l %= 0x10000L;
6136
6137         point_l += ((point_h % 100) << 16);
6138         point_h /= 100;
6139         point_l /= 100;
6140
6141         point = (point_h << 16) + (point_l);
6142         if (p_ptr->arena_number < 99)
6143                 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
6144
6145         if (ironman_downward) point *= 2;
6146         if (p_ptr->pclass == CLASS_BERSERKER)
6147         {
6148                 if ((p_ptr->prace == RACE_SPECTRE) || (p_ptr->prace == RACE_AMBERITE))
6149                         point = point / 5;
6150         }
6151
6152         if ((p_ptr->pseikaku == SEIKAKU_MUNCHKIN) && point)
6153         {
6154                 point = 1;
6155                 if (total_winner) point = 2;
6156         }
6157         if (easy_band) point = (0 - point);
6158
6159         return point;
6160 }
6161
6162
6163
6164 /*
6165  * Centers a string within a 31 character string                -JWT-
6166  */
6167 static void center_string(char *buf, cptr str)
6168 {
6169         int i, j;
6170
6171         /* Total length */
6172         i = strlen(str);
6173
6174         /* Necessary border */
6175         j = 15 - i / 2;
6176
6177         /* Mega-Hack */
6178         (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, "");
6179 }
6180
6181
6182 #if 0
6183 /*
6184  * Save a "bones" file for a dead character
6185  *
6186  * Note that we will not use these files until Angband 2.8.0, and
6187  * then we will only use the name and level on which death occured.
6188  *
6189  * Should probably attempt some form of locking...
6190  */
6191 static void make_bones(void)
6192 {
6193         FILE                *fp;
6194
6195         char                str[1024];
6196
6197
6198         /* Ignore wizards and borgs */
6199         if (!(noscore & 0x00FF))
6200         {
6201                 /* Ignore people who die in town */
6202                 if (dun_level)
6203                 {
6204                         char tmp[128];
6205
6206                         /* XXX XXX XXX "Bones" name */
6207                         sprintf(tmp, "bone.%03d", dun_level);
6208
6209                         /* Build the filename */
6210                         path_build(str, 1024, ANGBAND_DIR_BONE, tmp);
6211
6212                         /* Attempt to open the bones file */
6213                         fp = my_fopen(str, "r");
6214
6215                         /* Close it right away */
6216                         if (fp) my_fclose(fp);
6217
6218                         /* Do not over-write a previous ghost */
6219                         if (fp) return;
6220
6221                         /* File type is "TEXT" */
6222                         FILE_TYPE(FILE_TYPE_TEXT);
6223
6224                         /* Try to write a new "Bones File" */
6225                         fp = my_fopen(str, "w");
6226
6227                         /* Not allowed to write it?  Weird. */
6228                         if (!fp) return;
6229
6230                         /* Save the info */
6231                         fprintf(fp, "%s\n", player_name);
6232                         fprintf(fp, "%d\n", p_ptr->mhp);
6233                         fprintf(fp, "%d\n", p_ptr->prace);
6234                         fprintf(fp, "%d\n", p_ptr->pclass);
6235
6236                         /* Close and save the Bones file */
6237                         my_fclose(fp);
6238                 }
6239         }
6240 }
6241 #endif
6242
6243
6244 /*
6245  * Redefinable "print_tombstone" action
6246  */
6247 bool (*tombstone_aux)(void) = NULL;
6248
6249
6250 /*
6251  * Display a "tomb-stone"
6252  */
6253 static void print_tomb(void)
6254 {
6255         bool done = FALSE;
6256
6257         /* Do we use a special tombstone ? */
6258         if (tombstone_aux)
6259         {
6260                 /* Use tombstone hook */
6261                 done = (*tombstone_aux)();
6262         }
6263
6264         /* Print the text-tombstone */
6265         if (!done)
6266         {
6267                 cptr    p;
6268
6269                 char    tmp[160];
6270
6271                 char    buf[1024];
6272 #ifndef JP
6273                 char    dummy[80];
6274 #endif
6275
6276                 FILE        *fp;
6277
6278                 time_t  ct = time((time_t)0);
6279
6280
6281                 /* Clear screen */
6282                 Term_clear();
6283
6284                 /* Build the filename */
6285 #ifdef JP
6286                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead_j.txt");
6287 #else
6288                 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt");
6289 #endif
6290
6291
6292                 /* Open the News file */
6293                 fp = my_fopen(buf, "r");
6294
6295                 /* Dump */
6296                 if (fp)
6297                 {
6298                         int i = 0;
6299
6300                         /* Dump the file to the screen */
6301                         while (0 == my_fgets(fp, buf, 1024))
6302                         {
6303                                 /* Display and advance */
6304                                 put_str(buf, i++, 0);
6305                         }
6306
6307                         /* Close */
6308                         my_fclose(fp);
6309                 }
6310
6311
6312                 /* King or Queen */
6313                 if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
6314                 {
6315 #ifdef JP
6316                 /* ±ÑÆüÀÚ¤êÂؤ¨ */
6317                   p= "°ÎÂç¤Ê¤ë¼Ô";
6318 #else
6319                         p = "Magnificent";
6320 #endif
6321
6322                 }
6323
6324                 /* Normal */
6325                 else
6326                 {
6327                         p =  player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
6328                 }
6329
6330                 center_string(buf, player_name);
6331                 put_str(buf, 6, 11);
6332
6333 #ifndef JP
6334                 center_string(buf, "the");
6335                 put_str(buf, 7, 11);
6336 #endif
6337
6338                 center_string(buf, p);
6339                 put_str(buf, 8, 11);
6340
6341
6342                 center_string(buf, cp_ptr->title);
6343
6344                 put_str(buf, 10, 11);
6345
6346 #ifdef JP
6347 (void)sprintf(tmp, "¥ì¥Ù¥ë: %d", (int)p_ptr->lev);
6348 #else
6349                 (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
6350 #endif
6351
6352                 center_string(buf, tmp);
6353                 put_str(buf, 11, 11);
6354
6355 #ifdef JP
6356 (void)sprintf(tmp, "·Ð¸³ÃÍ: %ld", (long)p_ptr->exp);
6357 #else
6358                 (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp);
6359 #endif
6360
6361                 center_string(buf, tmp);
6362                 put_str(buf, 12, 11);
6363
6364 #ifdef JP
6365 (void)sprintf(tmp, "½ê»ý¶â: %ld", (long)p_ptr->au);
6366 #else
6367                 (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au);
6368 #endif
6369
6370                 center_string(buf, tmp);
6371                 put_str(buf, 13, 11);
6372
6373 #ifdef JP
6374         /* Êè¤Ë¹ï¤à¸ÀÍÕ¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
6375         if (streq(died_from, "ÅÓÃ潪λ"))
6376         {
6377                 strcpy(tmp, "<¼«»¦>");
6378         }
6379         else
6380         {
6381                 if (streq(died_from, "ripe"))
6382                 {
6383                         strcpy(tmp, "°úÂà¸å¤ËÅ·¼÷¤òÁ´¤¦");
6384                 }
6385                 else if (streq(died_from, "Seppuku"))
6386                 {
6387                         strcpy(tmp, "¾¡Íø¤Î¸å¡¢ÀÚÊ¢");
6388                 }
6389                 else
6390                 {
6391                         strcpy(tmp, died_from);
6392                 }
6393         }
6394         center_string(buf, tmp);
6395         put_str(buf, 14, 11);
6396
6397         if(!streq(died_from, "ripe") && !streq(died_from, "Seppuku"))
6398         {
6399                 if( dun_level == 0 )
6400                 {
6401                         cptr town = (p_ptr->town_num ? "³¹" : "¹ÓÌî");
6402                         if(streq(died_from, "ÅÓÃ潪λ"))
6403                         {
6404                                 sprintf(tmp, "%s¤Ç»à¤ó¤À", town);
6405                         }
6406                         else
6407                         {
6408                                 sprintf(tmp, "¤Ë%s¤Ç»¦¤µ¤ì¤¿", town);
6409                         }
6410                 }
6411                 else
6412                 {
6413                         if(streq(died_from, "ÅÓÃ潪λ"))
6414                         {
6415                                 sprintf(tmp, "Ãϲ¼ %d ³¬¤Ç»à¤ó¤À", dun_level);
6416                         }
6417                         else
6418                         {
6419                                 sprintf(tmp, "¤ËÃϲ¼ %d ³¬¤Ç»¦¤µ¤ì¤¿", dun_level);
6420                         }
6421                 }
6422                 center_string(buf, tmp);
6423                 put_str(buf, 15, 11);
6424         }
6425 #else
6426                 (void)sprintf(tmp, "Killed on Level %d", dun_level);
6427                 center_string(buf, tmp);
6428                 put_str(buf, 14, 11);
6429
6430
6431                 if (strlen(died_from) > 24)
6432                 {
6433                         strncpy(dummy, died_from, 24);
6434                         dummy[24] = '\0';
6435                         (void)sprintf(tmp, "by %s.", dummy);
6436                 }
6437                 else
6438                         (void)sprintf(tmp, "by %s.", died_from);
6439
6440                 center_string(buf, tmp);
6441                 put_str(buf, 15, 11);
6442 #endif
6443
6444
6445
6446                 (void)sprintf(tmp, "%-.24s", ctime(&ct));
6447                 center_string(buf, tmp);
6448                 put_str(buf, 17, 11);
6449
6450 #ifdef JP
6451 msg_format("¤µ¤è¤¦¤Ê¤é¡¢%s!", player_name);
6452 #else
6453                 msg_format("Goodbye, %s!", player_name);
6454 #endif
6455
6456         }
6457 }
6458
6459
6460 /*
6461  * Display some character info
6462  */
6463 static void show_info(void)
6464 {
6465         int             i, j, k, l;
6466         object_type             *o_ptr;
6467         store_type              *st_ptr;
6468
6469         /* Hack -- Know everything in the inven/equip */
6470         for (i = 0; i < INVEN_TOTAL; i++)
6471         {
6472                 o_ptr = &inventory[i];
6473
6474                 /* Skip non-objects */
6475                 if (!o_ptr->k_idx) continue;
6476
6477                 /* Aware and Known */
6478                 object_aware(o_ptr);
6479                 object_known(o_ptr);
6480         }
6481
6482         for (i = 1; i < max_towns; i++)
6483         {
6484                 st_ptr = &town[i].store[STORE_HOME];
6485
6486                 /* Hack -- Know everything in the home */
6487                 for (j = 0; j < st_ptr->stock_num; j++)
6488                 {
6489                         o_ptr = &st_ptr->stock[j];
6490
6491                         /* Skip non-objects */
6492                         if (!o_ptr->k_idx) continue;
6493
6494                         /* Aware and Known */
6495                         object_aware(o_ptr);
6496                         object_known(o_ptr);
6497                 }
6498         }
6499
6500         /* Hack -- Recalculate bonuses */
6501         p_ptr->update |= (PU_BONUS);
6502
6503         /* Handle stuff */
6504         handle_stuff();
6505
6506         /* Flush all input keys */
6507         flush();
6508
6509         /* Flush messages */
6510         msg_print(NULL);
6511
6512
6513         /* Describe options */
6514 #ifdef JP
6515 prt("¥­¥ã¥é¥¯¥¿¡¼¤Îµ­Ï¿¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£", 21, 0);
6516 prt("¥ê¥¿¡¼¥ó¥­¡¼¤Ç¥­¥ã¥é¥¯¥¿¡¼¤ò¸«¤Þ¤¹¡£ESC¤ÇÃæÃǤ·¤Þ¤¹¡£", 22, 0);
6517 #else
6518         prt("You may now dump a character record to one or more files.", 21, 0);
6519         prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
6520 #endif
6521
6522
6523         /* Dump character records as requested */
6524         while (TRUE)
6525         {
6526                 char out_val[160];
6527
6528                 /* Prompt */
6529 #ifdef JP
6530 put_str("¥Õ¥¡¥¤¥ë¥Í¡¼¥à: ", 23, 0);
6531 #else
6532                 put_str("Filename: ", 23, 0);
6533 #endif
6534
6535
6536                 /* Default */
6537                 strcpy(out_val, "");
6538
6539                 /* Ask for filename (or abort) */
6540                 if (!askfor_aux(out_val, 60)) return;
6541
6542                 /* Return means "show on screen" */
6543                 if (!out_val[0]) break;
6544
6545                 /* Save screen */
6546                 screen_save();
6547
6548                 /* Dump a character file */
6549                 (void)file_character(out_val, TRUE);
6550
6551                 /* Load screen */
6552                 screen_load();
6553         }
6554
6555         update_playtime();
6556
6557         /* Display player */
6558         display_player(0);
6559
6560         /* Prompt for inventory */
6561 #ifdef JP
6562 prt("²¿¤«¥­¡¼¤ò²¡¤¹¤È¤µ¤é¤Ë¾ðÊó¤¬Â³¤­¤Þ¤¹ (ESC¤ÇÃæÃÇ): ", 23, 0);
6563 #else
6564         prt("Hit any key to see more information (ESC to abort): ", 23, 0);
6565 #endif
6566
6567
6568         /* Allow abort at this point */
6569         if (inkey() == ESCAPE) return;
6570
6571
6572         /* Show equipment and inventory */
6573
6574         /* Equipment -- if any */
6575         if (equip_cnt)
6576         {
6577                 Term_clear();
6578                 item_tester_full = TRUE;
6579                 (void)show_equip(0);
6580 #ifdef JP
6581 prt("ÁõÈ÷¤·¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6582 #else
6583                 prt("You are using: -more-", 0, 0);
6584 #endif
6585
6586                 if (inkey() == ESCAPE) return;
6587         }
6588
6589         /* Inventory -- if any */
6590         if (inven_cnt)
6591         {
6592                 Term_clear();
6593                 item_tester_full = TRUE;
6594                 (void)show_inven(0);
6595 #ifdef JP
6596 prt("»ý¤Ã¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6597 #else
6598                 prt("You are carrying: -more-", 0, 0);
6599 #endif
6600
6601                 if (inkey() == ESCAPE) return;
6602         }
6603
6604         /* Homes in the different towns */
6605         for (l = 1; l < max_towns; l++)
6606         {
6607                 st_ptr = &town[l].store[STORE_HOME];
6608
6609                 /* Home -- if anything there */
6610                 if (st_ptr->stock_num)
6611                 {
6612                         /* Display contents of the home */
6613                         for (k = 0, i = 0; i < st_ptr->stock_num; k++)
6614                         {
6615                                 /* Clear screen */
6616                                 Term_clear();
6617
6618                                 /* Show 12 items */
6619                                 for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++)
6620                                 {
6621                                         char o_name[MAX_NLEN];
6622                                         char tmp_val[80];
6623
6624                                         /* Acquire item */
6625                                         o_ptr = &st_ptr->stock[i];
6626
6627                                         /* Print header, clear line */
6628                                         sprintf(tmp_val, "%c) ", I2A(j));
6629                                         prt(tmp_val, j+2, 4);
6630
6631                                         /* Display object description */
6632                                         object_desc(o_name, o_ptr, TRUE, 3);
6633                                         c_put_str(tval_to_attr[o_ptr->tval], o_name, j+2, 7);
6634                                 }
6635
6636                                 /* Caption */
6637 #ifdef JP
6638 prt(format("²æ¤¬²È¤ËÃÖ¤¤¤Æ¤¢¤Ã¤¿¥¢¥¤¥Æ¥à ( %d ¥Ú¡¼¥¸): -³¤¯-", k+1), 0, 0);
6639 #else
6640                                 prt(format("Your home contains (page %d): -more-", k+1), 0, 0);
6641 #endif
6642
6643
6644                                 /* Wait for it */
6645                                 if (inkey() == ESCAPE) return;
6646                         }
6647                 }
6648         }
6649 }
6650
6651
6652 static bool check_score(void)
6653 {
6654         /* Clear screen */
6655         Term_clear();
6656
6657         /* No score file */
6658         if (highscore_fd < 0)
6659         {
6660 #ifdef JP
6661 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
6662 #else
6663                 msg_print("Score file unavailable.");
6664 #endif
6665
6666                 msg_print(NULL);
6667                 return FALSE;
6668         }
6669
6670 #ifndef SCORE_WIZARDS
6671         /* Wizard-mode pre-empts scoring */
6672         if (noscore & 0x000F)
6673         {
6674 #ifdef JP
6675 msg_print("¥¦¥£¥¶¡¼¥É¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6676 #else
6677                 msg_print("Score not registered for wizards.");
6678 #endif
6679
6680                 msg_print(NULL);
6681                 return FALSE;
6682         }
6683 #endif
6684
6685 #ifndef SCORE_BORGS
6686         /* Borg-mode pre-empts scoring */
6687         if (noscore & 0x00F0)
6688         {
6689 #ifdef JP
6690 msg_print("¥Ü¡¼¥°¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6691 #else
6692                 msg_print("Score not registered for borgs.");
6693 #endif
6694
6695                 msg_print(NULL);
6696                 return FALSE;
6697         }
6698 #endif
6699
6700 #ifndef SCORE_CHEATERS
6701         /* Cheaters are not scored */
6702         if (noscore & 0xFF00)
6703         {
6704 #ifdef JP
6705 msg_print("º¾µ½¤ò¤ä¤Ã¤¿¿Í¤Ï¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6706 #else
6707                 msg_print("Score not registered for cheaters.");
6708 #endif
6709
6710                 msg_print(NULL);
6711                 return FALSE;
6712         }
6713 #endif
6714
6715         /* Interupted */
6716 #ifdef JP
6717 if (!total_winner && streq(died_from, "¶¯À©½ªÎ»"))
6718 #else
6719         if (!total_winner && streq(died_from, "Interrupting"))
6720 #endif
6721
6722         {
6723 #ifdef JP
6724 msg_print("¶¯À©½ªÎ»¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6725 #else
6726                 msg_print("Score not registered due to interruption.");
6727 #endif
6728
6729                 msg_print(NULL);
6730                 return FALSE;
6731         }
6732
6733         /* Quitter */
6734 #ifdef JP
6735 if (!total_winner && streq(died_from, "ÅÓÃ潪λ"))
6736 #else
6737         if (!total_winner && streq(died_from, "Quitting"))
6738 #endif
6739
6740         {
6741 #ifdef JP
6742 msg_print("ÅÓÃ潪λ¤Î¤¿¤á¥¹¥³¥¢¤¬µ­Ï¿¤µ¤ì¤Þ¤»¤ó¡£");
6743 #else
6744                 msg_print("Score not registered due to quitting.");
6745 #endif
6746
6747                 msg_print(NULL);
6748                 return FALSE;
6749         }
6750         return TRUE;
6751 }
6752
6753 /*
6754  * Close up the current game (player may or may not be dead)
6755  *
6756  * This function is called only from "main.c" and "signals.c".
6757  */
6758 void close_game(void)
6759 {
6760         char buf[1024];
6761         bool do_send = TRUE;
6762
6763 /*      cptr p = "[i:¥­¥ã¥é¥¯¥¿¤Î¾ðÊó, f:¥Õ¥¡¥¤¥ë½ñ¤­½Ð¤·, t:¥¹¥³¥¢, x:*´ÕÄê*, ESC:¥²¡¼¥à½ªÎ»]"; */
6764
6765         /* Handle stuff */
6766         handle_stuff();
6767
6768         /* Flush the messages */
6769         msg_print(NULL);
6770
6771         /* Flush the input */
6772         flush();
6773
6774
6775         /* No suspending now */
6776         signals_ignore_tstp();
6777
6778
6779         /* Hack -- Character is now "icky" */
6780         character_icky = TRUE;
6781
6782
6783         /* Build the filename */
6784         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
6785
6786         /* Open the high score file, for reading/writing */
6787         highscore_fd = fd_open(buf, O_RDWR);
6788
6789
6790         /* Handle death */
6791         if (death)
6792         {
6793                 /* Handle retirement */
6794                 if (total_winner) kingly();
6795
6796                 /* Save memories */
6797 #ifdef JP
6798                 if (!munchkin_death || get_check("»à¤ó¤À¥Ç¡¼¥¿¤ò¥»¡¼¥Ö¤·¤Þ¤¹¤«¡© "))
6799 #else
6800                 if (!munchkin_death || get_check("Save death? "))
6801 #endif
6802                 {
6803
6804 #ifdef JP
6805 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6806 #else
6807                         if (!save_player()) msg_print("death save failed!");
6808 #endif
6809                 }
6810                 else do_send = FALSE;
6811
6812                 /* You are dead */
6813                 print_tomb();
6814
6815                 flush();
6816
6817                 /* Show more info */
6818                 show_info();
6819
6820                 /* Clear screen */
6821                 Term_clear();
6822
6823                 if (check_score())
6824                 {
6825                         if ((!send_world_score(do_send)))
6826                         {
6827 #ifdef JP
6828                                 if (get_check_strict("¸å¤Ç¥¹¥³¥¢¤òÅÐÏ¿¤¹¤ë¤¿¤á¤ËÂÔµ¡¤·¤Þ¤¹¤«¡©", (CHECK_NO_ESCAPE | CHECK_NO_HISTORY)))
6829 #else
6830                                 if (get_check_strict("Stand by for later score registration? ", (CHECK_NO_ESCAPE | CHECK_NO_HISTORY)))
6831 #endif
6832                                 {
6833                                         wait_report_score = TRUE;
6834                                         death = FALSE;
6835 #ifdef JP
6836                                         if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6837 #else
6838                                         if (!save_player()) msg_print("death save failed!");
6839 #endif
6840                                 }
6841                         }
6842                         if (!wait_report_score)
6843                                 (void)top_twenty();
6844                 }
6845                 else if (highscore_fd >= 0)
6846                 {
6847                         display_scores_aux(0, 10, -1, NULL);
6848                 }
6849 #if 0
6850                 /* Dump bones file */
6851                 make_bones();
6852 #endif
6853         }
6854
6855         /* Still alive */
6856         else
6857         {
6858                 /* Save the game */
6859                 do_cmd_save_game(FALSE);
6860
6861                 /* Prompt for scores XXX XXX XXX */
6862 #ifdef JP
6863 prt("¥ê¥¿¡¼¥ó¥­¡¼¤« ESC ¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 40);
6864 #else
6865                 prt("Press Return (or Escape).", 0, 40);
6866 #endif
6867
6868
6869                 /* Predict score (or ESCAPE) */
6870                 if (inkey() != ESCAPE) predict_score();
6871         }
6872
6873
6874         /* Shut the high score file */
6875         (void)fd_close(highscore_fd);
6876
6877         /* Forget the high score fd */
6878         highscore_fd = -1;
6879
6880
6881         /* Allow suspending now */
6882         signals_handle_tstp();
6883 }
6884
6885
6886 /*
6887  * Handle abrupt death of the visual system
6888  *
6889  * This routine is called only in very rare situations, and only
6890  * by certain visual systems, when they experience fatal errors.
6891  *
6892  * XXX XXX Hack -- clear the death flag when creating a HANGUP
6893  * save file so that player can see tombstone when restart.
6894  */
6895 void exit_game_panic(void)
6896 {
6897         /* If nothing important has happened, just quit */
6898 #ifdef JP
6899 if (!character_generated || character_saved) quit("¶ÛµÞ»öÂÖ");
6900 #else
6901         if (!character_generated || character_saved) quit("panic");
6902 #endif
6903
6904
6905         /* Mega-Hack -- see "msg_print()" */
6906         msg_flag = FALSE;
6907
6908         /* Clear the top line */
6909         prt("", 0, 0);
6910
6911         /* Hack -- turn off some things */
6912         disturb(1, 0);
6913
6914         /* Mega-Hack -- Delay death */
6915         if (p_ptr->chp < 0) death = FALSE;
6916
6917         /* Hardcode panic save */
6918         panic_save = 1;
6919
6920         /* Forbid suspend */
6921         signals_ignore_tstp();
6922
6923         /* Indicate panic save */
6924 #ifdef JP
6925 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
6926 #else
6927         (void)strcpy(died_from, "(panic save)");
6928 #endif
6929
6930
6931         /* Panic save, or get worried */
6932 #ifdef JP
6933 if (!save_player()) quit("¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
6934 #else
6935         if (!save_player()) quit("panic save failed!");
6936 #endif
6937
6938
6939         /* Successful panic save */
6940 #ifdef JP
6941 quit("¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
6942 #else
6943         quit("panic save succeeded!");
6944 #endif
6945
6946 }
6947
6948
6949 /*
6950  * Get a random line from a file
6951  * Based on the monster speech patch by Matt Graham,
6952  */
6953 errr get_rnd_line(cptr file_name, int entry, char *output)
6954 {
6955         FILE    *fp;
6956         char    buf[1024];
6957         int     line, counter, test, numentries;
6958         int     line_num = 0;
6959         bool    found = FALSE;
6960
6961
6962         /* Build the filename */
6963         path_build(buf, 1024, ANGBAND_DIR_FILE, file_name);
6964
6965         /* Open the file */
6966         fp = my_fopen(buf, "r");
6967
6968         /* Failed */
6969         if (!fp) return (-1);
6970
6971         /* Find the entry of the monster */
6972         while (TRUE)
6973         {
6974                 /* Get a line from the file */
6975                 if (my_fgets(fp, buf, 1024) == 0)
6976                 {
6977                         /* Count the lines */
6978                         line_num++;
6979
6980                         /* Look for lines starting with 'N:' */
6981                         if ((buf[0] == 'N') && (buf[1] == ':'))
6982                         {
6983                                 /* Allow default lines */
6984                                 if (buf[2] == '*')
6985                                 {
6986                                         /* Default lines */
6987                                         found = TRUE;
6988                                         break;
6989                                 }
6990                                 else if (buf[2] == 'M')
6991                                 {
6992                                         if (r_info[entry].flags1 & RF1_MALE)
6993                                         {
6994                                                 found = TRUE;
6995                                                 break;
6996                                         }
6997                                 }
6998                                 else if (buf[2] == 'F')
6999                                 {
7000                                         if (r_info[entry].flags1 & RF1_FEMALE)
7001                                         {
7002                                                 found = TRUE;
7003                                                 break;
7004                                         }
7005                                 }
7006                                 /* Get the monster number */
7007                                 else if (sscanf(&(buf[2]), "%d", &test) != EOF)
7008                                 {
7009                                         /* Is it the right monster? */
7010                                         if (test == entry)
7011                                         {
7012                                                 found = TRUE;
7013                                                 break;
7014                                         }
7015                                 }
7016                                 else
7017                                 {
7018                                         /* Error while converting the monster number */
7019                                         msg_format("Error in line %d of %s!",
7020                                                   line_num, file_name);
7021                                         my_fclose(fp);
7022                                         return (-1);
7023                                 }
7024                         }
7025                 }
7026                 else
7027                 {
7028                         /* Reached end of file */
7029                         my_fclose(fp);
7030                         return (-1);
7031                 }
7032
7033         }
7034         
7035         /* Get the number of entries */
7036         while (TRUE)
7037         {
7038                 /* Get the line */
7039                 if (my_fgets(fp, buf, 1024) == 0)
7040                 {
7041                         /* Count the lines */
7042                         line_num++;
7043
7044                         /* Look for the number of entries */
7045                         if (isdigit(buf[0]))
7046                         {
7047                                 /* Get the number of entries */
7048                                 numentries = atoi(buf);
7049                                 break;
7050                         }
7051                 }
7052                 else
7053                 {
7054                         /* Count the lines */
7055                         line_num++;
7056
7057                         /* Reached end of file without finding the number */
7058                         msg_format("Error in line %d of %s!",
7059                                   line_num, file_name);
7060
7061                         my_fclose(fp);
7062                         return (-1);
7063                 }
7064         }
7065
7066         if (numentries > 0)
7067         {
7068                 /* Grab an appropriate line number */
7069                 line = randint0(numentries);
7070
7071                 /* Get the random line */
7072                 for (counter = 0; counter <= line; counter++)
7073                 {
7074                         /* Count the lines */
7075                         line_num++;
7076
7077                         while(TRUE)
7078                         {
7079                                 test = my_fgets(fp, buf, 1024);
7080                                 if(test || buf[0] != '#')
7081                                         break;
7082                         }
7083
7084                         if (test==0)
7085                         {
7086                                 /* Found the line */
7087                                 if (counter == line) break;
7088                         }
7089                         else
7090                         {
7091                                 /* Error - End of file */
7092                                 msg_format("Error in line %d of %s!",
7093                                           line_num, file_name);
7094
7095                                 my_fclose(fp);
7096                                 return (-1);
7097                         }
7098                 }
7099
7100                 /* Copy the line */
7101                 strcpy(output, buf);
7102         }
7103         else
7104         {
7105                 return (-1);
7106         }
7107
7108         /* Close the file */
7109         my_fclose(fp);
7110
7111         /* Success */
7112         return (0);
7113 }
7114
7115
7116 #ifdef JP
7117 errr get_rnd_line_jonly(cptr file_name, int entry, char *output, int count)
7118 {
7119   int i,j,kanji;
7120   errr result=1;
7121   for (i=0;i<count;i++){
7122     result=get_rnd_line(file_name, entry, output);
7123     if(result)break;
7124     kanji=0;
7125     for(j=0; output[j]; j++) kanji |= iskanji(output[j]);
7126     if(kanji)break;
7127   }
7128   return(result);
7129 }
7130 #endif
7131
7132 /*
7133  * Process file for auto picker/destroyer.
7134  */
7135 errr process_pickpref_file(cptr name)
7136 {
7137         char buf[1024];
7138
7139         errr err = 0;
7140
7141         /* Drop priv's */
7142         safe_setuid_drop();
7143
7144         /* Build the filename */
7145         path_build(buf, 1024, ANGBAND_DIR_USER, name);
7146
7147         err = process_pref_file_aux(buf, TRUE);
7148
7149         /* Grab priv's */
7150         safe_setuid_grab();
7151
7152         /* Result */
7153         return (err);
7154 }
7155
7156 static errr counts_seek(int fd, u32b where, bool flag)
7157 {
7158         huge seekpoint;
7159         char temp1[128], temp2[128];
7160         u32b zero_header[3] = {0L, 0L, 0L};
7161         int i;
7162
7163 #ifdef SAVEFILE_USE_UID
7164         (void)sprintf(temp1, "%d.%s.%d%d%d", player_uid, savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7165 #else
7166         (void)sprintf(temp1, "%s.%d%d%d", savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7167 #endif
7168         for (i = 0; temp1[i]; i++)
7169                 temp1[i] ^= (i+1) * 63;
7170
7171         seekpoint = 0;
7172         while (1)
7173         {
7174                 if (fd_seek(fd, seekpoint + 3 * sizeof(u32b)))
7175                         return 1;
7176                 if (fd_read(fd, (char*)(temp2), sizeof(temp2)))
7177                 {
7178                         if (!flag)
7179                                 return 1;
7180                         /* add new name */
7181                         fd_seek(fd, seekpoint);
7182                         fd_write(fd, (char*)zero_header, 3*sizeof(u32b));
7183                         fd_write(fd, (char*)(temp1), sizeof(temp1));
7184                         break;
7185                 }
7186
7187                 if (strcmp(temp1, temp2) == 0)
7188                         break;
7189
7190                 seekpoint += 128 + 3 * sizeof(u32b);
7191         }
7192
7193         return fd_seek(fd, seekpoint + where * sizeof(u32b));
7194 }
7195
7196 u32b counts_read(int where)
7197 {
7198         int fd;
7199         u32b count = 0;
7200         char buf[1024];
7201
7202 #ifdef JP
7203         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7204 #else
7205         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7206 #endif
7207         fd = fd_open(buf, O_RDONLY);
7208
7209         if (counts_seek(fd, where, FALSE) ||
7210             fd_read(fd, (char*)(&count), sizeof(u32b)))
7211                 count = 0;
7212
7213         (void)fd_close(fd);
7214
7215         return count;
7216 }
7217
7218 errr counts_write(int where, u32b count)
7219 {
7220         int fd;
7221         char buf[1024];
7222
7223 #ifdef JP
7224         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7225 #else
7226         path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7227 #endif
7228         fd = fd_open(buf, O_RDWR);
7229         if (fd < 0)
7230         {
7231                 /* File type is "DATA" */
7232                 FILE_TYPE(FILE_TYPE_DATA);
7233
7234                 /* Create a new high score file */
7235                 fd = fd_make(buf, 0644);
7236         }
7237
7238         if (fd_lock(fd, F_WRLCK)) return 1;
7239
7240         counts_seek(fd, where, TRUE);
7241         fd_write(fd, (char*)(&count), sizeof(u32b));
7242
7243         if (fd_lock(fd, F_UNLCK)) return 1;
7244
7245         (void)fd_close(fd);
7246
7247         return 0;
7248 }
7249
7250
7251 #ifdef HANDLE_SIGNALS
7252
7253
7254 #include <signal.h>
7255
7256
7257 /*
7258  * Handle signals -- suspend
7259  *
7260  * Actually suspend the game, and then resume cleanly
7261  */
7262 static void handle_signal_suspend(int sig)
7263 {
7264         /* Disable handler */
7265         (void)signal(sig, SIG_IGN);
7266
7267 #ifdef SIGSTOP
7268
7269         /* Flush output */
7270         Term_fresh();
7271
7272         /* Suspend the "Term" */
7273         Term_xtra(TERM_XTRA_ALIVE, 0);
7274
7275         /* Suspend ourself */
7276         (void)kill(0, SIGSTOP);
7277
7278         /* Resume the "Term" */
7279         Term_xtra(TERM_XTRA_ALIVE, 1);
7280
7281         /* Redraw the term */
7282         Term_redraw();
7283
7284         /* Flush the term */
7285         Term_fresh();
7286
7287 #endif
7288
7289         /* Restore handler */
7290         (void)signal(sig, handle_signal_suspend);
7291 }
7292
7293
7294 /*
7295  * Handle signals -- simple (interrupt and quit)
7296  *
7297  * This function was causing a *huge* number of problems, so it has
7298  * been simplified greatly.  We keep a global variable which counts
7299  * the number of times the user attempts to kill the process, and
7300  * we commit suicide if the user does this a certain number of times.
7301  *
7302  * We attempt to give "feedback" to the user as he approaches the
7303  * suicide thresh-hold, but without penalizing accidental keypresses.
7304  *
7305  * To prevent messy accidents, we should reset this global variable
7306  * whenever the user enters a keypress, or something like that.
7307  */
7308 static void handle_signal_simple(int sig)
7309 {
7310         /* Disable handler */
7311         (void)signal(sig, SIG_IGN);
7312
7313
7314         /* Nothing to save, just quit */
7315         if (!character_generated || character_saved) quit(NULL);
7316
7317
7318         /* Count the signals */
7319         signal_count++;
7320
7321
7322         /* Terminate dead characters */
7323         if (death)
7324         {
7325                 /* Mark the savefile */
7326 #ifdef JP
7327 (void)strcpy(died_from, "¶¯À©½ªÎ»");
7328 #else
7329                 (void)strcpy(died_from, "Abortion");
7330 #endif
7331
7332                 forget_lite();
7333                 forget_view();
7334                 clear_mon_lite();
7335
7336                 /* Close stuff */
7337                 close_game();
7338
7339                 /* Quit */
7340 #ifdef JP
7341 quit("¶¯À©½ªÎ»");
7342 #else
7343                 quit("interrupt");
7344 #endif
7345
7346         }
7347
7348         /* Allow suicide (after 5) */
7349         else if (signal_count >= 5)
7350         {
7351                 /* Cause of "death" */
7352 #ifdef JP
7353 (void)strcpy(died_from, "¶¯À©½ªÎ»Ãæ");
7354 #else
7355                 (void)strcpy(died_from, "Interrupting");
7356 #endif
7357
7358
7359                 forget_lite();
7360                 forget_view();
7361                 clear_mon_lite();
7362
7363                 /* Stop playing */
7364                 alive = FALSE;
7365
7366                 /* Suicide */
7367                 death = TRUE;
7368
7369                 /* Leaving */
7370                 p_ptr->leaving = TRUE;
7371
7372                 /* Close stuff */
7373                 close_game();
7374
7375                 /* Quit */
7376 #ifdef JP
7377 quit("¶¯À©½ªÎ»");
7378 #else
7379                 quit("interrupt");
7380 #endif
7381
7382         }
7383
7384         /* Give warning (after 4) */
7385         else if (signal_count >= 4)
7386         {
7387                 /* Make a noise */
7388                 Term_xtra(TERM_XTRA_NOISE, 0);
7389
7390                 /* Clear the top line */
7391                 Term_erase(0, 0, 255);
7392
7393                 /* Display the cause */
7394 #ifdef JP
7395 Term_putstr(0, 0, -1, TERM_WHITE, "½Ïθ¤Î¾å¤Î¼«»¦¡ª");
7396 #else
7397                 Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");
7398 #endif
7399
7400
7401                 /* Flush */
7402                 Term_fresh();
7403         }
7404
7405         /* Give warning (after 2) */
7406         else if (signal_count >= 2)
7407         {
7408                 /* Make a noise */
7409                 Term_xtra(TERM_XTRA_NOISE, 0);
7410         }
7411
7412         /* Restore handler */
7413         (void)signal(sig, handle_signal_simple);
7414 }
7415
7416
7417 /*
7418  * Handle signal -- abort, kill, etc
7419  */
7420 static void handle_signal_abort(int sig)
7421 {
7422         int wid, hgt, rows;
7423
7424         Term_get_size(&wid, &hgt);
7425         rows = hgt - 4;
7426
7427         /* Disable handler */
7428         (void)signal(sig, SIG_IGN);
7429
7430
7431         /* Nothing to save, just quit */
7432         if (!character_generated || character_saved) quit(NULL);
7433
7434
7435         forget_lite();
7436         forget_view();
7437         clear_mon_lite();
7438
7439         /* Clear the bottom line */
7440         Term_erase(0, hgt - 1, 255);
7441
7442         /* Give a warning */
7443         Term_putstr(0, hgt - 1, -1, TERM_RED,
7444 #ifdef JP
7445 "¶²¤í¤·¤¤¥½¥Õ¥È¤Î¥Ð¥°¤¬Èô¤Ó¤«¤«¤Ã¤Æ¤­¤¿¡ª");
7446 #else
7447                     "A gruesome software bug LEAPS out at you!");
7448 #endif
7449
7450
7451         /* Message */
7452 #ifdef JP
7453 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö...");
7454 #else
7455         Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save...");
7456 #endif
7457
7458
7459         /* Flush output */
7460         Term_fresh();
7461
7462         /* Panic Save */
7463         panic_save = 1;
7464
7465         /* Panic save */
7466 #ifdef JP
7467 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
7468 #else
7469         (void)strcpy(died_from, "(panic save)");
7470 #endif
7471
7472
7473         /* Forbid suspend */
7474         signals_ignore_tstp();
7475
7476         /* Attempt to save */
7477         if (save_player())
7478         {
7479 #ifdef JP
7480 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
7481 #else
7482                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save succeeded!");
7483 #endif
7484
7485         }
7486
7487         /* Save failed */
7488         else
7489         {
7490 #ifdef JP
7491 Term_putstr(45, hgt - 1, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
7492 #else
7493                 Term_putstr(45, hgt - 1, -1, TERM_RED, "Panic save failed!");
7494 #endif
7495
7496         }
7497
7498         /* Flush output */
7499         Term_fresh();
7500
7501         /* Quit */
7502 #ifdef JP
7503 quit("¥½¥Õ¥È¤Î¥Ð¥°");
7504 #else
7505         quit("software bug");
7506 #endif
7507
7508 }
7509
7510
7511
7512
7513 /*
7514  * Ignore SIGTSTP signals (keyboard suspend)
7515  */
7516 void signals_ignore_tstp(void)
7517 {
7518
7519 #ifdef SIGTSTP
7520         (void)signal(SIGTSTP, SIG_IGN);
7521 #endif
7522
7523 }
7524
7525 /*
7526  * Handle SIGTSTP signals (keyboard suspend)
7527  */
7528 void signals_handle_tstp(void)
7529 {
7530
7531 #ifdef SIGTSTP
7532         (void)signal(SIGTSTP, handle_signal_suspend);
7533 #endif
7534
7535 }
7536
7537
7538 /*
7539  * Prepare to handle the relevant signals
7540  */
7541 void signals_init(void)
7542 {
7543
7544 #ifdef SIGHUP
7545         (void)signal(SIGHUP, SIG_IGN);
7546 #endif
7547
7548
7549 #ifdef SIGTSTP
7550         (void)signal(SIGTSTP, handle_signal_suspend);
7551 #endif
7552
7553
7554 #ifdef SIGINT
7555         (void)signal(SIGINT, handle_signal_simple);
7556 #endif
7557
7558 #ifdef SIGQUIT
7559         (void)signal(SIGQUIT, handle_signal_simple);
7560 #endif
7561
7562
7563 #ifdef SIGFPE
7564         (void)signal(SIGFPE, handle_signal_abort);
7565 #endif
7566
7567 #ifdef SIGILL
7568         (void)signal(SIGILL, handle_signal_abort);
7569 #endif
7570
7571 #ifdef SIGTRAP
7572         (void)signal(SIGTRAP, handle_signal_abort);
7573 #endif
7574
7575 #ifdef SIGIOT
7576         (void)signal(SIGIOT, handle_signal_abort);
7577 #endif
7578
7579 #ifdef SIGKILL
7580         (void)signal(SIGKILL, handle_signal_abort);
7581 #endif
7582
7583 #ifdef SIGBUS
7584         (void)signal(SIGBUS, handle_signal_abort);
7585 #endif
7586
7587 #ifdef SIGSEGV
7588         (void)signal(SIGSEGV, handle_signal_abort);
7589 #endif
7590
7591 #ifdef SIGTERM
7592         (void)signal(SIGTERM, handle_signal_abort);
7593 #endif
7594
7595 #ifdef SIGPIPE
7596         (void)signal(SIGPIPE, handle_signal_abort);
7597 #endif
7598
7599 #ifdef SIGEMT
7600         (void)signal(SIGEMT, handle_signal_abort);
7601 #endif
7602
7603 #ifdef SIGDANGER
7604         (void)signal(SIGDANGER, handle_signal_abort);
7605 #endif
7606
7607 #ifdef SIGSYS
7608         (void)signal(SIGSYS, handle_signal_abort);
7609 #endif
7610
7611 #ifdef SIGXCPU
7612         (void)signal(SIGXCPU, handle_signal_abort);
7613 #endif
7614
7615 #ifdef SIGPWR
7616         (void)signal(SIGPWR, handle_signal_abort);
7617 #endif
7618
7619 }
7620
7621
7622 #else   /* HANDLE_SIGNALS */
7623
7624
7625 /*
7626  * Do nothing
7627  */
7628 void signals_ignore_tstp(void)
7629 {
7630 }
7631
7632 /*
7633  * Do nothing
7634  */
7635 void signals_handle_tstp(void)
7636 {
7637 }
7638
7639 /*
7640  * Do nothing
7641  */
7642 void signals_init(void)
7643 {
7644 }
7645 #endif  /* HANDLE_SIGNALS */