diff options
author | Bardur Arantsson <bardur@scientician.net> | 2013-03-26 17:10:10 +0100 |
---|---|---|
committer | Bardur Arantsson <bardur@scientician.net> | 2013-09-27 14:46:42 +0200 |
commit | cbef37bd5bfb938a2303ee3887520c08be85d8e8 (patch) | |
tree | b604e49323e46af4ea582f9a9e1977b3daa90611 /src/files.c | |
parent | b9f824effb037a53556e02955cace6c09ff646c3 (diff) |
Switch almost everything over to C++
Diffstat (limited to 'src/files.c')
-rw-r--r-- | src/files.c | 5842 |
1 files changed, 0 insertions, 5842 deletions
diff --git a/src/files.c b/src/files.c deleted file mode 100644 index a599af23..00000000 --- a/src/files.c +++ /dev/null @@ -1,5842 +0,0 @@ -/* File: files.c */ - -/* Purpose: code dealing with files (and death) */ - -/* - * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke - * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. - */ - -#include "angband.h" - -#include "hiscore.h" -#include "hooks.h" - - -/* - * Extract the first few "tokens" from a buffer - * - * This function uses "colon" and "slash" and delim arg as the delimeter characters. - * - * We never extract more than "num" tokens. The "last" token may include - * "delimeter" characters, allowing the buffer to include a "string" token. - * - * We save pointers to the tokens in "tokens", and return the number found. - * - * Hack -- Attempt to handle the 'c' character formalism - * - * Hack -- An empty buffer, or a final delimeter, yields an "empty" token. - * - * Hack -- We will always extract at least one token - */ -s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2) -{ - int i = 0; - - char *s = buf; - - - /* Process */ - while (i < num - 1) - { - char *t; - - /* Scan the string */ - for (t = s; *t; t++) - { - /* Found a delimiter */ - if ((*t == delim1) || (*t == delim2)) break; - - /* Handle single quotes */ - if (*t == '\'') - { - /* Advance */ - t++; - - /* Handle backslash */ - if (*t == '\\') t++; - - /* Require a character */ - if (!*t) break; - - /* Advance */ - t++; - - /* Hack -- Require a close quote */ - if (*t != '\'') *t = '\''; - } - - /* Handle back-slash */ - if (*t == '\\') t++; - } - - /* Nothing left */ - if (!*t) break; - - /* Nuke and advance */ - *t++ = '\0'; - - /* Save the token */ - tokens[i++] = s; - - /* Advance */ - s = t; - } - - /* Save the token */ - tokens[i++] = s; - - /* Number found */ - return (i); -} - - - -/* - * Parse a sub-file of the "extra info" (format shown below) - * - * Each "action" line has an "action symbol" in the first column, - * followed by a colon, followed by some command specific info, - * usually in the form of "tokens" separated by colons or slashes. - * - * Blank lines, lines starting with white space, and lines starting - * with pound signs ("#") are ignored (as comments). - * - * Note the use of "tokenize()" to allow the use of both colons and - * slashes as delimeters, while still allowing final tokens which - * may contain any characters including "delimiters". - * - * Note the use of "strtol()" to allow all "integers" to be encoded - * in decimal, hexidecimal, or octal form. - * - * Note that "monster zero" is used for the "player" attr/char, "object - * zero" will be used for the "stack" attr/char, and "feature zero" is - * used for the "nothing" attr/char. - * - * Parse another file recursively, see below for details - * %:<filename> - * - * Specify the attr/char values for "monsters" by race index - * R:<num>:<a>:<c> - * - * Specify the attr/char values for "objects" by kind index - * K:<num>:<a>:<c> - * - * Specify the attr/char values for "features" by feature index - * F:<num>:<a>:<c> - * - * Specify the attr/char values for "stores" by store index - * B:<num>:<a>:<c> - * - * Specify the attr/char values for unaware "objects" by kind tval - * U:<tv>:<a>:<c> - * - * Specify the attr/char values for inventory "objects" by kind tval - * E:<tv>:<a>:<c> - * - * Define a macro action, given an encoded macro action - * A:<str> - * - * Create a normal macro, given an encoded macro trigger - * P:<str> - * - * Create a command macro, given an encoded macro trigger - * C:<str> - * - * Create a keyset mapping - * S:<key>:<key>:<dir> - * - * Turn an option off, given its name - * X:<str> - * - * Turn an option on, given its name - * Y:<str> - * - * Specify visual information, given an index, and some data - * V:<num>:<kv>:<rv>:<gv>:<bv> - * - * Specify squelch settings - * Q:<num>:<squelch> - */ -errr process_pref_file_aux(char *buf) -{ - int i, j, n1, n2; - - char *zz[16]; - - - /* Skip "empty" lines */ - if (!buf[0]) return (0); - - /* Skip "blank" lines */ - if (isspace(buf[0])) return (0); - - /* Skip comments */ - if (buf[0] == '#') return (0); - - /* Require "?:*" format */ - if (buf[1] != ':') return (1); - - - /* Process "%:<fname>" */ - if (buf[0] == '%') - { - /* Attempt to Process the given file */ - return (process_pref_file(buf + 2)); - } - - - /* Process "R:<num>:<a>/<c>" -- attr/char for monster races */ - if (buf[0] == 'R') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - monster_race *r_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_r_idx) return (1); - r_ptr = &r_info[i]; - if (n1) r_ptr->x_attr = n1; - if (n2) - { - r_ptr->x_char = n2; - } - return (0); - } - } - - - /* Process "G:<type>:<num>:<a>/<c>" -- attr/char for overlay graphics */ - if (buf[0] == 'G') - { - /* Process "G:M:<num>:<a>/<c>" -- attr/char for ego monsters */ - if (buf[2] == 'M') - { - if (tokenize(buf + 4, 3, zz, ':', '/') == 3) - { - monster_ego *re_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_re_idx) return (1); - re_ptr = &re_info[i]; - if (n1) re_ptr->g_attr = n1; - if (n2) - { - re_ptr->g_char = n2; - } - return (0); - } - } - - /* Process "G:P:<num>:<a>/<c>" -- attr/char for race modifiers */ - if (buf[2] == 'P') - { - if (tokenize(buf + 4, 3, zz, ':', '/') == 3) - { - player_race_mod *rmp_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_rmp_idx) return (1); - rmp_ptr = &race_mod_info[i]; - if (n1) rmp_ptr->g_attr = n1; - if (n2) - { - rmp_ptr->g_char = n2; - } - return (0); - } - } - - /* Process "G:T:<num>:<a>/<c>" -- attr/char for traps */ - if (buf[2] == 'T') - { - if (tokenize(buf + 4, 3, zz, ':', '/') == 3) - { - trap_type *t_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_t_idx) return (1); - t_ptr = &t_info[i]; - if (n1) t_ptr->g_attr = n1; - if (n2) - { - t_ptr->g_char = n2; - } - return (0); - } - } - } - - - /* Process "K:<num>:<a>/<c>" -- attr/char for object kinds */ - else if (buf[0] == 'K') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - object_kind *k_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_k_idx) return (1); - k_ptr = &k_info[i]; - if (n1) k_ptr->x_attr = n1; - if (n2) - { - k_ptr->x_char = n2; - } - return (0); - } - } - - - /* Process "F:<num>:<a>/<c>" -- attr/char for terrain features */ - else if (buf[0] == 'F') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - feature_type *f_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_f_idx) return (1); - f_ptr = &f_info[i]; - if (n1) f_ptr->x_attr = n1; - if (n2) - { - f_ptr->x_char = n2; - } - return (0); - } - } - - /* Process "B:<num>:<a>/<c>" -- attr/char for stores */ - else if (buf[0] == 'B') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - store_info_type *st_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_st_idx) return (1); - st_ptr = &st_info[i]; - if (n1) st_ptr->x_attr = n1; - if (n2) st_ptr->x_char = n2; - return (0); - } - } - - /* Process "S:<num>:<a>/<c>" -- attr/char for special things */ - else if (buf[0] == 'S') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - j = (byte)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - misc_to_attr[j] = n1; - misc_to_char[j] = n2; - return (0); - } - } - - /* Process "U:<tv>:<a>/<c>" -- attr/char for unaware items */ - else if (buf[0] == 'U') - { - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - j = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - for (i = 1; i < max_k_idx; i++) - { - object_kind *k_ptr = &k_info[i]; - if (k_ptr->tval == j) - { - if (n1) k_ptr->d_attr = n1; - if (n2) k_ptr->d_char = n2; - } - } - return (0); - } - } - - - /* Process "E:<tv>:<a>" -- attribute for inventory objects */ - else if (buf[0] == 'E') - { - if (tokenize(buf + 2, 2, zz, ':', '/') == 2) - { - j = (byte)strtol(zz[0], NULL, 0) % 128; - n1 = strtol(zz[1], NULL, 0); - if (n1) tval_to_attr[j] = n1; - return (0); - } - } - - - /* Process "A:<str>" -- save an "action" for later */ - else if (buf[0] == 'A') - { - text_to_ascii(macro__buf, buf + 2); - return (0); - } - - /* Process "P:<str>" -- normal macro */ - else if (buf[0] == 'P') - { - char tmp[1024]; - text_to_ascii(tmp, buf + 2); - macro_add(tmp, macro__buf); - return (0); - } - - /* Process "L:<num>:<trigger>:<descr> -- extended command macro */ - else if (buf[0] == 'L') - { - switch (tokenize(buf + 2, 3, zz, ':', 0)) - { - case 3: - cli_add(zz[0], zz[1], zz[2]); - return 0; - case 2: - cli_add(zz[0], zz[1], 0); - return 0; - default: - return 1; - } - } - - /* Process "C:<str>" -- create keymap */ - else if (buf[0] == 'C') - { - int mode; - - char tmp[1024]; - - if (tokenize(buf + 2, 2, zz, ':', '/') != 2) return (1); - - mode = strtol(zz[0], NULL, 0); - if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1); - - text_to_ascii(tmp, zz[1]); - if (!tmp[0] || tmp[1]) return (1); - i = (byte)(tmp[0]); - - string_free(keymap_act[mode][i]); - - keymap_act[mode][i] = string_make(macro__buf); - - return (0); - } - - - /* Process "V:<num>:<kv>:<rv>:<gv>:<bv>" -- visual info */ - else if (buf[0] == 'V') - { - if (tokenize(buf + 2, 5, zz, ':', '/') == 5) - { - i = (byte)strtol(zz[0], NULL, 0); - angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0); - angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0); - angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0); - angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0); - return (0); - } - } - /* set macro trigger names and a template */ - /* Process "T:<trigger>:<keycode>:<shift-keycode>" */ - /* Process "T:<template>:<modifier chr>:<modifier name>:..." */ - else if (buf[0] == 'T') - { - int len, tok; - tok = tokenize(buf + 2, 2 + MAX_MACRO_MOD, zz, ':', '/'); - if (tok >= 4) - { - int i; - int num; - - if (macro_template != NULL) - { - free(macro_template); - macro_template = NULL; - for (i = 0; i < max_macrotrigger; i++) - free(macro_trigger_name[i]); - max_macrotrigger = 0; - } - - if (*zz[0] == '\0') return 0; /* clear template */ - num = strlen(zz[1]); - if (2 + num != tok) return 1; /* error */ - - len = strlen(zz[0]) + 1 + num + 1; - for (i = 0; i < num; i++) - len += strlen(zz[2 + i]) + 1; - macro_template = malloc(len); - - strcpy(macro_template, zz[0]); - macro_modifier_chr = - macro_template + strlen(macro_template) + 1; - strcpy(macro_modifier_chr, zz[1]); - macro_modifier_name[0] = - macro_modifier_chr + strlen(macro_modifier_chr) + 1; - for (i = 0; i < num; i++) - { - strcpy(macro_modifier_name[i], zz[2 + i]); - macro_modifier_name[i + 1] = macro_modifier_name[i] + - strlen(macro_modifier_name[i]) + 1; - } - } - else if (tok >= 2) - { - int m; - char *t, *s; - if (max_macrotrigger >= MAX_MACRO_TRIG) - { - msg_print("Too many macro triggers!"); - return 1; - } - m = max_macrotrigger; - max_macrotrigger++; - - len = strlen(zz[0]) + 1 + strlen(zz[1]) + 1; - if (tok == 3) - len += strlen(zz[2]) + 1; - macro_trigger_name[m] = malloc(len); - - t = macro_trigger_name[m]; - s = zz[0]; - while (*s) - { - if ('\\' == *s) s++; - *t++ = *s++; - } - *t = '\0'; - - macro_trigger_keycode[0][m] = macro_trigger_name[m] + - strlen(macro_trigger_name[m]) + 1; - strcpy(macro_trigger_keycode[0][m], zz[1]); - if (tok == 3) - { - macro_trigger_keycode[1][m] = macro_trigger_keycode[0][m] + - strlen(macro_trigger_keycode[0][m]) + 1; - strcpy(macro_trigger_keycode[1][m], zz[2]); - } - else - { - macro_trigger_keycode[1][m] = macro_trigger_keycode[0][m]; - } - } - return 0; - } - - /* Process "X:<str>" -- turn option off */ - else if (buf[0] == 'X') - { - for (i = 0; option_info[i].o_desc; i++) - { - if (option_info[i].o_var && - option_info[i].o_text && - streq(option_info[i].o_text, buf + 2)) - { - (*option_info[i].o_var) = FALSE; - return (0); - } - } - } - - /* Process "Y:<str>" -- turn option on */ - else if (buf[0] == 'Y') - { - for (i = 0; option_info[i].o_desc; i++) - { - if (option_info[i].o_var && - option_info[i].o_text && - streq(option_info[i].o_text, buf + 2)) - { - (*option_info[i].o_var) = TRUE; - return (0); - } - } - } - - /* Process "W:<win>:<flag>:<value>" -- window flags */ - else if (buf[0] == 'W') - { - int win, flag, value; - - if (tokenize(buf + 2, 3, zz, ':', '/') == 3) - { - win = strtol(zz[0], NULL, 0); - flag = strtol(zz[1], NULL, 0); - value = strtol(zz[2], NULL, 0); - - /* Ignore illegal windows */ - /* Hack -- Ignore the main window */ - if ((win <= 0) || (win >= ANGBAND_TERM_MAX)) return (1); - - /* Ignore illegal flags */ - if ((flag < 0) || (flag >= 32)) return (1); - - /* Require a real flag */ - if (window_flag_desc[flag]) - { - if (value) - { - /* Turn flag on */ - window_flag[win] |= (1L << flag); - } - else - { - /* Turn flag off */ - window_flag[win] &= ~(1L << flag); - } - } - - /* Success */ - return (0); - } - } - - /* Process "Q:<num>:<squelch>" -- item squelch flags */ - else if (buf[0] == 'Q') - { - /* This option isn't used anymore */ - return (0); - } - /* Failure */ - return (1); -} - - -/* - * Helper function for "process_pref_file()" - * - * Input: - * v: output buffer array - * f: final character - * - * Output: - * result - */ -static cptr process_pref_file_expr(char **sp, char *fp) -{ - cptr v; - - char *b; - char *s; - - char b1 = '['; - char b2 = ']'; - - char f = ' '; - - /* Initial */ - s = (*sp); - - /* Skip spaces */ - while (isspace(*s)) s++; - - /* Save start */ - b = s; - - /* Default */ - v = "?o?o?"; - - /* Analyze */ - if (*s == b1) - { - const char *p; - const char *t; - - /* Skip b1 */ - s++; - - /* First */ - t = process_pref_file_expr(&s, &f); - - /* Oops */ - if (!*t) - { - /* Nothing */ - } - - /* Function: IOR */ - else if (streq(t, "IOR")) - { - v = "0"; - while (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - if (*t && !streq(t, "0")) v = "1"; - } - } - - /* Function: AND */ - else if (streq(t, "AND")) - { - v = "1"; - while (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - if (*t && streq(t, "0")) v = "0"; - } - } - - /* Function: NOT */ - else if (streq(t, "NOT")) - { - v = "1"; - while (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - if (*t && !streq(t, "0")) v = "0"; - } - } - - /* Function: EQU */ - else if (streq(t, "EQU")) - { - v = "1"; - if (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - } - while (*s && (f != b2)) - { - p = t; - t = process_pref_file_expr(&s, &f); - if (*t && !streq(p, t)) v = "0"; - } - } - - /* Function: LEQ */ - else if (streq(t, "LEQ")) - { - v = "1"; - if (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - } - while (*s && (f != b2)) - { - p = t; - t = process_pref_file_expr(&s, &f); - if (*t && (strcmp(p, t) > 0)) v = "0"; - } - } - - /* Function: GEQ */ - else if (streq(t, "GEQ")) - { - v = "1"; - if (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - } - while (*s && (f != b2)) - { - p = t; - t = process_pref_file_expr(&s, &f); - if (*t && (strcmp(p, t) < 0)) v = "0"; - } - } - - /* Function: LEQN */ - else if (streq(t, "LEQN")) - { - int n = 0; - v = "1"; - if (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - n = atoi(t); - } - while (*s && (f != b2)) - { - p = t; - t = process_pref_file_expr(&s, &f); - if (*t && (atoi(t) < n)) v = "0"; - } - } - - /* Function: GEQN */ - else if (streq(t, "GEQN")) - { - int n = 0; - v = "1"; - if (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - n = atoi(t); - } - while (*s && (f != b2)) - { - p = t; - t = process_pref_file_expr(&s, &f); - if (*t && (atoi(t) > n)) v = "0"; - } - } - - /* Function SKILL */ - else if (streq(t, "SKILL")) - { - static char skill_val[4*sizeof(int) + 1]; - s16b skill = -1; - v = "0"; - while (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - if (*t) skill = find_skill_i(t); - } - if (skill > 0) - { - sprintf(skill_val, "%d", (int)get_skill(skill)); - v = skill_val; - } - } - - /* Oops */ - else - { - while (*s && (f != b2)) - { - t = process_pref_file_expr(&s, &f); - } - } - - /* Verify ending */ - if (f != b2) v = "?x?x?"; - - /* Extract final and Terminate */ - if ((f = *s) != '\0') * s++ = '\0'; - } - - /* Other */ - else - { - /* Accept all printables except spaces and brackets */ - while (isprint(*s) && !strchr(" []", *s)) ++s; - - /* Extract final and Terminate */ - if ((f = *s) != '\0') * s++ = '\0'; - - /* Variable */ - if (*b == '$') - { - /* System */ - if (streq(b + 1, "SYS")) - { - v = ANGBAND_SYS; - } - - else if (streq(b + 1, "KEYBOARD")) - { - v = ANGBAND_KEYBOARD; - } - - /* Graphics */ - if (streq(b + 1, "GRAF")) - { - v = ANGBAND_GRAF; - } - - /* Race */ - else if (streq(b + 1, "RACE")) - { - v = rp_ptr->title + rp_name; - } - - /* Race */ - else if (streq(b + 1, "RACEMOD")) - { - v = rmp_ptr->title + rmp_name; - } - - /* Class */ - else if (streq(b + 1, "CLASS")) - { - v = spp_ptr->title + c_name; - } - - /* Player */ - else if (streq(b + 1, "PLAYER")) - { - v = player_base; - } - } - - /* Constant */ - else - { - v = b; - } - } - - /* Save */ - (*fp) = f; - - /* Save */ - (*sp) = s; - - /* Result */ - return (v); -} - - - - -/* - * Process the "user pref file" with the given name - * - * See the function above for a list of legal "commands". - * - * We also accept the special "?" and "%" directives, which - * allow conditional evaluation and filename inclusion. - */ -errr process_pref_file(cptr name) -{ - FILE *fp; - - char buf[1024]; - - int num = -1; - - errr err = 0; - - bool_ bypass = FALSE; - - /* Build the filename -- Allow users to override system pref files */ - path_build(buf, 1024, ANGBAND_DIR_USER, name); - - /* Open the file */ - fp = my_fopen(buf, "r"); - - /* No such file -- Try system pref file */ - if (!fp) - { - /* Build the pathname, this time using the system pref directory */ - path_build(buf, 1024, ANGBAND_DIR_PREF, name); - - /* Open the file */ - fp = my_fopen(buf, "r"); - - /* Failed again */ - if (!fp) return ( -1); - } - - - /* Process the file */ - while (0 == my_fgets(fp, buf, 1024)) - { - /* Count lines */ - num++; - - - /* Skip "empty" lines */ - if (!buf[0]) continue; - - /* Skip "blank" lines */ - if (isspace(buf[0])) continue; - - /* Skip comments */ - if (buf[0] == '#') continue; - - - /* Process "?:<expr>" */ - if ((buf[0] == '?') && (buf[1] == ':')) - { - char f; - cptr v; - char *s; - - /* Start */ - s = buf + 2; - - /* Parse the expr */ - v = process_pref_file_expr(&s, &f); - - /* Set flag */ - bypass = (streq(v, "0") ? TRUE : FALSE); - - /* Continue */ - continue; - } - - /* Apply conditionals */ - if (bypass) continue; - - - /* Process "%:<file>" */ - if (buf[0] == '%') - { - /* Process that file if allowed */ - (void)process_pref_file(buf + 2); - - /* Continue */ - continue; - } - - - /* Process the line */ - err = process_pref_file_aux(buf); - - /* Oops */ - if (err) break; - } - - - /* Error */ - if (err) - { - /* Useful error message */ - msg_format("Error %d in line %d of file '%s'.", err, num, name); - msg_format("Parsing '%s'", buf); - } - - /* Close the file */ - my_fclose(fp); - - /* Result */ - return (err); -} - - - - -/* - * Print long number with header at given row, column - * Use the color for the number, not the header - */ -static void prt_lnum(cptr header, s32b num, int row, int col, byte color) -{ - int len = strlen(header); - char out_val[32]; - - put_str(header, row, col); - (void)sprintf(out_val, "%9ld", (long)num); - c_put_str(color, out_val, row, col + len); -} - - -/* - * Print number with header at given row, column - */ -static void prt_num(cptr header, int num, int row, int col, byte color, - cptr space) -{ - int len = strlen(header); - char out_val[32]; - - put_str(header, row, col); - put_str(space, row, col + len); - (void)sprintf(out_val, "%6ld", (long)num); - c_put_str(color, out_val, row, col + len + strlen(space)); -} - - -/* - * Print str with header at given row, column - */ -static void prt_str(cptr header, cptr str, int row, int col, byte color) -{ - int len = strlen(header); - char out_val[32]; - - put_str(header, row, col); - put_str(" ", row, col + len); - (void)sprintf(out_val, "%6s", str); - c_put_str(color, out_val, row, col + len + 3); -} - - -/* - * Prints the following information on the screen. - * - * For this to look right, the following should be spaced the - * same as in the prt_lnum code... -CFT - */ -static void display_player_middle(void) -{ - int show_tohit = p_ptr->dis_to_h; - int show_todam = p_ptr->dis_to_d; - - object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD]; - char num[7]; - byte color; - int speed; - - - /* Hack -- add in weapon info if known */ - if (object_known_p(o_ptr)) show_tohit = p_ptr->dis_to_h + p_ptr->to_h_melee + o_ptr->to_h; - else show_tohit = p_ptr->dis_to_h + p_ptr->to_h_melee; - if (object_known_p(o_ptr)) show_todam = p_ptr->dis_to_d + p_ptr->to_d_melee + o_ptr->to_d; - else show_todam = p_ptr->dis_to_d + p_ptr->to_d_melee; - - /* Dump the bonuses to hit/dam */ - prt_num("+ To Melee Hit ", show_tohit, 9, 1, TERM_L_BLUE, " "); - prt_num("+ To Melee Damage", show_todam, 10, 1, TERM_L_BLUE, " "); - - o_ptr = &p_ptr->inventory[INVEN_BOW]; - - /* Hack -- add in weapon info if known */ - if (object_known_p(o_ptr)) show_tohit = p_ptr->dis_to_h + p_ptr->to_h_ranged + o_ptr->to_h; - else show_tohit = p_ptr->dis_to_h + p_ptr->to_h_ranged; - if (object_known_p(o_ptr)) show_todam = p_ptr->to_d_ranged + o_ptr->to_d; - else show_todam = p_ptr->to_d_ranged; - - prt_num("+ To Ranged Hit ", show_tohit, 11, 1, TERM_L_BLUE, " "); - prt_num("+ To Ranged Damage", show_todam, 12, 1, TERM_L_BLUE, " "); - - /* Dump the total armor class */ - prt_str(" AC ", format("%d+%d", p_ptr->ac, p_ptr->dis_to_a), 13, 1, TERM_L_BLUE); - - prt_num("Level ", (int)p_ptr->lev, 9, 28, TERM_L_GREEN, " "); - - if (p_ptr->exp >= p_ptr->max_exp) - { - prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_L_GREEN); - } - else - { - prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_YELLOW); - } - - prt_lnum("Max Exp ", p_ptr->max_exp, 11, 28, TERM_L_GREEN); - - if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev)) - { - put_str("Exp to Adv.", 12, 28); - c_put_str(TERM_L_GREEN, " *****", 12, 28 + 11); - } - else - { - prt_lnum("Exp to Adv.", - (s32b)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L), - 12, 28, TERM_L_GREEN); - } - - prt_lnum("Gold ", p_ptr->au, 13, 28, TERM_L_GREEN); - - if (p_ptr->necro_extra & CLASS_UNDEAD) - { - put_str("Death Points ", 9, 52); - if (p_ptr->chp >= p_ptr->mhp) - { - color = TERM_L_BLUE; - } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) - { - color = TERM_VIOLET; - } - else - { - color = TERM_L_RED; - } - (void)sprintf(num, "%6ld", (long)p_ptr->chp); - c_put_str(color, num, 9, 65); - put_str("/", 9, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->mhp); - c_put_str(TERM_L_BLUE, num, 9, 72); - } - else - { - put_str("Hit Points ", 9, 52); - if (p_ptr->chp >= p_ptr->mhp) - { - color = TERM_L_GREEN; - } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) - { - color = TERM_YELLOW; - } - else - { - color = TERM_RED; - } - (void)sprintf(num, "%6ld", (long)p_ptr->chp); - c_put_str(color, num, 9, 65); - put_str("/", 9, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->mhp); - c_put_str(TERM_L_GREEN, num, 9, 72); - } - - put_str("Spell Points ", 10, 52); - if (p_ptr->csp >= p_ptr->msp) - { - color = TERM_L_GREEN; - } - else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10) - { - color = TERM_YELLOW; - } - else - { - color = TERM_RED; - } - (void)sprintf(num, "%6ld", (long)p_ptr->csp); - c_put_str(color, num, 10, 65); - put_str("/", 10, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->msp); - c_put_str(TERM_L_GREEN, num, 10, 72); - - put_str("Sanity ", 11, 52); - if (p_ptr->csane >= p_ptr->msane) - { - color = TERM_L_GREEN; - } - else if (p_ptr->csane > (p_ptr->msane * hitpoint_warn) / 10) - { - color = TERM_YELLOW; - } - else - { - color = TERM_RED; - } - (void)sprintf(num, "%6ld", (long)p_ptr->csane); - c_put_str(color, num, 11, 65); - put_str("/", 11, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->msane); - c_put_str(TERM_L_GREEN, num, 11, 72); - - if (p_ptr->pgod != GOD_NONE) - { - prt_num("Piety ", p_ptr->grace, 12, 52, TERM_L_GREEN, " "); - } - - put_str("Speed ", 13, 52); - speed = p_ptr->pspeed; - /* Hack -- Visually "undo" the Search Mode Slowdown */ - if (p_ptr->searching) speed += 10; - if (speed > 110) - { - char s[11]; - (void)sprintf(s, "Fast (+%d)", speed - 110); - c_put_str(TERM_L_GREEN, s, 13, (speed >= 120) ? 68 : 69); - } - else if (speed < 110) - { - char s[11]; - (void)sprintf(s, "Slow (-%d)", 110 - speed); - c_put_str(TERM_L_UMBER, s, 13, (speed <= 100) ? 68 : 69); - } - else - { - put_str("Normal", 13, 72); - } -} - - - - -/* - * Hack -- pass color info around this file - */ -static byte likert_color = TERM_WHITE; - - -/* - * Returns a "rating" of x depending on y - */ -static cptr likert(int x, int y) -{ - static char dummy[20] = ""; - - /* Paranoia */ - if (y <= 0) y = 1; - - /* Negative value */ - if (x < 0) - { - likert_color = TERM_L_DARK; - return ("Very Bad"); - } - - /* Analyze the value */ - switch ((x / y)) - { - case 0: - case 1: - { - likert_color = TERM_RED; - return ("Bad"); - } - case 2: - { - likert_color = TERM_L_RED; - return ("Poor"); - } - case 3: - case 4: - { - likert_color = TERM_ORANGE; - return ("Fair"); - } - case 5: - { - likert_color = TERM_YELLOW; - return ("Good"); - } - case 6: - { - likert_color = TERM_YELLOW; - return ("Very Good"); - } - case 7: - case 8: - { - likert_color = TERM_L_GREEN; - return ("Excellent"); - } - case 9: - case 10: - case 11: - case 12: - case 13: - { - likert_color = TERM_GREEN; - return ("Superb"); - } - case 14: - case 15: - case 16: - case 17: - { - likert_color = TERM_L_GREEN; - return ("Heroic"); - } - default: - { - likert_color = TERM_L_GREEN; - sprintf(dummy, "Legendary[%d]", (int)((((x / y) - 17) * 5) / 2)); - return dummy; - } - } -} - - -/* - * Prints ratings on certain abilities - * - * This code is "imitated" elsewhere to "dump" a character sheet. - */ -static void display_player_various(void) -{ - int tmp, tmp2, damdice, damsides, dambonus, blows; - int xthn, xthb, xfos, xsrh; - int xdis, xdev, xsav, xstl; - cptr desc; - int i; - - object_type *o_ptr; - - - /* Fighting Skill (with current weapon) */ - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - tmp = p_ptr->to_h + o_ptr->to_h + p_ptr->to_h_melee; - xthn = p_ptr->skill_thn + (tmp * BTH_PLUS_ADJ); - - /* Shooting Skill (with current bow and normal missile) */ - o_ptr = &p_ptr->inventory[INVEN_BOW]; - tmp = p_ptr->to_h + o_ptr->to_h + p_ptr->to_h_ranged; - xthb = p_ptr->skill_thb + (tmp * BTH_PLUS_ADJ); - - /* variables for all types of melee damage */ - dambonus = p_ptr->dis_to_d; - blows = p_ptr->num_blow; - - /* Basic abilities */ - xdis = p_ptr->skill_dis; - xdev = p_ptr->skill_dev; - xsav = p_ptr->skill_sav; - xstl = p_ptr->skill_stl; - xsrh = p_ptr->skill_srh; - xfos = p_ptr->skill_fos; - - - put_str("Fighting :", 16, 1); - desc = likert(xthn, 12); - c_put_str(likert_color, desc, 16, 15); - - put_str("Bows/Throw :", 17, 1); - desc = likert(xthb, 12); - c_put_str(likert_color, desc, 17, 15); - - put_str("Saving Throw:", 18, 1); - desc = likert(xsav, 6); - c_put_str(likert_color, desc, 18, 15); - - put_str("Stealth :", 19, 1); - desc = likert(xstl, 1); - c_put_str(likert_color, desc, 19, 15); - - - put_str("Perception :", 16, 28); - desc = likert(xfos, 6); - c_put_str(likert_color, desc, 16, 42); - - put_str("Searching :", 17, 28); - desc = likert(xsrh, 6); - c_put_str(likert_color, desc, 17, 42); - - put_str("Disarming :", 18, 28); - desc = likert(xdis, 8); - c_put_str(likert_color, desc, 18, 42); - - put_str("Magic Device:", 19, 28); - desc = likert(xdev, 6); - c_put_str(likert_color, desc, 19, 42); - - - put_str("Blows/Round:", 16, 55); - put_str(format("%d", p_ptr->num_blow), 16, 69); - - put_str("Shots/Round:", 17, 55); - put_str(format("%d", p_ptr->num_fire), 17, 69); - - put_str("Mel.dmg/Rnd:", 18, 55); /* From PsiAngband */ - - if (p_ptr->melee_style == SKILL_HAND || p_ptr->melee_style == SKILL_BEAR) - { - /* This is all based on py_attack_hand */ - martial_arts *blow_table, *min_attack, *max_attack; - int max_blow, plev, i; - - if (p_ptr->melee_style == SKILL_HAND) - { - blow_table = ma_blows; - max_blow = MAX_MA; - plev = get_skill(SKILL_HAND); - } - else /* SKILL_BEAR */ - { - blow_table = bear_blows; - max_blow = MAX_BEAR; - plev = get_skill(SKILL_BEAR); - } - min_attack = blow_table; - i = max_blow - 1; - while (blow_table[i].min_level > plev && i != 0) - --i; - max_attack = &blow_table[i]; - - dambonus += p_ptr->to_d_melee; - tmp = min_attack->dd + dambonus; - if (tmp < 0) tmp = 0; - tmp2 = maxroll(max_attack->dd, max_attack->ds) + dambonus; - if (tmp2 < 0) tmp2 = 0; - if (!tmp && !tmp2) - desc = "0"; - else - desc = format("%d-%d", blows * tmp, blows * tmp2); - } - else if (!r_info[p_ptr->body_monster].body_parts[BODY_WEAPON]) - { - if (r_info[p_ptr->body_monster].flags1 & RF1_NEVER_BLOW) - desc = "nil!"; - else - { - tmp = tmp2 = 0; - for (i = 0; i < blows; i++) - { - tmp += r_info[p_ptr->body_monster].blow[i].d_dice; - tmp2 += maxroll(r_info[p_ptr->body_monster].blow[i].d_dice, - r_info[p_ptr->body_monster].blow[i].d_side); - } - if (dambonus > 0) - { - tmp += dambonus; - tmp2 += dambonus; - } - desc = format("%d-%d", tmp, tmp2); - } - } - else - { - /* Increase the bonus to damage for weapon combat */ - dambonus += p_ptr->to_d_melee; - - /* Access the first weapon */ - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - - if (object_known_p(o_ptr)) dambonus += o_ptr->to_d; - - damdice = o_ptr->dd; - damsides = o_ptr->ds; - - if ((damdice == 0) || (damsides == 0)) - { - if (dambonus <= 0) - desc = "nil!"; - else - desc = format("%d", blows * dambonus); - } - else - { - if (dambonus == 0) - desc = format("%dd%d", blows * damdice, damsides); - else - desc = format("%dd%d%c%d", blows * damdice, damsides, - ( dambonus > 0 ? '+' : '\0' ), blows * dambonus ); - } - } - put_str(desc, 18, 69); - - - put_str("Infra-Vision:", 19, 55); - put_str(format("%d feet", p_ptr->see_infra * 10), 19, 69); - - /* jk - add tactic */ - put_str("Tactic:", 20, 55); - c_put_str(TERM_L_BLUE, tactic_info[(byte)p_ptr->tactic].name, 20, 69); - - /* jk - add movement */ - put_str("Explor:", 21, 55); - c_put_str(TERM_L_BLUE, move_info[(byte)p_ptr->movement].name, 21, 69); -} - - - -/* - * Obtain the "flags" of the wielded symbiote - */ - -void wield_monster_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) -{ - object_type *o_ptr; - monster_race *r_ptr; - - /* Clear */ - (*f1) = (*f2) = (*f3) = (*f4) = (*f5) = (*esp) = 0L; - - /* Get the carried monster */ - o_ptr = &p_ptr->inventory[INVEN_CARRY]; - - if (o_ptr->k_idx) - { - r_ptr = &r_info[o_ptr->pval]; - - if (r_ptr->flags2 & RF2_INVISIBLE) - (*f2) |= TR2_INVIS; - if (r_ptr->flags2 & RF2_REFLECTING) - (*f2) |= TR2_REFLECT; - if (r_ptr->flags7 & RF7_CAN_FLY) - (*f3) |= TR3_FEATHER; - if (r_ptr->flags7 & RF7_AQUATIC) - (*f5) |= TR5_WATER_BREATH; - } -} - - -/* - * Obtain the "flags" for the player as if he was an item - */ -void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) -{ - int i; - - /* Clear */ - (*f1) = (*f2) = (*f3) = (*f4) = (*f5) = (*esp) = 0L; - - /* Astral chars */ - if (p_ptr->astral) - { - (*f3) |= TR3_WRAITH; - } - -/* Skills */ - if (get_skill(SKILL_DAEMON) > 20) (*f2) |= TR2_RES_CONF; - if (get_skill(SKILL_DAEMON) > 30) (*f2) |= TR2_RES_FEAR; - if (get_skill(SKILL_MINDCRAFT) >= 40) (*esp) |= ESP_ALL; - if (p_ptr->melee_style == SKILL_HAND && get_skill(SKILL_HAND) > 24 && !monk_heavy_armor()) - (*f2) |= TR2_FREE_ACT; -/* Hack - from Lua */ - if (get_skill(SKILL_MANA) >= 35) (*f1) |= TR1_MANA; - if (get_skill(SKILL_AIR) >= 50) (*f5) |= (TR5_MAGIC_BREATH | TR5_WATER_BREATH); - if (get_skill(SKILL_WATER) >= 30) (*f5) |= TR5_WATER_BREATH; - -/* Gods */ - GOD(GOD_ERU) - { - if ((p_ptr->grace >= 100) || (p_ptr->grace <= -100)) (*f1) |= TR1_MANA; - if (p_ptr->grace > 10000) (*f1) |= TR1_WIS; - } - - GOD(GOD_MELKOR) - { - (*f2) |= TR2_RES_FIRE; - if (p_ptr->melkor_sacrifice > 0) (*f2) |= TR2_LIFE; - if (p_ptr->grace > 10000) (*f1) |= (TR1_STR | TR1_CON | TR1_INT | TR1_WIS | TR1_CHR); - PRAY_GOD(GOD_MELKOR) - { - if (p_ptr->grace > 5000) (*f2) |= TR2_INVIS; - if (p_ptr->grace > 15000) (*f2) |= TR2_IM_FIRE; - } - } - - GOD(GOD_MANWE) - { - if (p_ptr->grace >= 2000) (*f3) |= TR3_FEATHER; - PRAY_GOD(GOD_MANWE) - { - if (p_ptr->grace >= 7000) (*f2) |= TR2_FREE_ACT; - if (p_ptr->grace >= 15000) (*f4) |= TR4_FLY; - if ((p_ptr->grace >= 5000) || (p_ptr->grace <= -5000)) (*f1) |= TR1_SPEED; - } - } - - GOD(GOD_TULKAS) - { - if (p_ptr->grace > 5000) (*f1) |= TR1_CON; - if (p_ptr->grace > 10000) (*f1) |= TR1_STR; - } - - GOD(GOD_AULE) - { - if (p_ptr->grace > 5000) - { - (*f2) |= TR2_RES_FIRE; - } - } - - GOD(GOD_MANDOS) - { - (*f2) |= TR2_RES_NETHER; - - if ((p_ptr->grace > 10000) && - (p_ptr->praying == TRUE)) - { - (*f3) |= TR3_NO_TELE; - } - - if ((p_ptr->grace > 20000) && - (p_ptr->praying == TRUE)) - { - (*f4) |= TR4_IM_NETHER; - } - } - - GOD(GOD_ULMO) - { - (*f5) |= TR5_WATER_BREATH; - - if ((p_ptr->grace > 1000) && - (p_ptr->praying == TRUE)) - { - (*f2) |= TR2_RES_POIS; - } - - if ((p_ptr->grace > 15000) && - (p_ptr->praying == TRUE)) - { - (*f5) |= TR5_MAGIC_BREATH; - } - } - - /* Classes */ - for (i = 1; i <= p_ptr->lev; i++) - { - (*f1) |= cp_ptr->oflags1[i]; - (*f2) |= cp_ptr->oflags2[i]; - (*f3) |= cp_ptr->oflags3[i]; - (*f4) |= cp_ptr->oflags4[i]; - (*f5) |= cp_ptr->oflags5[i]; - (*esp) |= cp_ptr->oesp[i]; - } - - /* Races */ - if ((!p_ptr->mimic_form) && (!p_ptr->body_monster)) - { - for (i = 1; i <= p_ptr->lev; i++) - { - (*f1) |= rp_ptr->oflags1[i]; - (*f2) |= rp_ptr->oflags2[i]; - (*f3) |= rp_ptr->oflags3[i]; - (*f4) |= rp_ptr->oflags4[i]; - (*f5) |= rp_ptr->oflags5[i]; - (*esp) |= rp_ptr->oesp[i]; - - (*f1) |= rmp_ptr->oflags1[i]; - (*f2) |= rmp_ptr->oflags2[i]; - (*f3) |= rmp_ptr->oflags3[i]; - (*f4) |= rmp_ptr->oflags4[i]; - (*f5) |= rmp_ptr->oflags5[i]; - (*esp) |= rmp_ptr->oesp[i]; - } - } - else - { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - - if (r_ptr->flags2 & RF2_REFLECTING) (*f2) |= TR2_REFLECT; - if (r_ptr->flags2 & RF2_REGENERATE) (*f3) |= TR3_REGEN; - if (r_ptr->flags2 & RF2_AURA_FIRE) (*f3) |= TR3_SH_FIRE; - if (r_ptr->flags2 & RF2_AURA_ELEC) (*f3) |= TR3_SH_ELEC; - if (r_ptr->flags2 & RF2_PASS_WALL) (*f3) |= TR3_WRAITH; - if (r_ptr->flags3 & RF3_SUSCEP_FIRE) (*f2) |= TR2_SENS_FIRE; - if (r_ptr->flags3 & RF3_IM_ACID) (*f2) |= TR2_RES_ACID; - if (r_ptr->flags3 & RF3_IM_ELEC) (*f2) |= TR2_RES_ELEC; - if (r_ptr->flags3 & RF3_IM_FIRE) (*f2) |= TR2_RES_FIRE; - if (r_ptr->flags3 & RF3_IM_POIS) (*f2) |= TR2_RES_POIS; - if (r_ptr->flags3 & RF3_IM_COLD) (*f2) |= TR2_RES_COLD; - if (r_ptr->flags3 & RF3_RES_NETH) (*f2) |= TR2_RES_NETHER; - if (r_ptr->flags3 & RF3_RES_NEXU) (*f2) |= TR2_RES_NEXUS; - if (r_ptr->flags3 & RF3_RES_DISE) (*f2) |= TR2_RES_DISEN; - if (r_ptr->flags3 & RF3_NO_FEAR) (*f2) |= TR2_RES_FEAR; - if (r_ptr->flags3 & RF3_NO_SLEEP) (*f2) |= TR2_FREE_ACT; - if (r_ptr->flags3 & RF3_NO_CONF) (*f2) |= TR2_RES_CONF; - if (r_ptr->flags7 & RF7_CAN_FLY) (*f3) |= TR3_FEATHER; - } - - (*f1) |= p_ptr->xtra_f1; - (*f2) |= p_ptr->xtra_f2; - (*f3) |= p_ptr->xtra_f3; - (*f4) |= p_ptr->xtra_f4; - (*f5) |= p_ptr->xtra_f5; - (*esp) |= p_ptr->xtra_esp; - - if (p_ptr->black_breath) - { - (*f4) |= TR4_BLACK_BREATH; - } - - if (p_ptr->hp_mod != 0) - { - (*f2) |= TR2_LIFE; - } -} - -/* - * Object flag names - */ -static cptr object_flag_names[192] = -{ - "Add Str", - "Add Int", - "Add Wis", - "Add Dex", - "Add Con", - "Add Chr", - "Mul Mana", - "Mul SPower", - "Add Stea.", - "Add Sear.", - "Add Infra", - "Add Tun..", - "Add Speed", - "Add Blows", - "Chaotic", - "Vampiric", - "Slay Anim.", - "Slay Evil", - "Slay Und.", - "Slay Demon", - "Slay Orc", - "Slay Troll", - "Slay Giant", - "Slay Drag.", - "Kill Drag.", - "Sharpness", - "Impact", - "Poison Brd", - "Acid Brand", - "Elec Brand", - "Fire Brand", - "Cold Brand", - - "Sust Str", - "Sust Int", - "Sust Wis", - "Sust Dex", - "Sust Con", - "Sust Chr", - "Invisible", - "Mul life", - "Imm Acid", - "Imm Elec", - "Imm Fire", - "Imm Cold", - "Sens Fire", - "Reflect", - "Free Act", - "Hold Life", - "Res Acid", - "Res Elec", - "Res Fire", - "Res Cold", - "Res Pois", - "Res Fear", - "Res Light", - "Res Dark", - "Res Blind", - "Res Conf", - "Res Sound", - "Res Shard", - "Res Neth", - "Res Nexus", - "Res Chaos", - "Res Disen", - - - - "Aura Fire", - "Aura Elec", - "Auto Curse", - NULL, - "NoTeleport", - "AntiMagic", - "WraithForm", - "EvilCurse", - NULL, - NULL, - NULL, - NULL, - "Levitate", - "Lite", - "See Invis", - NULL, - "Digestion", - "Regen", - "Xtra Might", - "Xtra Shots", - NULL, - NULL, - NULL, - NULL, - "Activate", - "Drain Exp", - "Teleport", - "Aggravate", - "Blessed", - "Cursed", - "Hvy Curse", - "Prm Curse", - - "No blows", - "Precogn.", - "B.Breath", - "Recharge", - "Fly", - "Mrg.Curse", - NULL, - NULL, - "Sentient", - "Clone", - NULL, - "Climb", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Imm Neth", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - "Orc.ESP", - "Troll.ESP", - "Dragon.ESP", - "Giant.ESP", - "Demon.ESP", - "Undead.ESP", - "Evil.ESP", - "Animal.ESP", - "TLord.ESP", - "Good.ESP", - "Nlive.ESP", - "Unique.ESP", - "Spider ESP", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Full ESP", -}; - -/* - * Summarize resistances - */ -static void display_player_ben_one(int mode) -{ - int i, n, x, y, z, dispx, modetemp, xtemp; - - object_type *o_ptr; - - char dummy[80], c; - - u32b f1, f2, f3, f4, f5, esp; - - u16b b[INVEN_TOTAL - INVEN_WIELD + 1][10]; - - int d[INVEN_TOTAL - INVEN_WIELD + 1]; - - bool_ got; - - byte a; - - cptr name; - - /* Scan equipment */ - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) - { - /* Index */ - n = (i - INVEN_WIELD); - - /* Object */ - o_ptr = &p_ptr->inventory[i]; - - /* Known object flags */ - object_flags_known(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); - d[n] = o_ptr->pval; - } - - /* Carried symbiote */ - n = INVEN_CARRY - INVEN_WIELD; - - /* Player flags */ - wield_monster_flags(&f1, &f2, &f3, &f4, &f5, &esp); - - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); - - /* Index */ - n = INVEN_TOTAL - INVEN_WIELD; - - /* Player flags */ - player_flags(&f1, &f2, &f3, &f4, &f5, &esp); - - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); - - /* Generate the equip chars */ - sprintf(dummy, " "); - for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++) - { - /* If you have that body part then show it */ - if (p_ptr->body_parts[i]) - { - strcat(dummy, format("%c", i + 'a')); - } - } - strcat(dummy, "@"); - - /* Scan cols */ - for (x = 1; x > -1; x--) - { - /* Label */ - Term_putstr(x * 40 + 11, 3, -1, TERM_WHITE, dummy); - - /* Scan rows */ - for (y = 0; y < 16; y++) - { - if (mode == 3 && x == 1) - { - modetemp = 4; - xtemp = 0; - } - else - { - modetemp = mode; - xtemp = x; - } - - for (z = mode; z <= modetemp; z++) - { - if (mode == 3 && x == 1 && z == modetemp) xtemp = 1; - name = object_flag_names[32 * modetemp + 16 * xtemp + y]; - got = FALSE; - - /* No name */ - if (!name) continue; - - /* Dump colon */ - if (!(modetemp == 1 && x == 0 && y > 7 && y < 12)) - { - Term_putch(x * 40 + 10, y + 4, TERM_WHITE, ':'); - } - - /* Check flags */ - dispx = 0; - for (n = 0; n < INVEN_TOTAL - INVEN_WIELD + 1; n++) - { - /* Change colour every two columns */ - bool_ is_green = (dispx & 0x02); - a = (is_green ? TERM_GREEN : TERM_SLATE); - c = '.'; - - /* If the body part doesn't exists then skip it :) */ - if ((n < INVEN_TOTAL - INVEN_WIELD) && (!p_ptr->body_parts[n])) continue; - - /* Increment the drawing coordinates */ - dispx++; - - /* Check flag */ - if (b[n][2 * modetemp + xtemp] & (1 << y)) - { - a = (is_green ? TERM_L_GREEN : TERM_WHITE); - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - c = '*'; - } - else if (modetemp == 0 && x == 0 && y < 14 && (y < 6 || y > 7)) - { - if (n == INVEN_TOTAL - INVEN_WIELD) - { - c = '+'; - } - else - { - c = d[n]; - if (c < 0) - { - c = -c; - a = TERM_RED; - } - c = (c > 9 ? '*' : I2D(c)); - } - } - else - { - c = '+'; - } - got = TRUE; - } - - /* HACK - Check for nether immunity and - apply to Res Neth line */ - if (modetemp == 1 && x == 1 && y == 12) - { - if (b[n][7] & (1 << 6)) - { - a = (is_green ? TERM_L_GREEN : TERM_WHITE); - c = '*'; - got = TRUE; - } - } - - /* Dump flag */ - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - if (c == '*') Term_putch(40 + 11 + dispx, y - 4, a, c); - } - else - { - Term_putch(x * 40 + 11 + dispx, y + 4, a, c); - } - } - - a = TERM_WHITE; - if (got) - { - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - a = TERM_L_GREEN; - } - else if (modetemp != 0) - { - a = TERM_GREEN; - } - } - - /* HACK - Check for nether immunity and change "Res Neth" */ - if (modetemp == 1 && x == 1 && y == 12 && p_ptr->immune_neth) - { - name = "Imm Neth"; - a = TERM_L_GREEN; - } - - /* Dump name */ - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - if (got) Term_putstr(40, y - 4, -1, a, name); - } - else - { - Term_putstr(x * 40, y + 4, -1, a, name); - } - } - } - } -} - - -/* - * Display the character on the screen (various modes) - * - * The top two and bottom two lines are left blank. - * - * Mode 0 = standard display with skills - * Mode 1 = standard display with history - * Mode 2 = current flags (part 1) - * Mode 3 = current flags (part 2) - * Mode 4 = current flags (part 3) - * Mode 5 = current flags (part 4) - * Mode 6 = current flags (part 5 -- esp) - */ -void display_player(int mode) -{ - int i; - - char buf[80]; - - - /* Erase screen */ - clear_from(0); - - /* Standard */ - if ((mode == 0) || (mode == 1)) - { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - - /* Name, Sex, Race, Class */ - put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class :", 5, 1); - put_str("Body :", 6, 1); - put_str("God :", 7, 1); - c_put_str(TERM_L_BLUE, player_name, 2, 9); - if (p_ptr->body_monster != 0) - { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - char tmp[12]; - - if ((r_ptr->flags1 & RF1_MALE) != 0) - strcpy(tmp, "Male"); - else if ((r_ptr->flags1 & RF1_FEMALE) != 0) - strcpy(tmp, "Female"); - else - strcpy(tmp, "Neuter"); - c_put_str(TERM_L_BLUE, tmp, 3, 9); - } - else - c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9); - sprintf(buf, "%s", get_player_race_name(p_ptr->prace, p_ptr->pracem)); - c_put_str(TERM_L_BLUE, buf, 4, 9); - c_put_str(TERM_L_BLUE, spp_ptr->title + c_name, 5, 9); - c_put_str(TERM_L_BLUE, r_name + r_ptr->name, 6, 9); - c_put_str(TERM_L_BLUE, deity_info[p_ptr->pgod].name, 7, 9); - - /* Age, Height, Weight, Social */ - prt_num("Age ", (int)p_ptr->age + bst(YEAR, turn - (START_DAY * 10)), 2, 32, TERM_L_BLUE, " "); - prt_num("Height ", (int)p_ptr->ht, 3, 32, TERM_L_BLUE, " "); - prt_num("Weight ", (int)p_ptr->wt, 4, 32, TERM_L_BLUE, " "); - prt_num("Social Class ", (int)p_ptr->sc, 5, 32, TERM_L_BLUE, " "); - - /* Display the stats */ - for (i = 0; i < 6; i++) - { - char punctuation = p_ptr->stat_max[i] == 18 + 100 ? '!' : ':'; - /* Special treatment of "injured" stats */ - if (p_ptr->stat_cur[i] < p_ptr->stat_max[i]) - { - int value; - int colour; - - if (p_ptr->stat_cnt[i]) - colour = TERM_ORANGE; - else - colour = TERM_YELLOW; - - /* Use lowercase stat name */ - put_str(format("%s%c ", stat_names_reduced[i], punctuation), 2 + i, 61); - - /* Get the current stat */ - value = p_ptr->stat_use[i]; - - /* Obtain the current stat (modified) */ - cnv_stat(value, buf); - - /* Display the current stat (modified) */ - c_put_str(colour, buf, 2 + i, 66); - - /* Acquire the max stat */ - value = p_ptr->stat_top[i]; - - /* Obtain the maximum stat (modified) */ - cnv_stat(value, buf); - - /* Display the maximum stat (modified) */ - c_put_str(TERM_L_GREEN, buf, 2 + i, 73); - } - - /* Normal treatment of "normal" stats */ - else - { - /* Assume uppercase stat name */ - put_str(format("%s%c ", stat_names[i], punctuation), 2 + i, 61); - - /* Obtain the current stat (modified) */ - cnv_stat(p_ptr->stat_use[i], buf); - - /* Display the current stat (modified) */ - c_put_str(TERM_L_GREEN, buf, 2 + i, 66); - } - } - - /* Extra info */ - display_player_middle(); - - /* Display "history" info */ - if (mode == 1) - { - put_str("(Character Background)", 15, 25); - - for (i = 0; i < 4; i++) - { - put_str(history[i], i + 16, 10); - } - } - - /* Display "various" info */ - else - { - put_str("(Miscellaneous Abilities)", 15, 25); - - display_player_various(); - } - } - - /* Special */ - else - { - display_player_ben_one(mode - 2); - } -} - -/* - * Utility function; should probably be in some other file... - * - * Describe the player's location -- either by dungeon level, town, or in - * wilderness with landmark reference. - */ -cptr describe_player_location() -{ - int i; - static char desc[80]; - int pwx = (p_ptr->wild_mode ? p_ptr->px : p_ptr->wilderness_x); - int pwy = (p_ptr->wild_mode ? p_ptr->py : p_ptr->wilderness_y); - int feat = wild_map[pwy][pwx].feat; - - if (dungeon_type != DUNGEON_WILDERNESS && dun_level > 0) - sprintf(desc, "on level %d of %s", dun_level, d_info[dungeon_type].name + d_name); - else if (wf_info[feat].terrain_idx == TERRAIN_TOWN) - sprintf(desc, "in the town of %s", wf_info[feat].name + wf_name); - else if (wf_info[feat].entrance) - sprintf(desc, "near %s", wf_info[feat].name + wf_name); - else - { - /* - * The complicated case. Find the nearest known landmark, - * and describe our position relative to that. Note that - * we may not even have any known landmarks (for instance, - * a Lost Soul character just after escaping the Halls of - * Mandos). - */ - int landmark = 0, lwx = 0, lwy = 0; - int l_dist = -1; - int i; - - for (i = 0; i < max_wf_idx; i++) - { - int wx = wf_info[i].wild_x; - int wy = wf_info[i].wild_y; - int dist; - - /* Skip if not a landmark */ - if (!wf_info[i].entrance) continue; - - /* Skip if we haven't seen it */ - if (!wild_map[wy][wx].known) continue; - - dist = distance(wy, wx, pwy, pwx); - if (dist < l_dist || l_dist < 0) - { - landmark = i; - l_dist = dist; - lwx = wx; - lwy = wy; - } - } - - if (!landmark) - sprintf(desc, "in %s", wf_info[feat].text + wf_text); - else if (pwx == lwx && pwy == lwy) - /* Paranoia; this should have been caught above */ - sprintf(desc, "near %s", wf_info[feat].name + wf_name); - else - { - /* - * We split the circle into eight equal octants of - * size pi/4 radians; the "east" octant, for - * instance, is defined as due east plus or minus - * pi/8 radians. Now sin(pi/8) ~= 0.3826 ~= 31/81, - * so we check |dx|/|dy| and |dy|/|dx| against that - * ratio to determine which octant we're in. - */ - int dx = pwx - lwx; - int dy = pwy - lwy; - cptr ns = (dy > 0 ? "south" : "north"); - cptr ew = (dx > 0 ? "east" : "west"); - - dx = (dx < 0 ? -dx : dx); - dy = (dy < 0 ? -dy : dy); - if (dy * 81 < dx * 31) ns = ""; - if (dx * 81 < dy * 31) ew = ""; - - sprintf(desc, "in %s %s%s of %s", - wf_info[feat].text + wf_text, ns, ew, - wf_info[landmark].name + wf_name); - } - } - - /* strip trailing whitespace */ - for (i = 0; desc[i]; ++i); - while (desc[--i] == ' ') - desc[i] = 0; - - return desc; -} - -/* - * Helper function or file_character_print_grid - * - * Figure out if a row on the grid is empty - */ -static bool_ file_character_print_grid_check_row(const char *buf) -{ - if (strstr(buf + 12, "+")) return TRUE; - if (strstr(buf + 12, "*")) return TRUE; - if (strstr(buf + 12, "1")) return TRUE; - if (strstr(buf + 12, "2")) return TRUE; - if (strstr(buf + 12, "3")) return TRUE; - if (strstr(buf + 12, "4")) return TRUE; - if (strstr(buf + 12, "5")) return TRUE; - if (strstr(buf + 12, "6")) return TRUE; - if (strstr(buf + 12, "7")) return TRUE; - if (strstr(buf + 12, "8")) return TRUE; - if (strstr(buf + 12, "9")) return TRUE; - return FALSE; -} - -/* - * Helper function for file_character - * - * Prints the big ugly grid - */ -static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_legend) -{ - static cptr blank_line = " "; - static char buf[1024]; - byte a; - char c; - int x, y; - - y = show_legend ? 3 : 4; - for (; y < 23; y++) - { - for (x = 0; x < 40; x++) - { - (void)(Term_what(x, y, &a, &c)); - buf[x] = c; - } - - buf[x] = '\0'; - if (strcmp(buf, blank_line) && - (y == 3 || show_gaps || file_character_print_grid_check_row(buf))) - fprintf (fff, " %s\n", buf); - } - for (y = 4; y < 23; y++) - { - for (x = 40; x < 80; x++) - { - (void)(Term_what(x, y, &a, &c)); - buf[x - 40] = c; - } - - buf[x] = '\0'; - if (strcmp(buf, blank_line) && - (show_gaps || file_character_print_grid_check_row(buf))) - fprintf (fff, " %s\n", buf); - } -} - -/* - * Helper function for file_character - * - * Outputs one item (for Inventory, Equipment, Home, and Mathom-house) - */ -void file_character_print_item(FILE *fff, char label, object_type *obj, bool_ full) -{ - static char o_name[80]; - static cptr paren = ")"; - object_desc(o_name, obj, TRUE, 3); - fprintf(fff, "%c%s %s\n", label, paren, o_name); - - if ((artifact_p(obj) || ego_item_p(obj) || obj->tval == TV_RING || obj->tval == TV_AMULET || full) && - (obj->ident & IDENT_MENTAL)) - { - object_out_desc(obj, fff, TRUE, TRUE); - } -} - -/* - * Helper function for file_character - * - * Prints out one "store" (for Home and Mathom-house) - */ -void file_character_print_store(FILE *fff, wilderness_type_info *place, int store, bool_ full) -{ - int i; - town_type *town = &town_info[place->entrance]; - store_type *st_ptr = &town->store[store]; - - if (st_ptr->stock_num) - { - /* Header with name of the town */ - fprintf(fff, " [%s Inventory - %s]\n\n", st_name + st_info[store].name, wf_name + place->name); - - /* Dump all available items */ - for (i = 0; i < st_ptr->stock_num; i++) - { - file_character_print_item(fff, I2A(i%24), &st_ptr->stock[i], full); - } - - /* Add an empty line */ - fprintf(fff, "\n\n"); - } -} - -/* - * Helper function for file_character - * - * Checks if the store hasn't been added to the list yet, and then adds it if it - * was not already there. XXX This is an ugly workaround for the double Gondolin - * problem. - * - * Beware of the ugly pointer gymnastics. - */ -bool_ file_character_check_stores(store_type ***store_list, int *store_list_count, wilderness_type_info *place, int store) -{ - town_type *town = &town_info[place->entrance]; - store_type *st_ptr = &town->store[store]; - store_type **head = *store_list; - int i; - - /* check the list for this store */ - for (i = 0; i < *store_list_count; ++i) - { - if (*head == st_ptr) return FALSE; - ++head; - } - - /* make room for the new one in the array */ - if (*store_list) - { - head = *store_list; - *store_list = C_RNEW(*store_list_count + 1, store_type *); - C_COPY(*store_list, head, *store_list_count, store_type *); - C_FREE(head, *store_list_count, store_type *); - } - else - { - *store_list = RNEW(store_type *); - } - - /* update data */ - (*store_list)[*store_list_count] = st_ptr; - ++*store_list_count; - - return TRUE; -} - -/* - * Hack -- Dump a character description file - * - * XXX XXX XXX Allow the "full" flag to dump additional info, - * and trigger its usage from various places in the code. - */ -errr file_character(cptr name, bool_ full) -{ - int i, j, x, y; - byte a; - char c; - int fd = -1; - FILE *fff = NULL; - char buf[1024]; - store_type **store_list = NULL; - int store_list_count = 0; - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, name); - - /* File type is "TEXT" */ - FILE_TYPE(FILE_TYPE_TEXT); - - /* Check for existing file */ - fd = fd_open(buf, O_RDONLY); - - /* Existing file */ - if (fd >= 0) - { - char out_val[160]; - - /* Close the file */ - (void)fd_close(fd); - - /* Build query */ - (void)sprintf(out_val, "Replace existing file %s? ", buf); - - /* Ask */ - if (get_check(out_val)) fd = -1; - } - - /* Open the non-existing file */ - if (fd < 0) fff = my_fopen(buf, "w"); - - /* Invalid file */ - if (!fff) - { - /* Message */ - msg_format("Character sheet creation failed!"); - msg_print(NULL); - - /* Error */ - return ( -1); - } - - - /* Begin dump */ - fprintf(fff, " [%s Character Sheet]\n\n", get_version_string()); - - - /* Display player */ - display_player(0); - - /* Dump part of the screen */ - for (y = 2; y < 22; y++) - { - /* Dump each row */ - for (x = 0; x < 79; x++) - { - /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); - - /* Dump it */ - buf[x] = c; - } - - /* Terminate */ - buf[x] = '\0'; - - /* End the row */ - fprintf(fff, "%s\n", buf); - } - - /* Display history */ - display_player(1); - - /* Dump part of the screen */ - for (y = 15; y < 20; y++) - { - /* Dump each row */ - for (x = 0; x < 79; x++) - { - /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); - - /* Dump it */ - buf[x] = c; - } - - /* Terminate */ - buf[x] = '\0'; - - /* End the row */ - fprintf(fff, "%s\n", buf); - } - - /* List the patches */ - hook_file = fff; - - fprintf(fff, "\n\n [Miscellaneous information]\n"); - if (joke_monsters) - fprintf(fff, "\n Joke monsters: ON"); - else - fprintf(fff, "\n Joke monsters: OFF"); - - if (p_ptr->maximize) - fprintf(fff, "\n Maximize mode: ON"); - else - fprintf(fff, "\n Maximize mode: OFF"); - - if (p_ptr->preserve) - fprintf(fff, "\n Preserve Mode: ON"); - else - fprintf(fff, "\n Preserve Mode: OFF"); - - if (auto_scum) - fprintf(fff, "\n Autoscum: ON"); - else - fprintf(fff, "\n Autoscum: OFF"); - - if (always_small_level) - fprintf(fff, "\n Small Levels: ALWAYS"); - else if (small_levels) - fprintf(fff, "\n Small Levels: ON"); - else - fprintf(fff, "\n Small Levels: OFF"); - - if (empty_levels) - fprintf(fff, "\n Arena Levels: ON"); - else - fprintf(fff, "\n Arena Levels: OFF"); - - if (ironman_rooms) - fprintf(fff, "\n Always unusual rooms: ON"); - else - fprintf(fff, "\n Always unusual rooms: OFF"); - - fprintf(fff, "\n\n Recall Depth:"); - for (y = 1; y < max_d_idx; y++) - { - if (max_dlv[y]) - fprintf(fff, "\n %s: Level %d (%d')", - d_name + d_info[y].name, - max_dlv[y], 50 * (max_dlv[y])); - } - fprintf(fff, "\n"); - - if (noscore) - fprintf(fff, "\n You have done something illegal."); - - if (PRACE_FLAGS(PR1_EXPERIMENTAL)) - fprintf(fff, "\n You have done something experimental."); - - { - char desc[80]; - cptr mimic; - - monster_race_desc(desc, p_ptr->body_monster, 0); - fprintf(fff, "\n Your body %s %s.", (death ? "was" : "is"), desc); - - if (p_ptr->tim_mimic) - { - mimic = get_mimic_name(p_ptr->mimic_form); - fprintf(fff, "\n You %s disguised as a %s.", (death ? "were" : "are"), mimic); - } - } - - /* Where we are, if we're alive */ - if (!death) fprintf(fff, "\n You are currently %s.", describe_player_location()); - - /* Monsters slain */ - { - int k; - s32b Total = 0; - - for (k = 1; k < max_r_idx; k++) - { - monster_race *r_ptr = &r_info[k]; - - if (r_ptr->flags1 & (RF1_UNIQUE)) - { - bool_ dead = (r_ptr->max_num == 0); - if (dead) - { - Total++; - } - } - else - { - s16b This = r_ptr->r_pkills; - if (This > 0) - { - Total += This; - } - } - } - - if (Total < 1) - fprintf(fff, "\n You have defeated no enemies yet."); - else if (Total == 1) - fprintf(fff, "\n You have defeated one enemy."); - else - fprintf(fff, "\n You have defeated %ld enemies.", (long int) Total); - } - - hook_file = fff; - process_hooks(HOOK_CHAR_DUMP, "()"); - - /* Date */ - { - char buf2[20]; - u32b days = bst(DAY, turn - (START_DAY * 10)); - - strnfmt(buf2, 20, get_day(bst(YEAR, START_DAY * 10) + START_YEAR)); - fprintf(fff, "\n\n You started your adventure the %s of the %s year of the third age.", - get_month_name(bst(DAY, START_DAY * 10), wizard, FALSE), buf2); - - strnfmt(buf2, 20, get_day(bst(YEAR, turn) + START_YEAR)); - fprintf(fff, "\n %s the %s of the %s year of the third age.", - (death ? "You ended your adventure" : "It is currently"), - get_month_name(bst(DAY, turn), wizard, FALSE), buf2); - fprintf(fff, - (death ? "\n Your adventure lasted %ld day%s." : "\n You have been adventuring for %ld day%s."), - (long int) days, (days == 1) ? "" : "s"); - } - - fprintf (fff, "\n\n"); - - /* Emit the self-knowledge lines, even though they duplicate the - information in the grids (below), because they contain information - that's not in the grids (racial abilities, luck, etc.). */ - if (full) - { - self_knowledge(fff); - fprintf(fff, "\n\n"); - } - - /* adds and slays */ - display_player (2); - file_character_print_grid(fff, FALSE, TRUE); - - /* sustains and resistances */ - display_player (3); - file_character_print_grid(fff, TRUE, FALSE); - - /* stuff */ - display_player (4); - file_character_print_grid(fff, FALSE, FALSE); - - /* a little bit of stuff */ - display_player (5); - file_character_print_grid(fff, FALSE, FALSE); - - /* Dump corruptions */ - dump_corruptions(fff, FALSE, TRUE); - - /* Dump skills */ - dump_skills(fff); - dump_abilities(fff); - - /* Dump companions. */ - dump_companions(fff); - - if (p_ptr->companion_killed) - { - if (p_ptr->companion_killed == 1) - fprintf(fff, "\n One of your companion(s) has been killed."); - else - fprintf(fff, "\n %d of your companions have been killed.", p_ptr->companion_killed); - } - - for (i = 0; i < MAX_FATES; i++) - { - if ((fates[i].fate) && (fates[i].know)) - { - fprintf(fff, "\n\n [Fates]\n\n"); - dump_fates(fff); - break; - } - } - - /* Skip some lines */ - fprintf(fff, "\n\n"); - - - /* Dump the equipment */ - text_out_indent = 4; - if (equip_cnt) - { - fprintf(fff, " [Character Equipment]\n\n"); - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) - { - if (!p_ptr->body_parts[i - INVEN_WIELD]) continue; - - file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i], full); - } - fprintf(fff, "\n\n"); - } - - /* Dump the inventory */ - fprintf(fff, " [Character Inventory]\n\n"); - for (i = 0; i < INVEN_PACK; i++) - { - file_character_print_item(fff, index_to_label(i), &p_ptr->inventory[i], full); - } - fprintf(fff, "\n\n"); - - /* Print all homes in the different towns */ - for (j = 0; j < max_wf_idx; j++) - { - if (wf_info[j].feat == FEAT_TOWN && - file_character_check_stores(&store_list, &store_list_count, &wf_info[j], 7)) - file_character_print_store(fff, &wf_info[j], 7, full); - } - store_list = C_FREE(store_list, store_list_count, store_type *); - store_list_count = 0; - - /* Print all Mathom-houses in the different towns */ - for (j = 0; j < max_wf_idx; j++) - { - if (wf_info[j].feat == FEAT_TOWN && - file_character_check_stores(&store_list, &store_list_count, &wf_info[j], 57)) - file_character_print_store(fff, &wf_info[j], 57, full); - } - store_list = C_FREE(store_list, store_list_count, store_type *); - store_list_count = 0; - - text_out_indent = 0; - - /* Close it */ - my_fclose(fff); - - - /* Message */ - msg_print("Character sheet creation successful."); - msg_print(NULL); - - /* Success */ - return (0); -} - - -/* - * Recursive file perusal. - * - * Return FALSE on "ESCAPE", otherwise TRUE. - * - * Process various special text in the input file, including - * the "menu" structures used by the "help file" system. - * - * XXX XXX XXX Consider using a temporary file. - * - * XXX XXX XXX Allow the user to "save" the current file. - */ - -/* - * A structure to hold (some of == XXX) the hyperlink information. - * This prevents excessive use of stack. - */ -#define MAX_LINKS 1024 -struct hyperlink -{ - /* Path buffer */ - char path[1024]; - - /* General buffer */ - char rbuf[1024]; - - /* Hold a string to find */ - char finder[81]; - - /* Hold a string to show */ - char shower[81]; - - /* Describe this thing */ - char caption[128]; - - /* Hypertext info */ - char link[MAX_LINKS][32], link_key[MAX_LINKS]; - int link_x[MAX_LINKS], link_y[MAX_LINKS], link_line[MAX_LINKS]; -}; - -typedef struct hyperlink hyperlink_type; - -bool_ show_file(cptr name, cptr what, int line, int mode) -{ - int i, k, x; - - byte link_color = TERM_ORANGE, link_color_sel = TERM_YELLOW; - - /* Number of "real" lines passed by */ - int next = 0; - - /* Number of "real" lines in the file */ - int size = 0; - - /* Backup value for "line" */ - int back = 0; - - /* Color of the next line */ - byte color = TERM_WHITE; - - /* This screen has sub-screens */ - bool_ menu = FALSE; - - /* Current help file */ - FILE *fff = NULL; - - /* Find this string (if any) */ - cptr find = NULL; - - /* Char array type of hyperlink info */ - hyperlink_type *h_ptr; - - /* Pointer to general buffer in the above */ - char *buf; - - int cur_link = 0, max_link = 0; - - /* Read size of screen for big-screen stuff -pav- */ - int wid, hgt; - - /* Allocate hyperlink data */ - MAKE(h_ptr, hyperlink_type); - - /* Setup buffer pointer */ - buf = h_ptr->rbuf; - - /* Wipe the links */ - for (i = 0; i < MAX_LINKS; i++) - { - h_ptr->link_x[i] = -1; - } - - /* Hack XXX XXX XXX */ - if (what) - { - /* h_ptr->caption */ - strcpy(h_ptr->caption, what); - - /* Access the "file" */ - strcpy(h_ptr->path, name); - - /* Open */ - fff = my_fopen(h_ptr->path, "r"); - } - - /* Look in "help" */ - if (!fff) - { - /* h_ptr->caption */ - sprintf(h_ptr->caption, "Help file '%s'", name); - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, name); - - /* Open the file */ - fff = my_fopen(h_ptr->path, "r"); - } - - /* Look in "info" */ - if (!fff) - { - /* h_ptr->caption */ - sprintf(h_ptr->caption, "Info file '%s'", name); - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_INFO, name); - - /* Open the file */ - fff = my_fopen(h_ptr->path, "r"); - } - - /* Look in "file" */ - if (!fff) - { - /* h_ptr->caption */ - sprintf(h_ptr->caption, "File '%s'", name); - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_FILE, name); - - /* Open the file */ - fff = my_fopen(h_ptr->path, "r"); - } - - /* Oops */ - if (!fff) - { - /* Message */ - msg_format("Cannot open '%s'.", name); - msg_print(NULL); - - /* Free hyperlink info */ - KILL(h_ptr, hyperlink_type); - - /* Oops */ - return (TRUE); - } - - - /* Pre-Parse the file */ - while (TRUE) - { - /* Read a line or stop */ - if (my_fgets(fff, h_ptr->rbuf, 1024)) break; - - /* Get a color */ - if (prefix(h_ptr->rbuf, "#####")) - { - buf = &h_ptr->rbuf[6]; - } - else buf = h_ptr->rbuf; - - /* Get the link colors */ - if (prefix(buf, "|||||")) - { - link_color = color_char_to_attr(buf[5]); - link_color_sel = color_char_to_attr(buf[6]); - } - - /* Tag ? */ - if (prefix(buf, "~~~~~")) - { - if (line < 0) - { - int i; - char old_c; - - for (i = 5; (buf[i] >= '0') && (buf[i] <= '9'); i++) - ; - old_c = buf[i]; - buf[i] = '\0'; - - if (atoi(buf + 5) == -line) - { - line = next + 1; - } - buf[i] = old_c; - } - } - - x = 0; - while (buf[x]) - { - /* Hyperlink ? */ - if (prefix(buf + x, "*****")) - { - int xx = x + 5, stmp, xdeb = x + 5, z; - char tmp[20]; - - for (z = 0; z < 20; z++) tmp[z] = '\0'; - - h_ptr->link_x[max_link] = x; - h_ptr->link_y[max_link] = next; - - if (buf[xx] == '/') - { - xx++; - h_ptr->link_key[max_link] = buf[xx]; - xx++; - xdeb += 2; - } - else - { - h_ptr->link_key[max_link] = 0; - } - - /* Zap the link info */ - while (buf[xx] != '*') - { - h_ptr->link[max_link][xx - xdeb] = buf[xx]; - xx++; - } - h_ptr->link[max_link][xx - xdeb] = '\0'; - xx++; - stmp = xx; - while (buf[xx] != '[') - { - tmp[xx - stmp] = buf[xx]; - xx++; - } - xx++; - tmp[xx - stmp] = '\0'; - h_ptr->link_line[max_link] = -atoi(tmp); - max_link++; - } - x++; - } - - /* Count the "real" lines */ - next++; - } - - /* Save the number of "real" lines */ - size = next; - - - - /* Display the file */ - while (TRUE) - { - /* Clear screen */ - Term_clear(); - - Term_get_size(&wid, &hgt); - - /* Restart when necessary */ - if (line >= size) line = 0; - - - /* Re-open the file if needed */ - if (next > line) - { - /* Close it */ - my_fclose(fff); - - /* Hack -- Re-Open the file */ - fff = my_fopen(h_ptr->path, "r"); - - /* Oops */ - if (!fff) - { - /* Free hyperlink info */ - KILL(h_ptr, hyperlink_type); - - return (FALSE); - } - - /* File has been restarted */ - next = 0; - } - - /* Skip lines if needed */ - for (; next < line; next++) - { - /* Skip a line */ - if (my_fgets(fff, buf, 1024)) break; - } - - - /* Dump the next 20 (or more in bigscreen) lines of the file */ - for (i = 0; i < (hgt - 4); ) - { - int print_x; - - /* Hack -- track the "first" line */ - if (!i) line = next; - - /* Get a line of the file or stop */ - if (my_fgets(fff, h_ptr->rbuf, 1024)) break; - - /* Get a color */ - if (prefix(h_ptr->rbuf, "#####")) - { - color = color_char_to_attr(h_ptr->rbuf[5]); - buf = &h_ptr->rbuf[6]; - } - else buf = h_ptr->rbuf; - - /* Count the "real" lines */ - next++; - - /* Skip link colors */ - if (prefix(buf, "|||||")) continue; - - /* Skip tags */ - if (prefix(buf, "~~~~~")) - { - i++; - continue; - } - - /* Hack -- keep searching */ - if (find && !i && !strstr(buf, find)) continue; - - /* Hack -- stop searching */ - find = NULL; - - /* Be sure to get a correct cur_link */ - if (h_ptr->link_y[cur_link] >= line + (hgt - 4)) - { - while ((cur_link > 0) && (h_ptr->link_y[cur_link] >= line + (hgt - 4))) - { - cur_link--; - } - } - if (h_ptr->link_y[cur_link] < line) - { - while ((cur_link < max_link) && (h_ptr->link_y[cur_link] < line)) - { - cur_link++; - } - } - - /* Dump the line */ - print_x = 0; - if (!prefix(buf, "&&&&&")) - { - x = 0; - while (buf[x]) - { - /* Hyperlink ? */ - if (prefix(buf + x, "*****")) - { - int xx = x + 5; - - /* Zap the link info */ - while (buf[xx] != '[') - { - xx++; - } - xx++; - /* Ok print the link name */ - while (buf[xx] != ']') - { - byte color = link_color; - - if ((h_ptr->link_x[cur_link] == x) && (h_ptr->link_y[cur_link] == line + i)) - color = link_color_sel; - - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - - Term_putch(print_x, i + 2, color, buf[xx]); - xx++; - print_x++; - } - x = xx; - } - /* Color ? */ - else if (prefix(buf + x, "[[[[[")) - { - int xx = x + 6; - - /* Ok print the link name */ - while (buf[xx] != ']') - { - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - Term_putch(print_x, i + 2, color_char_to_attr(buf[x + 5]), buf[xx]); - xx++; - print_x++; - } - x = xx; - } - /* Remove HTML ? */ - else if (prefix(buf + x, "{{{{{")) - { - int xx = x + 6; - - /* Ok remove this section */ - while (buf[xx] != '}') - { - xx++; - } - x = xx; - } - else - { - Term_putch(print_x, i + 2, color, buf[x]); - print_x++; - } - - x++; - } - } - /* Verbatim mode: i.e: acacacac */ - else - { - x = 5; - while (buf[x]) - { - Term_putch(print_x, i + 2, color_char_to_attr(buf[x]), buf[x + 1]); - print_x++; - x += 2; - } - } - color = TERM_WHITE; - - /* Hilite "h_ptr->shower" */ - if (h_ptr->shower[0]) - { - cptr str = buf; - - /* Display matches */ - while ((str = strstr(str, h_ptr->shower)) != NULL) - { - int len = strlen(h_ptr->shower); - - /* Display the match */ - Term_putstr(str - buf, i + 2, len, TERM_YELLOW, h_ptr->shower); - - /* Advance */ - str += len; - } - } - - /* Count the printed lines */ - i++; - } - - /* Hack -- failed search */ - if (find) - { - bell(); - line = back; - find = NULL; - continue; - } - - - /* Show a general "title" */ - prt(format("[%s, %s, Line %d/%d]", get_version_string(), - h_ptr->caption, line, size), 0, 0); - - /* Prompt -- menu screen */ - if (menu) - { - /* Wait for it */ - prt("[Press a Number, or ESC to exit.]", hgt - 1, 0); - } - - /* Prompt -- small files */ - else if (size <= (hgt - 4)) - { - /* Wait for it */ - prt("[Press ESC to exit.]", hgt - 1, 0); - } - - /* Prompt -- large files */ - else - { - /* Wait for it */ - prt("[Press 2, 8, 4, 6, /, =, #, %, backspace, or ESC to exit.]", hgt - 1, 0); - } - - /* Get a keypress */ - k = inkey(); - - /* Hack -- return to last screen */ - if ((k == '?') || (k == 0x7F) || (k == '\010')) break; - - /* Hack -- try showing */ - if (k == '=') - { - /* Get "h_ptr->shower" */ - prt("Show: ", hgt - 1, 0); - (void)askfor_aux(h_ptr->shower, 80); - } - - /* Hack -- try finding */ - if (k == '/') - { - /* Get "h_ptr->finder" */ - prt("Find: ", hgt - 1, 0); - if (askfor_aux(h_ptr->finder, 80)) - { - /* Find it */ - find = h_ptr->finder; - back = line; - line = line + 1; - - /* Show it */ - strcpy(h_ptr->shower, h_ptr->finder); - } - } - - /* Hack -- go to a specific line */ - if (k == '#') - { - char tmp[81]; - prt("Goto Line: ", hgt - 1, 0); - strcpy(tmp, "0"); - if (askfor_aux(tmp, 80)) - { - line = atoi(tmp); - } - } - - /* Hack -- go to a specific file */ - if (k == '%') - { - char tmp[81]; - prt("Goto File: ", hgt - 1, 0); - strcpy(tmp, "help.hlp"); - if (askfor_aux(tmp, 80)) - { - if (!show_file(tmp, NULL, 0, mode)) k = ESCAPE; - } - } - - /* Hack -- Allow backing up */ - if (k == '-') - { - line = line - (hgt - 4); - if (line < 0) line = 0; - } - - if (k == '8') - { - line--; - if (line < 0) line = 0; - } - - /* Hack -- Advance a single line */ - if (k == '2') - { - line = line + 1; - } - - /* Advance one page */ - if (k == ' ') - { - line = line + (hgt - 4); - } - - /* Advance one link */ - if ((k == '6') || (k == '\t')) - { - cur_link++; - if (cur_link >= max_link) cur_link = max_link - 1; - - if (h_ptr->link_y[cur_link] < line) line = h_ptr->link_y[cur_link]; - if (h_ptr->link_y[cur_link] >= line + (hgt - 4)) line = h_ptr->link_y[cur_link] - (hgt - 4); - } - /* Return one link */ - if (k == '4') - { - cur_link--; - if (cur_link < 0) cur_link = 0; - - if (h_ptr->link_y[cur_link] < line) line = h_ptr->link_y[cur_link]; - if (h_ptr->link_y[cur_link] >= line + (hgt - 4)) line = h_ptr->link_y[cur_link] - (hgt - 4); - } - - /* Recurse on numbers */ - if (k == '\r') - { - if (h_ptr->link_x[cur_link] != -1) - { - /* Recurse on that file */ - if (!show_file(h_ptr->link[cur_link], NULL, h_ptr->link_line[cur_link], mode)) k = ESCAPE; - } - } - - /* Exit on escape */ - if (k == ESCAPE) break; - - /* No other key ? lets look for a shortcut */ - for (i = 0; i < max_link; i++) - { - if (h_ptr->link_key[i] == k) - { - /* Recurse on that file */ - if (!show_file(h_ptr->link[i], NULL, h_ptr->link_line[i], mode)) k = ESCAPE; - break; - } - } - } - - /* Close the file */ - my_fclose(fff); - - /* Free hyperlink buffers */ - KILL(h_ptr, hyperlink_type); - - /* Escape */ - if (k == ESCAPE) return (FALSE); - - /* Normal return */ - return (TRUE); -} - -bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_ recur) -{ - int i, x; - - /* Number of "real" lines passed by */ - int next = 0; - - char buf_name[80]; - - /* Color of the next line */ - byte color = TERM_WHITE; - - /* Current help file */ - FILE *fff = NULL; - - /* Current aux file */ - FILE *aux = NULL; - - /* Current html file */ - FILE *htm = NULL; - - /* Char array type of hyperlink info */ - hyperlink_type *h_ptr; - - cptr file_ext = "html"; - cptr link_prefix = ""; - cptr link_suffix = ""; - - /* Pointer to general buffer in the above */ - char *buf; - - /* Allocate hyperlink data */ - MAKE(h_ptr, hyperlink_type); - - /* Setup buffer pointer */ - buf = h_ptr->rbuf; - - /* Wipe the links */ - for (i = 0; i < MAX_LINKS; i++) - { - h_ptr->link_x[i] = -1; - } - - sprintf(buf_name, "%s.%s", base, file_ext); - - if ((!force) && file_exist(buf_name)) return FALSE; - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, buf_name); - - /* Open the file */ - htm = my_fopen(h_ptr->path, "w"); - - sprintf(buf_name, "%s.%s", base, ext); - - /* h_ptr->caption */ - sprintf(h_ptr->caption, "Help file '%s'", buf_name); - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, buf_name); - - /* Open the file */ - fff = my_fopen(h_ptr->path, "r"); - - /* Oops */ - if (!fff || !htm) - { - /* Free hyperlink info */ - KILL(h_ptr, hyperlink_type); - - my_fclose(fff); - my_fclose(htm); - - /* Oops */ - return (TRUE); - } - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, head); - - /* Open the file */ - aux = my_fopen(h_ptr->path, "r"); - - /* Copy the header */ - if (aux) - { - while (TRUE) - { - char *find; - - if (my_fgets(aux, h_ptr->rbuf, 1024)) break; - find = strstr(h_ptr->rbuf, "%t"); - if (find != NULL) - { - *find = '\0'; - find += 2; - fprintf(htm, "%s", h_ptr->rbuf); - fprintf(htm, "%s", base); - fprintf(htm, "%s\n", find); - } - else - fprintf(htm, "%s\n", h_ptr->rbuf); - } - my_fclose(aux); - } - - /* Display the file */ - while (TRUE) - { - bool_ do_color = FALSE; - - /* Skip a line */ - if (my_fgets(fff, h_ptr->rbuf, 1024)) break; - - color = TERM_WHITE; - - { - int print_x; - - /* Get a color */ - if (prefix(h_ptr->rbuf, "#####")) - { - color = color_char_to_attr(h_ptr->rbuf[5]); - do_color = TRUE; - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - buf = &h_ptr->rbuf[6]; - } - else buf = h_ptr->rbuf; - - /* Count the "real" lines */ - next++; - - /* Skip link colors */ - if (prefix(buf, "|||||")) continue; - - /* Skip tags */ - if (prefix(buf, "~~~~~")) - { - int i; - - for (i = 5; (buf[i] >= '0') && (buf[i] <= '9'); i++) - ; - buf[i] = '\0'; - fprintf(htm, "<A NAME=\"%s\"></A>", buf + 5); - continue; - } - - /* Dump the line */ - print_x = 0; - if (!prefix(buf, "&&&&&")) - { - x = 0; - while (buf[x]) - { - /* Hyperlink ? */ - if (prefix(buf + x, "*****")) - { - int xx = x + 5, z = 0; - char buff[80]; - char link_line[80], *s; - - if (buf[xx] == '/') xx += 2; - - /* Zap the link info */ - while (buf[xx] != '*') - { - buff[z++] = buf[xx]; - xx++; - } - xx++; - buff[z] = '\0'; - - /* Zap the link info */ - z = 0; - while (buf[xx] != '[') - { - link_line[z++] = buf[xx]; - xx++; - } - xx++; - link_line[z] = '\0'; - - /* parse it */ - s = buff; - while (*s != '.') s++; - *s = '\0'; - s++; - if (recur) txt_to_html(head, foot, buff, s, FALSE, recur); - - if (atoi(link_line)) fprintf(htm, "<A HREF=\"%s%s.%s%s#%d\">", link_prefix, buff, file_ext, link_suffix, atoi(link_line)); - else fprintf(htm, "<A HREF=\"%s%s.%s%s\">", link_prefix, buff, file_ext, link_suffix); - - /* Ok print the link name */ - while (buf[xx] != ']') - { - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - fprintf(htm, "%c", buf[xx]); - xx++; - print_x++; - } - x = xx; - - fprintf(htm, "</A>"); - } - /* Color ? */ - else if (prefix(buf + x, "[[[[[")) - { - int xx = x + 6; - - color = color_char_to_attr(buf[x + 5]); - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - - /* Ok print the link name */ - while (buf[xx] != ']') - { - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - fprintf(htm, "%c", buf[xx]); - xx++; - print_x++; - } - x++; - x = xx; - - fprintf(htm, "</FONT>"); - } - /* Hidden HTML tag? */ - else if (prefix(buf + x, "{{{{{")) - { - int xx = x + 5; - - /* Ok output the tag inside */ - while (buf[xx] != '}') - { - fprintf(htm, "%c", buf[xx]); - xx++; - } - x++; - x = xx; - } - else - { - fprintf(htm, "%c", buf[x]); - print_x++; - } - - x++; - } - } - /* Verbatim mode: i.e: acacacac */ - else - { - byte old_color; - - x = 5; - old_color = color_char_to_attr(buf[x]); - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - while (buf[x]) - { - color = color_char_to_attr(buf[x]); - if (color != old_color) - fprintf(htm, "</FONT><FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - - fprintf(htm, "%c", buf[x + 1]); - print_x++; - x += 2; - } - fprintf(htm, "</FONT>"); - } - } - if (do_color) - { - fprintf(htm, "</FONT>"); - } - fprintf(htm, "\n"); - } - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, foot); - - /* Open the file */ - aux = my_fopen(h_ptr->path, "r"); - - /* Copy the footer */ - if (aux) - { - while (TRUE) - { - if (my_fgets(aux, h_ptr->rbuf, 1024)) break; - fprintf(htm, "%s\n", h_ptr->rbuf); - } - my_fclose(aux); - } - - /* Close the file */ - my_fclose(htm); - my_fclose(fff); - - /* Free hyperlink buffers */ - KILL(h_ptr, hyperlink_type); - - /* Normal return */ - return (TRUE); -} - -/* Take an help file screenshot(yes yes I know..) */ -void help_file_screenshot(cptr name) -{ - int y, x; - int wid, hgt; - - byte a = 0; - char c = ' '; - - FILE *htm; - - char buf[1024]; - - /* The terms package supports up to 255x255 screen size */ - char abuf[256]; - char cbuf[256]; - - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, name); - - /* File type is "TEXT" */ - FILE_TYPE(FILE_TYPE_TEXT); - - /* Append to the file */ - htm = my_fopen(buf, "w"); - - /* Oops */ - if (!htm) return; - - /* Retrieve current screen size */ - Term_get_size(&wid, &hgt); - - /* Dump the screen */ - for (y = 0; y < hgt; y++) - { - cmovie_clean_line(y, abuf, cbuf); - - /* Dump each row */ - fprintf(htm, "&&&&&"); - for (x = 0; x < wid; x++) - { - a = abuf[x]; - c = cbuf[x]; - - fprintf(htm, "%c%c", a, c); - } - - /* End the row */ - fprintf(htm, "\n"); - } - - /* Close it */ - my_fclose(htm); -} - -/* Take an html screenshot */ -void html_screenshot(cptr name) -{ - int y, x; - int wid, hgt; - - byte a = 0, oa = TERM_WHITE; - char c = ' '; - - FILE *htm; - - char buf[1024]; - - /* The terms package supports up to 255x255 screen size */ - char abuf[256]; - char cbuf[256]; - - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, name); - - /* File type is "TEXT" */ - FILE_TYPE(FILE_TYPE_TEXT); - - /* Append to the file */ - htm = my_fopen(buf, "w"); - - /* Oops */ - if (!htm) return; - - /* Retrieve current screen size */ - Term_get_size(&wid, &hgt); - - fprintf(htm, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" - "<head>\n"); - fprintf(htm, "<meta name=\"GENERATOR\" content=\"%s\"/>\n", - get_version_string()); - fprintf(htm, "<title>%s</title>\n", name); - fprintf(htm, "</head>\n" - "<body>\n" - "<pre style=\"color: #ffffff; background-color: #000000; font-family: monospace\">\n"); - fprintf(htm, "<span style=\"color: #%02X%02X%02X\">\n", - angband_color_table[TERM_WHITE][1], - angband_color_table[TERM_WHITE][2], - angband_color_table[TERM_WHITE][3]); - - /* Dump the screen */ - for (y = 0; y < hgt; y++) - { - cmovie_clean_line(y, abuf, cbuf); - - /* Dump each row */ - for (x = 0; x < wid; x++) - { - a = color_char_to_attr(abuf[x]); - c = cbuf[x]; - - if (oa != a) - { - fprintf(htm, "</span><span style=\"color: #%02X%02X%02X\">", angband_color_table[a][1], angband_color_table[a][2], angband_color_table[a][3]); - oa = a; - } - if (c == '<') - fprintf(htm, "<"); - else if (c == '>') - fprintf(htm, ">"); - else if (c == '&') - fprintf(htm, "&"); - else - fprintf(htm, "%c", c); - } - - /* End the row */ - fprintf(htm, "\n"); - } - fprintf(htm, "</span>\n" - "</pre>\n" - "</body>\n" - "</html>\n"); - - /* Close it */ - my_fclose(htm); -} - - -/* - * Peruse the On-Line-Help - */ -void do_cmd_help(void) -{ - /* Save screen */ - screen_save(); - - /* Peruse the main help file */ - (void)show_file("help.hlp", NULL, 0, 0); - - /* Load screen */ - screen_load(); -} - - - - -/* - * Process the player name. - * Extract a clean "base name". - * Build the savefile name if needed. - */ -void process_player_base() -{ - char temp[128]; - - /* Rename the savefile, using the player_base */ - (void)sprintf(temp, "%s", player_base); - - /* Build the filename */ - path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp); -} - -void process_player_name(bool_ sf) -{ - int i, k = 0; - char tmp[50]; - - /* Cannot be too long */ - if (strlen(player_base) > 15) - { - /* Name too long */ - quit_fmt("The name '%s' is too long!", player_base); - } - - /* Cannot contain "icky" characters */ - for (i = 0; player_base[i]; i++) - { - /* No control characters */ - if (iscntrl(player_base[i])) - { - /* Illegal characters */ - quit_fmt("The name '%s' contains control chars!", player_base); - } - } - - -#ifdef MACINTOSH - - /* Extract "useful" letters */ - for (i = 0; player_base[i]; i++) - { - char c = player_base[i]; - - /* Convert "dot" to "underscore" */ - if (c == '@.') c = '_'; - - /* Accept all the letters */ - tmp[k++] = c; - } - -#else - - /* Extract "useful" letters */ - for (i = 0; player_base[i]; i++) - { - char c = player_base[i]; - - /* Accept some letters */ - if (isalpha(c) || isdigit(c)) tmp[k++] = c; - - /* Convert space, dot, and underscore to underscore */ - else if (strchr("@. _", c)) tmp[k++] = '_'; - } - -#endif - - -#if defined(WINDOWS) || defined(MSDOS) - - /* Hack -- max length */ - if (k > 8) k = 8; - -#endif - - /* Terminate */ - tmp[k] = '\0'; - sprintf(player_base, "%s", tmp); - - /* Require a "base" name */ - if (!player_base[0]) strcpy(player_base, "PLAYER"); - - - /* Change the savefile name */ - if (sf) - { - process_player_base(); - } -} - - -/* - * Gets a name for the character, reacting to name changes. - * - * Assumes that "display_player(0)" has just been called - * - * Perhaps we should NOT ask for a name (at "birth()") on - * Unix machines? XXX XXX - * - * What a horrible name for a global function. XXX XXX XXX - */ -void get_name(void) -{ - char tmp[32]; - - /* Clear last line */ - clear_from(22); - - /* Prompt and ask */ - prt("[Enter your player's name above, or hit ESCAPE]", 23, 2); - - /* Ask until happy */ - while (1) - { - /* Go to the "name" field */ - move_cursor(2, 9); - - /* Save the player name */ - strcpy(tmp, player_name); - - /* Get an input, ignore "Escape" */ - if (askfor_aux(tmp, 31)) strcpy(player_name, tmp); - - /* Process the player name */ - process_player_name(FALSE); - - /* All done */ - break; - } - - /* Pad the name (to clear junk) */ - sprintf(tmp, "%-31.31s", player_name); - - /* Re-Draw the name (in light blue) */ - c_put_str(TERM_L_BLUE, tmp, 2, 9); - - /* Erase the prompt, etc */ - clear_from(22); -} - - - -/* - * Hack -- commit suicide - */ -void do_cmd_suicide(void) -{ - int i; - - /* Flush input */ - flush(); - - /* Verify Retirement */ - if (total_winner) - { - /* Verify */ - if (!get_check("Do you want to retire? ")) return; - } - - /* Verify Suicide */ - else - { - /* Verify */ - if (!get_check("Do you really want to quit? ")) return; - - if (!noscore) - { - /* Special Verification for suicide */ - prt("Please verify QUITTING by typing the '@' sign: ", 0, 0); - flush(); - i = inkey(); - prt("", 0, 0); - if (i != '@') return; - } - } - - /* Stop playing */ - alive = FALSE; - - /* Kill the player */ - death = TRUE; - - /* Leaving */ - p_ptr->leaving = TRUE; - - /* Cause of death */ - (void)strcpy(died_from, "Quitting"); -} - - - /* HACK - Remove / set the CAVE_VIEW flag, since view_x / view_y - * is not saved, and the visible locations are not lighted correctly - * when the game is loaded again - * Alternatively forget_view() and update_view() can be used - */ -void remove_cave_view(bool_ remove) -{ - int i; - cave_type *c_ptr; - - if (view_n) - { - /* Clear them all */ - for (i = 0; i < view_n; i++) - { - int y = view_y[i]; - int x = view_x[i]; - - /* Access the grid */ - c_ptr = &cave[y][x]; - - if (remove) - c_ptr->info &= ~(CAVE_VIEW); - else - c_ptr->info |= (CAVE_VIEW); - } - } -} - -/* - * Save the game - */ -void do_cmd_save_game(void) -{ - remove_cave_view(TRUE); - - /* Save the current level if in a persistent level */ - save_dungeon(); - - /* Autosaves do not disturb */ - if (!is_autosave) - { - /* Disturb the player */ - disturb(1); - } - - /* Clear messages */ - msg_print(NULL); - - /* Handle stuff */ - handle_stuff(); - - /* Message */ - prt("Saving game...", 0, 0); - - /* Refresh */ - Term_fresh(); - - /* The player is not dead */ - (void)strcpy(died_from, "(saved)"); - - /* Save the player */ - if (save_player()) - { - prt("Saving game... done.", 0, 0); - } - - /* Save failed (oops) */ - else - { - prt("Saving game... failed!", 0, 0); - } - - remove_cave_view(FALSE); - - /* Refresh */ - Term_fresh(); - - /* Note that the player is not dead */ - (void)strcpy(died_from, "(alive and well)"); -} - -/* - * Auto-save depending on whether the auto save flag is set. - */ -void autosave_checkpoint() -{ - if (autosave_l) - { - is_autosave = TRUE; - msg_print("Autosaving the game..."); - do_cmd_save_game(); - is_autosave = FALSE; - } -} - -/* - * Hack -- Calculates the total number of points earned -JWT- - */ -long total_points(void) -{ - s16b max_dl = 0, i, k; - long temp, Total = 0; - long mult = 20; /* was 100. Divided values by 5 because of an overflow error */ - long comp_death = (p_ptr->companion_killed * 2 / 5); - - if (!comp_death) comp_death = 1; - - if (p_ptr->preserve) mult -= 1; /* Penalize preserve, maximize modes */ - if (p_ptr->maximize) mult -= 1; - if (auto_scum) mult -= 4; - if (small_levels) mult += ((always_small_level) ? 4 : 10); - if (empty_levels) mult += 2; - if (smart_learn) mult += 4; - if (smart_cheat) mult += 4; - - if (mult < 2) mult = 2; /* At least 10% of the original score */ - /* mult is now between 2 and 40, i.e. 10% and 200% */ - - for (i = 0; i < max_d_idx; i++) - if (max_dlv[i] > max_dl) - max_dl = max_dlv[i]; - - temp = p_ptr->lev * p_ptr->lev * p_ptr->lev * p_ptr->lev + (100 * max_dl); - - temp += p_ptr->max_exp / 5; - - temp = (temp * mult / 20); - - /* Gold increases score */ - temp += p_ptr->au / 5; - - /* Completing quest increase score */ - for (i = 0; i < MAX_Q_IDX; i++) - { - if (quest[i].status >= QUEST_STATUS_COMPLETED) - { - temp += 2000; - temp += quest[i].level * 100; - } - } - - /* Death of a companion is BAD */ - temp /= comp_death; - - /* The know objects increase the score */ - /* Scan the object kinds */ - for (k = 1; k < max_k_idx; k++) - { - object_kind *k_ptr = &k_info[k]; - - /* Hack -- skip artifacts */ - if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; - - /* List known flavored objects */ - if (k_ptr->flavor && k_ptr->aware) - { - object_type *i_ptr; - object_type object_type_body; - - /* Get local object */ - i_ptr = &object_type_body; - - /* Create fake object */ - object_prep(i_ptr, k); - - temp += object_value_real(i_ptr); - } - } - - for (k = 1; k < max_r_idx; k++) - { - monster_race *r_ptr = &r_info[k]; - - if (r_ptr->flags1 & (RF1_UNIQUE)) - { - bool_ dead = (r_ptr->max_num == 0); - - if (dead) - { - /* Uniques are supposed to be harder */ - Total += 50; - } - } - else - { - s16b This = r_ptr->r_pkills; - - if (This > 0) - { - Total += This; - } - } - } - temp += Total * 50; - - temp += total_bounties * 100; - - if (total_winner) temp += 1000000; - - - - return (temp); -} - - - -/* - * Centers a string within a 31 character string -JWT- - */ -static void center_string(char *buf, cptr str) -{ - int i, j; - - /* Total length */ - i = strlen(str); - - /* Necessary border */ - j = 15 - i / 2; - - /* Mega-Hack */ - (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, ""); -} - - -/* - * Redefinable "print_tombstone" action - */ -bool_ (*tombstone_aux)(void) = NULL; - - -/* - * Display a "tomb-stone" - */ -static void print_tomb(void) -{ - bool_ done = FALSE; - - /* Do we use a special tombstone ? */ - if (tombstone_aux) - { - /* Use tombstone hook */ - done = (*tombstone_aux)(); - } - - /* Print the text-tombstone */ - if (!done) - { - cptr p; - - char tmp[160]; - - char buf[1024]; - char dummy[80]; - - FILE *fp; - - time_t ct = time((time_t)0); - - - /* Clear screen */ - Term_clear(); - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt"); - - /* Open the News file */ - fp = my_fopen(buf, "r"); - - /* Dump */ - if (fp) - { - int i = 0; - - /* Dump the file to the screen */ - while (0 == my_fgets(fp, buf, 1024)) - { - /* Display and advance */ - display_message(0, i++, strlen(buf), TERM_WHITE, buf); - } - - /* Close */ - my_fclose(fp); - } - - - /* King or Queen */ - if (total_winner || (p_ptr->lev > PY_MAX_LEVEL)) - { - p = "Magnificent"; - } - - /* Normal */ - else - { - p = cp_ptr->titles[(p_ptr->lev - 1) / 5] + c_text; - } - - center_string(buf, player_name); - put_str(buf, 6, 11); - - center_string(buf, "the"); - put_str(buf, 7, 11); - - center_string(buf, p); - put_str(buf, 8, 11); - - - center_string(buf, spp_ptr->title + c_name); - put_str(buf, 10, 11); - - (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev); - center_string(buf, tmp); - put_str(buf, 11, 11); - - (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp); - center_string(buf, tmp); - put_str(buf, 12, 11); - - (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au); - center_string(buf, tmp); - put_str(buf, 13, 11); - - (void)sprintf(tmp, "Killed on Level %d", dun_level); - center_string(buf, tmp); - put_str(buf, 14, 11); - - - if (strlen(died_from) > 24) - { - strncpy(dummy, died_from, 24); - dummy[24] = '\0'; - (void)sprintf(tmp, "by %s.", dummy); - } - else - (void)sprintf(tmp, "by %s.", died_from); - - center_string(buf, tmp); - put_str(buf, 15, 11); - - - (void)sprintf(tmp, "%-.24s", ctime(&ct)); - center_string(buf, tmp); - put_str(buf, 17, 11); - } -} - - -/* - * Display some character info - */ -static void show_info(void) -{ - int i, j, k; - object_type *o_ptr; - store_type *st_ptr; - - /* Hack -- Know everything in the inven/equip */ - for (i = 0; i < INVEN_TOTAL; i++) - { - o_ptr = &p_ptr->inventory[i]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Aware and Known */ - object_aware(o_ptr); - object_known(o_ptr); - } - - for (i = 1; i < max_towns; i++) - { - st_ptr = &town_info[i].store[7]; - - /* Hack -- Know everything in the home */ - for (j = 0; j < st_ptr->stock_num; j++) - { - o_ptr = &st_ptr->stock[j]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Aware and Known */ - object_aware(o_ptr); - object_known(o_ptr); - } - } - - /* Hack -- Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - /* Handle stuff */ - handle_stuff(); - - /* Flush all input keys */ - flush(); - - /* Flush messages */ - msg_print(NULL); - - - /* Describe options */ - prt("You may now dump a character record to one or more files.", 21, 0); - prt("Then, hit RETURN to see the character, or ESC to abort.", 22, 0); - - /* Dump character records as requested */ - while (TRUE) - { - char out_val[160]; - - /* Prompt */ - put_str("Filename(you can post it to http://angband.oook.cz/): ", 23, 0); - - /* Default */ - strcpy(out_val, ""); - - /* Ask for filename (or abort) */ - if (!askfor_aux(out_val, 60)) return; - - /* Return means "show on screen" */ - if (!out_val[0]) break; - - /* Save screen */ - character_icky = TRUE; - Term_save(); - - /* Dump a character file */ - (void)file_character(out_val, TRUE); - - /* Load screen */ - Term_load(); - character_icky = FALSE; - } - - - /* Display player */ - display_player(0); - - /* Prompt for p_ptr->inventory */ - prt("Hit any key to see more information (ESC to abort): ", 23, 0); - - /* Allow abort at this point */ - if (inkey() == ESCAPE) return; - - - /* Show equipment and inventory */ - - /* Equipment -- if any */ - if (equip_cnt) - { - Term_clear(); - item_tester_full = TRUE; - show_equip(); - prt("You are using: -more-", 0, 0); - if (inkey() == ESCAPE) return; - } - - /* Inventory -- if any */ - if (inven_cnt) - { - Term_clear(); - item_tester_full = TRUE; - show_inven(); - prt("You are carrying: -more-", 0, 0); - if (inkey() == ESCAPE) return; - } - - /* Homes in the different towns */ - for (k = 1; k < max_towns; k++) - { - st_ptr = &town_info[k].store[7]; - - /* Home -- if anything there */ - if (st_ptr->stock_num) - { - /* Display contents of the home */ - for (k = 0, i = 0; i < st_ptr->stock_num; k++) - { - /* Clear screen */ - Term_clear(); - - /* Show 12 items */ - for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++) - { - char o_name[80]; - char tmp_val[80]; - - /* Acquire item */ - o_ptr = &st_ptr->stock[i]; - - /* Print header, clear line */ - sprintf(tmp_val, "%c) ", I2A(j)); - prt(tmp_val, j + 2, 4); - - /* Display object description */ - object_desc(o_name, o_ptr, TRUE, 3); - c_put_str(tval_to_attr[o_ptr->tval], o_name, j + 2, 7); - } - - /* h_ptr->caption */ - prt(format("Your home contains (page %d): -more-", k + 1), 0, 0); - - /* Wait for it */ - if (inkey() == ESCAPE) return; - } - } - } -} - - - - - -/* - * Display the scores in a given range. - * Assumes the high score list is already open. - * Only five entries per line, too much info. - * - * Mega-Hack -- allow "fake" entry at the given position. - */ -static void display_scores_aux(int highscore_fd, int from, int to, int note, high_score *score) -{ - int i, j, k, n, place; - byte attr; - char out_val[256]; - char tmp_val[160]; - high_score the_score; - - - /* Paranoia -- it may not have opened */ - if (highscore_fd < 0) return; - - - /* Assume we will show the first 10 */ - if (from < 0) from = 0; - if (to < 0) to = 10; - if (to > MAX_HISCORES) to = MAX_HISCORES; - - - /* Seek to the beginning */ - if (highscore_seek(highscore_fd, 0)) return; - - /* Hack -- Count the high scores */ - for (i = 0; i < MAX_HISCORES; i++) - { - if (highscore_read(highscore_fd, &the_score)) break; - } - - /* Hack -- allow "fake" entry to be last */ - if ((note == i) && score) i++; - - /* Forget about the last entries */ - if (i > to) i = to; - - - /* Show 5 per page, until "done" */ - for (k = from, place = k + 1; k < i; k += 5) - { - /* Clear screen */ - Term_clear(); - - /* Title */ - put_str(format(" %s Hall of Fame", game_module), 0, 0); - - /* Indicate non-top scores */ - if (k > 0) - { - sprintf(tmp_val, "(from position %d)", k + 1); - put_str(tmp_val, 0, 40); - } - - /* Dump 5 entries */ - for (j = k, n = 0; j < i && n < 5; place++, j++, n++) - { - int pcs, pr, ps, pc, clev, mlev, cdun, mdun; - - cptr gold, when, aged; - - int in_arena, in_quest; - - /* Hack -- indicate death in yellow */ - attr = (j == note) ? TERM_YELLOW : TERM_WHITE; - - - /* Mega-Hack -- insert a "fake" record */ - if ((note == j) && score) - { - the_score = (*score); - attr = TERM_L_GREEN; - score = NULL; - note = -1; - j--; - } - - /* Read a normal record */ - else - { - /* Read the proper record */ - if (highscore_seek(highscore_fd, j)) break; - if (highscore_read(highscore_fd, &the_score)) break; - } - - /* Extract the race/class */ - pr = atoi(the_score.p_r); - ps = atoi(the_score.p_s); - pc = atoi(the_score.p_c); - pcs = atoi(the_score.p_cs); - - /* Extract the level info */ - clev = atoi(the_score.cur_lev); - mlev = atoi(the_score.max_lev); - cdun = atoi(the_score.cur_dun); - mdun = atoi(the_score.max_dun); - - in_arena = atoi(the_score.inside_arena); - in_quest = atoi(the_score.inside_quest); - - /* Hack -- extract the gold and such */ - for (when = the_score.day; isspace(*when); when++) /* loop */; - for (gold = the_score.gold; isspace(*gold); gold++) /* loop */; - for (aged = the_score.turns; isspace(*aged); aged++) /* loop */; - - /* Dump some info */ - sprintf(out_val, "%3d.%9s %s the %s %s, Level %d", - place, the_score.pts, the_score.who, - get_player_race_name(pr, ps), class_info[pc].spec[pcs].title + c_name, - clev); - - /* Append a "maximum level" */ - if (mlev > clev) strcat(out_val, format(" (Max %d)", mlev)); - - /* Dump the first line */ - c_put_str(attr, out_val, n*4 + 2, 0); - - /* Another line of info */ - if (in_arena) - { - sprintf(out_val, " Killed by %s in the Arena", - the_score.how); - } - else if (in_quest) - { - sprintf(out_val, " Killed by %s while questing", - the_score.how); - } - /* Hack -- some people die in the town */ - else if (!cdun) - { - sprintf(out_val, " Killed by %s in the Town", - the_score.how); - } - else - { - sprintf(out_val, " Killed by %s on %s %d", - the_score.how, "Dungeon Level", cdun); - } - - /* Append a "maximum level" */ - if (mdun > cdun) strcat(out_val, format(" (Max %d)", mdun)); - - /* Dump the info */ - c_put_str(attr, out_val, n*4 + 3, 0); - - /* And still another line of info */ - sprintf(out_val, - " (Date %s, Gold %s, Turn %s).", - when, gold, aged); - c_put_str(attr, out_val, n*4 + 4, 0); - } - - - /* Wait for response */ - prt("[Press ESC to quit, any other key to continue.]", 23, 17); - j = inkey(); - prt("", 23, 0); - - /* Hack -- notice Escape */ - if (j == ESCAPE) break; - } -} - - -/* - * Hack -- Display the scores in a given range and quit. - * - * This function is only called from "main.c" when the user asks - * to see the "high scores". - */ -void display_scores(int from, int to) -{ - char buf[1024]; - int highscore_fd; - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw"); - - /* Open the binary high score file, for reading */ - highscore_fd = fd_open(buf, O_RDONLY); - - /* Paranoia -- No score file */ - if (highscore_fd < 0) quit("Score file unavailable."); - - /* Clear screen */ - Term_clear(); - - /* Display the scores */ - display_scores_aux(highscore_fd, from, to, -1, NULL); - - /* Shut the high score file */ - fd_close(highscore_fd); - - /* Quit */ - quit(NULL); -} - - -/* - * show_highclass - selectively list highscores based on class - * -KMW- - */ -void show_highclass(int building) -{ - - register int i = 0, j, m = 0; - int pr, pc, clev, al; - high_score the_score; - char buf[1024], out_val[256]; - int highscore_fd; - - switch (building) - { - case 1: - prt(" Busts of Greatest Kings", 5, 0); - break; - case 2: - prt(" Plaque - Greatest Arena Champions", 5, 0); - break; - case 10: - prt(" Plaque - Greatest Fighters", 5, 0); - break; - case 11: - prt(" Spires of the Greatest Magic-Users", 5, 0); - break; - case 12: - prt(" Busts of Greatest Priests", 5, 0); - break; - case 13: - prt(" Wall Inscriptions - Greatest Thieves", 5, 0); - break; - case 14: - prt(" Plaque - Greatest Rangers", 5, 0); - break; - case 15: - prt(" Plaque - Greatest Paladins", 5, 0); - break; - case 16: - prt(" Spires of the Greatest Illusionists", 5, 0); - break; - default: - bell(); - break; - } - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw"); - - /* Open file */ - highscore_fd = fd_open(buf, O_RDONLY); - - if (highscore_fd < 0) - { - msg_print("Score file unavailable."); - msg_print(NULL); - return; - } - - if (highscore_seek(highscore_fd, 0)) return; - - for (i = 0; i < MAX_HISCORES; i++) - if (highscore_read(highscore_fd, &the_score)) break; - - m = 0; - j = 0; - clev = 0; - - while ((m < 9) || (j < MAX_HISCORES)) - { - if (highscore_seek(highscore_fd, j)) break; - if (highscore_read(highscore_fd, &the_score)) break; - pr = atoi(the_score.p_r); - pc = atoi(the_score.p_c); - clev = atoi(the_score.cur_lev); - al = atoi(the_score.arena_number); - if (((pc == (building - 10)) && (building != 1) && (building != 2)) || - ((building == 1) && (clev >= PY_MAX_LEVEL)) || - ((building == 2) && (al > MAX_ARENA_MONS))) - { - sprintf(out_val, "%3d) %s the %s (Level %2d)", - (m + 1), the_score.who, rp_name + race_info[pr].title, clev); - prt(out_val, (m + 7), 0); - m++; - } - j++; - } - - /* Now, list the active player if they qualify */ - if ((building == 1) && (p_ptr->lev >= PY_MAX_LEVEL)) - { - sprintf(out_val, "You) %s the %s (Level %2d)", - player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); - } - else if ((building == 2) && (p_ptr->arena_number > MAX_ARENA_MONS)) - { - sprintf(out_val, "You) %s the %s (Level %2d)", - player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); - } - else if ((building != 1) && (building != 2)) - { - if ((p_ptr->lev > clev) && (p_ptr->pclass == (building - 10))) - { - sprintf(out_val, "You) %s the %s (Level %2d)", - player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); - } - } - - fd_close(highscore_fd); - - msg_print("Hit any key to continue"); - msg_print(NULL); - for (j = 5; j < 18; j++) - prt("", j, 0); -} - - -/* - * Race Legends - * -KMW- - */ -void race_score(int race_num) -{ - register int i = 0, j, m = 0; - int pr, clev, lastlev; - high_score the_score; - char buf[1024], out_val[256], tmp_str[80]; - int highscore_fd; - - lastlev = 0; - - /* rr9: TODO - pluralize the race */ - sprintf(tmp_str, "The Greatest of all the %s", rp_name + race_info[race_num].title); - prt(tmp_str, 5, 3); - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw"); - - /* Open the highscore file */ - highscore_fd = fd_open(buf, O_RDONLY); - - if (highscore_fd < 0) - { - msg_print("Score file unavailable."); - msg_print(NULL); - return; - } - - if (highscore_seek(highscore_fd, 0)) return; - - for (i = 0; i < MAX_HISCORES; i++) - { - if (highscore_read(highscore_fd, &the_score)) break; - } - - m = 0; - j = 0; - - while ((m < 10) && (j < i)) - { - if (highscore_seek(highscore_fd, j)) break; - if (highscore_read(highscore_fd, &the_score)) break; - pr = atoi(the_score.p_r); - clev = atoi(the_score.cur_lev); - if (pr == race_num) - { - sprintf(out_val, "%3d) %s the %s (Level %3d)", - (m + 1), the_score.who, - rp_name + race_info[pr].title, clev); - prt(out_val, (m + 7), 0); - m++; - lastlev = clev; - } - j++; - } - - /* add player if qualified */ - if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev)) - { - sprintf(out_val, "You) %s the %s (Level %3d)", - player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); - } - - fd_close(highscore_fd); -} - - -/* - * Race Legends - * -KMW- - */ -void race_legends(void) -{ - int i, j; - - for (i = 0; i < max_rp_idx; i++) - { - race_score(i); - msg_print("Hit any key to continue"); - msg_print(NULL); - for (j = 5; j < 19; j++) - prt("", j, 0); - } -} - - - - -/* - * Enters a players name on a hi-score table, if "legal", and in any - * case, displays some relevant portion of the high score list. - */ -static errr top_twenty(void) -{ - int j; - - high_score the_score; - - time_t ct = time((time_t*)0); - - char buf[1024]; - - int highscore_fd = 0; - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "scores.raw"); - - /* Open the highscore file, for reading/writing */ - highscore_fd = fd_open(buf, O_RDWR); - - if (highscore_fd < 0) - { - msg_print("Score file unavailable."); - msg_print(NULL); - goto out; - } - - /* Clear screen */ - Term_clear(); - - /* Wizard-mode pre-empts scoring */ - if (noscore & 0x000F) - { - msg_print("Score not registered for wizards."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - - /* Borg-mode pre-empts scoring */ - if (noscore & 0x00F0) - { - msg_print("Score not registered for borgs."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - - /* Cheaters are not scored */ - if (noscore & 0xFF00) - { - msg_print("Score not registered for cheaters."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - - /* Interupted */ - if (!total_winner && streq(died_from, "Interrupting")) - { - msg_print("Score not registered due to interruption."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - - /* Quitter */ - if (!total_winner && streq(died_from, "Quitting")) - { - msg_print("Score not registered due to quitting."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - - - /* Clear the record */ - WIPE(&the_score, high_score); - - /* Save the version */ - sprintf(the_score.what, "%ld.%ld.%ld", - (long int) VERSION_MAJOR, (long int) VERSION_MINOR, (long int) VERSION_PATCH); - - /* Calculate and save the points */ - sprintf(the_score.pts, "%9lu", (long)total_points()); - the_score.pts[9] = '\0'; - - /* Save the current gold */ - sprintf(the_score.gold, "%9lu", (long)p_ptr->au); - the_score.gold[9] = '\0'; - - /* Save the current turn */ - sprintf(the_score.turns, "%9lu", (long)turn - (START_DAY * 10L)); - the_score.turns[9] = '\0'; - - /* Save the date in standard form (8 chars) */ - strftime(the_score.day, 9, "%m/%d/%y", localtime(&ct)); - - /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", player_name); - - /* Save the player info XXX XXX XXX */ - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); - sprintf(the_score.p_r, "%2d", p_ptr->prace); - sprintf(the_score.p_s, "%2d", p_ptr->pracem); - sprintf(the_score.p_c, "%2d", p_ptr->pclass); - sprintf(the_score.p_cs, "%2d", p_ptr->pspec); - - /* Save the level and such */ - sprintf(the_score.cur_lev, "%3d", p_ptr->lev); - sprintf(the_score.cur_dun, "%3d", dun_level); - sprintf(the_score.max_lev, "%3d", p_ptr->max_plv); - sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]); - - sprintf(the_score.arena_number, "%3d", p_ptr->arena_number); /* -KMW- */ - sprintf(the_score.inside_arena, "%3d", p_ptr->inside_arena); - sprintf(the_score.inside_quest, "%3d", p_ptr->inside_quest); - sprintf(the_score.exit_bldg, "%3d", p_ptr->exit_bldg); /* -KMW- */ - - /* Save the cause of death (31 chars) */ - sprintf(the_score.how, "%-.31s", died_from); - - - /* Add a new entry to the score list, see where it went */ - j = highscore_add(highscore_fd, &the_score); - - - /* Hack -- Display the top fifteen scores */ - if (j < 10) - { - display_scores_aux(highscore_fd, 0, 15, j, NULL); - } - - /* Display the scores surrounding the player */ - else - { - display_scores_aux(highscore_fd, 0, 5, j, NULL); - display_scores_aux(highscore_fd, j - 2, j + 7, j, NULL); - } - - -out: - if (highscore_fd >= 0) - { - fd_close(highscore_fd); - } - - /* Success */ - return (0); -} - - -/* - * Predict the players location, and display it. - */ -errr predict_score(void) -{ - int j; - - high_score the_score; - - char buf[1024]; - - int highscore_fd = 0; - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "scores.raw"); - - /* Open the highscore file */ - highscore_fd = fd_open(buf, O_RDONLY); - - if (highscore_fd < 0) - { - msg_print("Score file unavailable."); - msg_print(NULL); - goto out; - } - - /* Clear the record */ - WIPE(&the_score, high_score); - - /* Save the version */ - sprintf(the_score.what, "%ld.%ld.%ld", - (long int) VERSION_MAJOR, (long int) VERSION_MINOR, (long int) VERSION_PATCH); - - /* Calculate and save the points */ - sprintf(the_score.pts, "%9lu", (long)total_points()); - the_score.pts[9] = '\0'; - - /* Save the current gold */ - sprintf(the_score.gold, "%9lu", (long)p_ptr->au); - the_score.gold[9] = '\0'; - - /* Save the current turn */ - sprintf(the_score.turns, "%9lu", (long)turn - (START_DAY * 10L)); - the_score.turns[9] = '\0'; - - /* Hack -- no time needed */ - strcpy(the_score.day, "TODAY"); - - /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", player_name); - - /* Save the player info XXX XXX XXX */ - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); - sprintf(the_score.p_r, "%2d", p_ptr->prace); - sprintf(the_score.p_s, "%2d", p_ptr->pracem); - sprintf(the_score.p_c, "%2d", p_ptr->pclass); - sprintf(the_score.p_cs, "%2d", p_ptr->pspec); - - /* Save the level and such */ - sprintf(the_score.cur_lev, "%3d", p_ptr->lev); - sprintf(the_score.cur_dun, "%3d", dun_level); - sprintf(the_score.max_lev, "%3d", p_ptr->max_plv); - sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]); - - sprintf(the_score.arena_number, "%3d", p_ptr->arena_number); /* -KMW- */ - sprintf(the_score.inside_arena, "%3d", p_ptr->inside_arena); - sprintf(the_score.inside_quest, "%3d", p_ptr->inside_quest); - sprintf(the_score.exit_bldg, "%3d", p_ptr->exit_bldg); /* -KMW- */ - - /* Hack -- no cause of death */ - strcpy(the_score.how, "nobody (yet!)"); - - - /* See where the entry would be placed */ - j = highscore_where(highscore_fd, &the_score); - - - /* Hack -- Display the top fifteen scores */ - if (j < 10) - { - display_scores_aux(highscore_fd, 0, 15, j, &the_score); - } - - /* Display some "useful" scores */ - else - { - display_scores_aux(highscore_fd, 0, 5, -1, NULL); - display_scores_aux(highscore_fd, j - 2, j + 7, j, &the_score); - } - -out: - if (highscore_fd >= 0) - { - fd_close(highscore_fd); - } - - /* Success */ - return (0); -} - - -void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p) -{ - char buf[1024]; - int highscore_fd; - - /* Paranoia */ - if (!(*initialized_p) || character_icky || - !(*game_in_progress_p) || !character_generated) - { - /* Can't happen but just in case */ - plog("You may not do that right now."); - return; - } - - /* Build the pathname of the score file */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "scores.raw"); - - /* Hack - open the score file for reading */ - highscore_fd = fd_open(buf, O_RDONLY); - - /* Paranoia - No score file */ - if (highscore_fd < 0) - { - msg_print("Score file is not available."); - return; - } - - /* Mega-Hack - prevent various functions XXX XXX XXX */ - *initialized_p = FALSE; - - /* Save screen */ - screen_save(); - - /* Clear screen */ - Term_clear(); - - /* Prepare scores */ - if ((*game_in_progress_p) && character_generated) - { - predict_score(); - } - - /* Close the high score file */ - (void)fd_close(highscore_fd); - - /* Forget the fd */ - highscore_fd = -1; - - /* Restore screen */ - screen_load(); - - /* Hack - Flush it */ - Term_fresh(); - - /* Mega-Hack - We are ready again */ - *initialized_p = TRUE; -} - - -/* - * Change the player into a King! -RAK- - */ -static void kingly(void) -{ - /* Hack -- retire in town */ - dun_level = 0; - - /* Fake death */ - (void)strcpy(died_from, "Ripe Old Age"); - - /* Restore the experience */ - p_ptr->exp = p_ptr->max_exp; - - /* Restore the level */ - p_ptr->lev = p_ptr->max_plv; - - /* Hack -- Instant Gold */ - p_ptr->au += 10000000L; - - /* Clear screen */ - Term_clear(); - - /* Would like to see something more Tolkienian here... */ - - /* Display a crown */ - put_str("#", 1, 34); - put_str("#####", 2, 32); - put_str("#", 3, 34); - put_str(",,, $$$ ,,,", 4, 28); - put_str(",,=$ \"$$$$$\" $=,,", 5, 24); - put_str(",$$ $$$ $$,", 6, 22); - put_str("*> <*> <*", 7, 22); - put_str("$$ $$$ $$", 8, 22); - put_str("\"$$ $$$ $$\"", 9, 22); - put_str("\"$$ $$$ $$\"", 10, 23); - put_str("*#########*#########*", 11, 24); - put_str("*#########*#########*", 12, 24); - - /* Display a message */ - put_str("Veni, Vidi, Vici!", 15, 26); - put_str("I came, I saw, I conquered!", 16, 21); - put_str(format("All Hail the Mighty %s!", sp_ptr->winner), 17, 22); - - /* Flush input */ - flush(); - - /* Wait for response */ - pause_line(23); -} - - -/* - * Wipe the saved levels - */ -void wipe_saved() -{ - int d, l, od = dungeon_type, ol = dun_level; - - for (d = 0; d < max_d_idx; d++) - { - dungeon_info_type *d_ptr = &d_info[d]; - - for (l = d_ptr->mindepth; l <= d_ptr->maxdepth; l++) - { - char buf[10]; - - dun_level = l; - dungeon_type = d; - if (get_dungeon_save(buf)) - { - char tmp[80], name[1024]; - - sprintf(tmp, "%s.%s", player_base, buf); - path_build(name, 1024, ANGBAND_DIR_SAVE, tmp); - - /* Remove the dungeon save file */ - fd_kill(name); - } - } - } - - dungeon_type = od; - dun_level = ol; -} - - -/* - * Close up the current game (player may or may not be dead) - * - * This function is called only from "main.c" and "signals.c". - */ -void close_game(void) -{ - /* Handle stuff */ - handle_stuff(); - - /* Flush the messages */ - msg_print(NULL); - - /* Flush the input */ - flush(); - - - /* Hack -- Character is now "icky" */ - character_icky = TRUE; - - - /* Handle death */ - if (death) - { - /* Handle retirement */ - if (total_winner) - { - /* Make a note */ - add_note_type(NOTE_WINNER); - - kingly(); - } - - /* Wipe the saved levels */ - wipe_saved(); - - /* Save memories */ - if (!save_player()) msg_print("Death save failed!"); - - /* You are dead */ - print_tomb(); - - /* Show more info */ - show_info(); - - /* Make a note */ - { - char long_day[30]; - char buf[80]; - time_t ct = time((time_t*)NULL); - - /* Get the date */ - strftime(long_day, 30, - "%Y-%m-%d at %H:%M:%S", localtime(&ct)); - - /* Create string */ - sprintf(buf, "\n%s was killed by %s on %s\n", player_name, - died_from, long_day); - - /* Output to the notes file */ - output_note(buf); - } - - /* Handle score, show Top scores */ - top_twenty(); - } - - /* Still alive */ - else - { - is_autosave = FALSE; - - /* Save the game */ - do_cmd_save_game(); - - /* Make a note pf session end */ - add_note_type(NOTE_SAVE_GAME); - - /* Prompt for scores XXX XXX XXX */ - prt("Press Return (or Escape).", 0, 40); - - /* Predict score (or ESCAPE) */ - if (inkey() != ESCAPE) predict_score(); - } -} - - -/* - * Grab a randomly selected line in lib/file/file_name - */ -errr get_rnd_line(const char *file_name, char *output) -{ - FILE *fp; - - char buf[1024]; - - int lines = 0; - - int line; - - int i; - - - /* Clear the output buffer */ - strcpy(output, ""); - - /* test hack */ - if (wizard && cheat_xtra) msg_print(file_name); - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_FILE, file_name); - - /* Open the file */ - fp = my_fopen(buf, "r"); - - /* Failed */ - if (!fp) return ( -1); - - /* Read the first line */ - if (0 != my_fgets(fp, buf, 80)) - { - my_fclose(fp); - return ( -1); - } - - /* Retrieve number of valid lines in the file */ - lines = atoi(buf); - - /* Pick a line in the file */ - line = randint(lines); - - /* - * Scan through the file XXX XXX XXX - * Seemingly wrong use of the counter is justified by the - * stupid 'buffer' lines in the random text files. - */ - for (i = 0; i <= line; i++) - { - if (0 != my_fgets(fp, buf, 80)) - { - my_fclose(fp); - return ( -1); - } - - /* Found the line */ - if (i == line) break; - } - - /* Copy the line to the output buffer */ - strcpy(output, buf); - - /* Close the file */ - my_fclose(fp); - - /* Success */ - return (0); -} - - -/* - * Read line'th line file the file - * and return pointer to it, or NULL if it fails. - * - * Nuked the static buffer. Caller should provide one. -- pelpel - * - * Caution: 'linbuf' should be at least 80 byte long. - */ -char *get_line(const char* fname, cptr fdir, char *linbuf, int line) -{ - FILE* fp; - int i; - char buf[1024]; - - - /* Don't count the first line in the file, which is a comment line */ - line++; - - /* Build the filename */ - path_build(buf, 1024, fdir, fname); - - /* Open the file */ - fp = my_fopen(buf, "r"); - - /* Failed */ - if (!fp) return (NULL); - - /* Read past specified number of lines */ - for (i = 0; i <= line; i++) - { - /* Oops */ - if (my_fgets(fp, linbuf, 80) != 0) - { - my_fclose(fp); - return (NULL); - } - } - - my_fclose(fp); - - return (linbuf); -} - - -/* - * Return a line for a speaking unique, by Matt G. - * - * XXX XXX XXX Opening a file and scanning it through whenever a unique - * tries to say something? Something like DELAY_LOAD_?_TEXT would be - * much better -- pelpel - * - * XXX XXX XXX I must say the original is an extremely poor and unreliable - * implementation... I removed noxious flag -- I'm too stupid to - * understand such complexities -- and added extra error checkings - * and made sure fd is always closed -- pelpel - */ -errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output) -{ - FILE *fp; - char buf[1024]; - int line; - int num_entries; - int i; - int mnum; - - - /* Clear the message buffer */ - strcpy(output, ""); - - /* test and DEBUG hack */ - if (wizard && cheat_xtra) - { - msg_print(file_name); - } - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_FILE, file_name); - - /* Open the file */ - fp = my_fopen(buf, "r"); - - /* Failed */ - if (!fp) return ( -1); - - /* Monster number we are looking for */ - mnum = m_ptr->r_idx; - - /* Find matching N: line */ - while (1) - { - int n; - - /* Read a line */ - if (my_fgets(fp, buf, 90) != 0) - { - my_fclose(fp); - return ( -1); - } - - /* Not a N: line */ - if (buf[0] != 'N') continue; - - /* Skip "N:" and parse off a number */ - sscanf(buf + 2, "%d", &n); - - /* Match found */ - if (n == mnum) break; - } - - /* Retrieve number of normal messages */ - while (1) - { - /* Read next line */ - if (my_fgets(fp, buf, 90) != 0) - { - my_fclose(fp); - return ( -1); - } - - /* The first line not beginning with 'N:' holds number of lines */ - if (buf[0] != 'N') - { - num_entries = atoi(buf); - break; - } - } - - /* The monster is afraid */ - if (m_ptr->monfear) - { - /* Read past normal lines */ - for (line = 0; line < num_entries + 1; line++) - { - if (my_fgets(fp, buf, 90)) - { - my_fclose(fp); - return ( -1); - } - } - - /* Retrieve number of 'afraid' lines */ - num_entries = atoi(buf); - } - - - /* Pick a random line */ - line = rand_int(num_entries); - - /* test and DEBUG hack */ - if (wizard && cheat_xtra) - { - sprintf(buf, "Line number %d", line); - msg_print(buf); - } - - /* Find the selected line */ - for (i = 0; i <= line; i++) - { - /* Oops */ - if (0 != my_fgets(fp, buf, 90)) - { - my_fclose(fp); - return ( -1); - } - - /* Found it */ - if (i == line) break; - } - - /* Copy it to the output buffer */ - strcpy(output, buf); - - /* Close the file */ - my_fclose(fp); - - /* Success */ - return (0); -} |