3 /* Purpose: code dealing with files (and death) */
6 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
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.
17 * You may or may not want to use the following "#undef".
19 /* #undef _POSIX_SAVED_IDS */
23 * Hack -- drop permissions
25 void safe_setuid_drop(void)
32 # ifdef SAFE_SETUID_POSIX
34 if (setuid(getuid()) != 0)
37 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
39 quit("setuid(): cannot set permissions correctly!");
43 if (setgid(getgid()) != 0)
46 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
48 quit("setgid(): cannot set permissions correctly!");
55 if (setreuid(geteuid(), getuid()) != 0)
58 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
60 quit("setreuid(): cannot set permissions correctly!");
64 if (setregid(getegid(), getgid()) != 0)
67 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
69 quit("setregid(): cannot set permissions correctly!");
84 * Hack -- grab permissions
86 void safe_setuid_grab(void)
93 # ifdef SAFE_SETUID_POSIX
95 if (setuid(player_euid) != 0)
98 quit("setuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
100 quit("setuid(): cannot set permissions correctly!");
104 if (setgid(player_egid) != 0)
107 quit("setgid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
109 quit("setgid(): cannot set permissions correctly!");
116 if (setreuid(geteuid(), getuid()) != 0)
119 quit("setreuid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
121 quit("setreuid(): cannot set permissions correctly!");
125 if (setregid(getegid(), getgid()) != 0)
128 quit("setregid(): Àµ¤·¤¯µö²Ä¤¬¼è¤ì¤Þ¤»¤ó¡ª");
130 quit("setregid(): cannot set permissions correctly!");
135 # endif /* SAFE_SETUID_POSIX */
137 # endif /* SAFE_SETUID */
145 * Extract the first few "tokens" from a buffer
147 * This function uses "colon" and "slash" as the delimeter characters.
149 * We never extract more than "num" tokens. The "last" token may include
150 * "delimeter" characters, allowing the buffer to include a "string" token.
152 * We save pointers to the tokens in "tokens", and return the number found.
154 * Hack -- Attempt to handle the 'c' character formalism
156 * Hack -- An empty buffer, or a final delimeter, yields an "empty" token.
158 * Hack -- We will always extract at least one token
160 s16b tokenize(char *buf, s16b num, char **tokens, int mode)
172 /* Scan the string */
175 /* Found a delimiter */
176 if ((*t == ':') || (*t == '/')) break;
178 /* Handle single quotes */
179 if ((mode & TOKENIZE_CHECKQUOTE) && (*t == '\''))
184 /* Handle backslash */
187 /* Require a character */
193 /* Hack -- Require a close quote */
194 if (*t != '\'') *t = '\'';
197 /* Handle back-slash */
204 /* Nuke and advance */
222 /* A number with a name */
223 typedef struct named_num named_num;
227 cptr name; /* The name of this thing */
228 int num; /* A number associated with it */
232 /* Index of spell type names */
233 static named_num gf_desc[] =
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 },
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 },
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 },
335 * Parse a sub-file of the "extra info" (format shown below)
337 * Each "action" line has an "action symbol" in the first column,
338 * followed by a colon, followed by some command specific info,
339 * usually in the form of "tokens" separated by colons or slashes.
341 * Blank lines, lines starting with white space, and lines starting
342 * with pound signs ("#") are ignored (as comments).
344 * Note the use of "tokenize()" to allow the use of both colons and
345 * slashes as delimeters, while still allowing final tokens which
346 * may contain any characters including "delimiters".
348 * Note the use of "strtol()" to allow all "integers" to be encoded
349 * in decimal, hexidecimal, or octal form.
351 * Note that "monster zero" is used for the "player" attr/char, "object
352 * zero" will be used for the "stack" attr/char, and "feature zero" is
353 * used for the "nothing" attr/char.
355 * Parse another file recursively, see below for details
358 * Specify the attr/char values for "monsters" by race index
361 * Specify the attr/char values for "objects" by kind index
364 * Specify the attr/char values for "features" by feature index
367 * Specify the attr/char values for unaware "objects" by kind tval
370 * Specify the attr/char values for inventory "objects" by kind tval
373 * Define a macro action, given an encoded macro action
376 * Create a normal macro, given an encoded macro trigger
379 * Create a command macro, given an encoded macro trigger
382 * Create a keyset mapping
383 * S:<key>:<key>:<dir>
385 * Turn an option off, given its name
388 * Turn an option on, given its name
391 * Specify visual information, given an index, and some data
392 * V:<num>:<kv>:<rv>:<gv>:<bv>
394 * Specify the set of colors to use when drawing a zapped spell
397 errr process_pref_file_command(char *buf)
404 /* Skip "empty" lines */
405 if (!buf[0]) return (0);
407 /* Skip "blank" lines */
408 if (isspace(buf[0])) return (0);
411 if (buf[0] == '#') return (0);
413 /* Require "?:*" format */
414 if (buf[1] != ':') return (1);
417 /* Process "%:<fname>" */
420 /* Attempt to Process the given file */
421 return (process_pref_file(buf + 2));
425 /* Process "R:<num>:<a>/<c>" -- attr/char for monster races */
428 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
431 i = (huge)strtol(zz[0], NULL, 0);
432 n1 = strtol(zz[1], NULL, 0);
433 n2 = strtol(zz[2], NULL, 0);
434 if (i >= max_r_idx) return (1);
436 if (n1) r_ptr->x_attr = n1;
437 if (n2) r_ptr->x_char = n2;
442 /* Process "K:<num>:<a>/<c>" -- attr/char for object kinds */
443 else if (buf[0] == 'K')
445 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
448 i = (huge)strtol(zz[0], NULL, 0);
449 n1 = strtol(zz[1], NULL, 0);
450 n2 = strtol(zz[2], NULL, 0);
451 if (i >= max_k_idx) return (1);
453 if (n1) k_ptr->x_attr = n1;
454 if (n2) k_ptr->x_char = n2;
459 /* Process "F:<num>:<a>/<c>" -- attr/char for terrain features */
460 else if (buf[0] == 'F')
462 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
465 i = (huge)strtol(zz[0], NULL, 0);
466 n1 = strtol(zz[1], NULL, 0);
467 n2 = strtol(zz[2], NULL, 0);
468 if (i >= max_f_idx) return (1);
470 if (n1) f_ptr->x_attr = n1;
471 if (n2) f_ptr->x_char = n2;
476 /* Process "S:<num>:<a>/<c>" -- attr/char for special things */
477 else if (buf[0] == 'S')
479 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
481 j = (byte)strtol(zz[0], NULL, 0);
482 n1 = strtol(zz[1], NULL, 0);
483 n2 = strtol(zz[2], NULL, 0);
484 misc_to_attr[j] = n1;
485 misc_to_char[j] = n2;
490 /* Process "U:<tv>:<a>/<c>" -- attr/char for unaware items */
491 else if (buf[0] == 'U')
493 if (tokenize(buf+2, 3, zz, TOKENIZE_CHECKQUOTE) == 3)
495 j = (huge)strtol(zz[0], NULL, 0);
496 n1 = strtol(zz[1], NULL, 0);
497 n2 = strtol(zz[2], NULL, 0);
498 for (i = 1; i < max_k_idx; i++)
500 object_kind *k_ptr = &k_info[i];
501 if (k_ptr->tval == j)
503 if (n1) k_ptr->d_attr = n1;
504 if (n2) k_ptr->d_char = n2;
511 /* Process "E:<tv>:<a>" -- attribute for inventory objects */
512 else if (buf[0] == 'E')
514 if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) == 2)
516 j = (byte)strtol(zz[0], NULL, 0) % 128;
517 n1 = strtol(zz[1], NULL, 0);
518 if (n1) tval_to_attr[j] = n1;
524 /* Process "A:<str>" -- save an "action" for later */
525 else if (buf[0] == 'A')
527 text_to_ascii(macro__buf, buf+2);
531 /* Process "P:<str>" -- normal macro */
532 else if (buf[0] == 'P')
535 text_to_ascii(tmp, buf+2);
536 macro_add(tmp, macro__buf);
541 /* Process "C:<str>" -- create keymap */
542 else if (buf[0] == 'C')
548 if (tokenize(buf+2, 2, zz, TOKENIZE_CHECKQUOTE) != 2) return (1);
550 mode = strtol(zz[0], NULL, 0);
551 if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1);
553 text_to_ascii(tmp, zz[1]);
554 if (!tmp[0] || tmp[1]) return (1);
557 string_free(keymap_act[mode][i]);
559 keymap_act[mode][i] = string_make(macro__buf);
565 /* Process "V:<num>:<kv>:<rv>:<gv>:<bv>" -- visual info */
566 else if (buf[0] == 'V')
568 if (tokenize(buf+2, 5, zz, TOKENIZE_CHECKQUOTE) == 5)
570 i = (byte)strtol(zz[0], NULL, 0);
571 angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0);
572 angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0);
573 angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0);
574 angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0);
580 /* Process "X:<str>" -- turn option off */
581 else if (buf[0] == 'X')
583 for (i = 0; option_info[i].o_desc; i++)
585 int os = option_info[i].o_set;
586 int ob = option_info[i].o_bit;
588 if (option_info[i].o_var &&
589 option_info[i].o_text &&
590 streq(option_info[i].o_text, buf + 2) &&
591 (!alive || option_info[i].o_page !=6))
594 option_flag[os] &= ~(1L << ob);
595 (*option_info[i].o_var) = FALSE;
601 /* Process "Y:<str>" -- turn option on */
602 else if (buf[0] == 'Y')
604 for (i = 0; option_info[i].o_desc; i++)
606 int os = option_info[i].o_set;
607 int ob = option_info[i].o_bit;
609 if (option_info[i].o_var &&
610 option_info[i].o_text &&
611 streq(option_info[i].o_text, buf + 2) &&
612 (!alive || option_info[i].o_page !=6))
615 option_flag[os] |= (1L << ob);
616 (*option_info[i].o_var) = TRUE;
622 /* Process "Z:<type>:<str>" -- set spell color */
623 else if (buf[0] == 'Z')
626 char *t = strchr(buf + 2, ':');
634 for (i = 0; gf_desc[i].name; i++)
636 /* Match this type */
637 if (streq(gf_desc[i].name, buf + 2))
639 /* Remember this color set */
640 gf_color[gf_desc[i].num] = quark_add(t);
655 * Helper function for "process_pref_file()"
658 * v: output buffer array
664 static cptr process_pref_file_expr(char **sp, char *fp)
681 while (isspace(*s)) s++;
699 t = process_pref_file_expr(&s, &f);
708 else if (streq(t, "IOR"))
711 while (*s && (f != b2))
713 t = process_pref_file_expr(&s, &f);
714 if (*t && !streq(t, "0")) v = "1";
719 else if (streq(t, "AND"))
722 while (*s && (f != b2))
724 t = process_pref_file_expr(&s, &f);
725 if (*t && streq(t, "0")) v = "0";
730 else if (streq(t, "NOT"))
733 while (*s && (f != b2))
735 t = process_pref_file_expr(&s, &f);
736 if (*t && streq(t, "1")) v = "0";
741 else if (streq(t, "EQU"))
746 t = process_pref_file_expr(&s, &f);
748 while (*s && (f != b2))
751 t = process_pref_file_expr(&s, &f);
752 if (*t && !streq(p, t)) v = "0";
757 else if (streq(t, "LEQ"))
762 t = process_pref_file_expr(&s, &f);
764 while (*s && (f != b2))
767 t = process_pref_file_expr(&s, &f);
768 if (*t && (strcmp(p, t) > 0)) v = "0";
773 else if (streq(t, "GEQ"))
778 t = process_pref_file_expr(&s, &f);
780 while (*s && (f != b2))
783 t = process_pref_file_expr(&s, &f);
784 if (*t && (strcmp(p, t) < 0)) v = "0";
791 while (*s && (f != b2))
793 t = process_pref_file_expr(&s, &f);
798 if (f != b2) v = "?x?x?";
800 /* Extract final and Terminate */
801 if ((f = *s) != '\0') *s++ = '\0';
807 /* Accept all printables except spaces and brackets */
808 while (isprint(*s) && !strchr(" []", *s)) ++s;
810 /* Extract final and Terminate */
811 if ((f = *s) != '\0') *s++ = '\0';
817 if (streq(b+1, "SYS"))
823 else if (streq(b+1, "GRAF"))
828 /* Monochrome mode */
829 else if (streq(b+1, "MONOCHROME"))
838 else if (streq(b+1, "RACE"))
848 else if (streq(b+1, "CLASS"))
858 else if (streq(b+1, "REALM1"))
861 v = E_realm_names[p_ptr->realm1];
863 v = realm_names[p_ptr->realm1];
868 else if (streq(b+1, "REALM2"))
871 v = E_realm_names[p_ptr->realm2];
873 v = realm_names[p_ptr->realm2];
878 else if (streq(b+1, "PLAYER"))
884 else if (streq(b+1, "REALM1"))
887 v = E_realm_names[p_ptr->realm1];
889 v = realm_names[p_ptr->realm1];
894 else if (streq(b+1, "REALM2"))
897 v = E_realm_names[p_ptr->realm2];
899 v = realm_names[p_ptr->realm2];
904 else if (streq(b+1, "LEVEL"))
906 sprintf(tmp, "%02d", p_ptr->lev);
930 * Open the "user pref file" and parse it.
932 static errr process_pref_file_aux(cptr name)
948 fp = my_fopen(name, "r");
951 if (!fp) return (-1);
953 /* Process the file */
954 while (0 == my_fgets(fp, buf, 1024))
960 /* Skip "empty" lines */
961 if (!buf[0]) continue;
963 /* Skip "blank" lines */
964 if (isspace(buf[0])) continue;
967 if (buf[0] == '#') continue;
974 /* Process "?:<expr>" */
975 if ((buf[0] == '?') && (buf[1] == ':'))
985 v = process_pref_file_expr(&s, &f);
988 bypass = (streq(v, "0") ? TRUE : FALSE);
994 /* Apply conditionals */
995 if (bypass) continue;
998 /* Process "%:<file>" */
1001 /* Process that file if allowed */
1002 (void)process_pref_file(buf + 2);
1009 /* Process the line */
1010 err = process_pref_file_command(buf);
1020 /* Print error message */
1021 /* ToDo: Add better error messages */
1023 msg_format("¥Õ¥¡¥¤¥ë'%s'¤Î%d¹Ô¤Ç¥¨¥é¡¼ÈÖ¹æ%d¤Î¥¨¥é¡¼¡£", name, line, err);
1024 msg_format("('%s'¤ò²òÀÏÃæ)", old);
1026 msg_format("Error %d in line %d of file '%s'.", err, line, name);
1027 msg_format("Parsing '%s'", old);
1032 /* Close the file */
1042 * Process the "user pref file" with the given name
1044 * See the functions above for a list of legal "commands".
1046 * We also accept the special "?" and "%" directives, which
1047 * allow conditional evaluation and filename inclusion.
1049 errr process_pref_file(cptr name)
1055 /* Build the filename */
1056 path_build(buf, 1024, ANGBAND_DIR_PREF, name);
1058 /* Process the pref file */
1059 err = process_pref_file_aux(buf);
1061 /* Stop at parser errors, but not at non-existing file */
1064 /* Build the filename */
1065 path_build(buf, 1024, ANGBAND_DIR_USER, name);
1067 /* Process the pref file */
1068 err = process_pref_file_aux(buf);
1080 * Operating hours for ANGBAND (defaults to non-work hours)
1082 static char days[7][29] =
1084 "SUN:XXXXXXXXXXXXXXXXXXXXXXXX",
1085 "MON:XXXXXXXX.........XXXXXXX",
1086 "TUE:XXXXXXXX.........XXXXXXX",
1087 "WED:XXXXXXXX.........XXXXXXX",
1088 "THU:XXXXXXXX.........XXXXXXX",
1089 "FRI:XXXXXXXX.........XXXXXXX",
1090 "SAT:XXXXXXXXXXXXXXXXXXXXXXXX"
1094 * Restict usage (defaults to no restrictions)
1096 static bool check_time_flag = FALSE;
1104 errr check_time(void)
1112 /* No restrictions */
1113 if (!check_time_flag) return (0);
1115 /* Check for time violation */
1116 c = time((time_t *)0);
1120 if (days[tp->tm_wday][tp->tm_hour + 4] != 'X') return (1);
1131 * Initialize CHECK_TIME
1133 errr check_time_init(void)
1143 /* Build the filename */
1144 path_build(buf, 1024, ANGBAND_DIR_FILE, "time.txt");
1147 fp = my_fopen(buf, "r");
1149 /* No file, no restrictions */
1150 if (!fp) return (0);
1152 /* Assume restrictions */
1153 check_time_flag = TRUE;
1155 /* Parse the file */
1156 while (0 == my_fgets(fp, buf, 80))
1158 /* Skip comments and blank lines */
1159 if (!buf[0] || (buf[0] == '#')) continue;
1161 /* Chop the buffer */
1164 /* Extract the info */
1165 if (prefix(buf, "SUN:")) strcpy(days[0], buf);
1166 if (prefix(buf, "MON:")) strcpy(days[1], buf);
1167 if (prefix(buf, "TUE:")) strcpy(days[2], buf);
1168 if (prefix(buf, "WED:")) strcpy(days[3], buf);
1169 if (prefix(buf, "THU:")) strcpy(days[4], buf);
1170 if (prefix(buf, "FRI:")) strcpy(days[5], buf);
1171 if (prefix(buf, "SAT:")) strcpy(days[6], buf);
1187 #ifndef MAXHOSTNAMELEN
1188 # define MAXHOSTNAMELEN 64
1191 typedef struct statstime statstime;
1197 unsigned int v_pgpgin;
1198 unsigned int v_pgpgout;
1199 unsigned int v_pswpin;
1200 unsigned int v_pswpout;
1201 unsigned int v_intr;
1207 unsigned int v_swtch;
1209 struct timeval boottime;
1210 struct timeval curtime;
1214 * Maximal load (if any).
1216 static int check_load_value = 0;
1224 errr check_load(void)
1229 struct statstime st;
1231 /* Success if not checking */
1232 if (!check_load_value) return (0);
1234 /* Check the load */
1235 if (0 == rstat("localhost", &st))
1237 long val1 = (long)(st.avenrun[2]);
1238 long val2 = (long)(check_load_value) * FSCALE;
1240 /* Check for violation */
1241 if (val1 >= val2) return (1);
1252 * Initialize CHECK_LOAD
1254 errr check_load_init(void)
1263 char temphost[MAXHOSTNAMELEN+1];
1264 char thishost[MAXHOSTNAMELEN+1];
1267 /* Build the filename */
1268 path_build(buf, 1024, ANGBAND_DIR_FILE, "load.txt");
1270 /* Open the "load" file */
1271 fp = my_fopen(buf, "r");
1273 /* No file, no restrictions */
1274 if (!fp) return (0);
1277 check_load_value = 100;
1279 /* Get the host name */
1280 (void)gethostname(thishost, (sizeof thishost) - 1);
1283 while (0 == my_fgets(fp, buf, 1024))
1287 /* Skip comments and blank lines */
1288 if (!buf[0] || (buf[0] == '#')) continue;
1290 /* Parse, or ignore */
1291 if (sscanf(buf, "%s%d", temphost, &value) != 2) continue;
1293 /* Skip other hosts */
1294 if (!streq(temphost, thishost) &&
1295 !streq(temphost, "localhost")) continue;
1297 /* Use that value */
1298 check_load_value = value;
1304 /* Close the file */
1315 * Print long number with header at given row, column
1316 * Use the color for the number, not the header
1318 static void prt_lnum(cptr header, s32b num, int row, int col, byte color)
1320 int len = strlen(header);
1322 put_str(header, row, col);
1323 (void)sprintf(out_val, "%9ld", (long)num);
1324 c_put_str(color, out_val, row, col + len);
1329 * Print number with header at given row, column
1331 static void prt_num(cptr header, int num, int row, int col, byte color)
1333 int len = strlen(header);
1335 put_str(header, row, col);
1336 put_str(" ", row, col + len);
1337 (void)sprintf(out_val, "%6ld", (long)num);
1338 c_put_str(color, out_val, row, col + len + 3);
1344 * £È£Ð / ºÇÂç ¤Î¤è¤¦¤Êɽ¼¨
1347 static void prt_num_max( int num, int max , int row, int col, byte color1, byte color2 )
1350 (void)sprintf(out_val, "%5ld", (long)num);
1351 c_put_str(color1, out_val, row, col );
1352 put_str("/",row, col+6);
1353 (void)sprintf(out_val, "%5ld", (long)max);
1354 c_put_str(color2, out_val, row, col+8 );
1358 * xx ºÐ ¤È¤« xx kg ¤Ê¤É¤Îɽ¼¨ÍÑ cptr tailer ¤Ëñ°Ì¤¬Æþ¤ë¡£
1360 static void prt_num2(cptr header, cptr tailer, int num, int row, int col, byte color)
1362 int len = strlen(header);
1364 put_str(header, row, col);
1365 put_str(" ", row, col + len);
1366 (void)sprintf(out_val, "%6ld", (long)num);
1367 c_put_str(color, out_val, row, col + len + 3);
1368 put_str(tailer, row, col + len + 3+6);
1372 * Prints the following information on the screen.
1374 * For this to look right, the following should be spaced the
1375 * same as in the prt_lnum code... -CFT
1377 static void display_player_middle(void)
1383 int show_tohit, show_todam;
1389 show_tohit = p_ptr->dis_to_h[0];
1390 show_todam = p_ptr->dis_to_d[0];
1392 o_ptr = &inventory[INVEN_RARM];
1394 /* Hack -- add in weapon info if known */
1395 if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1396 if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1399 sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);
1401 /* Dump the bonuses to hit/dam */
1403 if(!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
1404 Term_putstr(1, 9, -1, TERM_WHITE, "ÂǷ⽤Àµ(³ÊÆ®)");
1405 else if(p_ptr->ryoute)
1406 Term_putstr(1, 9, -1, TERM_WHITE, "ÂǷ⽤Àµ(ξ¼ê)");
1408 Term_putstr(1, 9, -1, TERM_WHITE, (left_hander ? "ÂǷ⽤Àµ(º¸¼ê)" : "ÂǷ⽤Àµ(±¦¼ê)"));
1410 if(!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
1411 Term_putstr(1, 9, -1, TERM_WHITE, "Melee(bare h.)");
1412 else if(p_ptr->ryoute)
1413 Term_putstr(1, 9, -1, TERM_WHITE, "Melee(2hands)");
1415 Term_putstr(1, 9, -1, TERM_WHITE, (left_hander ? "Melee(Left)" : "Melee(Right)"));
1417 Term_putstr(15, 9, -1, TERM_L_BLUE, format("%11s", buf));
1422 show_tohit = p_ptr->dis_to_h[1];
1423 show_todam = p_ptr->dis_to_d[1];
1425 o_ptr = &inventory[INVEN_LARM];
1427 /* Hack -- add in weapon info if known */
1428 if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1429 if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1432 sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);
1434 /* Dump the bonuses to hit/dam */
1436 Term_putstr(1, 10, -1, TERM_WHITE, (left_hander ? "ÂǷ⽤Àµ(±¦¼ê)" : "ÂǷ⽤Àµ(º¸¼ê)"));
1438 Term_putstr(1, 10, -1, TERM_WHITE, "Melee(Left)");
1440 Term_putstr(15, 10, -1, TERM_L_BLUE, format("%11s", buf));
1442 else if ((p_ptr->pclass == CLASS_MONK) && (empty_hands(TRUE) > 1))
1445 if (p_ptr->special_defense & KAMAE_MASK)
1447 for (i = 0; i < MAX_KAMAE; i++)
1449 if ((p_ptr->special_defense >> i) & KAMAE_GENBU) break;
1452 if (i < MAX_KAMAE) Term_putstr(16, 10, -1, TERM_YELLOW, format("%s¤Î¹½¤¨", kamae_shurui[i].desc));
1454 if (i < MAX_KAMAE) Term_putstr(10, 10, -1, TERM_YELLOW, format("%11.11s form", kamae_shurui[i].desc));
1459 Term_putstr(18, 10, -1, TERM_YELLOW, "¹½¤¨¤Ê¤·");
1461 Term_putstr(16, 10, -1, TERM_YELLOW, "no posture");
1466 o_ptr = &inventory[INVEN_BOW];
1469 show_tohit = p_ptr->dis_to_h_b;
1472 /* Apply weapon bonuses */
1473 if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h;
1474 if (object_known_p(o_ptr)) show_todam += o_ptr->to_d;
1476 show_tohit += (weapon_exp[0][o_ptr->sval]-4000)/200;
1479 sprintf(buf, "(%+d,%+d)", show_tohit, show_todam);
1481 Term_putstr(1, 11, -1, TERM_WHITE, "¼Í·â¹¶·â½¤Àµ");
1483 Term_putstr(1, 11, -1, TERM_WHITE, "Shoot");
1485 Term_putstr(15, 11, -1, TERM_L_BLUE, format("%11s", buf));
1488 if (inventory[INVEN_BOW].k_idx)
1490 switch (inventory[INVEN_BOW].sval)
1492 /* Sling and ammo */
1499 /* Short Bow and Arrow */
1506 /* Long Bow and Arrow */
1514 /* Light Crossbow and Bolt */
1521 /* Heavy Crossbow and Bolt */
1528 /* Long Bow and Arrow */
1535 /* Get extra "power" from "extra might" */
1536 if (p_ptr->xtra_might) tmul++;
1538 tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
1540 sprintf(buf, "x%d.%02d", tmul/100, tmul%100);
1542 Term_putstr(1, 12, -1, TERM_WHITE, "¼Í·âÉð´ïÇÜΨ");
1544 Term_putstr(1, 12, -1, TERM_WHITE, "Shoot Power");
1546 Term_putstr(15, 12, -1, TERM_L_BLUE, format("%11s", buf));
1548 /* Dump the armor class bonus */
1550 prt_num("AC ½¤Àµ ", p_ptr->dis_to_a, 13, 1, TERM_L_BLUE);
1552 prt_num("+ To AC ", p_ptr->dis_to_a, 13, 1, TERM_L_BLUE);
1556 /* Dump the total armor class */
1558 prt_num("´ðËÜ AC ", p_ptr->dis_ac, 14, 1, TERM_L_BLUE);
1560 prt_num("Base AC ", p_ptr->dis_ac, 14, 1, TERM_L_BLUE);
1564 prt_num("¥ì¥Ù¥ë ", (int)p_ptr->lev, 9, 28, TERM_L_GREEN);
1566 prt_num("Level ", (int)p_ptr->lev, 9, 28, TERM_L_GREEN);
1569 if (p_ptr->prace == RACE_ANDROID)
1571 put_str("·Ð¸³ÃÍ ", 10, 28);
1572 c_put_str(TERM_L_GREEN, " *****", 10, 28+11);
1574 else if (p_ptr->exp >= p_ptr->max_exp)
1577 prt_lnum("·Ð¸³ÃÍ ", p_ptr->exp, 10, 28, TERM_L_GREEN);
1579 prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_L_GREEN);
1586 prt_lnum("·Ð¸³ÃÍ ", p_ptr->exp, 10, 28, TERM_YELLOW);
1588 prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_YELLOW);
1593 if (p_ptr->prace == RACE_ANDROID)
1595 put_str("ºÇÂç·Ð¸³ ", 11, 28);
1596 c_put_str(TERM_L_GREEN, " *****", 11, 28+11);
1600 prt_lnum("ºÇÂç·Ð¸³ ", p_ptr->max_exp, 11, 28, TERM_L_GREEN);
1602 prt_lnum("Max Exp ", p_ptr->max_exp, 11, 28, TERM_L_GREEN);
1606 if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->prace == RACE_ANDROID))
1609 put_str("¼¡¥ì¥Ù¥ë ", 12, 28);
1610 c_put_str(TERM_L_GREEN, " *****", 12, 28+11);
1612 put_str("Exp to Adv.", 12, 28);
1613 c_put_str(TERM_L_GREEN, " *****", 12, 28+11);
1620 prt_lnum("¼¡¥ì¥Ù¥ë ",
1622 prt_lnum("Exp to Adv.",
1625 (s32b)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L),
1626 12, 28, TERM_L_GREEN);
1630 prt_lnum("½ê»ý¶â ", p_ptr->au, 13, 28, TERM_L_GREEN);
1632 prt_lnum("Gold ", p_ptr->au, 13, 28, TERM_L_GREEN);
1636 prt_lnum("¥¿¡¼¥ó¿ô ", MAX(turn_real(turn),0), 14, 28, TERM_L_GREEN );
1638 prt_lnum("Total turn ", MAX(turn_real(turn),0), 14, 28, TERM_L_GREEN );
1643 put_str(" £È£Ð / ºÇÂç ", 9, 52);
1644 if (p_ptr->chp >= p_ptr->mhp)
1645 statcolor = TERM_L_GREEN;
1647 if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
1648 statcolor = TERM_YELLOW;
1651 prt_num_max( p_ptr->chp , p_ptr->mhp, 10, 56, statcolor , TERM_L_GREEN);
1654 prt_num("Max Hit Points ", p_ptr->mhp, 9, 52, TERM_L_GREEN);
1656 if (p_ptr->chp >= p_ptr->mhp)
1658 prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_L_GREEN);
1660 else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
1662 prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_YELLOW);
1666 prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_RED);
1673 put_str(" £Í£Ð / ºÇÂç ", 11, 52);
1674 if (p_ptr->csp >= p_ptr->msp)
1675 statcolor = TERM_L_GREEN;
1677 if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10)
1678 statcolor = TERM_YELLOW;
1681 prt_num_max( p_ptr->csp , p_ptr->msp, 12, 56, statcolor , TERM_L_GREEN);
1683 prt_num("Max SP (Mana) ", p_ptr->msp, 11, 52, TERM_L_GREEN);
1685 if (p_ptr->csp >= p_ptr->msp)
1687 prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_L_GREEN);
1689 else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10)
1691 prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_YELLOW);
1695 prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_RED);
1699 sprintf(buf, "%.2lu:%.2lu:%.2lu", playtime/(60*60), (playtime/60)%60, playtime%60);
1701 Term_putstr(52, 14, -1, TERM_WHITE, "¥×¥ì¥¤»þ´Ö");
1703 Term_putstr(52, 14, -1, TERM_WHITE, "Playtime");
1705 Term_putstr(63, 14, -1, TERM_L_GREEN, format("%11s", buf));
1711 * Hack -- pass color info around this file
1713 static byte likert_color = TERM_WHITE;
1717 * Returns a "rating" of x depending on y
1719 static cptr likert(int x, int y)
1721 static char dummy[20] = "";
1726 /* Negative value */
1729 likert_color = TERM_L_DARK;
1733 return ("Very Bad");
1738 /* Analyze the value */
1744 likert_color = TERM_RED;
1754 likert_color = TERM_L_RED;
1765 likert_color = TERM_ORANGE;
1775 likert_color = TERM_YELLOW;
1785 likert_color = TERM_YELLOW;
1787 return ("ÂçÊÑÎɤ¤");
1789 return ("Very Good");
1796 likert_color = TERM_L_GREEN;
1800 return ("Excellent");
1810 likert_color = TERM_GREEN;
1823 likert_color = TERM_BLUE;
1825 return ("¥«¥ª¥¹¥é¥ó¥¯");
1827 return ("Chaos Rank");
1833 likert_color = TERM_VIOLET;
1835 sprintf(dummy,"¥¢¥ó¥Ð¡¼ [%d]", (int) ((((x/y)-17)*5)/2));
1837 sprintf(dummy,"Amber [%d]", (int) ((((x/y)-17)*5)/2));
1847 * Prints ratings on certain abilities
1849 * This code is "imitated" elsewhere to "dump" a character sheet.
1851 static void display_player_various(void)
1853 int tmp, damage[2], blows1, blows2, i, basedam;
1854 int xthn, xthb, xfos, xsrh;
1855 int xdis, xdev, xsav, xstl;
1859 int energy_fire = 100;
1860 int shots, shot_frac;
1864 if (p_ptr->muta2 & MUT2_HORNS) muta_att++;
1865 if (p_ptr->muta2 & MUT2_SCOR_TAIL) muta_att++;
1866 if (p_ptr->muta2 & MUT2_BEAK) muta_att++;
1867 if (p_ptr->muta2 & MUT2_TRUNK) muta_att++;
1868 if (p_ptr->muta2 & MUT2_TENTACLES) muta_att++;
1870 xthn = p_ptr->skill_thn + (p_ptr->to_h_m * BTH_PLUS_ADJ);
1872 /* Shooting Skill (with current bow and normal missile) */
1873 o_ptr = &inventory[INVEN_BOW];
1874 tmp = p_ptr->to_h_b + o_ptr->to_h;
1875 xthb = p_ptr->skill_thb + (tmp * BTH_PLUS_ADJ);
1877 /* If the player is wielding one? */
1880 /* Analyze the launcher */
1881 switch (o_ptr->sval)
1883 /* Sling and ammo */
1890 /* Short Bow and Arrow */
1893 energy_fire = 10000;
1897 /* Long Bow and Arrow */
1900 energy_fire = 10000;
1910 /* Light Crossbow and Bolt */
1913 energy_fire = 12000;
1917 /* Heavy Crossbow and Bolt */
1920 energy_fire = 13333;
1924 /* Calculate shots per round */
1925 shots = p_ptr->num_fire * 100;
1926 shot_frac = (shots * 100 / energy_fire) % 100;
1927 shots = shots / energy_fire;
1928 if (o_ptr->name1 == ART_CRIMSON)
1932 if (p_ptr->pclass == CLASS_ARCHER)
1934 /* Extra shot at level 10 */
1935 if (p_ptr->lev >= 10) shots++;
1937 /* Extra shot at level 30 */
1938 if (p_ptr->lev >= 30) shots++;
1940 /* Extra shot at level 45 */
1941 if (p_ptr->lev >= 45) shots++;
1951 for(i = 0; i< 2; i++)
1953 damage[i] = p_ptr->dis_to_d[i]*100;
1954 if (((p_ptr->pclass == CLASS_MONK) || (p_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(TRUE) > 1))
1956 int level = p_ptr->lev;
1962 if (p_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
1963 if (p_ptr->special_defense & KAMAE_BYAKKO)
1964 basedam = monk_ave_damage[level][1];
1965 else if (p_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
1966 basedam = monk_ave_damage[level][2];
1968 basedam = monk_ave_damage[level][0];
1972 /* Average damage per round */
1973 o_ptr = &inventory[INVEN_RARM+i];
1974 if (object_known_p(o_ptr)) damage[i] += o_ptr->to_d*100;
1975 basedam = (o_ptr->dd * (o_ptr->ds + 1))*50;
1976 object_flags(o_ptr, &f1, &f2, &f3);
1977 if ((o_ptr->ident & IDENT_MENTAL) && (o_ptr->name1 == ART_VORPAL_BLADE))
1983 else if (object_known_p(o_ptr) && (f1 & TR1_VORPAL))
1985 /* vorpal flag only */
1989 if (object_known_p(o_ptr) && (p_ptr->pclass != CLASS_SAMURAI) && (f1 & TR1_FORCE_WEPON) && (p_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
1990 basedam = basedam * 7 / 2;
1991 if (p_ptr->riding && (o_ptr->tval == TV_POLEARM) && ((o_ptr->sval == SV_LANCE) || (o_ptr->sval == SV_HEAVY_LANCE)))
1992 basedam = basedam*(o_ptr->dd+2)/o_ptr->dd;
1994 damage[i] += basedam;
1995 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DOKUBARI)) damage[i] = 1;
1996 if (damage[i] < 0) damage[i] = 0;
1998 blows1 = p_ptr->migite ? p_ptr->num_blow[0]: 0;
1999 blows2 = p_ptr->hidarite ? p_ptr->num_blow[1] : 0;
2001 /* Basic abilities */
2003 xdis = p_ptr->skill_dis;
2004 xdev = p_ptr->skill_dev;
2005 xsav = p_ptr->skill_sav;
2006 xstl = p_ptr->skill_stl;
2007 xsrh = p_ptr->skill_srh;
2008 xfos = p_ptr->skill_fos;
2012 put_str("ÂǷ⹶·âǽÎÏ :", 17, 1);
2014 put_str("Fighting :", 17, 1);
2017 desc = likert(xthn, 12);
2018 c_put_str(likert_color, desc, 17, 15);
2021 put_str("¼Í·â¹¶·âǽÎÏ :", 18, 1);
2023 put_str("Bows/Throw :", 18, 1);
2026 desc = likert(xthb, 12);
2027 c_put_str(likert_color, desc, 18, 15);
2030 put_str("ËâË¡ËɸæǽÎÏ :", 19, 1);
2032 put_str("Saving Throw:", 19, 1);
2035 desc = likert(xsav, 7);
2036 c_put_str(likert_color, desc, 19, 15);
2039 put_str("±£Ì©¹ÔưǽÎÏ :", 20, 1);
2041 put_str("Stealth :", 20, 1);
2044 desc = likert(xstl, 1);
2045 c_put_str(likert_color, desc, 20, 15);
2049 put_str("ÃγÐǽÎÏ :", 17, 28);
2051 put_str("Perception :", 17, 28);
2054 desc = likert(xfos, 6);
2055 c_put_str(likert_color, desc, 17, 42);
2058 put_str("õº÷ǽÎÏ :", 18, 28);
2060 put_str("Searching :", 18, 28);
2063 desc = likert(xsrh, 6);
2064 c_put_str(likert_color, desc, 18, 42);
2067 put_str("²ò½üǽÎÏ :", 19, 28);
2069 put_str("Disarming :", 19, 28);
2072 desc = likert(xdis, 8);
2073 c_put_str(likert_color, desc, 19, 42);
2076 put_str("ËâË¡Æ»¶ñ»ÈÍÑ :", 20, 28);
2078 put_str("Magic Device:", 20, 28);
2081 desc = likert(xdev, 6);
2082 c_put_str(likert_color, desc, 20, 42);
2086 put_str("ÂÇ·â²ó¿ô :", 17, 55);
2088 put_str("Blows/Round:", 17, 55);
2092 put_str(format("%d+%d", blows1, blows2), 17, 69);
2094 put_str(format("%d+%d+%d", blows1, blows2, muta_att), 17, 69);
2097 put_str("¼Í·â²ó¿ô :", 18, 55);
2099 put_str("Shots/Round:", 18, 55);
2102 put_str(format("%d.%02d", shots, shot_frac), 18, 69);
2105 put_str("Ê¿¶Ñ¥À¥á¡¼¥¸:", 19, 55);
2107 put_str("Wpn.dmg/Rnd:", 19, 55); /* From PsiAngband */
2111 if ((damage[0]+damage[1]) == 0)
2114 desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
2116 put_str(desc, 19, 69);
2119 put_str("ÀÖ³°Àþ»ëÎÏ :", 20, 55);
2121 put_str("Infra-Vision:", 20, 55);
2125 put_str(format("%d feet", p_ptr->see_infra * 10), 20, 69);
2127 put_str(format("%d feet", p_ptr->see_infra * 10), 20, 69);
2135 * Obtain the "flags" for the player as if he was an item
2137 static void player_flags(u32b *f1, u32b *f2, u32b *f3)
2140 (*f1) = (*f2) = (*f3) = 0L;
2143 switch (p_ptr->pclass)
2146 if (p_ptr->lev > 44)
2147 (*f3) |= (TR3_REGEN);
2149 if (p_ptr->lev > 29)
2150 (*f2) |= (TR2_RES_FEAR);
2153 if (p_ptr->lev > 39)
2154 (*f2) |= (TR2_RES_FEAR);
2156 case CLASS_CHAOS_WARRIOR:
2157 if (p_ptr->lev > 29)
2158 (*f2) |= (TR2_RES_CHAOS);
2159 if (p_ptr->lev > 39)
2160 (*f2) |= (TR2_RES_FEAR);
2163 case CLASS_FORCETRAINER:
2164 if ((p_ptr->lev > 9) && !heavy_armor())
2166 if ((p_ptr->lev>24) && !heavy_armor())
2167 (*f2) |= (TR2_FREE_ACT);
2174 if (!inventory[INVEN_LARM].tval || p_ptr->hidarite)
2177 (*f2) |= (TR2_FREE_ACT);
2179 (*f3) |= TR3_SLOW_DIGEST;
2180 (*f2) |= TR2_RES_FEAR;
2181 if (p_ptr->lev > 19) (*f2) |= TR2_RES_POIS;
2182 if (p_ptr->lev > 24) (*f2) |= TR2_SUST_DEX;
2183 if (p_ptr->lev > 29) (*f3) |= TR3_SEE_INVIS;
2185 case CLASS_MINDCRAFTER:
2187 (*f2) |= (TR2_RES_FEAR);
2188 if (p_ptr->lev > 19)
2189 (*f2) |= (TR2_SUST_WIS);
2190 if (p_ptr->lev > 29)
2191 (*f2) |= (TR2_RES_CONF);
2192 if (p_ptr->lev > 39)
2193 (*f3) |= (TR3_TELEPATHY);
2196 (*f2) |= (TR2_RES_SOUND);
2198 case CLASS_BERSERKER:
2199 (*f2) |= (TR2_SUST_STR);
2200 (*f2) |= (TR2_SUST_DEX);
2201 (*f2) |= (TR2_SUST_CON);
2202 (*f3) |= (TR3_REGEN);
2203 (*f2) |= (TR2_FREE_ACT);
2204 (*f1) |= (TR1_SPEED);
2205 if (p_ptr->lev > 39) (*f2) |= (TR2_REFLECT);
2207 case CLASS_MIRROR_MASTER:
2208 if(p_ptr->lev > 39)(*f2) |= (TR2_REFLECT);
2211 break; /* Do nothing */
2215 if (p_ptr->mimic_form)
2217 switch(p_ptr->mimic_form)
2220 (*f2) |= (TR2_HOLD_LIFE);
2221 (*f2) |= (TR2_RES_CHAOS);
2222 (*f2) |= (TR2_RES_NETHER);
2223 (*f2) |= (TR2_RES_FIRE);
2224 (*f3) |= (TR3_SEE_INVIS);
2225 (*f1) |= (TR1_SPEED);
2227 case MIMIC_DEMON_LORD:
2228 (*f2) |= (TR2_HOLD_LIFE);
2229 (*f2) |= (TR2_RES_CHAOS);
2230 (*f2) |= (TR2_RES_NETHER);
2231 (*f2) |= (TR2_RES_FIRE);
2232 (*f2) |= (TR2_RES_COLD);
2233 (*f2) |= (TR2_RES_ELEC);
2234 (*f2) |= (TR2_RES_ACID);
2235 (*f2) |= (TR2_RES_POIS);
2236 (*f2) |= (TR2_RES_CONF);
2237 (*f2) |= (TR2_RES_DISEN);
2238 (*f2) |= (TR2_RES_NEXUS);
2239 (*f2) |= (TR2_RES_FEAR);
2240 (*f2) |= (TR2_IM_FIRE);
2241 (*f3) |= (TR3_SH_FIRE);
2242 (*f3) |= (TR3_SEE_INVIS);
2243 (*f3) |= (TR3_TELEPATHY);
2244 (*f3) |= (TR3_FEATHER);
2245 (*f1) |= (TR1_SPEED);
2248 (*f2) |= (TR2_HOLD_LIFE);
2249 (*f2) |= (TR2_RES_DARK);
2250 (*f2) |= (TR2_RES_NETHER);
2251 if (p_ptr->pclass != CLASS_NINJA) (*f3) |= (TR3_LITE);
2252 (*f2) |= (TR2_RES_POIS);
2253 (*f2) |= (TR2_RES_COLD);
2254 (*f3) |= (TR3_SEE_INVIS);
2255 (*f1) |= (TR1_SPEED);
2261 switch (p_ptr->prace)
2264 (*f2) |= (TR2_RES_LITE);
2267 (*f2) |= (TR2_SUST_DEX);
2270 (*f2) |= (TR2_FREE_ACT);
2273 (*f2) |= (TR2_RES_BLIND);
2276 (*f2) |= (TR2_RES_DARK);
2278 case RACE_HALF_TROLL:
2279 (*f2) |= (TR2_SUST_STR);
2280 if (p_ptr->lev > 14)
2282 (*f3) |= (TR3_REGEN);
2283 if (p_ptr->pclass == CLASS_WARRIOR)
2285 (*f3) |= (TR3_SLOW_DIGEST);
2287 * Let's not make Regeneration a disadvantage
2288 * for the poor warriors who can never learn
2289 * a spell that satisfies hunger (actually
2290 * neither can rogues, but half-trolls are not
2291 * supposed to play rogues)
2297 (*f2) |= (TR2_SUST_CON);
2298 (*f3) |= (TR3_REGEN); /* Amberites heal fast */
2301 (*f2) |= (TR2_RES_LITE);
2302 (*f3) |= (TR3_SEE_INVIS);
2304 case RACE_BARBARIAN:
2305 (*f2) |= (TR2_RES_FEAR);
2307 case RACE_HALF_OGRE:
2308 (*f2) |= (TR2_SUST_STR);
2309 (*f2) |= (TR2_RES_DARK);
2311 case RACE_HALF_GIANT:
2312 (*f2) |= (TR2_RES_SHARDS);
2313 (*f2) |= (TR2_SUST_STR);
2315 case RACE_HALF_TITAN:
2316 (*f2) |= (TR2_RES_CHAOS);
2319 (*f2) |= (TR2_RES_SOUND);
2322 (*f2) |= (TR2_RES_ACID);
2323 if (p_ptr->lev > 19)
2324 (*f2) |= (TR2_IM_ACID);
2327 (*f2) |= (TR2_RES_CONF);
2328 (*f2) |= (TR2_RES_ACID);
2333 (*f2) |= (TR2_RES_POIS);
2336 (*f2) |= (TR2_RES_DISEN);
2337 (*f2) |= (TR2_RES_DARK);
2340 (*f2) |= (TR2_RES_DARK);
2341 if (p_ptr->lev > 19)
2342 (*f3) |= (TR3_SEE_INVIS);
2344 case RACE_DRACONIAN:
2345 (*f3) |= TR3_FEATHER;
2347 (*f2) |= (TR2_RES_FIRE);
2349 (*f2) |= (TR2_RES_COLD);
2350 if (p_ptr->lev > 14)
2351 (*f2) |= (TR2_RES_ACID);
2352 if (p_ptr->lev > 19)
2353 (*f2) |= (TR2_RES_ELEC);
2354 if (p_ptr->lev > 34)
2355 (*f2) |= (TR2_RES_POIS);
2357 case RACE_MIND_FLAYER:
2358 (*f2) |= (TR2_SUST_INT);
2359 (*f2) |= (TR2_SUST_WIS);
2360 if (p_ptr->lev > 14)
2361 (*f3) |= (TR3_SEE_INVIS);
2362 if (p_ptr->lev > 29)
2363 (*f3) |= (TR3_TELEPATHY);
2366 (*f2) |= (TR2_RES_FIRE);
2368 (*f3) |= (TR3_SEE_INVIS);
2371 (*f3) |= (TR3_SEE_INVIS);
2372 (*f2) |= (TR2_FREE_ACT);
2373 (*f2) |= (TR2_RES_POIS);
2374 (*f3) |= (TR3_SLOW_DIGEST);
2375 if (p_ptr->lev > 34)
2376 (*f2) |= (TR2_HOLD_LIFE);
2379 (*f3) |= (TR3_SEE_INVIS);
2380 (*f2) |= (TR2_RES_SHARDS);
2381 (*f2) |= (TR2_HOLD_LIFE);
2382 (*f2) |= (TR2_RES_POIS);
2384 (*f2) |= (TR2_RES_COLD);
2387 (*f3) |= (TR3_SEE_INVIS);
2388 (*f2) |= (TR2_HOLD_LIFE);
2389 (*f2) |= (TR2_RES_NETHER);
2390 (*f2) |= (TR2_RES_POIS);
2391 (*f3) |= (TR3_SLOW_DIGEST);
2393 (*f2) |= (TR2_RES_COLD);
2396 (*f2) |= (TR2_HOLD_LIFE);
2397 (*f2) |= (TR2_RES_DARK);
2398 (*f2) |= (TR2_RES_NETHER);
2399 if (p_ptr->pclass != CLASS_NINJA) (*f3) |= (TR3_LITE);
2400 (*f2) |= (TR2_RES_POIS);
2401 (*f2) |= (TR2_RES_COLD);
2404 (*f3) |= (TR3_FEATHER);
2405 (*f2) |= (TR2_FREE_ACT);
2406 (*f2) |= (TR2_RES_COLD);
2407 (*f3) |= (TR3_SEE_INVIS);
2408 (*f2) |= (TR2_HOLD_LIFE);
2409 (*f2) |= (TR2_RES_NETHER);
2410 (*f2) |= (TR2_RES_POIS);
2411 (*f3) |= (TR3_SLOW_DIGEST);
2413 if (p_ptr->lev > 34)
2414 (*f3) |= TR3_TELEPATHY;
2417 (*f2) |= (TR2_RES_LITE);
2418 (*f3) |= (TR3_FEATHER);
2420 (*f1) |= (TR1_SPEED);
2423 (*f2) |= (TR2_RES_SOUND);
2424 (*f2) |= (TR2_RES_CONF);
2427 (*f3) |= (TR3_FEATHER);
2428 (*f3) |= (TR3_SEE_INVIS);
2431 (*f2) |= (TR2_RES_FIRE);
2432 (*f2) |= (TR2_RES_NETHER);
2433 (*f2) |= (TR2_HOLD_LIFE);
2435 (*f3) |= (TR3_SEE_INVIS);
2438 (*f2) |= (TR2_SUST_CON);
2441 (*f3) |= (TR3_FEATHER);
2444 (*f2) |= (TR2_RES_CONF);
2447 (*f2) |= (TR2_FREE_ACT);
2448 (*f2) |= (TR2_RES_POIS);
2449 (*f3) |= (TR3_SLOW_DIGEST);
2450 (*f2) |= (TR2_HOLD_LIFE);
2460 if (p_ptr->muta3 & MUT3_FLESH_ROT)
2462 (*f3) &= ~(TR3_REGEN);
2465 if ((p_ptr->muta3 & MUT3_XTRA_FAT) ||
2466 (p_ptr->muta3 & MUT3_XTRA_LEGS) ||
2467 (p_ptr->muta3 & MUT3_SHORT_LEG))
2472 if (p_ptr->muta3 & MUT3_ELEC_TOUC)
2474 (*f3) |= TR3_SH_ELEC;
2477 if (p_ptr->muta3 & MUT3_FIRE_BODY)
2479 (*f3) |= TR3_SH_FIRE;
2483 if (p_ptr->muta3 & MUT3_WINGS)
2485 (*f3) |= TR3_FEATHER;
2488 if (p_ptr->muta3 & MUT3_FEARLESS)
2490 (*f2) |= (TR2_RES_FEAR);
2493 if (p_ptr->muta3 & MUT3_REGEN)
2498 if (p_ptr->muta3 & MUT3_ESP)
2500 (*f3) |= TR3_TELEPATHY;
2503 if (p_ptr->muta3 & MUT3_MOTION)
2505 (*f2) |= TR2_FREE_ACT;
2509 if (p_ptr->pseikaku == SEIKAKU_SEXY)
2510 (*f3) |= TR3_AGGRAVATE;
2511 if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN)
2513 (*f2) |= (TR2_RES_BLIND);
2514 (*f2) |= (TR2_RES_CONF);
2515 (*f2) |= (TR2_HOLD_LIFE);
2516 (*f3) |= (TR3_LITE);
2518 (*f1) |= (TR1_SPEED);
2520 if (p_ptr->special_defense & KATA_FUUJIN)
2521 (*f2) |= TR2_REFLECT;
2522 if (p_ptr->special_defense & KAMAE_GENBU)
2523 (*f2) |= TR2_REFLECT;
2524 if (p_ptr->special_defense & KAMAE_SUZAKU)
2525 (*f3) |= TR3_FEATHER;
2526 if (p_ptr->special_defense & KAMAE_SEIRYU)
2528 (*f2) |= (TR2_RES_FIRE);
2529 (*f2) |= (TR2_RES_COLD);
2530 (*f2) |= (TR2_RES_ACID);
2531 (*f2) |= (TR2_RES_ELEC);
2532 (*f2) |= (TR2_RES_POIS);
2533 (*f3) |= (TR3_FEATHER);
2534 (*f3) |= (TR3_SH_FIRE);
2535 (*f3) |= (TR3_SH_ELEC);
2536 (*f3) |= (TR3_SH_COLD);
2538 if (p_ptr->special_defense & KATA_MUSOU)
2540 (*f2) |= TR2_RES_FEAR;
2541 (*f2) |= TR2_RES_LITE;
2542 (*f2) |= TR2_RES_DARK;
2543 (*f2) |= TR2_RES_BLIND;
2544 (*f2) |= TR2_RES_CONF;
2545 (*f2) |= TR2_RES_SOUND;
2546 (*f2) |= TR2_RES_SHARDS;
2547 (*f2) |= TR2_RES_NETHER;
2548 (*f2) |= TR2_RES_NEXUS;
2549 (*f2) |= TR2_RES_CHAOS;
2550 (*f2) |= TR2_RES_DISEN;
2551 (*f2) |= TR2_REFLECT;
2552 (*f2) |= TR2_HOLD_LIFE;
2553 (*f2) |= TR2_FREE_ACT;
2554 (*f3) |= TR3_SH_FIRE;
2555 (*f3) |= TR3_SH_ELEC;
2556 (*f3) |= TR3_SH_COLD;
2557 (*f3) |= TR3_FEATHER;
2559 (*f3) |= TR3_SEE_INVIS;
2560 (*f3) |= TR3_TELEPATHY;
2561 (*f3) |= TR3_SLOW_DIGEST;
2563 (*f2) |= (TR2_SUST_STR);
2564 (*f2) |= (TR2_SUST_INT);
2565 (*f2) |= (TR2_SUST_WIS);
2566 (*f2) |= (TR2_SUST_DEX);
2567 (*f2) |= (TR2_SUST_CON);
2568 (*f2) |= (TR2_SUST_CHR);
2573 static void tim_player_flags(u32b *f1, u32b *f2, u32b *f3, bool im_and_res)
2576 (*f1) = (*f2) = (*f3) = 0L;
2578 if (p_ptr->hero || p_ptr->shero || music_singing(MUSIC_HERO) || music_singing(MUSIC_SHERO))
2579 (*f2) |= TR2_RES_FEAR;
2580 if (p_ptr->tim_invis)
2581 (*f3) |= TR3_SEE_INVIS;
2582 if (p_ptr->tim_regen)
2584 if (p_ptr->tim_esp || music_singing(MUSIC_MIND))
2585 (*f3) |= TR3_TELEPATHY;
2586 if (p_ptr->fast || p_ptr->slow || music_singing(MUSIC_SPEED) || music_singing(MUSIC_SHERO))
2588 if ((p_ptr->special_defense & KATA_MUSOU) || music_singing(MUSIC_RESIST))
2590 (*f2) |= (TR2_RES_FIRE);
2591 (*f2) |= (TR2_RES_COLD);
2592 (*f2) |= (TR2_RES_ACID);
2593 (*f2) |= (TR2_RES_ELEC);
2594 (*f2) |= (TR2_RES_POIS);
2598 if (p_ptr->oppose_acid && !(p_ptr->special_defense & DEFENSE_ACID) && !((prace_is_(RACE_YEEK)) && (p_ptr->lev > 19)))
2599 (*f2) |= TR2_RES_ACID;
2600 if (p_ptr->oppose_elec && !(p_ptr->special_defense & DEFENSE_ELEC))
2601 (*f2) |= TR2_RES_ELEC;
2602 if (p_ptr->oppose_fire && !(p_ptr->special_defense & DEFENSE_FIRE))
2603 (*f2) |= TR2_RES_FIRE;
2604 if (p_ptr->oppose_cold && !(p_ptr->special_defense & DEFENSE_COLD))
2605 (*f2) |= TR2_RES_COLD;
2609 if (p_ptr->oppose_acid)
2610 (*f2) |= TR2_RES_ACID;
2611 if (p_ptr->oppose_elec)
2612 (*f2) |= TR2_RES_ELEC;
2613 if (p_ptr->oppose_fire)
2614 (*f2) |= TR2_RES_FIRE;
2615 if (p_ptr->oppose_cold)
2616 (*f2) |= TR2_RES_COLD;
2618 if (p_ptr->oppose_pois)
2619 (*f2) |= TR2_RES_POIS;
2620 if (p_ptr->special_attack & ATTACK_ACID)
2621 (*f1) |= TR1_BRAND_ACID;
2622 if (p_ptr->special_attack & ATTACK_ELEC)
2623 (*f1) |= TR1_BRAND_ELEC;
2624 if (p_ptr->special_attack & ATTACK_FIRE)
2625 (*f1) |= TR1_BRAND_FIRE;
2626 if (p_ptr->special_attack & ATTACK_COLD)
2627 (*f1) |= TR1_BRAND_COLD;
2628 if (p_ptr->special_attack & ATTACK_POIS)
2629 (*f1) |= TR1_BRAND_POIS;
2630 if (p_ptr->special_defense & DEFENSE_ACID)
2631 (*f2) |= TR2_IM_ACID;
2632 if (p_ptr->special_defense & DEFENSE_ELEC)
2633 (*f2) |= TR2_IM_ELEC;
2634 if (p_ptr->special_defense & DEFENSE_FIRE)
2635 (*f2) |= TR2_IM_FIRE;
2636 if (p_ptr->special_defense & DEFENSE_COLD)
2637 (*f2) |= TR2_IM_COLD;
2638 if (p_ptr->wraith_form)
2639 (*f2) |= TR2_REFLECT;
2641 if (p_ptr->tim_reflect){
2642 (*f2) |= TR2_REFLECT;
2645 if (p_ptr->magicdef)
2647 (*f2) |= TR2_RES_BLIND;
2648 (*f2) |= TR2_RES_CONF;
2649 (*f2) |= TR2_REFLECT;
2650 (*f2) |= TR2_FREE_ACT;
2651 (*f3) |= TR3_FEATHER;
2653 if (p_ptr->tim_res_nether)
2655 (*f2) |= TR2_RES_NETHER;
2657 if (p_ptr->tim_sh_fire)
2659 (*f3) |= TR3_SH_FIRE;
2663 (*f2) |= TR2_RES_FEAR;
2664 (*f2) |= TR2_RES_LITE;
2665 (*f2) |= TR2_RES_DARK;
2666 (*f2) |= TR2_RES_BLIND;
2667 (*f2) |= TR2_RES_CONF;
2668 (*f2) |= TR2_RES_SOUND;
2669 (*f2) |= TR2_RES_SHARDS;
2670 (*f2) |= TR2_RES_NETHER;
2671 (*f2) |= TR2_RES_NEXUS;
2672 (*f2) |= TR2_RES_CHAOS;
2673 (*f2) |= TR2_RES_DISEN;
2674 (*f2) |= TR2_REFLECT;
2675 (*f2) |= TR2_HOLD_LIFE;
2676 (*f2) |= TR2_FREE_ACT;
2677 (*f3) |= TR3_SH_FIRE;
2678 (*f3) |= TR3_SH_ELEC;
2679 (*f3) |= TR3_SH_COLD;
2680 (*f3) |= TR3_FEATHER;
2682 (*f3) |= TR3_SEE_INVIS;
2683 (*f3) |= TR3_TELEPATHY;
2684 (*f3) |= TR3_SLOW_DIGEST;
2686 (*f2) |= (TR2_SUST_STR);
2687 (*f2) |= (TR2_SUST_INT);
2688 (*f2) |= (TR2_SUST_WIS);
2689 (*f2) |= (TR2_SUST_DEX);
2690 (*f2) |= (TR2_SUST_CON);
2691 (*f2) |= (TR2_SUST_CHR);
2699 static void display_player_equippy(int y, int x)
2709 /* Dump equippy chars */
2710 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2713 o_ptr = &inventory[i];
2715 a = object_attr(o_ptr);
2716 c = object_char(o_ptr);
2718 /* Clear the part of the screen */
2719 if (!equippy_chars || !o_ptr->k_idx)
2726 Term_putch(x + i - INVEN_RARM, y, a, c);
2731 void print_equippy(void)
2733 display_player_equippy(ROW_EQUIPPY, COL_EQUIPPY);
2740 static void known_obj_immunity(u32b *f1, u32b *f2, u32b *f3)
2745 (*f1) = (*f2) = (*f3) = 0L;
2747 /* Check equipment */
2748 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2750 u32b o_f1, o_f2, o_f3;
2755 o_ptr = &inventory[i];
2757 if (!o_ptr->k_idx) continue;
2760 object_flags_known(o_ptr, &o_f1, &o_f2, &o_f3);
2762 if (o_f2 & TR2_IM_ACID) (*f2) |= TR2_RES_ACID;
2763 if (o_f2 & TR2_IM_ELEC) (*f2) |= TR2_RES_ELEC;
2764 if (o_f2 & TR2_IM_FIRE) (*f2) |= TR2_RES_FIRE;
2765 if (o_f2 & TR2_IM_COLD) (*f2) |= TR2_RES_COLD;
2769 static void player_immunity(u32b *f1, u32b *f2, u32b *f3)
2772 (*f1) = (*f2) = (*f3) = 0L;
2774 if (prace_is_(RACE_SPECTRE))
2775 (*f2) |= TR2_RES_NETHER;
2776 if (p_ptr->mimic_form == MIMIC_VAMPIRE || prace_is_(RACE_VAMPIRE))
2777 (*f2) |= TR2_RES_DARK;
2778 if (p_ptr->mimic_form == MIMIC_DEMON_LORD)
2779 (*f2) |= TR2_RES_FIRE;
2780 else if (prace_is_(RACE_YEEK) && p_ptr->lev > 19)
2781 (*f2) |= TR2_RES_ACID;
2784 static void tim_player_immunity(u32b *f1, u32b *f2, u32b *f3)
2787 (*f1) = (*f2) = (*f3) = 0L;
2789 if (p_ptr->special_defense & DEFENSE_ACID)
2790 (*f2) |= TR2_RES_ACID;
2791 if (p_ptr->special_defense & DEFENSE_ELEC)
2792 (*f2) |= TR2_RES_ELEC;
2793 if (p_ptr->special_defense & DEFENSE_FIRE)
2794 (*f2) |= TR2_RES_FIRE;
2795 if (p_ptr->special_defense & DEFENSE_COLD)
2796 (*f2) |= TR2_RES_COLD;
2797 if (p_ptr->wraith_form)
2798 (*f2) |= TR2_RES_DARK;
2801 static void player_vuln_flags(u32b *f1, u32b *f2, u32b *f3)
2804 (*f1) = (*f2) = (*f3) = 0L;
2806 if ((p_ptr->muta3 & MUT3_VULN_ELEM) || (p_ptr->special_defense & KATA_KOUKIJIN))
2808 (*f2) |= TR2_RES_ACID;
2809 (*f2) |= TR2_RES_ELEC;
2810 (*f2) |= TR2_RES_FIRE;
2811 (*f2) |= TR2_RES_COLD;
2813 if (prace_is_(RACE_ANDROID))
2814 (*f2) |= TR2_RES_ELEC;
2815 if (prace_is_(RACE_ENT))
2816 (*f2) |= TR2_RES_FIRE;
2817 if (prace_is_(RACE_VAMPIRE) || prace_is_(RACE_S_FAIRY) ||
2818 (p_ptr->mimic_form == MIMIC_VAMPIRE))
2819 (*f2) |= TR2_RES_LITE;
2823 * Helper function, see below
2825 static void display_player_flag_aux(int row, int col, char *header,
2826 int n, u32b flag1, u32b flag2,
2827 s32b im_f[], s32b vul_f)
2833 if ((vul_f & flag1) && !((im_f[0] | im_f[1] | im_f[2]) & flag1))
2837 c_put_str(TERM_WHITE, header, row, col);
2840 col += strlen(header) + 1;
2842 /* Check equipment */
2843 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
2846 f[0] = f[1] = f[2] = 0L;
2849 o_ptr = &inventory[i];
2852 object_flags_known(o_ptr, &f[0], &f[1], &f[2]);
2855 c_put_str(vuln ? TERM_RED : TERM_SLATE, ".", row, col);
2858 if (f[n - 1] & flag1) c_put_str(vuln ? TERM_L_RED : TERM_WHITE, "+", row, col);
2859 if (f[n - 1] & flag2) c_put_str(TERM_WHITE, "*", row, col);
2866 player_flags(&f[0], &f[1], &f[2]);
2869 c_put_str(vuln ? TERM_RED : TERM_SLATE, ".", row, col);
2872 if (f[n-1] & flag1) c_put_str(vuln ? TERM_L_RED : TERM_WHITE, "+", row, col);
2874 /* Timed player flags */
2875 tim_player_flags(&f[0], &f[1], &f[2], TRUE);
2878 if (f[n-1] & flag1) c_put_str(vuln ? TERM_ORANGE : TERM_YELLOW, "#", row, col);
2881 if (im_f[2] & flag1) c_put_str(TERM_YELLOW, "*", row, col);
2882 if (im_f[1] & flag1) c_put_str(TERM_WHITE, "*", row, col);
2885 if (vuln) c_put_str(TERM_RED, "v", row, col + 1);
2890 * Special display, part 1
2892 static void display_player_flag_info(void)
2897 u32b im_f[3][3], vul_f[3];
2899 known_obj_immunity(&im_f[0][0], &im_f[1][0], &im_f[2][0]);
2900 player_immunity(&im_f[0][1], &im_f[1][1], &im_f[2][1]);
2901 tim_player_immunity(&im_f[0][2], &im_f[1][2], &im_f[2][2]);
2903 player_vuln_flags(&vul_f[0], &vul_f[1], &vul_f[2]);
2910 display_player_equippy(row-2, col+8);
2911 c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
2914 display_player_flag_aux(row+0, col, "ÂÑ»À :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
2915 display_player_flag_aux(row+1, col, "ÂÑÅÅ·â:", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
2916 display_player_flag_aux(row+2, col, "ÂѲбê:", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
2917 display_player_flag_aux(row+3, col, "ÂÑÎ䵤:", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
2918 display_player_flag_aux(row+4, col, "ÂÑÆÇ :", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
2919 display_player_flag_aux(row+5, col, "ÂÑÁ®¸÷:", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
2920 display_player_flag_aux(row+6, col, "ÂѰŹõ:", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
2921 display_player_flag_aux(row+7, col, "ÂÑÇËÊÒ:", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
2922 display_player_flag_aux(row+8, col, "ÂÑÌÕÌÜ:", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
2923 display_player_flag_aux(row+9, col, "ÂѺ®Íð:", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
2925 display_player_flag_aux(row+0, col, "Acid :", 2, TR2_RES_ACID, TR2_IM_ACID, im_f[1], vul_f[1]);
2926 display_player_flag_aux(row+1, col, "Elec :", 2, TR2_RES_ELEC, TR2_IM_ELEC, im_f[1], vul_f[1]);
2927 display_player_flag_aux(row+2, col, "Fire :", 2, TR2_RES_FIRE, TR2_IM_FIRE, im_f[1], vul_f[1]);
2928 display_player_flag_aux(row+3, col, "Cold :", 2, TR2_RES_COLD, TR2_IM_COLD, im_f[1], vul_f[1]);
2929 display_player_flag_aux(row+4, col, "Poison:", 2, TR2_RES_POIS, 0, im_f[1], vul_f[1]);
2930 display_player_flag_aux(row+5, col, "Light :", 2, TR2_RES_LITE, 0, im_f[1], vul_f[1]);
2931 display_player_flag_aux(row+6, col, "Dark :", 2, TR2_RES_DARK, 0, im_f[1], vul_f[1]);
2932 display_player_flag_aux(row+7, col, "Shard :", 2, TR2_RES_SHARDS, 0, im_f[1], vul_f[1]);
2933 display_player_flag_aux(row+8, col, "Blind :", 2, TR2_RES_BLIND, 0, im_f[1], vul_f[1]);
2934 display_player_flag_aux(row+9, col, "Conf :", 2, TR2_RES_CONF, 0, im_f[1], vul_f[1]);
2943 display_player_equippy(row-2, col+8);
2945 c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+8);
2948 display_player_flag_aux(row+0, col, "Âѹ첻:", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
2949 display_player_flag_aux(row+1, col, "ÂÑÃϹö:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
2950 display_player_flag_aux(row+2, col, "ÂÑ°øº®:", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
2951 display_player_flag_aux(row+3, col, "ÂÑ¥«¥ª:", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
2952 display_player_flag_aux(row+4, col, "ÂÑÎô²½:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
2953 display_player_flag_aux(row+5, col, "ÂѶ²ÉÝ:", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
2954 display_player_flag_aux(row+6, col, "È¿¼Í :", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
2955 display_player_flag_aux(row+7, col, "²Ð±ê¥ª:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
2956 display_player_flag_aux(row+8, col, "Åŵ¤¥ª:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
2957 display_player_flag_aux(row+9, col, "Î䵤¥ª:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
2959 display_player_flag_aux(row+0, col, "Sound :", 2, TR2_RES_SOUND, 0, im_f[1], vul_f[1]);
2960 display_player_flag_aux(row+1, col, "Nether:", 2, TR2_RES_NETHER, 0, im_f[1], vul_f[1]);
2961 display_player_flag_aux(row+2, col, "Nexus :", 2, TR2_RES_NEXUS, 0, im_f[1], vul_f[1]);
2962 display_player_flag_aux(row+3, col, "Chaos :", 2, TR2_RES_CHAOS, 0, im_f[1], vul_f[1]);
2963 display_player_flag_aux(row+4, col, "Disnch:", 2, TR2_RES_DISEN, 0, im_f[1], vul_f[1]);
2964 display_player_flag_aux(row+5, col, "Fear :", 2, TR2_RES_FEAR, 0, im_f[1], vul_f[1]);
2965 display_player_flag_aux(row+6, col, "Reflct:", 2, TR2_REFLECT, 0, im_f[1], vul_f[1]);
2966 display_player_flag_aux(row+7, col, "AuFire:", 3, TR3_SH_FIRE, 0, im_f[2], vul_f[2]);
2967 display_player_flag_aux(row+8, col, "AuElec:", 3, TR3_SH_ELEC, 0, im_f[2], vul_f[2]);
2968 display_player_flag_aux(row+9, col, "AuCold:", 3, TR3_SH_COLD, 0, im_f[2], vul_f[2]);
2977 display_player_equippy(row-2, col+12);
2979 c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col+12);
2982 display_player_flag_aux(row+0, col, "²Ã® :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
2983 display_player_flag_aux(row+1, col, "ÂÑËãáã :", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
2984 display_player_flag_aux(row+2, col, "Æ©ÌÀÂλëǧ:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
2985 display_player_flag_aux(row+3, col, "·Ð¸³ÃÍÊÝ»ý:", 2, TR2_HOLD_LIFE, 0, im_f[2], vul_f[1]);
2986 display_player_flag_aux(row+4, col, "¥Æ¥ì¥Ñ¥·¡¼:", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
2987 display_player_flag_aux(row+5, col, "Ãپò½ :", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
2988 display_player_flag_aux(row+6, col, "µÞ²óÉü :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
2989 display_player_flag_aux(row+7, col, "ÉâÍ· :", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
2990 display_player_flag_aux(row+8, col, "±Ê±ó¸÷¸» :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
2991 display_player_flag_aux(row+9, col, "¼ö¤¤ :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
2993 display_player_flag_aux(row+0, col, "Speed :", 1, TR1_SPEED, 0, im_f[0], vul_f[0]);
2994 display_player_flag_aux(row+1, col, "FreeAction:", 2, TR2_FREE_ACT, 0, im_f[1], vul_f[1]);
2995 display_player_flag_aux(row+2, col, "SeeInvisi.:", 3, TR3_SEE_INVIS, 0, im_f[2], vul_f[2]);
2996 display_player_flag_aux(row+3, col, "Hold Life :", 2, TR2_HOLD_LIFE, 0, im_f[1], vul_f[1]);
2997 display_player_flag_aux(row+4, col, "Telepathy :", 3, TR3_TELEPATHY, 0, im_f[2], vul_f[2]);
2998 display_player_flag_aux(row+5, col, "SlowDigest:", 3, TR3_SLOW_DIGEST, 0, im_f[2], vul_f[2]);
2999 display_player_flag_aux(row+6, col, "Regene. :", 3, TR3_REGEN, 0, im_f[2], vul_f[2]);
3000 display_player_flag_aux(row+7, col, "Levitation:", 3, TR3_FEATHER, 0, im_f[2], vul_f[2]);
3001 display_player_flag_aux(row+8, col, "Perm Lite :", 3, TR3_LITE, 0, im_f[2], vul_f[2]);
3002 display_player_flag_aux(row+9, col, "Cursed :", 3, (TR3_CURSED | TR3_HEAVY_CURSE), TR3_PERMA_CURSE, im_f[2], vul_f[2]);
3009 * Special display, part 2a
3011 static void display_player_misc_info(void)
3016 /* Display basics */
3018 put_str("̾Á° :", 1, 26);
3019 put_str("ÀÊÌ :", 3, 1);
3020 put_str("¼ï² :", 4, 1);
3021 put_str("¿¦¶È :", 5, 1);
3023 put_str("Name :", 1, 26);
3024 put_str("Sex :", 3, 1);
3025 put_str("Race :", 4, 1);
3026 put_str("Class :", 5, 1);
3029 strcpy(tmp,ap_ptr->title);
3036 strcat(tmp,player_name);
3038 c_put_str(TERM_L_BLUE, tmp, 1, 34);
3039 c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
3040 c_put_str(TERM_L_BLUE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), 4, 9);
3041 c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 9);
3043 /* Display extras */
3045 put_str("¥ì¥Ù¥ë:", 6, 1);
3046 put_str("£È£Ð :", 7, 1);
3047 put_str("£Í£Ð :", 8, 1);
3049 put_str("Level :", 6, 1);
3050 put_str("Hits :", 7, 1);
3051 put_str("Mana :", 8, 1);
3055 (void)sprintf(buf, "%d", (int)p_ptr->lev);
3056 c_put_str(TERM_L_BLUE, buf, 6, 9);
3057 (void)sprintf(buf, "%d/%d", (int)p_ptr->chp, (int)p_ptr->mhp);
3058 c_put_str(TERM_L_BLUE, buf, 7, 9);
3059 (void)sprintf(buf, "%d/%d", (int)p_ptr->csp, (int)p_ptr->msp);
3060 c_put_str(TERM_L_BLUE, buf, 8, 9);
3065 * Special display, part 2b
3067 * How to print out the modifications and sustains.
3068 * Positive mods with no sustain will be light green.
3069 * Positive mods with a sustain will be dark green.
3070 * Sustains (with no modification) will be a dark green 's'.
3071 * Negative mods (from a curse) will be red.
3072 * Huge mods (>9), like from MICoMorgoth, will be a '*'
3073 * No mod, no sustain, will be a slate '.'
3075 static void display_player_stat_info(void)
3097 /* Print out the labels for the columns */
3099 c_put_str(TERM_WHITE, "ǽÎÏ", row, stat_col+1);
3100 c_put_str(TERM_BLUE, " ´ðËÜ", row, stat_col+7);
3101 c_put_str(TERM_L_BLUE, " ¼ï ¿¦ À Áõ ", row, stat_col+13);
3102 c_put_str(TERM_L_GREEN, "¹ç·×", row, stat_col+28);
3103 c_put_str(TERM_YELLOW, "¸½ºß", row, stat_col+33);
3105 c_put_str(TERM_WHITE, "Stat", row, stat_col+1);
3106 c_put_str(TERM_BLUE, " Base", row, stat_col+7);
3107 c_put_str(TERM_L_BLUE, "RacClaPerMod", row, stat_col+13);
3108 c_put_str(TERM_L_GREEN, "Actual", row, stat_col+26);
3109 c_put_str(TERM_YELLOW, "Current", row, stat_col+32);
3113 /* Display the stats */
3114 for (i = 0; i < 6; i++)
3118 if (p_ptr->mimic_form) r_adj = mimic_info[p_ptr->mimic_form].r_adj[i];
3119 else r_adj = rp_ptr->r_adj[i];
3121 /* Calculate equipment adjustment */
3124 /* Icky formula to deal with the 18 barrier */
3125 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] > 18))
3126 e_adj = (p_ptr->stat_top[i] - p_ptr->stat_max[i]) / 10;
3127 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] <= 18))
3128 e_adj = p_ptr->stat_top[i] - p_ptr->stat_max[i];
3129 if ((p_ptr->stat_max[i] <= 18) && (p_ptr->stat_top[i] > 18))
3130 e_adj = (p_ptr->stat_top[i] - 18) / 10 - p_ptr->stat_max[i] + 18;
3132 if ((p_ptr->stat_max[i] > 18) && (p_ptr->stat_top[i] <= 18))
3133 e_adj = p_ptr->stat_top[i] - (p_ptr->stat_max[i] - 19) / 10 - 19;
3135 if (prace_is_(RACE_ENT))
3141 if (p_ptr->lev > 25) r_adj++;
3142 if (p_ptr->lev > 40) r_adj++;
3143 if (p_ptr->lev > 45) r_adj++;
3146 if (p_ptr->lev > 25) r_adj--;
3147 if (p_ptr->lev > 40) r_adj--;
3148 if (p_ptr->lev > 45) r_adj--;
3154 e_adj -= cp_ptr->c_adj[i];
3155 e_adj -= ap_ptr->a_adj[i];
3157 /* Reduced name of stat */
3159 c_put_str(TERM_WHITE, stat_names[i], row + i+1, stat_col+1);
3161 c_put_str(TERM_WHITE, stat_names_reduced[i], row + i+1, stat_col+1);
3165 /* Internal "natural" max value. Maxes at 18/100 */
3166 /* This is useful to see if you are maxed out */
3167 cnv_stat(p_ptr->stat_max[i], buf);
3168 if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
3170 c_put_str(TERM_WHITE, "!", row + i+1, stat_col + 6);
3172 c_put_str(TERM_BLUE, buf, row + i+1, stat_col + 13 - strlen(buf));
3174 /* Race, class, and equipment modifiers */
3175 (void)sprintf(buf, "%3d", r_adj);
3176 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 13);
3177 (void)sprintf(buf, "%3d", (int)cp_ptr->c_adj[i]);
3178 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 16);
3179 (void)sprintf(buf, "%3d", (int)ap_ptr->a_adj[i]);
3180 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 19);
3181 (void)sprintf(buf, "%3d", (int)e_adj);
3182 c_put_str(TERM_L_BLUE, buf, row + i+1, stat_col + 22);
3184 /* Actual maximal modified value */
3185 cnv_stat(p_ptr->stat_top[i], buf);
3186 c_put_str(TERM_L_GREEN, buf, row + i+1, stat_col + 26);
3188 /* Only display stat_use if not maximal */
3189 if (p_ptr->stat_use[i] < p_ptr->stat_top[i])
3191 cnv_stat(p_ptr->stat_use[i], buf);
3192 c_put_str(TERM_YELLOW, buf, row + i+1, stat_col + 33);
3197 col = stat_col + 41;
3199 /* Header and Footer */
3200 c_put_str(TERM_WHITE, "abcdefghijkl@", row, col);
3202 c_put_str(TERM_L_GREEN, "ǽÎϽ¤Àµ", row - 1, col);
3204 c_put_str(TERM_L_GREEN, "Modification", row - 1, col);
3208 /* Process equipment */
3209 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3212 o_ptr = &inventory[i];
3215 k_idx = o_ptr->k_idx;
3217 /* Acquire "known" flags */
3218 object_flags_known(o_ptr, &f1, &f2, &f3);
3220 /* Initialize color based of sign of pval. */
3221 for (stat = 0; stat < 6; stat++)
3234 if (o_ptr->pval > 0)
3240 if (o_ptr->pval < 10) c = '0' + o_ptr->pval;
3245 /* Dark green for sustained stats */
3250 if (o_ptr->pval < 0)
3256 if (o_ptr->pval < 10) c = '0' - o_ptr->pval;
3261 else if (f2 & 1 << stat)
3263 /* Dark green "s" */
3268 /* Dump proper character */
3269 Term_putch(col, row + stat+1, a, c);
3277 player_flags(&f1, &f2, &f3);
3280 for (stat = 0; stat < 6; stat++)
3287 if (p_ptr->muta3 || p_ptr->tsuyoshi)
3293 if (p_ptr->muta3 & MUT3_HYPER_STR) dummy += 4;
3294 if (p_ptr->muta3 & MUT3_PUNY) dummy -= 4;
3295 if (p_ptr->tsuyoshi) dummy += 4;
3297 else if (stat == A_WIS || stat == A_INT)
3299 if (p_ptr->muta3 & MUT3_HYPER_INT) dummy += 4;
3300 if (p_ptr->muta3 & MUT3_MORONIC) dummy -= 4;
3302 else if (stat == A_DEX)
3304 if (p_ptr->muta3 & MUT3_IRON_SKIN) dummy -= 1;
3305 if (p_ptr->muta3 & MUT3_LIMBER) dummy += 3;
3306 if (p_ptr->muta3 & MUT3_ARTHRITIS) dummy -= 3;
3308 else if (stat == A_CON)
3310 if (p_ptr->muta3 & MUT3_RESILIENT) dummy += 4;
3311 if (p_ptr->muta3 & MUT3_XTRA_FAT) dummy += 2;
3312 if (p_ptr->muta3 & MUT3_ALBINO) dummy -= 4;
3313 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 2;
3314 if (p_ptr->tsuyoshi) dummy += 4;
3316 else if (stat == A_CHR)
3318 if (p_ptr->muta3 & MUT3_SILLY_VOI) dummy -= 4;
3319 if (p_ptr->muta3 & MUT3_BLANK_FAC) dummy -= 1;
3320 if (p_ptr->muta3 & MUT3_FLESH_ROT) dummy -= 1;
3321 if (p_ptr->muta3 & MUT3_SCALES) dummy -= 1;
3322 if (p_ptr->muta3 & MUT3_WART_SKIN) dummy -= 2;
3323 if (p_ptr->muta3 & MUT3_ILL_NORM) dummy = 0;
3339 if (dummy < 10) c = '0' + dummy;
3349 if (dummy < 10) c = '0' - dummy;
3358 /* Dark green "s" */
3365 Term_putch(col, row + stat+1, a, c);
3373 static cptr object_flag_names[96] =
3614 * Summarize resistances
3616 static void display_player_ben(void)
3629 for (i = 0; i < 6; i++) b[i] = 0;
3632 /* Scan equipment */
3633 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3636 o_ptr = &inventory[i];
3638 /* Known object flags */
3639 object_flags_known(o_ptr, &f1, &f2, &f3);
3642 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3644 f3 &= ~(TR3_AGGRAVATE);
3649 b[0] |= (f1 & 0xFFFF);
3651 b[2] |= (f2 & 0xFFFF);
3653 b[4] |= (f3 & 0xFFFF);
3659 player_flags(&f1, &f2, &f3);
3662 b[0] |= (f1 & 0xFFFF);
3664 b[2] |= (f2 & 0xFFFF);
3666 b[4] |= (f3 & 0xFFFF);
3670 tim_player_flags(&f1, &f2, &f3, FALSE);
3673 b[0] |= (f1 & 0xFFFF);
3675 b[2] |= (f2 & 0xFFFF);
3677 b[4] |= (f3 & 0xFFFF);
3679 color[0] = (f1 & 0xFFFF);
3680 color[1] = (f1 >> 16);
3681 color[2] = (f2 & 0xFFFF);
3682 color[3] = (f2 >> 16);
3683 color[4] = (f3 & 0xFFFF);
3684 color[5] = (f3 >> 16);
3687 for (x = 0; x < 6; x++)
3690 for (y = 0; y < 16; y++)
3692 byte a = TERM_SLATE;
3695 cptr name = object_flag_names[16*x+y];
3698 if (!name) continue;
3701 Term_putstr(x * 13, y + 4, -1, TERM_WHITE, name);
3704 Term_putch(x * 13 + 10, y + 4, TERM_WHITE, ':');
3709 if (color[x] & (1<<y))
3722 Term_putch(x * 13 + 11, y + 4, a, c);
3729 * Summarize resistances
3731 static void display_player_ben_one(int mode)
3743 /* Scan equipment */
3744 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
3747 n = (i - INVEN_RARM);
3750 o_ptr = &inventory[i];
3752 object_flags_known(o_ptr, &f1, &f2, &f3);
3754 if ((prace_is_(RACE_S_FAIRY)) && (f3 & TR3_AGGRAVATE))
3756 f3 &= ~(TR3_AGGRAVATE);
3761 b[n][0] = (u16b)(f1 & 0xFFFF);
3762 b[n][1] = (u16b)(f1 >> 16);
3763 b[n][2] = (u16b)(f2 & 0xFFFF);
3764 b[n][3] = (u16b)(f2 >> 16);
3765 b[n][4] = (u16b)(f3 & 0xFFFF);
3766 b[n][5] = (u16b)(f3 >> 16);
3774 player_flags(&f1, &f2, &f3);
3777 b[n][0] = (u16b)(f1 & 0xFFFF);
3778 b[n][1] = (u16b)(f1 >> 16);
3779 b[n][2] = (u16b)(f2 & 0xFFFF);
3780 b[n][3] = (u16b)(f2 >> 16);
3781 b[n][4] = (u16b)(f3 & 0xFFFF);
3782 b[n][5] = (u16b)(f3 >> 16);
3785 tim_player_flags(&f1, &f2, &f3, FALSE);
3788 b[n][0] |= (f1 & 0xFFFF);
3789 b[n][1] |= (f1 >> 16);
3790 b[n][2] |= (f2 & 0xFFFF);
3791 b[n][3] |= (f2 >> 16);
3792 b[n][4] |= (f3 & 0xFFFF);
3793 b[n][5] |= (f3 >> 16);
3794 color[0] = (f1 & 0xFFFF);
3795 color[1] = (f1 >> 16);
3796 color[2] = (f2 & 0xFFFF);
3797 color[3] = (f2 >> 16);
3798 color[4] = (f3 & 0xFFFF);
3799 color[5] = (f3 >> 16);
3803 for (x = 0; x < 3; x++)
3806 display_player_equippy(2, x * 26 + 11);
3809 Term_putstr(x * 26 + 11, 3, -1, TERM_WHITE, "abcdefghijkl@");
3812 for (y = 0; y < 16; y++)
3814 cptr name = object_flag_names[48*mode+16*x+y];
3817 if (!name) continue;
3820 Term_putstr(x * 26, y + 4, -1, TERM_WHITE, name);
3823 Term_putch(x * 26 + 10, y + 4, TERM_WHITE, ':');
3826 for (n = 0; n < 13; n++)
3828 byte a = TERM_SLATE;
3832 if (b[n][3*mode+x] & (1<<y))
3834 if ((n == 12) && (color[3*mode+x] & (1<<y)))
3847 Term_putch(x * 26 + 11 + n, y + 4, a, c);
3855 * Display the character on the screen (various modes)
3857 * The top two and bottom two lines are left blank.
3859 * Mode 0 = standard display with skills
3860 * Mode 1 = standard display with history
3861 * Mode 2 = summary of various things
3862 * Mode 3 = current flags (combined)
3863 * Mode 4 = current flags (part 1)
3864 * Mode 5 = current flags (part 2)
3865 * Mode 6 = mutations
3867 void display_player(int mode)
3876 if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && skip_mutations)
3885 if ((mode == 0) || (mode == 1))
3887 /* Name, Sex, Race, Class */
3889 put_str("̾Á° :", 1,26);
3890 put_str("ÀÊÌ :", 3, 1);
3891 put_str("¼ï² :", 4, 1);
3892 put_str("¿¦¶È :", 5, 1);
3894 put_str("Name :", 1,26);
3895 put_str("Sex :", 3, 1);
3896 put_str("Race :", 4, 1);
3897 put_str("Class :", 5, 1);
3900 if (p_ptr->realm1 || p_ptr->realm2)
3902 put_str("ËâË¡ :", 6, 1);
3904 put_str("Magic :", 6, 1);
3907 if (p_ptr->pclass == CLASS_CHAOS_WARRIOR)
3909 put_str("¼é¸îËâ¿À :", 7, 1);
3911 put_str("Patron :", 7, 1);
3914 strcpy(tmp,ap_ptr->title);
3921 strcat(tmp,player_name);
3923 c_put_str(TERM_L_BLUE, tmp, 1, 34);
3924 c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 15);
3925 c_put_str(TERM_L_BLUE, (p_ptr->mimic_form ? mimic_info[p_ptr->mimic_form].title : rp_ptr->title), 4, 15);
3926 c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15);
3928 c_put_str(TERM_L_BLUE, realm_names[p_ptr->realm1], 6, 15);
3929 if (p_ptr->pclass == CLASS_CHAOS_WARRIOR)
3930 c_put_str(TERM_L_BLUE, chaos_patrons[p_ptr->chaos_patron], 7, 15);
3932 else if (p_ptr->realm2)
3933 c_put_str(TERM_L_BLUE, realm_names[p_ptr->realm2], 7, 15);
3935 /* Age, Height, Weight, Social */
3937 /* ¿ÈĹ¤Ï¥»¥ó¥Á¥á¡¼¥È¥ë¤Ë¡¢ÂνŤϥ¥í¥°¥é¥à¤ËÊѹ¹¤·¤Æ¤¢¤ê¤Þ¤¹ */
3938 /* ¹¹¤ËÆüËܸìÈǤÎÄɲäȤ·¤Æñ°Ì¤âɽ¼¨¤·¤Þ¤¹ */
3939 /* Ãæ±û¤Î¥«¥é¥à¤ÏÆüËܸì¤òɽ¼¨¤¹¤ë¤Ë¤Ï¶¹¤¤¤Î¤Ç¡¢º¸¤Ë4¤ÄÆ°¤«¤·¤Þ¤¹¡£ */
3940 prt_num2("ǯÎð ", "ºÍ",(int)p_ptr->age, 3, 32-2, TERM_L_BLUE);
3941 prt_num2("¿ÈĹ ","cm",(int)((p_ptr->ht*254)/100) , 4, 32-2, TERM_L_BLUE);
3942 prt_num2("ÂνŠ", "kg",(int)((p_ptr->wt*4536)/10000) , 5, 32-2, TERM_L_BLUE);
3943 prt_num("¼Ò²ñŪÃÏ°Ì ", (int)p_ptr->sc , 6, 32-2, TERM_L_BLUE);
3945 prt_num("Age ", (int)p_ptr->age, 3, 32, TERM_L_BLUE);
3946 prt_num("Height ", (int)p_ptr->ht , 4, 32, TERM_L_BLUE);
3947 prt_num("Weight ", (int)p_ptr->wt , 5, 32, TERM_L_BLUE);
3948 prt_num("Social Class ", (int)p_ptr->sc , 6, 32, TERM_L_BLUE);
3952 /* Display the stats */
3953 for (i = 0; i < 6; i++)
3955 /* Special treatment of "injured" stats */
3956 if (p_ptr->stat_cur[i] < p_ptr->stat_max[i])
3960 /* Use lowercase stat name */
3961 put_str(stat_names_reduced[i], 2 + i, 59);
3963 /* Get the current stat */
3964 value = p_ptr->stat_use[i];
3966 /* Obtain the current stat (modified) */
3967 cnv_stat(value, buf);
3969 /* Display the current stat (modified) */
3970 c_put_str(TERM_YELLOW, buf, 2 + i, 66);
3972 /* Acquire the max stat */
3973 value = p_ptr->stat_top[i];
3975 /* Obtain the maximum stat (modified) */
3976 cnv_stat(value, buf);
3978 /* Display the maximum stat (modified) */
3979 c_put_str(TERM_L_GREEN, buf, 2 + i, 73);
3982 /* Normal treatment of "normal" stats */
3985 /* Assume uppercase stat name */
3986 put_str(stat_names[i], 2 + i, 59);
3988 /* Obtain the current stat (modified) */
3989 cnv_stat(p_ptr->stat_use[i], buf);
3991 /* Display the current stat (modified) */
3992 c_put_str(TERM_L_GREEN, buf, 2 + i, 66);
3995 if (p_ptr->stat_max[i] == p_ptr->stat_max_max[i])
3997 c_put_str(TERM_WHITE, "!", 2+i, 64);
4002 display_player_middle();
4004 /* Display "history" info */
4008 put_str("(¥¥ã¥é¥¯¥¿¡¼¤ÎÀ¸¤¤Î©¤Á)", 16, 25);
4010 put_str("(Character Background)", 16, 25);
4014 for (i = 0; i < 4; i++)
4016 put_str(history[i], i + 17, 10);
4020 /* Display "various" info */
4024 put_str(" (¤½¤Î¾¤ÎǽÎÏ) ", 16, 25);
4026 put_str("(Miscellaneous Abilities)", 16, 25);
4030 display_player_various();
4037 /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */
4040 display_player_misc_info();
4041 display_player_stat_info();
4042 display_player_flag_info();
4048 display_player_ben();
4053 do_cmd_knowledge_mutations();
4059 display_player_ben_one(mode % 2);
4063 errr make_character_dump(FILE *fff)
4070 char o_name[MAX_NLEN];
4075 #ifndef FAKE_VERSION
4077 fprintf(fff, " [Angband %d.%d.%d Character Dump]\n\n",
4078 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
4081 fprintf(fff, " [ÊѶòÈÚÅÜ %d.%d.%d ¥¥ã¥é¥¯¥¿¾ðÊó]\n\n",
4082 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4084 fprintf(fff, " [Hengband %d.%d.%d Character Dump]\n\n",
4085 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
4092 /* Display player */
4095 /* Dump part of the screen */
4096 for (y = 1; y < 22; y++)
4099 for (x = 0; x < 79; x++)
4101 /* Get the attr/char */
4102 (void)(Term_what(x, y, &a, &c));
4108 /* End the string */
4111 /* Kill trailing spaces */
4112 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4116 fprintf(fff, "%s\n", buf);
4118 fprintf(fff, "%s\n", buf);
4123 /* Display history */
4126 /* Dump part of the screen */
4127 for (y = 16; y < 21; y++)
4130 for (x = 0; x < 79; x++)
4132 /* Get the attr/char */
4133 (void)(Term_what(x, y, &a, &c));
4139 /* End the string */
4142 /* Kill trailing spaces */
4143 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4146 fprintf(fff, "%s\n", buf);
4150 /* Display history */
4153 /* Dump part of the screen */
4154 for (y = 2; y < 22; y++)
4157 for (x = 0; x < 79; x++)
4159 /* Get the attr/char */
4160 (void)(Term_what(x, y, &a, &c));
4166 /* End the string */
4169 /* Kill trailing spaces */
4170 while ((x > 0) && (buf[x-1] == ' ')) buf[--x] = '\0';
4173 fprintf(fff, "%s\n", buf);
4176 for (i = 0; i < p_ptr->count / 80; i++)
4179 for (i = 0; i < p_ptr->count % 80; i++)
4184 for (i = m_max - 1; i >= 1; i--)
4186 monster_type *m_ptr = &m_list[i];
4189 if (!m_ptr->r_idx) continue;
4190 if (!is_pet(m_ptr)) continue;
4191 if (!m_ptr->nickname && (p_ptr->riding != i)) continue;
4195 fprintf(fff, "\n [¼ç¤Ê¥Ú¥Ã¥È]\n\n");
4197 fprintf(fff, "\n [leading pets]\n\n");
4201 monster_desc(pet_name, m_ptr, 0x88);
4202 fprintf(fff, "%s", pet_name);
4203 if (p_ptr->riding == i)
4205 fprintf(fff, " ¾èÇÏÃæ");
4207 fprintf(fff, " riding");
4211 if (pet) fprintf(fff, "\n");
4214 if (death && !total_winner)
4217 fprintf(fff, "\n [»à¤ÌľÁ°¤Î¥á¥Ã¥»¡¼¥¸]\n\n");
4219 fprintf(fff, "\n [Last messages]\n\n");
4221 for (i = MIN(message_num(), 15); i >= 0; i--)
4223 fprintf(fff,"> %s\n",message_str((s16b)i));
4229 fprintf(fff, "\n [¤½¤Î¾¤Î¾ðÊó] \n");
4231 fprintf(fff, "\n [Miscellaneous information]\n");
4235 fprintf(fff, "\n µ¢´Ô¾ì½ê:\n");
4237 fprintf(fff, "\n Recall Depth:\n");
4239 for (y = 1; y < max_d_idx; y++)
4243 if (!d_info[y].maxdepth) continue;
4244 if (!max_dlv[y]) continue;
4245 if (d_info[y].final_guardian)
4247 if (!r_info[d_info[y].final_guardian].max_num) seiha = TRUE;
4249 else if (max_dlv[y] == d_info[y].maxdepth) seiha = TRUE;
4252 fprintf(fff, " %c%-12s: %3d ³¬\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4254 fprintf(fff, " %c%-16s: level %3d\n", seiha ? '!' : ' ', d_name+d_info[y].name, max_dlv[y]);
4260 fprintf(fff, "\n Êݸ¥â¡¼¥É: ON");
4262 fprintf(fff, "\n Preserve Mode: ON");
4267 fprintf(fff, "\n Êݸ¥â¡¼¥É: OFF");
4269 fprintf(fff, "\n Preserve Mode: OFF");
4273 if (ironman_autoscum)
4275 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß : ALWAYS");
4277 fprintf(fff, "\n Autoscum: ALWAYS");
4282 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß : ON");
4284 fprintf(fff, "\n Autoscum: ON");
4289 fprintf(fff, "\n ¼«Æ°Áª¤ê¹¥¤ß : OFF");
4291 fprintf(fff, "\n Autoscum: OFF");
4295 if (ironman_small_levels)
4297 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó: ALWAYS");
4299 fprintf(fff, "\n Small Levels: ALWAYS");
4302 else if (always_small_levels)
4304 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó: ON");
4306 fprintf(fff, "\n Small Levels: ON");
4309 else if (small_levels)
4311 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó: ENABLED");
4313 fprintf(fff, "\n Small Levels: ENABLED");
4318 fprintf(fff, "\n ¾®¤µ¤¤¥À¥ó¥¸¥ç¥ó: OFF");
4320 fprintf(fff, "\n Small Levels: OFF");
4326 fprintf(fff, "\n ¸µÁĤÎÄ®¤Î¤ß: ON");
4328 fprintf(fff, "\n Vanilla Town: ON");
4333 fprintf(fff, "\n ¾®µ¬ÌϤÊÄ®: ON");
4335 fprintf(fff, "\n Lite Town: ON");
4341 fprintf(fff, "\n Ź¤Ê¤·: ON");
4343 fprintf(fff, "\n No Shops: ON");
4347 if (ironman_downward)
4349 fprintf(fff, "\n ³¬Ãʤò¾å¤¬¤ì¤Ê¤¤: ON");
4351 fprintf(fff, "\n Diving only: ON");
4357 fprintf(fff, "\n ÉáÄ̤Ǥʤ¤Éô²°¤òÀ¸À®: ON");
4359 fprintf(fff, "\n Unusual rooms: ON");
4363 if (ironman_nightmare)
4365 fprintf(fff, "\n °Ì´¥â¡¼¥É: ON");
4367 fprintf(fff, "\n Nightmare Mode: ON");
4371 if (ironman_empty_levels)
4373 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê: ALWAYS");
4375 fprintf(fff, "\n Arena Levels: ALWAYS");
4378 else if (empty_levels)
4380 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê: ON");
4382 fprintf(fff, "\n Arena Levels: ENABLED");
4387 fprintf(fff, "\n ¥¢¥ê¡¼¥Ê: OFF");
4389 fprintf(fff, "\n Arena Levels: OFF");
4394 fprintf(fff, "\n ¥é¥ó¥À¥à¥¯¥¨¥¹¥È¿ô: %d", number_of_quests());
4396 fprintf(fff, "\n Num. Random Quests: %d", number_of_quests());
4399 if (p_ptr->arena_number == 99)
4402 fprintf(fff, "\n Æ®µ»¾ì: ÇÔËÌ\n");
4404 fprintf(fff, "\n Arena: defeated\n");
4407 else if (p_ptr->arena_number > MAX_ARENA_MONS+2)
4410 fprintf(fff, "\n Æ®µ»¾ì: ¿¿¤Î¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4412 fprintf(fff, "\n Arena: True Champion\n");
4415 else if (p_ptr->arena_number > MAX_ARENA_MONS-1)
4418 fprintf(fff, "\n Æ®µ»¾ì: ¥Á¥ã¥ó¥Ô¥ª¥ó\n");
4420 fprintf(fff, "\n Arena: Champion\n");
4426 fprintf(fff, "\n Æ®µ»¾ì: %2d¾¡\n", (p_ptr->arena_number > MAX_ARENA_MONS ? MAX_ARENA_MONS : p_ptr->arena_number));
4428 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");
4434 fprintf(fff, "\n ²¿¤«ÉÔÀµ¤Ê¤³¤È¤ò¤·¤Æ¤·¤Þ¤Ã¤Æ¤Þ¤¹¡£");
4436 fprintf(fff, "\n You have done something illegal.");
4440 if (stupid_monsters)
4442 fprintf(fff, "\n Ũ¤Ï¶ò¤«¤Ê¹ÔÆ°¤ò¼è¤ê¤Þ¤¹¡£");
4444 fprintf(fff, "\n Your opponents are behaving stupidly.");
4450 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï»à¤ò²óÈò¤¹¤ë¥¤¥ó¥Á¥¤ÊÎϤò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£");
4452 fprintf(fff, "\n You possess munchkinish power over death.");
4457 /* Monsters slain */
4462 for (k = 1; k < max_r_idx; k++)
4464 monster_race *r_ptr = &r_info[k];
4466 if (r_ptr->flags1 & RF1_UNIQUE)
4468 bool dead = (r_ptr->max_num == 0);
4476 s16b This = r_ptr->r_pkills;
4486 fprintf(fff,"\n ¤Þ¤ÀŨ¤òÅݤ·¤Æ¤¤¤Þ¤»¤ó¡£\n");
4488 fprintf(fff,"\n You have defeated no enemies yet.\n");
4491 else if (Total == 1)
4493 fprintf(fff,"\n °ìÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n");
4495 fprintf(fff,"\n You have defeated one enemy.\n");
4500 fprintf(fff,"\n %lu ÂΤÎŨ¤òÅݤ·¤Æ¤¤¤Þ¤¹¡£\n", Total);
4502 fprintf(fff,"\n You have defeated %lu enemies.\n", Total);
4508 if (p_ptr->old_race1 || p_ptr->old_race2)
4511 fprintf(fff, "\n\n ¤¢¤Ê¤¿¤Ï%s¤È¤·¤ÆÀ¸¤Þ¤ì¤¿¡£", race_info[p_ptr->start_race].title);
4513 fprintf(fff, "\n\n You were born as %s.", race_info[p_ptr->start_race].title);
4515 for (i = 0; i < MAX_RACES; i++)
4517 if (p_ptr->start_race == i) continue;
4520 if (!(p_ptr->old_race1 & 1L << i)) continue;
4524 if (!(p_ptr->old_race2 & 1L << (i-32))) continue;
4527 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%s¤À¤Ã¤¿¡£", race_info[i].title);
4529 fprintf(fff, "\n You were a %s before.", race_info[i].title);
4534 if (p_ptr->old_realm)
4536 for (i = 0; i < MAX_MAGIC; i++)
4538 if (!(p_ptr->old_realm & 1L << i)) continue;
4540 fprintf(fff, "\n ¤¢¤Ê¤¿¤Ï¤«¤Ä¤Æ%sËâË¡¤ò»È¤¨¤¿¡£", realm_names[i+1]);
4542 fprintf(fff, "\n You were able to use %s magic before.", realm_names[i+1]);
4548 fprintf(fff, "\n\n [¥×¥ì¥¤¥ä¡¼¤ÎÆÁ]\n\n");
4550 fprintf(fff, "\n\n [Virtues]\n\n");
4554 if (p_ptr->align > 150) disp_align = "ÂçÁ±";
4555 else if (p_ptr->align > 50) disp_align = "ÃæÁ±";
4556 else if (p_ptr->align > 10) disp_align = "¾®Á±";
4557 else if (p_ptr->align > -11) disp_align = "ÃæΩ";
4558 else if (p_ptr->align > -51) disp_align = "¾®°";
4559 else if (p_ptr->align > -151) disp_align = "Ãæ°";
4560 else disp_align = "Âç°";
4561 fprintf(fff, "°À : %s\n", disp_align);
4563 if (p_ptr->align > 150) disp_align = "lawful";
4564 else if (p_ptr->align > 50) disp_align = "good";
4565 else if (p_ptr->align > 10) disp_align = "nutral good";
4566 else if (p_ptr->align > -11) disp_align = "nutral";
4567 else if (p_ptr->align > -51) disp_align = "nutral evil";
4568 else if (p_ptr->align > -151) disp_align = "evil";
4569 else disp_align = "chaotic";
4570 fprintf(fff, "Your alighnment : %s\n", disp_align);
4575 if (p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3)
4578 fprintf(fff, "\n\n [ÆÍÁ³ÊÑ°Û]\n\n");
4580 fprintf(fff, "\n\n [Mutations]\n\n");
4583 dump_mutations(fff);
4587 /* Skip some lines */
4588 fprintf(fff, "\n\n");
4591 /* Dump the equipment */
4595 fprintf(fff, " [ ¥¥ã¥é¥¯¥¿¤ÎÁõÈ÷ ]\n\n");
4597 fprintf(fff, " [Character Equipment]\n\n");
4600 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4602 object_desc(o_name, &inventory[i], TRUE, 3);
4603 if ((i == INVEN_LARM) && p_ptr->ryoute)
4605 strcpy(o_name, "(Éð´ï¤òξ¼ê»ý¤Á)");
4607 strcpy(o_name, "(wielding a weapon with two-handed.)");
4609 fprintf(fff, "%c%s %s\n",
4610 index_to_label(i), paren, o_name);
4612 fprintf(fff, "\n\n");
4615 /* Dump the inventory */
4617 fprintf(fff, " [ ¥¥ã¥é¥¯¥¿¤Î»ý¤Áʪ ]\n\n");
4619 fprintf(fff, " [Character Inventory]\n\n");
4622 for (i = 0; i < INVEN_PACK; i++)
4624 /* Don't dump the empty slots */
4625 if (!inventory[i].k_idx) break;
4627 /* Dump the inventory slots */
4628 object_desc(o_name, &inventory[i], TRUE, 3);
4629 fprintf(fff, "%c%s %s\n", index_to_label(i), paren, o_name);
4632 /* Add an empty line */
4633 fprintf(fff, "\n\n");
4635 process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
4637 /* Print all homes in the different towns */
4638 st_ptr = &town[1].store[STORE_HOME];
4640 /* Home -- if anything there */
4641 if (st_ptr->stock_num)
4643 /* Header with name of the town */
4645 fprintf(fff, " [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
4647 fprintf(fff, " [Home Inventory]\n");
4651 /* Dump all available items */
4652 for (i = 0; i < st_ptr->stock_num; i++)
4656 fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4658 fprintf(fff, "\n ( page %d )\n", x++);
4660 object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4661 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4664 /* Add an empty line */
4665 fprintf(fff, "\n\n");
4669 /* Print all homes in the different towns */
4670 st_ptr = &town[1].store[STORE_MUSEUM];
4672 /* Home -- if anything there */
4673 if (st_ptr->stock_num)
4675 /* Header with name of the town */
4677 fprintf(fff, " [ Çîʪ´Û¤Î¥¢¥¤¥Æ¥à ]\n");
4679 fprintf(fff, " [Museum]\n");
4683 /* Dump all available items */
4684 for (i = 0; i < st_ptr->stock_num; i++)
4687 if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
4688 object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4689 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4691 if ((i % 12) == 0) fprintf(fff, "\n ( page %d )\n", x++);
4692 object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
4693 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
4698 /* Add an empty line */
4699 fprintf(fff, "\n\n");
4706 * Hack -- Dump a character description file
4708 * XXX XXX XXX Allow the "full" flag to dump additional info,
4709 * and trigger its usage from various places in the code.
4711 errr file_character(cptr name, bool full)
4720 /* Build the filename */
4721 path_build(buf, 1024, ANGBAND_DIR_USER, name);
4723 /* File type is "TEXT" */
4724 FILE_TYPE(FILE_TYPE_TEXT);
4726 /* Check for existing file */
4727 fd = fd_open(buf, O_RDONLY);
4734 /* Close the file */
4739 (void)sprintf(out_val, "¸½Â¸¤¹¤ë¥Õ¥¡¥¤¥ë %s ¤Ë¾å½ñ¤¤·¤Þ¤¹¤«? ", buf);
4741 (void)sprintf(out_val, "Replace existing file %s? ", buf);
4746 if (get_check(out_val)) fd = -1;
4749 /* Open the non-existing file */
4750 if (fd < 0) fff = my_fopen(buf, "w");
4761 msg_format("¥¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤½Ð¤·¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡ª");
4763 msg_format("Character dump failed!");
4772 (void)make_character_dump(fff);
4780 msg_print("¥¥ã¥é¥¯¥¿¾ðÊó¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤½Ð¤·¤ËÀ®¸ù¤·¤Þ¤·¤¿¡£");
4782 msg_print("Character dump successful.");
4793 * Recursive file perusal.
4795 * Return FALSE on "ESCAPE", otherwise TRUE.
4797 * Process various special text in the input file, including
4798 * the "menu" structures used by the "help file" system.
4800 * XXX XXX XXX Consider using a temporary file.
4802 * XXX XXX XXX Allow the user to "save" the current file.
4804 bool show_file(bool show_version, cptr name, cptr what, int line, int mode)
4808 /* Number of "real" lines passed by */
4811 /* Number of "real" lines in the file */
4814 /* Backup value for "line" */
4820 /* This screen has sub-screens */
4823 /* Current help file */
4826 /* Find this string (if any) */
4829 /* Jump to this tag */
4832 /* Hold a string to find */
4835 /* Hold a string to show */
4839 char filename[1024];
4841 /* Describe this thing */
4847 /* General buffer */
4850 /* Lower case version of the buffer, for searching */
4853 /* Aux pointer for making lc_buf (and find!) lowercase */
4856 /* Sub-menu information */
4859 /* Tags for in-file references */
4862 bool reverse = (line < 0);
4871 strcpy(caption, "");
4873 /* Wipe the hooks */
4874 for (i = 0; i < 68; i++)
4879 /* Copy the filename */
4880 strcpy(filename, name);
4882 n = strlen(filename);
4884 /* Extract the tag from the filename */
4885 for (i = 0; i < n; i++)
4887 if (filename[i] == '#')
4890 tag = filename + i + 1;
4895 /* Redirect the name */
4898 /* Hack XXX XXX XXX */
4902 strcpy(caption, what);
4904 /* Access the "file" */
4908 fff = my_fopen(path, "r");
4911 /* Look in "help" */
4916 sprintf(caption, "¥Ø¥ë¥×¡¦¥Õ¥¡¥¤¥ë'%s'", name);
4918 sprintf(caption, "Help file '%s'", name);
4922 /* Build the filename */
4923 path_build(path, 1024, ANGBAND_DIR_HELP, name);
4926 fff = my_fopen(path, "r");
4929 /* Look in "info" */
4934 sprintf(caption, "¥¹¥Ý¥¤¥é¡¼¡¦¥Õ¥¡¥¤¥ë'%s'", name);
4936 sprintf(caption, "Info file '%s'", name);
4940 /* Build the filename */
4941 path_build(path, 1024, ANGBAND_DIR_INFO, name);
4944 fff = my_fopen(path, "r");
4952 msg_format("'%s'¤ò¥ª¡¼¥×¥ó¤Ç¤¤Þ¤»¤ó¡£", name);
4954 msg_format("Cannot open '%s'.", name);
4964 /* Pre-Parse the file */
4967 /* Read a line or stop */
4968 if (my_fgets(fff, buf, 1024)) break;
4970 /* XXX Parse "menu" items */
4971 if (prefix(buf, "***** "))
4973 /* Notice "menu" requests */
4974 if ((buf[6] == '[') && (isdigit(buf[7]) || isalpha(buf[7])))
4976 /* This is a menu file */
4979 /* Extract the menu item */
4980 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
4982 if ((buf[8] == ']') && (buf[9] == ' '))
4984 /* Extract the menu item */
4985 strcpy(hook[k], buf + 10);
4988 /* Notice "tag" requests */
4989 else if ((buf[6] == '<') && (isdigit(buf[7]) || isalpha(buf[7])) &&
4992 /* Extract the menu item */
4993 k = isdigit(buf[7]) ? D2I(buf[7]) : buf[7] - 'A' + 10;
4995 /* Extract the menu item */
5003 /* Count the "real" lines */
5007 /* Save the number of "real" lines */
5010 if (line == -1) line = ((size-1)/20)*20;
5012 /* Go to the tagged line */
5014 line = tags[isdigit(tag[0]) ? D2I(tag[0]) : tag[0] - 'A' + 10];
5016 /* Display the file */
5022 /* Restart when necessary */
5023 if (line >= size) line = 0;
5026 /* Re-open the file if needed */
5032 /* Hack -- Re-Open the file */
5033 fff = my_fopen(path, "r");
5036 if (!fff) return (FALSE);
5038 /* File has been restarted */
5042 /* Goto the selected line */
5046 if (my_fgets(fff, buf, 1024)) break;
5048 /* Skip tags/links */
5049 if (prefix(buf, "***** ")) continue;
5051 /* Count the lines */
5055 /* Dump the next 20 lines of the file */
5056 for (i = 0; i < 20; )
5058 /* Hack -- track the "first" line */
5059 if (!i) line = next;
5061 /* Get a line of the file or stop */
5062 if (my_fgets(fff, buf, 1024)) break;
5064 /* Hack -- skip "special" lines */
5065 if (prefix(buf, "***** ")) continue;
5067 /* Count the "real" lines */
5070 /* Make a lower case version of buf for searching */
5071 strcpy(lc_buf, buf);
5073 for (lc_buf_ptr = lc_buf; *lc_buf_ptr != 0; lc_buf_ptr++)
5075 lc_buf[lc_buf_ptr-lc_buf] = tolower(*lc_buf_ptr);
5078 /* Hack -- keep searching */
5079 if (find && !i && !strstr(lc_buf, find)) continue;
5081 /* Hack -- stop searching */
5085 Term_putstr(0, i+2, -1, TERM_WHITE, buf);
5087 /* Hilite "shower" */
5092 /* Display matches */
5093 while ((str = strstr(str, shower)) != NULL)
5095 int len = strlen(shower);
5097 /* Display the match */
5098 Term_putstr(str-lc_buf, i+2, len, TERM_YELLOW, &buf[str-lc_buf]);
5105 /* Count the printed lines */
5109 /* Hack -- failed search */
5119 /* Show a general "title" */
5123 prt(format("[ÊѶòÈÚÅÜ %d.%d.%d, %s, %d/%d]",
5125 prt(format("[Hengband %d.%d.%d, %s, Line %d/%d]",
5128 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH,
5129 caption, line, size), 0, 0);
5134 prt(format("[%s, %d/%d]",
5136 prt(format("[%s, Line %d/%d]",
5138 caption, line, size), 0, 0);
5141 /* Prompt -- menu screen */
5146 prt("[ ÈÖ¹æ¤òÆþÎϤ·¤Æ²¼¤µ¤¤( ESC¤Ç½ªÎ» ) ]", 23, 0);
5148 prt("[Press a Number, or ESC to exit.]", 23, 0);
5153 /* Prompt -- small files */
5154 else if (size <= 20)
5158 prt("[¥¡¼:(?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5160 prt("[Press ESC to exit.]", 23, 0);
5165 /* Prompt -- large files */
5170 prt("[¥¡¼:(RET/¥¹¥Ú¡¼¥¹)¢¬ (-)¢ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5172 prt("[¥¡¼:(RET/¥¹¥Ú¡¼¥¹)¢ (-)¢¬ (?)¥Ø¥ë¥× (ESC)½ªÎ»]", 23, 0);
5174 prt("[Press Return, Space, -, =, /, |, or ESC to exit.]", 23, 0);
5178 /* Get a keypress */
5181 /* Hack -- return to last screen */
5182 if (k == '<') break;
5184 /* Show the help for the help */
5187 /* Hack - prevent silly recursion */
5189 if (strcmp(name, "jhelpinfo.txt") != 0)
5190 show_file(TRUE, "jhelpinfo.txt", NULL, 0, mode);
5192 if (strcmp(name, "helpinfo.txt") != 0)
5193 show_file(TRUE, "helpinfo.txt", NULL, 0, mode);
5197 /* Hack -- try showing */
5202 prt("¶¯Ä´: ", 23, 0);
5204 prt("Show: ", 23, 0);
5207 (void)askfor_aux(shower, 80);
5210 /* Hack -- try finding */
5215 prt("¸¡º÷: ", 23, 0);
5217 prt("Find: ", 23, 0);
5221 if (askfor_aux(finder, 80))
5228 /* Make finder lowercase */
5229 for (cnt = 0; finder[cnt] != 0; cnt++)
5231 finder[cnt] = tolower(finder[cnt]);
5235 strcpy(shower, finder);
5239 /* Hack -- go to a specific line */
5246 prt("Goto Line: ", 23, 0);
5251 if (askfor_aux(tmp, 80))
5257 /* Hack -- go to a specific file */
5262 prt("¥Õ¥¡¥¤¥ë¡¦¥Í¡¼¥à: ", 23, 0);
5263 strcpy(tmp, "jhelp.hlp");
5265 prt("Goto File: ", 23, 0);
5266 strcpy(tmp, "help.hlp");
5270 if (askfor_aux(tmp, 80))
5272 if (!show_file(TRUE, tmp, NULL, 0, mode)) k = ESCAPE;
5276 /* Hack -- Allow backing up */
5279 line = line + (reverse ? 20 : -20);
5280 if (line < 0) line = ((size-1)/20)*20;
5283 /* Hack -- Advance a single line */
5284 if ((k == '\n') || (k == '\r'))
5286 line = line + (reverse ? -1 : 1);
5287 if (line < 0) line = ((size-1)/20)*20;
5290 /* Advance one page */
5293 line = line + (reverse ? -20 : 20);
5294 if (line < 0) line = ((size-1)/20)*20;
5298 /* ÆüËܸìÈǤÇÄɲ䵤줿¥Ø¥ë¥×¤Îɽ¼¨ */
5299 /* ¤¢¤Þ¤ê¤è¤¤½èÍý¤Î»ÅÊý¤È¤Ï»×¤¨¤Ê¤¤¡¦¡¦¡¦¤¹¤Þ¤ó */
5301 /* ´Ê°×¥³¥Þ¥ó¥É°ìÍ÷ */
5302 if (menu && (k == 'c' || k == 'C'))
5305 switch (rogue_like_commands)
5309 strcpy(tmp, "j_com_r.txt");
5310 if(!show_file(TRUE, tmp, NULL, 0, mode)) k = ESCAPE;
5315 strcpy(tmp, "j_com_o.txt");
5316 if(!show_file(TRUE, tmp, NULL, 0, mode)) k = ESCAPE;
5323 /* Recurse on numbers */
5328 if (isdigit(k)) key = D2I(k);
5329 else if (isalpha(k)) key = k - 'A' + 10;
5331 if ((key > -1) && hook[key][0])
5333 /* Recurse on that file */
5334 if (!show_file(TRUE, hook[key], NULL, 0, mode))
5339 /* Hack, dump to file */
5349 if (get_string("¥Õ¥¡¥¤¥ë̾: ", xtmp, 80))
5351 if (get_string("File name: ", xtmp, 80))
5355 if (xtmp[0] && (xtmp[0] != ' '))
5364 /* Build the filename */
5365 path_build(buff, 1024, ANGBAND_DIR_USER, xtmp);
5370 /* Hack -- Re-Open the file */
5371 fff = my_fopen(path, "r");
5373 ffp = my_fopen(buff, "w");
5379 msg_print("¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¡£");
5381 msg_print("Failed to open file.");
5388 sprintf(xtmp, "%s: %s", player_name, what);
5389 my_fputs(ffp, xtmp, 80);
5390 my_fputs(ffp, "\n", 80);
5392 while (!my_fgets(fff, buff, 80))
5393 my_fputs(ffp, buff, 80);
5399 /* Hack -- Re-Open the file */
5400 fff = my_fopen(path, "r");
5403 /* Exit on escape */
5404 if (k == ESCAPE) break;
5407 /* Close the file */
5411 if (k == ESCAPE) return (FALSE);
5419 * Peruse the On-Line-Help
5421 void do_cmd_help(void)
5426 /* Peruse the main help file */
5428 (void)show_file(TRUE, "jhelp.hlp", NULL, 0, 0);
5430 (void)show_file(TRUE, "help.hlp", NULL, 0, 0);
5440 * Process the player name.
5441 * Extract a clean "base name".
5442 * Build the savefile name if needed.
5444 void process_player_name(bool sf)
5449 /* Cannot be too long */
5450 #if defined(MACINTOSH) || defined(MSDOS) || defined(USE_EMX) || defined(AMIGA) || defined(ACORN) || defined(VM)
5452 if (strlen(player_name) > 8)
5454 if (strlen(player_name) > 15)
5459 quit_fmt("'%s'¤È¤¤¤¦Ì¾Á°¤ÏŤ¹¤®¤Þ¤¹¡ª", player_name);
5461 quit_fmt("The name '%s' is too long!", player_name);
5467 /* Cannot contain "icky" characters */
5468 for (i = 0; player_name[i]; i++)
5470 /* No control characters */
5472 if (iskanji(player_name[i])){i++;continue;}
5473 if (iscntrl( (unsigned char)player_name[i]))
5475 if (iscntrl(player_name[i]))
5479 /* Illegal characters */
5481 quit_fmt("'%s' ¤È¤¤¤¦Ì¾Á°¤ÏÉÔÀµ¤Ê¥³¥ó¥È¥í¡¼¥ë¥³¡¼¥É¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£", player_name);
5483 quit_fmt("The name '%s' contains control chars!", player_name);
5492 /* Extract "useful" letters */
5493 for (i = 0; player_name[i]; i++)
5496 unsigned char c = player_name[i];
5498 char c = player_name[i];
5502 /* Convert "dot" to "underscore" */
5503 if (c == '.') c = '_';
5505 /* Accept all the letters */
5506 player_base[k++] = c;
5511 /* Extract "useful" letters */
5512 for (i = 0; player_name[i]; i++)
5515 unsigned char c = player_name[i];
5517 char c = player_name[i];
5520 /* Accept some letters */
5523 if(k + 2 >= sizeof(player_base) || !player_name[i+1]) break;
5524 player_base[k++] = c;
5526 player_base[k++] = player_name[i];
5529 else if (iskana(c)) player_base[k++] = c;
5533 /* Convert path separator to underscore */
5534 if (!strncmp(PATH_SEP, player_name+i, strlen(PATH_SEP))){
5535 player_base[k++] = '_';
5536 i += strlen(PATH_SEP);
5539 /* Convert space, dot, and underscore to underscore */
5540 else if (strchr(". _", c)) player_base[k++] = '_';
5542 else if (isprint(c)) player_base[k++] = c;
5548 #if defined(WINDOWS) || defined(MSDOS)
5550 /* Hack -- max length */
5556 player_base[k] = '\0';
5558 /* Require a "base" name */
5559 if (!player_base[0]) strcpy(player_base, "PLAYER");
5562 #ifdef SAVEFILE_MUTABLE
5568 if (!savefile_base[0] && savefile[0])
5575 t = strstr(s, PATH_SEP);
5580 strcpy(savefile_base, s);
5583 if (!savefile_base[0] || !savefile[0])
5586 /* Change the savefile name */
5591 strcpy(savefile_base, player_base);
5593 #ifdef SAVEFILE_USE_UID
5594 /* Rename the savefile, using the player_uid and player_base */
5595 (void)sprintf(temp, "%d.%s", player_uid, player_base);
5597 /* Rename the savefile, using the player_base */
5598 (void)sprintf(temp, "%s", player_base);
5602 /* Hack -- support "flat directory" usage on VM/ESA */
5603 (void)sprintf(temp, "%s.sv", player_base);
5606 /* Build the filename */
5607 path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp);
5613 * Gets a name for the character, reacting to name changes.
5615 * Assumes that "display_player(0)" has just been called
5617 * Perhaps we should NOT ask for a name (at "birth()") on
5618 * Unix machines? XXX XXX
5620 * What a horrible name for a global function. XXX XXX XXX
5626 /* Save the player name */
5627 strcpy(tmp, player_name);
5629 /* Prompt for a new name */
5631 if (get_string("¥¥ã¥é¥¯¥¿¡¼¤Î̾Á°¤òÆþÎϤ·¤Æ²¼¤µ¤¤: ", tmp, 15))
5633 if (get_string("Enter a name for your character: ", tmp, 15))
5637 strcpy(player_name, tmp);
5639 /* Process the player name */
5640 process_player_name(FALSE);
5642 else if (strlen(player_name))
5644 /* Process the player name */
5645 process_player_name(FALSE);
5648 strcpy(tmp,ap_ptr->title);
5655 strcat(tmp,player_name);
5657 /* Re-Draw the name (in light blue) */
5658 c_put_str(TERM_L_BLUE, tmp, 1, 34);
5660 /* Erase the prompt, etc */
5667 * Hack -- commit suicide
5669 void do_cmd_suicide(void)
5676 /* Verify Retirement */
5681 if (!get_check("°úÂष¤Þ¤¹¤«? ")) return;
5683 if (!get_check("Do you want to retire? ")) return;
5688 /* Verify Suicide */
5693 if (!get_check("ËÜÅö¤Ë¼«»¦¤·¤Þ¤¹¤«¡©")) return;
5695 if (!get_check("Do you really want to commit suicide? ")) return;
5702 /* Special Verification for suicide */
5704 prt("³Îǧ¤Î¤¿¤á '@' ¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 0);
5706 prt("Please verify SUICIDE by typing the '@' sign: ", 0, 0);
5712 if (i != '@') return;
5718 /* Kill the player */
5722 p_ptr->leaving = TRUE;
5727 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤ËÀä˾¤·¤Æ¼«»¦¤·¤¿¡£");
5728 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
5730 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "give up all hope to commit suicide.");
5731 do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- Game Over --------");
5733 do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
5736 /* Cause of death */
5738 (void)strcpy(died_from, "ÅÓÃ潪λ");
5740 (void)strcpy(died_from, "Quitting");
5750 void do_cmd_save_game(int is_autosave)
5752 /* Autosaves do not disturb */
5756 msg_print("¼«Æ°¥»¡¼¥ÖÃæ");
5758 msg_print("Autosaving the game...");
5764 /* Disturb the player */
5768 /* Clear messages */
5776 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹...", 0, 0);
5778 prt("Saving game...", 0, 0);
5785 /* The player is not dead */
5787 (void)strcpy(died_from, "(¥»¡¼¥Ö)");
5789 (void)strcpy(died_from, "(saved)");
5793 /* Forbid suspend */
5794 signals_ignore_tstp();
5796 /* Save the player */
5800 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ½ªÎ»", 0, 0);
5802 prt("Saving game... done.", 0, 0);
5807 /* Save failed (oops) */
5811 prt("¥²¡¼¥à¤ò¥»¡¼¥Ö¤·¤Æ¤¤¤Þ¤¹... ¼ºÇÔ¡ª", 0, 0);
5813 prt("Saving game... failed!", 0, 0);
5818 /* Allow suspend again */
5819 signals_handle_tstp();
5824 /* Note that the player is not dead */
5826 (void)strcpy(died_from, "(¸µµ¤¤ËÀ¸¤¤Æ¤¤¤ë)");
5828 (void)strcpy(died_from, "(alive and well)");
5835 * Save the game and exit
5837 void do_cmd_save_and_exit(void)
5842 p_ptr->leaving = TRUE;
5844 do_cmd_write_nikki(NIKKI_GAMESTART, 0, "----¥²¡¼¥àÃæÃÇ----");
5846 do_cmd_write_nikki(NIKKI_GAMESTART, 0, "---- Save and Exit Game ----");
5852 * Hack -- Calculates the total number of points earned -JWT-
5854 long total_points(void)
5858 u32b point, point_h, point_l;
5859 int arena_win = MIN(p_ptr->arena_number, MAX_ARENA_MONS);
5861 if (stupid_monsters) mult -= 70;
5862 if (!preserve_mode) mult += 10;
5863 if (!autoroller) mult += 10;
5864 if (!smart_learn) mult -= 20;
5865 if (!terrain_streams) mult -= 20;
5866 if (smart_cheat) mult += 30;
5867 if (ironman_shops) mult += 50;
5868 if (ironman_small_levels) mult += 10;
5869 if (ironman_empty_levels) mult += 20;
5870 if (!powerup_home) mult += 50;
5871 if (ironman_rooms) mult += 100;
5872 if (ironman_nightmare) mult += 100;
5874 if (mult < 5) mult = 5;
5876 for (i = 0; i < max_d_idx; i++)
5877 if(max_dlv[i] > max_dl)
5878 max_dl = max_dlv[i];
5880 point_l = (p_ptr->max_exp + (100 * max_dl));
5881 point_h = point_l / 0x10000L;
5882 point_l = point_l % 0x10000L;
5885 point_h += point_l / 0x10000L;
5886 point_l %= 0x10000L;
5888 point_l += ((point_h % 100) << 16);
5892 point = (point_h << 16) + (point_l);
5893 if (p_ptr->arena_number < 99)
5894 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
5896 if (ironman_downward) point *= 2;
5897 if (p_ptr->pclass == CLASS_BERSERKER)
5899 if ((p_ptr->prace == RACE_SPECTRE) || (p_ptr->prace == RACE_AMBERITE))
5903 if ((p_ptr->pseikaku == SEIKAKU_MUNCHKIN) && point)
5906 if (total_winner) point = 2;
5908 if (easy_band) point = (0 - point);
5916 * Centers a string within a 31 character string -JWT-
5918 static void center_string(char *buf, cptr str)
5925 /* Necessary border */
5929 (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, "");
5935 * Save a "bones" file for a dead character
5937 * Note that we will not use these files until Angband 2.8.0, and
5938 * then we will only use the name and level on which death occured.
5940 * Should probably attempt some form of locking...
5942 static void make_bones(void)
5949 /* Ignore wizards and borgs */
5950 if (!(noscore & 0x00FF))
5952 /* Ignore people who die in town */
5957 /* XXX XXX XXX "Bones" name */
5958 sprintf(tmp, "bone.%03d", dun_level);
5960 /* Build the filename */
5961 path_build(str, 1024, ANGBAND_DIR_BONE, tmp);
5963 /* Attempt to open the bones file */
5964 fp = my_fopen(str, "r");
5966 /* Close it right away */
5967 if (fp) my_fclose(fp);
5969 /* Do not over-write a previous ghost */
5972 /* File type is "TEXT" */
5973 FILE_TYPE(FILE_TYPE_TEXT);
5975 /* Try to write a new "Bones File" */
5976 fp = my_fopen(str, "w");
5978 /* Not allowed to write it? Weird. */
5982 fprintf(fp, "%s\n", player_name);
5983 fprintf(fp, "%d\n", p_ptr->mhp);
5984 fprintf(fp, "%d\n", p_ptr->prace);
5985 fprintf(fp, "%d\n", p_ptr->pclass);
5987 /* Close and save the Bones file */
5996 * Redefinable "print_tombstone" action
5998 bool (*tombstone_aux)(void) = NULL;
6002 * Display a "tomb-stone"
6004 static void print_tomb(void)
6008 /* Do we use a special tombstone ? */
6011 /* Use tombstone hook */
6012 done = (*tombstone_aux)();
6015 /* Print the text-tombstone */
6029 time_t ct = time((time_t)0);
6035 /* Build the filename */
6037 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead_j.txt");
6039 path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt");
6043 /* Open the News file */
6044 fp = my_fopen(buf, "r");
6051 /* Dump the file to the screen */
6052 while (0 == my_fgets(fp, buf, 1024))
6054 /* Display and advance */
6055 put_str(buf, i++, 0);
6064 if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
6078 p = player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
6081 center_string(buf, player_name);
6082 put_str(buf, 6, 11);
6085 center_string(buf, "the");
6086 put_str(buf, 7, 11);
6089 center_string(buf, p);
6090 put_str(buf, 8, 11);
6093 center_string(buf, cp_ptr->title);
6095 put_str(buf, 10, 11);
6098 (void)sprintf(tmp, "¥ì¥Ù¥ë: %d", (int)p_ptr->lev);
6100 (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
6103 center_string(buf, tmp);
6104 put_str(buf, 11, 11);
6107 (void)sprintf(tmp, "·Ð¸³ÃÍ: %ld", (long)p_ptr->exp);
6109 (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp);
6112 center_string(buf, tmp);
6113 put_str(buf, 12, 11);
6116 (void)sprintf(tmp, "½ê»ý¶â: %ld", (long)p_ptr->au);
6118 (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au);
6121 center_string(buf, tmp);
6122 put_str(buf, 13, 11);
6125 /* Êè¤Ë¹ï¤à¸ÀÍÕ¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
6126 if (streq(died_from, "ÅÓÃ潪λ"))
6128 strcpy(tmp, "<¼«»¦>");
6132 if (streq(died_from, "ripe"))
6134 strcpy(tmp, "°úÂà¸å¤ËÅ·¼÷¤òÁ´¤¦");
6136 else if (streq(died_from, "Seppuku"))
6138 strcpy(tmp, "¾¡Íø¤Î¸å¡¢ÀÚÊ¢");
6142 strcpy(tmp, died_from);
6145 center_string(buf, tmp);
6146 put_str(buf, 14, 11);
6148 if(!streq(died_from, "ripe") && !streq(died_from, "Seppuku"))
6150 if( dun_level == 0 )
6152 cptr town = (p_ptr->town_num ? "³¹" : "¹ÓÌî");
6153 if(streq(died_from, "ÅÓÃ潪λ"))
6155 sprintf(tmp, "%s¤Ç»à¤ó¤À", town);
6159 sprintf(tmp, "¤Ë%s¤Ç»¦¤µ¤ì¤¿", town);
6164 if(streq(died_from, "ÅÓÃ潪λ"))
6166 sprintf(tmp, "Ãϲ¼ %d ³¬¤Ç»à¤ó¤À", dun_level);
6170 sprintf(tmp, "¤ËÃϲ¼ %d ³¬¤Ç»¦¤µ¤ì¤¿", dun_level);
6173 center_string(buf, tmp);
6174 put_str(buf, 15, 11);
6177 (void)sprintf(tmp, "Killed on Level %d", dun_level);
6178 center_string(buf, tmp);
6179 put_str(buf, 14, 11);
6182 if (strlen(died_from) > 24)
6184 strncpy(dummy, died_from, 24);
6186 (void)sprintf(tmp, "by %s.", dummy);
6189 (void)sprintf(tmp, "by %s.", died_from);
6191 center_string(buf, tmp);
6192 put_str(buf, 15, 11);
6197 (void)sprintf(tmp, "%-.24s", ctime(&ct));
6198 center_string(buf, tmp);
6199 put_str(buf, 17, 11);
6202 msg_format("¤µ¤è¤¦¤Ê¤é¡¢%s!", player_name);
6204 msg_format("Goodbye, %s!", player_name);
6212 * Display some character info
6214 static void show_info(void)
6220 /* Hack -- Know everything in the inven/equip */
6221 for (i = 0; i < INVEN_TOTAL; i++)
6223 o_ptr = &inventory[i];
6225 /* Skip non-objects */
6226 if (!o_ptr->k_idx) continue;
6228 /* Aware and Known */
6229 object_aware(o_ptr);
6230 object_known(o_ptr);
6233 for (i = 1; i < max_towns; i++)
6235 st_ptr = &town[i].store[STORE_HOME];
6237 /* Hack -- Know everything in the home */
6238 for (j = 0; j < st_ptr->stock_num; j++)
6240 o_ptr = &st_ptr->stock[j];
6242 /* Skip non-objects */
6243 if (!o_ptr->k_idx) continue;
6245 /* Aware and Known */
6246 object_aware(o_ptr);
6247 object_known(o_ptr);
6251 /* Hack -- Recalculate bonuses */
6252 p_ptr->update |= (PU_BONUS);
6257 /* Flush all input keys */
6260 /* Flush messages */
6264 /* Describe options */
6266 prt("¥¥ã¥é¥¯¥¿¡¼¤ÎµÏ¿¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤½Ð¤¹¤³¤È¤¬¤Ç¤¤Þ¤¹¡£", 21, 0);
6267 prt("¥ê¥¿¡¼¥ó¥¡¼¤Ç¥¥ã¥é¥¯¥¿¡¼¤ò¸«¤Þ¤¹¡£ESC¤ÇÃæÃǤ·¤Þ¤¹¡£", 22, 0);
6269 prt("You may now dump a character record to one or more files.", 21, 0);
6270 prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0);
6274 /* Dump character records as requested */
6281 put_str("¥Õ¥¡¥¤¥ë¥Í¡¼¥à: ", 23, 0);
6283 put_str("Filename: ", 23, 0);
6288 strcpy(out_val, "");
6290 /* Ask for filename (or abort) */
6291 if (!askfor_aux(out_val, 60)) return;
6293 /* Return means "show on screen" */
6294 if (!out_val[0]) break;
6299 /* Dump a character file */
6300 (void)file_character(out_val, TRUE);
6308 /* Display player */
6311 /* Prompt for inventory */
6313 prt("²¿¤«¥¡¼¤ò²¡¤¹¤È¤µ¤é¤Ë¾ðÊó¤¬Â³¤¤Þ¤¹ (ESC¤ÇÃæÃÇ): ", 23, 0);
6315 prt("Hit any key to see more information (ESC to abort): ", 23, 0);
6319 /* Allow abort at this point */
6320 if (inkey() == ESCAPE) return;
6323 /* Show equipment and inventory */
6325 /* Equipment -- if any */
6329 item_tester_full = TRUE;
6330 (void)show_equip(0);
6332 prt("ÁõÈ÷¤·¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6334 prt("You are using: -more-", 0, 0);
6337 if (inkey() == ESCAPE) return;
6340 /* Inventory -- if any */
6344 item_tester_full = TRUE;
6345 (void)show_inven(0);
6347 prt("»ý¤Ã¤Æ¤¤¤¿¥¢¥¤¥Æ¥à: -³¤¯-", 0, 0);
6349 prt("You are carrying: -more-", 0, 0);
6352 if (inkey() == ESCAPE) return;
6355 /* Homes in the different towns */
6356 for (l = 1; l < max_towns; l++)
6358 st_ptr = &town[l].store[STORE_HOME];
6360 /* Home -- if anything there */
6361 if (st_ptr->stock_num)
6363 /* Display contents of the home */
6364 for (k = 0, i = 0; i < st_ptr->stock_num; k++)
6370 for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++)
6372 char o_name[MAX_NLEN];
6376 o_ptr = &st_ptr->stock[i];
6378 /* Print header, clear line */
6379 sprintf(tmp_val, "%c) ", I2A(j));
6380 prt(tmp_val, j+2, 4);
6382 /* Display object description */
6383 object_desc(o_name, o_ptr, TRUE, 3);
6384 c_put_str(tval_to_attr[o_ptr->tval], o_name, j+2, 7);
6389 prt(format("²æ¤¬²È¤ËÃÖ¤¤¤Æ¤¢¤Ã¤¿¥¢¥¤¥Æ¥à ( %d ¥Ú¡¼¥¸): -³¤¯-", k+1), 0, 0);
6391 prt(format("Your home contains (page %d): -more-", k+1), 0, 0);
6396 if (inkey() == ESCAPE) return;
6403 static bool check_score(void)
6409 if (highscore_fd < 0)
6412 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ¤Þ¤»¤ó¡£");
6414 msg_print("Score file unavailable.");
6421 #ifndef SCORE_WIZARDS
6422 /* Wizard-mode pre-empts scoring */
6423 if (noscore & 0x000F)
6426 msg_print("¥¦¥£¥¶¡¼¥É¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µÏ¿¤µ¤ì¤Þ¤»¤ó¡£");
6428 msg_print("Score not registered for wizards.");
6437 /* Borg-mode pre-empts scoring */
6438 if (noscore & 0x00F0)
6441 msg_print("¥Ü¡¼¥°¡¦¥â¡¼¥É¤Ç¤Ï¥¹¥³¥¢¤¬µÏ¿¤µ¤ì¤Þ¤»¤ó¡£");
6443 msg_print("Score not registered for borgs.");
6451 #ifndef SCORE_CHEATERS
6452 /* Cheaters are not scored */
6453 if (noscore & 0xFF00)
6456 msg_print("º¾µ½¤ò¤ä¤Ã¤¿¿Í¤Ï¥¹¥³¥¢¤¬µÏ¿¤µ¤ì¤Þ¤»¤ó¡£");
6458 msg_print("Score not registered for cheaters.");
6468 if (!total_winner && streq(died_from, "¶¯À©½ªÎ»"))
6470 if (!total_winner && streq(died_from, "Interrupting"))
6475 msg_print("¶¯À©½ªÎ»¤Î¤¿¤á¥¹¥³¥¢¤¬µÏ¿¤µ¤ì¤Þ¤»¤ó¡£");
6477 msg_print("Score not registered due to interruption.");
6486 if (!total_winner && streq(died_from, "ÅÓÃ潪λ"))
6488 if (!total_winner && streq(died_from, "Quitting"))
6493 msg_print("ÅÓÃ潪λ¤Î¤¿¤á¥¹¥³¥¢¤¬µÏ¿¤µ¤ì¤Þ¤»¤ó¡£");
6495 msg_print("Score not registered due to quitting.");
6505 * Close up the current game (player may or may not be dead)
6507 * This function is called only from "main.c" and "signals.c".
6509 void close_game(void)
6512 bool do_send = TRUE;
6514 // cptr p = "[i:¥¥ã¥é¥¯¥¿¤Î¾ðÊó, f:¥Õ¥¡¥¤¥ë½ñ¤½Ð¤·, t:¥¹¥³¥¢, x:*´ÕÄê*, ESC:¥²¡¼¥à½ªÎ»]";
6519 /* Flush the messages */
6522 /* Flush the input */
6526 /* No suspending now */
6527 signals_ignore_tstp();
6530 /* Hack -- Character is now "icky" */
6531 character_icky = TRUE;
6534 /* Build the filename */
6535 path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
6537 /* Open the high score file, for reading/writing */
6538 highscore_fd = fd_open(buf, O_RDWR);
6544 /* Handle retirement */
6545 if (total_winner) kingly();
6549 if (!munchkin_death || get_check("»à¤ó¤À¥Ç¡¼¥¿¤ò¥»¡¼¥Ö¤·¤Þ¤¹¤«¡© "))
6551 if (!munchkin_death || get_check("Save death? "))
6556 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6558 if (!save_player()) msg_print("death save failed!");
6561 else do_send = FALSE;
6568 /* Show more info */
6576 if ((!send_world_score(do_send)))
6579 if (get_check("¸å¤Ç¥¹¥³¥¢¤òÅÐÏ¿¤¹¤ë¤¿¤á¤ËÂÔµ¡¤·¤Þ¤¹¤«¡©"))
6581 if (get_check("Stand by for later score registration? "))
6584 wait_report_score = TRUE;
6587 if (!save_player()) msg_print("¥»¡¼¥Ö¼ºÇÔ¡ª");
6589 if (!save_player()) msg_print("death save failed!");
6593 if (!wait_report_score)
6596 else if (highscore_fd >= 0)
6598 display_scores_aux(0, 10, -1, NULL);
6601 /* Dump bones file */
6610 do_cmd_save_game(FALSE);
6612 /* Prompt for scores XXX XXX XXX */
6614 prt("¥ê¥¿¡¼¥ó¥¡¼¤« ESC ¥¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£", 0, 40);
6616 prt("Press Return (or Escape).", 0, 40);
6620 /* Predict score (or ESCAPE) */
6621 if (inkey() != ESCAPE) predict_score();
6625 /* Shut the high score file */
6626 (void)fd_close(highscore_fd);
6628 /* Forget the high score fd */
6632 /* Allow suspending now */
6633 signals_handle_tstp();
6638 * Handle abrupt death of the visual system
6640 * This routine is called only in very rare situations, and only
6641 * by certain visual systems, when they experience fatal errors.
6643 * XXX XXX Hack -- clear the death flag when creating a HANGUP
6644 * save file so that player can see tombstone when restart.
6646 void exit_game_panic(void)
6648 /* If nothing important has happened, just quit */
6650 if (!character_generated || character_saved) quit("¶ÛµÞ»öÂÖ");
6652 if (!character_generated || character_saved) quit("panic");
6656 /* Mega-Hack -- see "msg_print()" */
6659 /* Clear the top line */
6662 /* Hack -- turn off some things */
6665 /* Mega-Hack -- Delay death */
6666 if (p_ptr->chp < 0) death = FALSE;
6668 /* Hardcode panic save */
6671 /* Forbid suspend */
6672 signals_ignore_tstp();
6674 /* Indicate panic save */
6676 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
6678 (void)strcpy(died_from, "(panic save)");
6682 /* Panic save, or get worried */
6684 if (!save_player()) quit("¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
6686 if (!save_player()) quit("panic save failed!");
6690 /* Successful panic save */
6692 quit("¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
6694 quit("panic save succeeded!");
6701 * Get a random line from a file
6702 * Based on the monster speech patch by Matt Graham,
6704 errr get_rnd_line(cptr file_name, int entry, char *output)
6708 int line, counter, test, numentries;
6713 /* Build the filename */
6714 path_build(buf, 1024, ANGBAND_DIR_FILE, file_name);
6717 fp = my_fopen(buf, "r");
6720 if (!fp) return (-1);
6722 /* Find the entry of the monster */
6725 /* Get a line from the file */
6726 if (my_fgets(fp, buf, 1024) == 0)
6728 /* Count the lines */
6731 /* Look for lines starting with 'N:' */
6732 if ((buf[0] == 'N') && (buf[1] == ':'))
6734 /* Allow default lines */
6741 else if (buf[2] == 'M')
6743 if (r_info[entry].flags1 & RF1_MALE)
6749 else if (buf[2] == 'F')
6751 if (r_info[entry].flags1 & RF1_FEMALE)
6757 /* Get the monster number */
6758 else if (sscanf(&(buf[2]), "%d", &test) != EOF)
6760 /* Is it the right monster? */
6769 /* Error while converting the monster number */
6770 msg_format("Error in line %d of %s!",
6771 line_num, file_name);
6779 /* Reached end of file */
6786 /* Get the number of entries */
6790 if (my_fgets(fp, buf, 1024) == 0)
6792 /* Count the lines */
6795 /* Look for the number of entries */
6796 if (isdigit(buf[0]))
6798 /* Get the number of entries */
6799 numentries = atoi(buf);
6805 /* Count the lines */
6808 /* Reached end of file without finding the number */
6809 msg_format("Error in line %d of %s!",
6810 line_num, file_name);
6819 /* Grab an appropriate line number */
6820 line = rand_int(numentries);
6822 /* Get the random line */
6823 for (counter = 0; counter <= line; counter++)
6825 /* Count the lines */
6830 test=my_fgets(fp, buf, 1024);
6831 if(test || buf[0]!='#')break;
6835 /* Try to read the line */
6836 if (my_fgets(fp, buf, 1024) == 0)
6840 /* Found the line */
6841 if (counter == line) break;
6845 /* Error - End of file */
6846 msg_format("Error in line %d of %s!",
6847 line_num, file_name);
6855 strcpy(output, buf);
6862 /* Close the file */
6871 errr get_rnd_line_jonly(cptr file_name, int entry, char *output, int count)
6875 for (i=0;i<count;i++){
6876 result=get_rnd_line(file_name, entry, output);
6879 for(j=0 ; j<strlen(output) ; j++) kanji|=iskanji( output[j] );
6888 errr process_pickpref_file(cptr name)
6892 unsigned char buf[1024] , *s, *s2, isnew;
6900 bool bypass = FALSE;
6902 /* Build the filename */
6903 path_build(buf, 1024, ANGBAND_DIR_USER, name);
6906 fp = my_fopen(buf, "r");
6909 if (!fp) return (-1);
6912 /* Process the file */
6913 while (0 == my_fgets(fp, buf, 1024))
6918 /* Skip "empty" lines */
6919 if (buf[0]<32) continue;
6921 /* Skip "blank" lines */
6922 if (isspace(buf[0])) continue;
6925 if (buf[0] == '#') continue;
6927 /* Process "?:<expr>" */
6928 if ((buf[0] == '?') && (buf[1] == ':'))
6937 /* Parse the expr */
6938 v = process_pref_file_expr(&s, &f);
6941 bypass = (streq(v, "0") ? TRUE : FALSE);
6947 /* Apply conditionals */
6948 if (bypass) continue;
6950 /* Process "%:<file>" */
6953 /* Process that file if allowed */
6954 (void)process_pickpref_file(buf + 2);
6960 /* Nuke illegal char */
6961 for(i=0 ; buf[i]>31 ; i++){/* Do nothing */} buf[i]=0;
6965 if(buf[0] == '!' || buf[0] == '~') s++;
6967 /* Auto-inscription? */
6969 if (s2) {*s2=0; s2++;}
6971 /* Skip empty line */
6972 if (*s == 0) continue;
6974 /* don't mind upper or lower case */
6975 for (i = 0; s[i]; i++)
6986 else if (isupper(s[i]))
6987 s[i] = tolower(s[i]);
6990 /* Already has the same entry? */
6992 for(i=0;i<max_autopick;i++)
6993 if( !strcmp(s,autopick_name[i]) ){isnew=0;break;}
6995 if(isnew==0) continue;
6996 autopick_name [max_autopick] = malloc(strlen(s) + 1);
6997 strcpy(autopick_name [max_autopick], s);
7000 autopick_action[max_autopick] = DONT_AUTOPICK;
7003 autopick_action[max_autopick] = DO_AUTODESTROY;
7006 autopick_action[max_autopick] = DO_AUTOPICK;
7010 autopick_insc[max_autopick] = malloc(strlen(s2) + 1);
7011 strcpy(autopick_insc[max_autopick], s2);
7013 autopick_insc[max_autopick]=NULL;
7016 if(max_autopick==MAX_AUTOPICK) break;
7019 /* Close the file */
7025 static errr counts_seek(int fd, s32b where, bool flag)
7028 char temp1[128], temp2[128];
7029 s32b zero_header[3] = {0L, 0L, 0L};
7032 #ifdef SAVEFILE_USE_UID
7033 (void)sprintf(temp1, "%d.%s.%d%d%d", player_uid, savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7035 (void)sprintf(temp1, "%s.%d%d%d", savefile_base, p_ptr->pclass, p_ptr->pseikaku, p_ptr->age);
7037 for (i = 0; temp1[i]; i++)
7038 temp1[i] ^= (i+1) * 63;
7043 if (fd_seek(fd, seekpoint + 3 * sizeof(s32b)))
7045 if (fd_read(fd, (char*)(temp2), sizeof(temp2)))
7050 fd_seek(fd, seekpoint);
7051 fd_write(fd, (char*)zero_header, 3*sizeof(s32b));
7052 fd_write(fd, (char*)(temp1), sizeof(temp1));
7056 if (strcmp(temp1, temp2) == 0)
7059 seekpoint += 128 + 3 * sizeof(s32b);
7062 return fd_seek(fd, seekpoint + where * sizeof(s32b));
7065 s32b counts_read(int where)
7072 path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7074 path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7076 fd = fd_open(buf, O_RDONLY);
7078 if (counts_seek(fd, where, FALSE) ||
7079 fd_read(fd, (char*)(&count), sizeof(s32b)))
7087 errr counts_write(int where, s32b count)
7093 path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info_j.raw");
7095 path_build(buf, 1024, ANGBAND_DIR_DATA, "z_info.raw");
7097 fd = fd_open(buf, O_RDWR);
7100 /* File type is "DATA" */
7101 FILE_TYPE(FILE_TYPE_DATA);
7103 /* Create a new high score file */
7104 fd = fd_make(buf, 0644);
7107 if (fd_lock(fd, F_WRLCK)) return 1;
7109 counts_seek(fd, where, TRUE);
7110 fd_write(fd, (char*)(&count), sizeof(s32b));
7112 if (fd_lock(fd, F_UNLCK)) return 1;
7120 #ifdef HANDLE_SIGNALS
7127 * Handle signals -- suspend
7129 * Actually suspend the game, and then resume cleanly
7131 static void handle_signal_suspend(int sig)
7133 /* Disable handler */
7134 (void)signal(sig, SIG_IGN);
7141 /* Suspend the "Term" */
7142 Term_xtra(TERM_XTRA_ALIVE, 0);
7144 /* Suspend ourself */
7145 (void)kill(0, SIGSTOP);
7147 /* Resume the "Term" */
7148 Term_xtra(TERM_XTRA_ALIVE, 1);
7150 /* Redraw the term */
7153 /* Flush the term */
7158 /* Restore handler */
7159 (void)signal(sig, handle_signal_suspend);
7164 * Handle signals -- simple (interrupt and quit)
7166 * This function was causing a *huge* number of problems, so it has
7167 * been simplified greatly. We keep a global variable which counts
7168 * the number of times the user attempts to kill the process, and
7169 * we commit suicide if the user does this a certain number of times.
7171 * We attempt to give "feedback" to the user as he approaches the
7172 * suicide thresh-hold, but without penalizing accidental keypresses.
7174 * To prevent messy accidents, we should reset this global variable
7175 * whenever the user enters a keypress, or something like that.
7177 static void handle_signal_simple(int sig)
7179 /* Disable handler */
7180 (void)signal(sig, SIG_IGN);
7183 /* Nothing to save, just quit */
7184 if (!character_generated || character_saved) quit(NULL);
7187 /* Count the signals */
7191 /* Terminate dead characters */
7194 /* Mark the savefile */
7196 (void)strcpy(died_from, "¶¯À©½ªÎ»");
7198 (void)strcpy(died_from, "Abortion");
7217 /* Allow suicide (after 5) */
7218 else if (signal_count >= 5)
7220 /* Cause of "death" */
7222 (void)strcpy(died_from, "¶¯À©½ªÎ»Ãæ");
7224 (void)strcpy(died_from, "Interrupting");
7239 p_ptr->leaving = TRUE;
7253 /* Give warning (after 4) */
7254 else if (signal_count >= 4)
7257 Term_xtra(TERM_XTRA_NOISE, 0);
7259 /* Clear the top line */
7260 Term_erase(0, 0, 255);
7262 /* Display the cause */
7264 Term_putstr(0, 0, -1, TERM_WHITE, "½Ïθ¤Î¾å¤Î¼«»¦¡ª");
7266 Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");
7274 /* Give warning (after 2) */
7275 else if (signal_count >= 2)
7278 Term_xtra(TERM_XTRA_NOISE, 0);
7281 /* Restore handler */
7282 (void)signal(sig, handle_signal_simple);
7287 * Handle signal -- abort, kill, etc
7289 static void handle_signal_abort(int sig)
7291 /* Disable handler */
7292 (void)signal(sig, SIG_IGN);
7295 /* Nothing to save, just quit */
7296 if (!character_generated || character_saved) quit(NULL);
7303 /* Clear the bottom line */
7304 Term_erase(0, 23, 255);
7306 /* Give a warning */
7307 Term_putstr(0, 23, -1, TERM_RED,
7309 "¶²¤í¤·¤¤¥½¥Õ¥È¤Î¥Ð¥°¤¬Èô¤Ó¤«¤«¤Ã¤Æ¤¤¿¡ª");
7311 "A gruesome software bug LEAPS out at you!");
7317 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö...");
7319 Term_putstr(45, 23, -1, TERM_RED, "Panic save...");
7331 (void)strcpy(died_from, "(¶ÛµÞ¥»¡¼¥Ö)");
7333 (void)strcpy(died_from, "(panic save)");
7337 /* Forbid suspend */
7338 signals_ignore_tstp();
7340 /* Attempt to save */
7344 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥ÖÀ®¸ù¡ª");
7346 Term_putstr(45, 23, -1, TERM_RED, "Panic save succeeded!");
7355 Term_putstr(45, 23, -1, TERM_RED, "¶ÛµÞ¥»¡¼¥Ö¼ºÇÔ¡ª");
7357 Term_putstr(45, 23, -1, TERM_RED, "Panic save failed!");
7367 quit("¥½¥Õ¥È¤Î¥Ð¥°");
7369 quit("software bug");
7378 * Ignore SIGTSTP signals (keyboard suspend)
7380 void signals_ignore_tstp(void)
7384 (void)signal(SIGTSTP, SIG_IGN);
7390 * Handle SIGTSTP signals (keyboard suspend)
7392 void signals_handle_tstp(void)
7396 (void)signal(SIGTSTP, handle_signal_suspend);
7403 * Prepare to handle the relevant signals
7405 void signals_init(void)
7409 (void)signal(SIGHUP, SIG_IGN);
7414 (void)signal(SIGTSTP, handle_signal_suspend);
7419 (void)signal(SIGINT, handle_signal_simple);
7423 (void)signal(SIGQUIT, handle_signal_simple);
7428 (void)signal(SIGFPE, handle_signal_abort);
7432 (void)signal(SIGILL, handle_signal_abort);
7436 (void)signal(SIGTRAP, handle_signal_abort);
7440 (void)signal(SIGIOT, handle_signal_abort);
7444 (void)signal(SIGKILL, handle_signal_abort);
7448 (void)signal(SIGBUS, handle_signal_abort);
7452 (void)signal(SIGSEGV, handle_signal_abort);
7456 (void)signal(SIGTERM, handle_signal_abort);
7460 (void)signal(SIGPIPE, handle_signal_abort);
7464 (void)signal(SIGEMT, handle_signal_abort);
7468 (void)signal(SIGDANGER, handle_signal_abort);
7472 (void)signal(SIGSYS, handle_signal_abort);
7476 (void)signal(SIGXCPU, handle_signal_abort);
7480 (void)signal(SIGPWR, handle_signal_abort);
7486 #else /* HANDLE_SIGNALS */
7492 void signals_ignore_tstp(void)
7499 void signals_handle_tstp(void)
7506 void signals_init(void)
7509 #endif /* HANDLE_SIGNALS */