X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Finit1.c;h=bfcdb7d740c4c9e7d47320f4492945d655402998;hb=f5b18fb048044ca364e009f49fecf44fd7231f28;hp=d70503d5f4fb160510702950ea59946261a91ee8;hpb=732b4d08c407ba107071a24f6231c005aa37c64b;p=hengband%2Fhengband.git diff --git a/src/init1.c b/src/init1.c index d70503d5f..bfcdb7d74 100644 --- a/src/init1.c +++ b/src/init1.c @@ -1,29 +1,18 @@ /* File: init1.c */ +/* + * Copyright (c) 1997 Ben Harrison + * + * 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. Other copyrights may also apply. + */ + /* Purpose: Initialization (part 1) -BEN- */ #include "angband.h" -#ifdef JP -#undef strchr -char* _strchr(char* ptr, char ch) -{ - int k_flag = 0; - - for ( ; *ptr != '\0'; ++ptr) - if (k_flag == 0) { - if (*ptr == ch) - return ptr; - if (iskanji(*ptr)) - k_flag = 1; - } else - k_flag = 0; - - return NULL; -} -#define strchr _strchr -#endif /* * This file is used to initialize various variables and arrays for the * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass @@ -53,9 +42,10 @@ char* _strchr(char* ptr, char ch) * of the platforms that we currently support. */ - #ifdef ALLOW_TEMPLATES +#include "init.h" + /*** Helper arrays for parsing ascii template files ***/ @@ -89,6 +79,7 @@ static cptr r_info_blow_method[] = "INSULT", "MOAN", "SHOW", + "SHOOT", NULL }; @@ -137,6 +128,130 @@ static cptr r_info_blow_effect[] = /* + * Feature info flags + */ +static cptr f_info_flags[] = +{ + "LOS", + "PROJECT", + "MOVE", + "PLACE", + "DROP", + "SECRET", + "NOTICE", + "REMEMBER", + "OPEN", + "CLOSE", + "BASH", + "SPIKE", + "DISARM", + "STORE", + "TUNNEL", + "MAY_HAVE_GOLD", + "HAS_GOLD", + "HAS_ITEM", + "DOOR", + "TRAP", + "STAIRS", + "GLYPH", + "LESS", + "MORE", + "AVOID_RUN", + "FLOOR", + "WALL", + "PERMANENT", + "XXX00", + "XXX01", + "XXX02", + "HIT_TRAP", + + "BRIDGE", + "RIVER", + "LAKE", + "BRIDGED", + "COVERED", + "GLOW", + "ENSECRET", + "WATER", + "LAVA", + "SHALLOW", + "DEEP", + "FILLED", + "HURT_ROCK", + "HURT_FIRE", + "HURT_COLD", + "HURT_ACID", + "ICE", + "ACID", + "OIL", + "XXX04", + "CAN_CLIMB", + "CAN_FLY", + "CAN_SWIM", + "CAN_PASS", + "CAN_OOZE", + "CAN_DIG", + "HIDE_ITEM", + "HIDE_SNEAK", + "HIDE_SWIM", + "HIDE_DIG", + "KILL_HUGE", + "KILL_MOVE", + + "PICK_TRAP", + "PICK_DOOR", + "ALLOC", + "CHEST", + "DROP_1D2", + "DROP_2D2", + "DROP_GOOD", + "DROP_GREAT", + "HURT_POIS", + "HURT_ELEC", + "HURT_WATER", + "HURT_BWATER", + "USE_FEAT", + "GET_FEAT", + "GROUND", + "OUTSIDE", + "EASY_HIDE", + "EASY_CLIMB", + "MUST_CLIMB", + "TREE", + "NEED_TREE", + "BLOOD", + "DUST", + "SLIME", + "PLANT", + "XXX2", + "INSTANT", + "EXPLODE", + "TIMED", + "ERUPT", + "STRIKE", + "SPREAD", + + "SPECIAL", + "HURT_DISI", + "QUEST_ENTER", + "QUEST_EXIT", + "QUEST", + "SHAFT", + "MOUNTAIN", + "BLDG", + "MINOR_GLYPH", + "PATTERN", + "TOWN", + "ENTRANCE", + "MIRROR", + "UNPERM", + "TELEPORTABLE", + "CONVERT", + "GLASS", +}; + + +/* * Monster race flags */ static cptr r_info_flags1[] = @@ -146,14 +261,14 @@ static cptr r_info_flags1[] = "MALE", "FEMALE", "CHAR_CLEAR", - "CHAR_MULTI", + "SHAPECHANGER", "ATTR_CLEAR", "ATTR_MULTI", "FORCE_DEPTH", "FORCE_MAXHP", "FORCE_SLEEP", "FORCE_EXTRA", - "FRIEND", + "ATTR_SEMIRAND", "FRIENDS", "ESCORT", "ESCORTS", @@ -171,8 +286,8 @@ static cptr r_info_flags1[] = "DROP_4D2", "DROP_GOOD", "DROP_GREAT", - "DROP_USEFUL", - "DROP_CHOSEN" + "XXX2", + "XXX3" }; /* @@ -190,7 +305,7 @@ static cptr r_info_flags2[] = "WEIRD_MIND", "MULTIPLY", "REGENERATE", - "SHAPECHANGER", + "CHAR_MULTI", "ATTR_ANY", "POWERFUL", "ELDRITCH_HORROR", @@ -204,13 +319,13 @@ static cptr r_info_flags2[] = "KILL_BODY", "TAKE_ITEM", "KILL_ITEM", - "BRAIN_1", - "BRAIN_2", - "BRAIN_3", - "BRAIN_4", - "BRAIN_5", - "BRAIN_6", - "BRAIN_7", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "HUMAN", "QUANTUM" }; @@ -235,18 +350,18 @@ static cptr r_info_flags3[] = "HURT_ROCK", "HURT_FIRE", "HURT_COLD", - "IM_ACID", - "IM_ELEC", - "IM_FIRE", - "IM_COLD", - "IM_POIS", - "RES_TELE", - "RES_NETH", - "RES_WATE", - "RES_PLAS", - "RES_NEXU", - "RES_DISE", - "RES_ALL", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", "NO_FEAR", "NO_STUN", "NO_CONF", @@ -262,10 +377,10 @@ static cptr r_info_flags4[] = "XXX1", "DISPEL", "ROCKET", - "ARROW_1", - "ARROW_2", - "ARROW_3", - "ARROW_4", + "SHOOT", + "XXX2", + "XXX3", + "XXX4", "BR_ACID", "BR_ELEC", "BR_FIRE", @@ -380,7 +495,7 @@ static cptr r_info_flags7[] = "CAN_SWIM", "CAN_FLY", "FRIENDLY", - "UNIQUE_7", + "NAZGUL", "UNIQUE2", "RIDING", "KAGE", @@ -391,11 +506,11 @@ static cptr r_info_flags7[] = "GUARDIAN", "CHAMELEON", "KILL_EXP", - "XXX7X15", - "XXX7X16", - "XXX7X17", - "XXX7X18", - "XXX7X19", + "TANUKI", + "HAS_DARK_1", + "SELF_DARK_1", + "HAS_DARK_2", + "SELF_DARK_2", "XXX7X20", "XXX7X21", "XXX7X22", @@ -446,7 +561,7 @@ static cptr r_info_flags8[] = "XXX8X28", "XXX8X29", "WILD_SWAMP", /* ToDo: Implement Swamp */ - "WILD_TOO", + "WILD_ALL", }; @@ -492,9 +607,49 @@ static cptr r_info_flags9[] = /* + * Monster race flags - Resistances + */ +static cptr r_info_flagsr[] = +{ + "IM_ACID", + "IM_ELEC", + "IM_FIRE", + "IM_COLD", + "IM_POIS", + "RES_LITE", + "RES_DARK", + "RES_NETH", + "RES_WATE", + "RES_PLAS", + "RES_SHAR", + "RES_SOUN", + "RES_CHAO", + "RES_NEXU", + "RES_DISE", + "RES_WALL", + "RES_INER", + "RES_TIME", + "RES_GRAV", + "RES_ALL", + "RES_TELE", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", +}; + + +/* * Object flags */ -static cptr k_info_flags1[] = +static cptr k_info_flags[] = { "STR", "INT", @@ -503,7 +658,7 @@ static cptr k_info_flags1[] = "CON", "CHR", "MAGIC_MASTERY", - "FORCE_WEPON", + "FORCE_WEAPON", "STEALTH", "SEARCH", "INFRA", @@ -527,14 +682,8 @@ static cptr k_info_flags1[] = "BRAND_ACID", "BRAND_ELEC", "BRAND_FIRE", - "BRAND_COLD" -}; + "BRAND_COLD", -/* - * Object flags - */ -static cptr k_info_flags2[] = -{ "SUST_STR", "SUST_INT", "SUST_WIS", @@ -542,7 +691,7 @@ static cptr k_info_flags2[] = "SUST_CON", "SUST_CHR", "RIDING", - "XXX2", + "EASY_SPELL", "IM_ACID", "IM_ELEC", "IM_FIRE", @@ -566,27 +715,21 @@ static cptr k_info_flags2[] = "RES_NETHER", "RES_NEXUS", "RES_CHAOS", - "RES_DISEN" -}; + "RES_DISEN", -/* - * Object flags - */ -static cptr k_info_flags3[] = -{ "SH_FIRE", "SH_ELEC", - "QUESTITEM", + "SLAY_HUMAN", "SH_COLD", "NO_TELE", "NO_MAGIC", "DEC_MANA", "TY_CURSE", - "XXX1", + "WARNING", "HIDE_TYPE", "SHOW_MODS", - "INSTA_ART", - "FEATHER", + "XXX1", + "LEVITATION", "LITE", "SEE_INVIS", "TELEPATHY", @@ -603,9 +746,69 @@ static cptr k_info_flags3[] = "TELEPORT", "AGGRAVATE", "BLESSED", + "XXX3", + "XXX4", + "XXX5", + + "KILL_ANIMAL", + "KILL_EVIL", + "KILL_UNDEAD", + "KILL_DEMON", + "KILL_ORC", + "KILL_TROLL", + "KILL_GIANT", + "KILL_HUMAN", + "ESP_ANIMAL", + "ESP_UNDEAD", + "ESP_DEMON", + "ESP_ORC", + "ESP_TROLL", + "ESP_GIANT", + "ESP_DRAGON", + "ESP_HUMAN", + "ESP_EVIL", + "ESP_GOOD", + "ESP_NONLIVING", + "ESP_UNIQUE", + "FULL_NAME", + "FIXED_FLAVOR", +}; + + +static cptr k_info_gen_flags[] = +{ + "INSTA_ART", + "QUESTITEM", + "XTRA_POWER", + "ONE_SUSTAIN", + "XTRA_RES_OR_POWER", + "XTRA_H_RES", + "XTRA_E_RES", + "XTRA_L_RES", + "XTRA_D_RES", + "XTRA_RES", "CURSED", "HEAVY_CURSE", - "PERMA_CURSE" + "PERMA_CURSE", + "RANDOM_CURSE0", + "RANDOM_CURSE1", + "RANDOM_CURSE2", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", + "XXX", }; @@ -614,46 +817,175 @@ static cptr k_info_flags3[] = */ static cptr d_info_flags1[] = { - "WINNER", - "MAZE", - "SMALLEST", - "BEGINNER", - "BIG", - "NO_DOORS", - "WATER_RIVER", - "LAVA_RIVER", - "WATER_RIVERS", - "LAVA_RIVERS", - "CAVE", - "CAVERN", - "NO_UP", - "HOT", - "COLD", - "NO_DOWN", - "FORGET", - "LAKE_WATER", - "LAKE_LAVA", - "LAKE_RUBBLE", - "LAKE_TREE", - "NO_VAULT", - "ARENA", - "DESTROY", - "XXX1", - "NO_CAVE", - "NO_MAGIC", - "NO_MELEE", - "CHAMELEON", - "DARKNESS", - "XXX1", - "XXX1" + "WINNER", + "MAZE", + "SMALLEST", + "BEGINNER", + "BIG", + "NO_DOORS", + "WATER_RIVER", + "LAVA_RIVER", + "CURTAIN", + "GLASS_DOOR", + "CAVE", + "CAVERN", + "XXX", + "XXX", + "XXX", + "XXX", + "FORGET", + "LAKE_WATER", + "LAKE_LAVA", + "LAKE_RUBBLE", + "LAKE_TREE", + "NO_VAULT", + "ARENA", + "DESTROY", + "GLASS_ROOM", + "NO_CAVE", + "NO_MAGIC", + "NO_MELEE", + "CHAMELEON", + "DARKNESS", + "XXX", + "XXX" }; /* + * Add a text to the text-storage and store offset to it. + * + * Returns FALSE when there isn't enough space available to store + * the text. + */ +static bool add_text(u32b *offset, header *head, cptr buf, bool normal_text) +{ + /* Hack -- Verify space */ + if (head->text_size + strlen(buf) + 8 > FAKE_TEXT_SIZE) + return (FALSE); + + /* New text? */ + if (*offset == 0) + { + /* Advance and save the text index */ + *offset = ++head->text_size; + } + + /* Additional text */ + else if (normal_text) + { + /* + * If neither the end of the last line nor + * the beginning of current line is not a space, + * fill up a space as a correct separator of two words. + */ + if (head->text_size > 0 && +#ifdef JP + (*(head->text_ptr + head->text_size - 1) != ' ') && + ((head->text_size == 1) || !iskanji(*(head->text_ptr + head->text_size - 2))) && + (buf[0] != ' ') && !iskanji(buf[0]) +#else + (*(head->text_ptr + head->text_size - 1) != ' ') && + (buf[0] != ' ') +#endif + ) + { + /* Append a space */ + *(head->text_ptr + head->text_size) = ' '; + + /* Advance the index */ + head->text_size++; + } + } + + /* Append chars to the text */ + strcpy(head->text_ptr + head->text_size, buf); + + /* Advance the index */ + head->text_size += strlen(buf); + + /* Success */ + return (TRUE); +} + + +/* + * Add a name to the name-storage and return an offset to it. + * + * Returns FALSE when there isn't enough space available to store + * the name. + */ +static bool add_name(u32b *offset, header *head, cptr buf) +{ + /* Hack -- Verify space */ + if (head->name_size + strlen(buf) + 8 > FAKE_NAME_SIZE) + return (FALSE); + + /* New name? */ + if (*offset == 0) + { + /* Advance and save the name index */ + *offset = ++head->name_size; + } + + /* Append chars to the names */ + strcpy(head->name_ptr + head->name_size, buf); + + /* Advance the index */ + head->name_size += strlen(buf); + + /* Success */ + return (TRUE); +} + + +/* + * Add a tag to the tag-storage and return an offset to it. + * + * Returns FALSE when there isn't enough space available to store + * the name. + */ +static bool add_tag(s16b *offset, header *head, cptr buf) +{ + u32b i; + + /* Search for an existing (fake) tag */ + for (i = 1; i < head->tag_size; i += strlen(&head->tag_ptr[i]) + 1) + { + /* Found it */ + if (streq(&head->tag_ptr[i], buf)) break; + } + + /* There was no existing tag */ + if (i >= head->tag_size) + { + /* Hack -- Verify space */ + if (head->tag_size + strlen(buf) + 8 > FAKE_TAG_SIZE) + return FALSE; + + /* Append chars to the tags */ + strcpy(head->tag_ptr + head->tag_size, buf); + + /* Point the new tag */ + i = head->tag_size; + + /* Advance the index */ + head->tag_size += strlen(buf) + 1; + } + + /* Return offset of the tag */ + *offset = (s16b)i; + + /* Success */ + return TRUE; +} + + +/* * Convert a "color letter" into an "actual" color * The colors are: dwsorgbuDWvyRGBU, as shown below */ -static int color_char_to_attr(char c) +byte color_char_to_attr(char c) { switch (c) { @@ -676,7 +1008,7 @@ static int color_char_to_attr(char c) case 'U': return (TERM_L_UMBER); } - return (-1); + return (255); } @@ -685,28 +1017,24 @@ static int color_char_to_attr(char c) /* - * Initialize the "v_info" array, by parsing an ascii "template" file + * Initialize an "*_info" array, by parsing an ascii "template" file */ -errr init_v_info_txt(FILE *fp, char *buf, bool start) +errr init_info_txt(FILE *fp, char *buf, header *head, + parse_info_txt_func parse_info_txt_line) { - int i; - char *s; + errr err; - /* Current entry */ - vault_type *v_ptr = NULL; + /* Just before the first record */ + error_idx = -1; - if (start) - { - /* Just before the first record */ - error_idx = -1; + /* Just before the first line */ + error_line = 0; - /* Just before the first line */ - error_line = -1; - /* Prepare the "fake" stuff */ - v_head->name_size = 0; - v_head->text_size = 0; - } + /* Prepare the "fake" stuff */ + head->name_size = 0; + head->text_size = 0; + head->tag_size = 0; /* Parse */ while (0 == my_fgets(fp, buf, 1024)) @@ -716,10 +1044,9 @@ errr init_v_info_txt(FILE *fp, char *buf, bool start) /* Skip comments and blank lines */ if (!buf[0] || (buf[0] == '#')) continue; - if ((buf[0] == 'Q') || (buf[0] == 'T')) continue; /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); + if (buf[1] != ':') return (PARSE_ERROR_GENERIC); /* Hack -- Process 'V' for "Version" */ @@ -729,111 +1056,108 @@ errr init_v_info_txt(FILE *fp, char *buf, bool start) continue; } - - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') + /* Mega Hack -- Calculate Check Sum */ + if (buf[0] != 'N' && buf[0] != 'D') { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); - - /* Verify that colon */ - if (!s) return (1); - - /* Nuke the colon, advance to the name */ - *s++ = '\0'; - - /* Paranoia -- require a name */ - if (!*s) return (1); - - /* Get the index */ - i = atoi(buf+2); - - /* Verify information */ - if (i <= error_idx) return (4); - - /* Verify information */ - if (i >= v_head->info_num) return (2); - - /* Save the index */ - error_idx = i; + int i; + for (i = 0; buf[i]; i++) + { + head->v_extra += (byte)buf[i]; + head->v_extra ^= (1 << (i % 8)); + } + } - /* Point at the "info" */ - v_ptr = &v_info[i]; + /* Parse the line */ + if ((err = (*parse_info_txt_line)(buf, head)) != 0) + return (err); + } - /* Hack -- Verify space */ - if (v_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - /* Advance and Save the name index */ - if (!v_ptr->name) v_ptr->name = ++v_head->name_size; + /* Complete the "name" and "text" sizes */ + if (head->name_size) head->name_size++; + if (head->text_size) head->text_size++; - /* Append chars to the name */ - strcpy(v_name + v_head->name_size, s); + /* Success */ + return (0); +} - /* Advance the index */ - v_head->name_size += strlen(s); - /* Next... */ - continue; - } +/* + * Initialize the "v_info" array, by parsing an ascii "template" file + */ +errr parse_v_info(char *buf, header *head) +{ + int i; + char *s; - /* There better be a current v_ptr */ - if (!v_ptr) return (3); + /* Current entry */ + static vault_type *v_ptr = NULL; - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { - /* Acquire the text */ - s = buf+2; + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') + { + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); - /* Hack -- Verify space */ - if (v_head->text_size + strlen(s) + 8 > fake_text_size) return (7); + /* Verify that colon */ + if (!s) return (1); - /* Advance and Save the text index */ - if (!v_ptr->text) v_ptr->text = ++v_head->text_size; + /* Nuke the colon, advance to the name */ + *s++ = '\0'; - /* Append chars to the name */ - strcpy(v_text + v_head->text_size, s); + /* Paranoia -- require a name */ + if (!*s) return (1); - /* Advance the index */ - v_head->text_size += strlen(s); + /* Get the index */ + i = atoi(buf+2); - /* Next... */ - continue; - } + /* Verify information */ + if (i <= error_idx) return (4); + /* Verify information */ + if (i >= head->info_num) return (2); - /* Process 'X' for "Extra info" (one line only) */ - if (buf[0] == 'X') - { - int typ, rat, hgt, wid; + /* Save the index */ + error_idx = i; - /* Scan for the values */ - if (4 != sscanf(buf+2, "%d:%d:%d:%d", - &typ, &rat, &hgt, &wid)) return (1); + /* Point at the "info" */ + v_ptr = &v_info[i]; - /* Save the values */ - v_ptr->typ = typ; - v_ptr->rat = rat; - v_ptr->hgt = hgt; - v_ptr->wid = wid; + /* Store the name */ + if (!add_name(&v_ptr->name, head, s)) return (7); + } - /* Next... */ - continue; - } + /* There better be a current v_ptr */ + else if (!v_ptr) return (3); + /* Process 'D' for "Description" */ + else if (buf[0] == 'D') + { + /* Acquire the text */ + s = buf+2; - /* Oops */ - return (6); + /* Store the text */ + if (!add_text(&v_ptr->text, head, s, FALSE)) return (7); } - - /* Complete the "name" and "text" sizes */ - if (!start) + /* Process 'X' for "Extra info" (one line only) */ + else if (buf[0] == 'X') { - ++v_head->name_size; - ++v_head->text_size; + int typ, rat, hgt, wid; + + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%d", + &typ, &rat, &hgt, &wid)) return (1); + + /* Save the values */ + v_ptr->typ = typ; + v_ptr->rat = rat; + v_ptr->hgt = hgt; + v_ptr->wid = wid; } + /* Oops */ + else return (6); /* Success */ return (0); @@ -842,237 +1166,208 @@ errr init_v_info_txt(FILE *fp, char *buf, bool start) /* - * Initialize the "f_info" array, by parsing an ascii "template" file + * Initialize the "s_info" array, by parsing an ascii "template" file */ -errr init_f_info_txt(FILE *fp, char *buf) +errr parse_s_info(char *buf, header *head) { int i; - char *s; - /* Current entry */ - feature_type *f_ptr = NULL; - - - /* Just before the first record */ - error_idx = -1; - - /* Just before the first line */ - error_line = -1; + static skill_table *s_ptr = NULL; - /* Prepare the "fake" stuff */ - f_head->name_size = 0; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - f_head->E_name_size = 0; -#endif - f_head->text_size = 0; - - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') { - /* Advance the line number */ - error_line++; + /* Get the index */ + i = atoi(buf+2); - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; + /* Verify information */ + if (i <= error_idx) return (4); - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); + /* Verify information */ + if (i >= head->info_num) return (2); + /* Save the index */ + error_idx = i; - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') - { - /* ignore */ - continue; - } + /* Point at the "info" */ + s_ptr = &s_info[i]; + } + /* There better be a current s_ptr */ + else if (!s_ptr) return (3); - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') + /* Process 'W' for "Weapon exp" */ + else if (buf[0] == 'W') + { + int tval, sval, start, max; + const s16b exp_conv_table[] = { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + WEAPON_EXP_UNSKILLED, WEAPON_EXP_BEGINNER, WEAPON_EXP_SKILLED, + WEAPON_EXP_EXPERT, WEAPON_EXP_MASTER + }; - /* Verify that colon */ - if (!s) return (1); + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%d", + &tval, &sval, &start, &max)) return (1); - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + if (start < EXP_LEVEL_UNSKILLED || start > EXP_LEVEL_MASTER + || max < EXP_LEVEL_UNSKILLED || max > EXP_LEVEL_MASTER) return (8); -#ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); -#endif + /* Save the values */ + s_ptr->w_start[tval][sval] = exp_conv_table[start]; + s_ptr->w_max[tval][sval] = exp_conv_table[max]; + } - /* Get the index */ - i = atoi(buf+2); + /* Process 'S' for "Skill exp" */ + else if (buf[0] == 'S') + { + int num, start, max; - /* Verify information */ - if (i <= error_idx) return (4); + /* Scan for the values */ + if (3 != sscanf(buf+2, "%d:%d:%d", + &num, &start, &max)) return (1); - /* Verify information */ - if (i >= f_head->info_num) return (2); + if (start < WEAPON_EXP_UNSKILLED || start > WEAPON_EXP_MASTER + || max < WEAPON_EXP_UNSKILLED || max > WEAPON_EXP_MASTER) return (8); - /* Save the index */ - error_idx = i; + /* Save the values */ + s_ptr->s_start[num] = start; + s_ptr->s_max[num] = max; + } - /* Point at the "info" */ - f_ptr = &f_info[i]; -#ifdef JP - /* Hack -- Verify space */ - if (f_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!f_ptr->name) f_ptr->name = ++f_head->name_size; - - /* Append chars to the name */ - strcpy(f_name + f_head->name_size, s); - - /* Advance the index */ - f_head->name_size += strlen(s); -#endif - /* Default "mimic" */ - f_ptr->mimic = i; - - /* Next... */ - continue; - } - - /* There better be a current f_ptr */ - if (!f_ptr) return (3); - -#ifdef JP - /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ - /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */ - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (f_head->E_name_size + strlen(s) + 8 > E_fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!f_ptr->E_name) f_ptr->E_name = ++f_head->E_name_size; + /* Oops */ + else return (6); - /* Append chars to the name */ - strcpy(E_f_name+ f_head->E_name_size, s); + /* Success */ + return (0); +} - /* Advance the index */ - f_head->E_name_size += strlen(s); - /* Next... */ - continue; - } -#else - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; +/* + * Initialize the "m_info" array, by parsing an ascii "template" file + */ +errr parse_m_info(char *buf, header *head) +{ + int i; - /* Hack -- Verify space */ - if (f_head->name_size + strlen(s) + 8 > fake_name_size) return (7); + char *s; - /* Advance and Save the name index */ - if (!f_ptr->name) f_ptr->name = ++f_head->name_size; + /* Current entry */ + static player_magic *m_ptr = NULL; - /* Append chars to the name */ - strcpy(f_name+ f_head->name_size, s); + /* ---Hack--- */ + static int realm, magic_idx = 0, readable = 0; - /* Advance the index */ - f_head->name_size += strlen(s); - /* Next... */ - continue; - } -#endif + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') + { + /* Get the index */ + i = atoi(buf+2); -#if 0 + /* Verify information */ + if (i <= error_idx) return (4); - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { - /* Acquire the text */ - s = buf+2; + /* Verify information */ + if (i >= head->info_num) return (2); - /* Hack -- Verify space */ - if (f_head->text_size + strlen(s) + 8 > fake_text_size) return (7); + /* Save the index */ + error_idx = i; - /* Advance and Save the text index */ - if (!f_ptr->text) f_ptr->text = ++f_head->text_size; + /* Point at the "info" */ + m_ptr = &m_info[i]; + } - /* Append chars to the name */ - strcpy(f_text + f_head->text_size, s); + /* There better be a current m_ptr */ + else if (!m_ptr) return (3); - /* Advance the index */ - f_head->text_size += strlen(s); + /* Process 'I' for "Info" (one line only) */ + else if (buf[0] == 'I') + { + char *book, *stat; + int xtra, type, first, weight; - /* Next... */ - continue; - } + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); -#endif + /* Verify that colon */ + if (!s) return (1); + /* Nuke the colon, advance to the name */ + *s++ = '\0'; - /* Process 'M' for "Mimic" (one line only) */ - if (buf[0] == 'M') - { - int mimic; + book = buf+2; - /* Scan for the values */ - if (1 != sscanf(buf+2, "%d", - &mimic)) return (1); + if (streq(book, "SORCERY")) m_ptr->spell_book = TV_SORCERY_BOOK; + else if (streq(book, "LIFE")) m_ptr->spell_book = TV_LIFE_BOOK; + else if (streq(book, "MUSIC")) m_ptr->spell_book = TV_MUSIC_BOOK; + else if (streq(book, "HISSATSU")) m_ptr->spell_book = TV_HISSATSU_BOOK; + else if (streq(book, "NONE")) m_ptr->spell_book = 0; + else return (5); - /* Save the values */ - f_ptr->mimic = mimic; + stat = s; - /* Next... */ - continue; - } + /* Find the colon before the name */ + s = my_strchr(s, ':'); + /* Verify that colon */ + if (!s) return (1); - /* Process 'G' for "Graphics" (one line only) */ - if (buf[0] == 'G') - { - int tmp; + /* Nuke the colon, advance to the name */ + *s++ = '\0'; - /* Paranoia */ - if (!buf[2]) return (1); - if (!buf[3]) return (1); - if (!buf[4]) return (1); + if (streq(stat, "STR")) m_ptr->spell_stat = A_STR; + else if (streq(stat, "INT")) m_ptr->spell_stat = A_INT; + else if (streq(stat, "WIS")) m_ptr->spell_stat = A_WIS; + else if (streq(stat, "DEX")) m_ptr->spell_stat = A_DEX; + else if (streq(stat, "CON")) m_ptr->spell_stat = A_CON; + else if (streq(stat, "CHR")) m_ptr->spell_stat = A_CHR; + else return (5); - /* Extract the color */ - tmp = color_char_to_attr(buf[4]); - /* Paranoia */ - if (tmp < 0) return (1); + /* Scan for the values */ + if (4 != sscanf(s, "%x:%d:%d:%d", + (uint *)&xtra, &type, &first, &weight)) return (1); - /* Save the values */ - f_ptr->d_attr = tmp; - f_ptr->d_char = buf[2]; + m_ptr->spell_xtra = xtra; + m_ptr->spell_type = type; + m_ptr->spell_first = first; + m_ptr->spell_weight = weight; + } - /* Next... */ - continue; - } + /* Process 'R' for "Realm" (one line only) */ + else if (buf[0] == 'R') + { + /* Scan for the values */ + if (2 != sscanf(buf+2, "%d:%d", + &realm, &readable)) return (1); - /* Oops */ - return (6); + magic_idx = 0; } + else if (buf[0] == 'T') + { + int level, mana, fail, exp; + + if (!readable) return (1); + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%d", + &level, &mana, &fail, &exp)) return (1); + + m_ptr->info[realm][magic_idx].slevel = level; + m_ptr->info[realm][magic_idx].smana = mana; + m_ptr->info[realm][magic_idx].sfail = fail; + m_ptr->info[realm][magic_idx].sexp = exp; + magic_idx ++; + } - /* Complete the "name" and "text" sizes */ - ++f_head->name_size; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - ++f_head->E_name_size; -#endif - ++f_head->text_size; + /* Oops */ + else return (6); /* Success */ return (0); @@ -1080,724 +1375,942 @@ errr init_f_info_txt(FILE *fp, char *buf) /* - * Grab one flag in an object_kind from a textual string + * Grab one flag from a textual string */ -static errr grab_one_kind_flag(object_kind *k_ptr, cptr what) +static errr grab_one_flag(u32b *flags, cptr names[], cptr what) { int i; - /* Check flags1 */ + /* Check flags */ for (i = 0; i < 32; i++) { - if (streq(what, k_info_flags1[i])) + if (streq(what, names[i])) { - k_ptr->flags1 |= (1L << i); - return (0); + *flags |= (1L << i); + return 0; } } - /* Check flags2 */ - for (i = 0; i < 32; i++) + return -1; +} + + +/* + * Grab one flag in an feature_type from a textual string + */ +static errr grab_one_feat_flag(feature_type *f_ptr, cptr what) +{ + int i; + + /* Check flags */ + for (i = 0; i < FF_FLAG_MAX; i++) { - if (streq(what, k_info_flags2[i])) + if (streq(what, f_info_flags[i])) { - k_ptr->flags2 |= (1L << i); - return (0); + add_flag(f_ptr->flags, i); + return 0; } } - /* Check flags3 */ - for (i = 0; i < 32; i++) + /* Oops */ +#ifdef JP + msg_format("̤ÃΤÎÃÏ·Á¥Õ¥é¥° '%s'¡£", what); +#else + msg_format("Unknown feature flag '%s'.", what); +#endif + + /* Error */ + return PARSE_ERROR_GENERIC; +} + + +/* + * Grab an action in an feature_type from a textual string + */ +static errr grab_one_feat_action(feature_type *f_ptr, cptr what, int count) +{ + int i; + + /* Check flags */ + for (i = 0; i < FF_FLAG_MAX; i++) { - if (streq(what, k_info_flags3[i])) + if (streq(what, f_info_flags[i])) { - k_ptr->flags3 |= (1L << i); - return (0); + f_ptr->state[count].action = i; + return 0; } } /* Oops */ #ifdef JP - msg_format("̤ÃΤΥ¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what); + msg_format("̤ÃΤÎÃÏ·Á¥¢¥¯¥·¥ç¥ó '%s'¡£", what); #else - msg_format("Unknown object flag '%s'.", what); + msg_format("Unknown feature action '%s'.", what); #endif - /* Error */ - return (1); + return PARSE_ERROR_GENERIC; } /* - * Initialize the "k_info" array, by parsing an ascii "template" file + * Initialize the "f_info" array, by parsing an ascii "template" file */ -errr init_k_info_txt(FILE *fp, char *buf) +errr parse_f_info(char *buf, header *head) { int i; char *s, *t; /* Current entry */ - object_kind *k_ptr = NULL; + static feature_type *f_ptr = NULL; - /* Just before the first record */ - error_idx = -1; - - /* Just before the first line */ - error_line = -1; + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') + { + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); + if (s) + { + /* Nuke the colon, advance to the name */ + *s++ = '\0'; + } - /* Prepare the "fake" stuff */ - k_head->name_size = 0; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - k_head->E_name_size = 0; -#endif - k_head->text_size = 0; + /* Get the index */ + i = atoi(buf+2); - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) - { - /* Advance the line number */ - error_line++; + /* Verify information */ + if (i <= error_idx) return (4); - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; + /* Verify information */ + if (i >= head->info_num) return (2); - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); + /* Save the index */ + error_idx = i; + /* Point at the "info" */ + f_ptr = &f_info[i]; - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') + /* Tag name is given */ + if (s) { - /* ignore */ - continue; + /* Store the tag */ + if (!add_tag(&f_ptr->tag, head, s)) return (7); } + /* Default "mimic" */ + f_ptr->mimic = i; - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') - { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + /* Default "destroyed state" -- if not specified */ + f_ptr->destroyed = i; - /* Verify that colon */ - if (!s) return (1); + /* Default "states" */ + for (i = 0; i < MAX_FEAT_STATES; i++) f_ptr->state[i].action = FF_FLAG_MAX; + } - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* There better be a current f_ptr */ + else if (!f_ptr) return (3); #ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); -#endif - /* Get the index */ - i = atoi(buf+2); + else if (buf[0] == 'J') + { + /* Store the name */ + if (!add_name(&f_ptr->name, head, buf+2)) return (7); + } - /* Verify information */ - if (i <= error_idx) return (4); + else if (buf[0] == 'E') + { + /* Ignore english name */ + } +#else + else if (buf[0] == 'J') + { + /* Ignore Japanese name */ + } - /* Verify information */ - if (i >= k_head->info_num) return (2); + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Save the index */ - error_idx = i; + /* Store the name */ + if (!add_name(&f_ptr->name, head, s)) return (7); + } +#endif - /* Point at the "info" */ - k_ptr = &k_info[i]; -#ifdef JP - /* Hack -- Verify space */ - if (k_head->name_size + strlen(s) + 8 > fake_name_size) - { - fake_name_size += 1000; + /* Process 'M' for "Mimic" (one line only) */ + else if (buf[0] == 'M') + { + s16b offset; - /* Reallocate the extra memory */ - k_info = realloc(k_name, fake_name_size); - } + if (!add_tag(&offset, head, buf + 2)) return PARSE_ERROR_OUT_OF_MEMORY; - /* Advance and Save the name index */ - if (!k_ptr->name) k_ptr->name = ++k_head->name_size; + /* Record a fake tag index */ + f_ptr->mimic = -offset; + } - /* Append chars to the name */ - strcpy(k_name + k_head->name_size, s); - /* Advance the index */ - k_head->name_size += strlen(s); -#endif - /* Next... */ - continue; - } + /* Process 'G' for "Graphics" (one line only) */ + else if (buf[0] == 'G') + { + int j; + byte s_attr; + char char_tmp[F_LIT_MAX]; - /* There better be a current k_ptr */ - if (!k_ptr) return (3); + /* Paranoia */ + if (buf[1] != ':') return (1); + if (!buf[2]) return (1); + if (buf[3] != ':') return (1); + if (!buf[4]) return (1); + /* Extract the char */ + char_tmp[F_LIT_STANDARD] = buf[2]; -#ifdef JP - /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ - /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */ - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; + /* Extract the color */ + s_attr = color_char_to_attr(buf[4]); - /* Hack -- Verify space */ - if (k_head->E_name_size + strlen(s) + 8 > E_fake_name_size) return (7); + /* Paranoia */ + if (s_attr > 127) return (1); - /* Advance and Save the name index */ - if (!k_ptr->E_name) k_ptr->E_name = ++k_head->E_name_size; + /* Save the standard values */ + f_ptr->d_attr[F_LIT_STANDARD] = s_attr; + f_ptr->d_char[F_LIT_STANDARD] = char_tmp[F_LIT_STANDARD]; - /* Append chars to the name */ - strcpy(E_k_name+ k_head->E_name_size, s); + /* Is this feature supports lighting? */ + if (buf[5] == ':') + { + /* G:c:a:LIT (default) */ + apply_default_feat_lighting(f_ptr->d_attr, f_ptr->d_char); - /* Advance the index */ - k_head->E_name_size += strlen(s); + /* G:c:a:lc:la:dc:da */ + if (!streq(buf + 6, "LIT")) + { + char attr_lite_tmp[F_LIT_MAX - F_LIT_NS_BEGIN]; - /* Next... */ - continue; + if ((F_LIT_MAX - F_LIT_NS_BEGIN) * 2 != sscanf(buf + 6, "%c:%c:%c:%c", + &char_tmp[F_LIT_LITE], &attr_lite_tmp[F_LIT_LITE - F_LIT_NS_BEGIN], + &char_tmp[F_LIT_DARK], &attr_lite_tmp[F_LIT_DARK - F_LIT_NS_BEGIN])) return 1; + if (buf[F_LIT_MAX * 4 + 1]) return 1; + + for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++) + { + switch (attr_lite_tmp[j - F_LIT_NS_BEGIN]) + { + case '*': + /* Use default lighting */ + break; + case '-': + /* No lighting support */ + f_ptr->d_attr[j] = f_ptr->d_attr[F_LIT_STANDARD]; + break; + default: + /* Extract the color */ + f_ptr->d_attr[j] = color_char_to_attr(attr_lite_tmp[j - F_LIT_NS_BEGIN]); + if (f_ptr->d_attr[j] > 127) return 1; + break; + } + f_ptr->d_char[j] = char_tmp[j]; + } + } } -#else - if (buf[0] == 'E') + else if (!buf[5]) { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (k_head->name_size + strlen(s) + 8 > fake_name_size) return (7); + for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++) + { + f_ptr->d_attr[j] = s_attr; + f_ptr->d_char[j] = char_tmp[F_LIT_STANDARD]; + } + } + else return 1; + } - /* Advance and Save the name index */ - if (!k_ptr->name) k_ptr->name = ++k_head->name_size; + /* Hack -- Process 'F' for flags */ + else if (buf[0] == 'F') + { + /* Parse every entry textually */ + for (s = buf + 2; *s; ) + { + /* Find the end of this entry */ + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - /* Append chars to the name */ - strcpy(k_name+ k_head->name_size, s); + /* Nuke and skip any dividers */ + if (*t) + { + *t++ = '\0'; + while (*t == ' ' || *t == '|') t++; + } - /* Advance the index */ - k_head->name_size += strlen(s); + /* XXX XXX XXX Hack -- Read feature subtype */ + if (1 == sscanf(s, "SUBTYPE_%d", &i)) + { + /* Extract a "subtype" */ + f_ptr->subtype = i; - /* Next... */ - continue; - } -#endif -#if 0 + /* Start at next entry */ + s = t; - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { - /* Acquire the text */ - s = buf+2; + /* Continue */ + continue; + } - /* Hack -- Verify space */ - if (k_head->text_size + strlen(s) + 8 > fake_text_size) return (7); + /* XXX XXX XXX Hack -- Read feature power */ + if (1 == sscanf(s, "POWER_%d", &i)) + { + /* Extract a "power" */ + f_ptr->power = i; - /* Advance and Save the text index */ - if (!k_ptr->text) k_ptr->text = ++k_head->text_size; + /* Start at next entry */ + s = t; - /* Append chars to the name */ - strcpy(k_text + k_head->text_size, s); + /* Continue */ + continue; + } - /* Advance the index */ - k_head->text_size += strlen(s); + /* Parse this entry */ + if (0 != grab_one_feat_flag(f_ptr, s)) return (PARSE_ERROR_INVALID_FLAG); - /* Next... */ - continue; + /* Start the next entry */ + s = t; } + } -#endif + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int priority; + /* Scan for the value */ + if (1 != sscanf(buf+2, "%d", &priority)) return (PARSE_ERROR_GENERIC); - /* Process 'G' for "Graphics" (one line only) */ - if (buf[0] == 'G') - { - char sym; - int tmp; + /* Save the value */ + f_ptr->priority = priority; + } - /* Paranoia */ - if (!buf[2]) return (1); - if (!buf[3]) return (1); - if (!buf[4]) return (1); + /* Process 'K' for "States" (up to four lines + default (which cannot be last)) */ + else if (buf[0] == 'K') + { + s16b offset; - /* Extract the char */ - sym = buf[2]; + /* Find the next empty state slot (if any) */ + for (i = 0; i < MAX_FEAT_STATES; i++) if (f_ptr->state[i].action == FF_FLAG_MAX) break; - /* Extract the attr */ - tmp = color_char_to_attr(buf[4]); + /* Oops, no more slots */ + if (i == MAX_FEAT_STATES) return PARSE_ERROR_GENERIC; - /* Paranoia */ - if (tmp < 0) return (1); + /* Analyze the first field */ + for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */; - /* Save the values */ - k_ptr->d_attr = tmp; - k_ptr->d_char = sym; + /* Terminate the field (if necessary) */ + if (*t == ':') *t++ = '\0'; - /* Next... */ - continue; - } + /* Is this default entry? */ + if (streq(s, "DESTROYED")) + { + if (!add_tag(&offset, head, t)) return PARSE_ERROR_OUT_OF_MEMORY; - /* Process 'I' for "Info" (one line only) */ - if (buf[0] == 'I') + /* Record a fake tag index */ + f_ptr->destroyed = -offset; + } + else { - int tval, sval, pval; + /* Reset */ + f_ptr->state[i].action = 0; - /* Scan for the values */ - if (3 != sscanf(buf+2, "%d:%d:%d", - &tval, &sval, &pval)) return (1); + /* Parse this entry */ + if (0 != grab_one_feat_action(f_ptr, s, i)) return PARSE_ERROR_INVALID_FLAG; - /* Save the values */ - k_ptr->tval = tval; - k_ptr->sval = sval; - k_ptr->pval = pval; + if (!add_tag(&offset, head, t)) return PARSE_ERROR_OUT_OF_MEMORY; - /* Next... */ - continue; + /* Record a fake tag index */ + f_ptr->state[i].result = -offset; } + } - /* Process 'W' for "More Info" (one line only) */ - if (buf[0] == 'W') - { - int level, extra, wgt; - long cost; + /* Oops */ + else return (6); - /* Scan for the values */ - if (4 != sscanf(buf+2, "%d:%d:%d:%ld", - &level, &extra, &wgt, &cost)) return (1); + /* Success */ + return (0); +} - /* Save the values */ - k_ptr->level = level; - k_ptr->extra = extra; - k_ptr->weight = wgt; - k_ptr->cost = cost; - /* Next... */ - continue; - } +/* + * Convert a fake tag to a real feat index + */ +s16b f_tag_to_index(cptr str) +{ + u16b i; - /* Process 'A' for "Allocation" (one line only) */ - if (buf[0] == 'A') + /* Search for real index corresponding to this fake tag */ + for (i = 0; i < f_head.info_num; i++) + { + if (streq(f_tag + f_info[i].tag, str)) { - int i; - - /* XXX XXX XXX Simply read each number following a colon */ - for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i) - { - /* Default chance */ - k_ptr->chance[i] = 1; - - /* Store the attack damage index */ - k_ptr->locale[i] = atoi(s+1); + /* Return the index */ + return (s16b)i; + } + } - /* Find the slash */ - t = strchr(s+1, '/'); + /* Not found */ + return -1; +} - /* Find the next colon */ - s = strchr(s+1, ':'); - /* If the slash is "nearby", use it */ - if (t && (!s || t < s)) - { - int chance = atoi(t+1); - if (chance > 0) k_ptr->chance[i] = chance; - } - } +/* + * Search for real index corresponding to this fake tag + */ +static void search_real_feat(s16b *feat) +{ + int i; - /* Next... */ - continue; - } + /* Don't convert non-fake tag */ + if (*feat >= 0) return; - /* Hack -- Process 'P' for "power" and such */ - if (buf[0] == 'P') + /* Search for real index corresponding to this fake tag */ + for (i = 0; i < f_head.info_num; i++) + { + if ((-(*feat)) == f_info[i].tag) { - int ac, hd1, hd2, th, td, ta; + /* Record real index */ + *feat = (s16b)i; + return; + } + } - /* Scan for the values */ - if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", - &ac, &hd1, &hd2, &th, &td, &ta)) return (1); + /* Undefined tag */ +#ifdef JP + msg_format("̤ÄêµÁ¤Î¥¿¥° '%s'¡£", f_tag + (-(*feat))); +#else + msg_format("%s is undefined.", f_tag + (-(*feat))); +#endif +} - k_ptr->ac = ac; - k_ptr->dd = hd1; - k_ptr->ds = hd2; - k_ptr->to_h = th; - k_ptr->to_d = td; - k_ptr->to_a = ta; - /* Next... */ - continue; - } +/* + * Retouch fake tags of f_info + */ +void retouch_f_info(header *head) +{ + int i; - /* Hack -- Process 'F' for flags */ - if (buf[0] == 'F') - { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + /* Convert fake tags to real feat indices */ + for (i = 0; i < head->info_num; i++) + { + feature_type *f_ptr = &f_info[i]; + int j; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + search_real_feat(&f_ptr->mimic); - /* Parse this entry */ - if (0 != grab_one_kind_flag(k_ptr, s)) return (5); + search_real_feat(&f_ptr->destroyed); - /* Start the next entry */ - s = t; - } + for (j = 0; j < MAX_FEAT_STATES; j++) search_real_feat(&f_ptr->state[j].result); + } +} - /* Next... */ - continue; - } +/* + * Grab one flag in an object_kind from a textual string + */ +static errr grab_one_kind_flag(object_kind *k_ptr, cptr what) +{ + int i; - /* Oops */ - return (6); + /* Check flags */ + for (i = 0; i < TR_FLAG_MAX; i++) + { + if (streq(what, k_info_flags[i])) + { + add_flag(k_ptr->flags, i); + return (0); + } } + if (grab_one_flag(&k_ptr->gen_flags, k_info_gen_flags, what) == 0) + return 0; - /* Complete the "name" and "text" sizes */ - ++k_head->name_size; + /* Oops */ #ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - ++k_head->E_name_size; + msg_format("̤ÃΤΥ¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what); +#else + msg_format("Unknown object flag '%s'.", what); #endif - ++k_head->text_size; - /* Success */ - return (0); + /* Error */ + return (1); } /* - * Grab one flag in an artifact_type from a textual string + * Initialize the "k_info" array, by parsing an ascii "template" file */ -static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what) +errr parse_k_info(char *buf, header *head) { int i; - /* Check flags1 */ - for (i = 0; i < 32; i++) + char *s, *t; + + /* Current entry */ + static object_kind *k_ptr = NULL; + + + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') { - if (streq(what, k_info_flags1[i])) +#ifdef JP + char *flavor; +#endif + + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); + + /* Verify that colon */ + if (!s) return (1); + + /* Nuke the colon, advance to the name */ + *s++ = '\0'; + + /* Get the index */ + i = atoi(buf+2); + + /* Verify information */ + if (i <= error_idx) return (4); + + /* Verify information */ + if (i >= head->info_num) return (2); + + /* Save the index */ + error_idx = i; + + /* Point at the "info" */ + k_ptr = &k_info[i]; + +#ifdef JP + /* Paranoia -- require a name */ + if (!*s) return (1); + + /* Find the colon before the flavor */ + flavor = my_strchr(s, ':'); + + /* Verify that colon */ + if (flavor) { - a_ptr->flags1 |= (1L << i); - return (0); + /* Nuke the colon, advance to the flavor */ + *flavor++ = '\0'; + + /* Store the flavor */ + if (!add_name(&k_ptr->flavor_name, head, flavor)) return (7); } + + /* Store the name */ + if (!add_name(&k_ptr->name, head, s)) return (7); +#endif } - /* Check flags2 */ - for (i = 0; i < 32; i++) + /* There better be a current k_ptr */ + else if (!k_ptr) return (3); + + +#ifdef JP + /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ + /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */ + else if (buf[0] == 'E') { - if (streq(what, k_info_flags2[i])) - { - a_ptr->flags2 |= (1L << i); - return (0); - } + /* nothing to do */ } - - /* Check flags3 */ - for (i = 0; i < 32; i++) +#else + else if (buf[0] == 'E') { - if (streq(what, k_info_flags3[i])) + char *flavor; + + /* Acquire the name */ + s = buf+2; + + /* Find the colon before the flavor */ + flavor = my_strchr(s, ':'); + + /* Verify that colon */ + if (flavor) { - a_ptr->flags3 |= (1L << i); - return (0); + /* Nuke the colon, advance to the flavor */ + *flavor++ = '\0'; + + /* Store the flavor */ + if (!add_name(&k_ptr->flavor_name, head, flavor)) return (7); } + + /* Store the name */ + if (!add_name(&k_ptr->name, head, s)) return (7); } +#endif - /* Oops */ + /* Process 'D' for "Description" */ + else if (buf[0] == 'D') + { #ifdef JP - msg_format("̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what); + if (buf[2] == '$') + return (0); + /* Acquire the text */ + s = buf+2; #else - msg_format("Unknown artifact flag '%s'.", what); + if (buf[2] != '$') + return (0); + /* Acquire the text */ + s = buf+3; #endif + /* Store the text */ + if (!add_text(&k_ptr->text, head, s, TRUE)) return (7); + } - /* Error */ - return (1); -} + /* Process 'G' for "Graphics" (one line only) */ + else if (buf[0] == 'G') + { + char sym; + byte tmp; + /* Paranoia */ + if (buf[1] != ':') return (1); + if (!buf[2]) return (1); + if (buf[3] != ':') return (1); + if (!buf[4]) return (1); + /* Extract the char */ + sym = buf[2]; + /* Extract the attr */ + tmp = color_char_to_attr(buf[4]); -/* - * Initialize the "a_info" array, by parsing an ascii "template" file - */ -errr init_a_info_txt(FILE *fp, char *buf) -{ - int i; + /* Paranoia */ + if (tmp > 127) return (1); - char *s, *t; + /* Save the values */ + k_ptr->d_attr = tmp; + k_ptr->d_char = sym; + } - /* Current entry */ - artifact_type *a_ptr = NULL; + /* Process 'I' for "Info" (one line only) */ + else if (buf[0] == 'I') + { + int tval, sval, pval; + /* Scan for the values */ + if (3 != sscanf(buf+2, "%d:%d:%d", + &tval, &sval, &pval)) return (1); - /* Just before the first record */ - error_idx = -1; + /* Save the values */ + k_ptr->tval = tval; + k_ptr->sval = sval; + k_ptr->pval = pval; + } - /* Just before the first line */ - error_line = -1; + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int level, extra, wgt; + long cost; + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%ld", + &level, &extra, &wgt, &cost)) return (1); - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) + /* Save the values */ + k_ptr->level = level; + k_ptr->extra = extra; + k_ptr->weight = wgt; + k_ptr->cost = cost; + } + + /* Process 'A' for "Allocation" (one line only) */ + else if (buf[0] == 'A') { - /* Advance the line number */ - error_line++; + int i; - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; + /* XXX XXX XXX Simply read each number following a colon */ + for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i) + { + /* Default chance */ + k_ptr->chance[i] = 1; - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); + /* Store the attack damage index */ + k_ptr->locale[i] = atoi(s+1); + /* Find the slash */ + t = my_strchr(s+1, '/'); - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') + /* Find the next colon */ + s = my_strchr(s+1, ':'); + + /* If the slash is "nearby", use it */ + if (t && (!s || t < s)) + { + int chance = atoi(t+1); + if (chance > 0) k_ptr->chance[i] = chance; + } + } + } + + /* Hack -- Process 'P' for "power" and such */ + else if (buf[0] == 'P') + { + int ac, hd1, hd2, th, td, ta; + + /* Scan for the values */ + if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", + &ac, &hd1, &hd2, &th, &td, &ta)) return (1); + + k_ptr->ac = ac; + k_ptr->dd = hd1; + k_ptr->ds = hd2; + k_ptr->to_h = th; + k_ptr->to_d = td; + k_ptr->to_a = ta; + } + + /* Hack -- Process 'F' for flags */ + else if (buf[0] == 'F') + { + /* Parse every entry textually */ + for (s = buf + 2; *s; ) { - /* ignore */ - continue; + /* Find the end of this entry */ + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + + /* Nuke and skip any dividers */ + if (*t) + { + *t++ = '\0'; + while (*t == ' ' || *t == '|') t++; + } + + /* Parse this entry */ + if (0 != grab_one_kind_flag(k_ptr, s)) return (5); + + /* Start the next entry */ + s = t; } + } - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') + /* Oops */ + else return (6); + + + /* Success */ + return (0); +} + + +/* + * Grab one flag in an artifact_type from a textual string + */ +static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what) +{ + int i; + + /* Check flags */ + for (i = 0; i < TR_FLAG_MAX; i++) + { + if (streq(what, k_info_flags[i])) { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + add_flag(a_ptr->flags, i); + return (0); + } + } - /* Verify that colon */ - if (!s) return (1); + if (grab_one_flag(&a_ptr->gen_flags, k_info_gen_flags, what) == 0) + return 0; - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* Oops */ #ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); + msg_format("̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what); +#else + msg_format("Unknown artifact flag '%s'.", what); #endif - /* Get the index */ - i = atoi(buf+2); - /* Verify information */ - if (i < error_idx) return (4); - /* Verify information */ - if (i >= a_head->info_num) return (2); + /* Error */ + return (1); +} + - /* Save the index */ - error_idx = i; - /* Point at the "info" */ - a_ptr = &a_info[i]; - /* Ignore everything */ - a_ptr->flags3 |= (TR3_IGNORE_ACID); - a_ptr->flags3 |= (TR3_IGNORE_ELEC); - a_ptr->flags3 |= (TR3_IGNORE_FIRE); - a_ptr->flags3 |= (TR3_IGNORE_COLD); -#ifdef JP - /* Hack -- Verify space */ - if (a_head->name_size + strlen(s) + 8 > fake_name_size) return (7); +/* + * Initialize the "a_info" array, by parsing an ascii "template" file + */ +errr parse_a_info(char *buf, header *head) +{ + int i; - /* Advance and Save the name index */ - if (!a_ptr->name) a_ptr->name = ++a_head->name_size; + char *s, *t; - /* Append chars to the name */ - strcpy(a_name + a_head->name_size, s); + /* Current entry */ + static artifact_type *a_ptr = NULL; - /* Advance the index */ - a_head->name_size += strlen(s); -#endif - /* Next... */ - continue; - } - /* There better be a current a_ptr */ - if (!a_ptr) return (3); + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') + { + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); + /* Verify that colon */ + if (!s) return (1); + /* Nuke the colon, advance to the name */ + *s++ = '\0'; #ifdef JP - /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ - /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */ - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (a_head->E_name_size + strlen(s) + 8 > E_fake_name_size) return (7); + /* Paranoia -- require a name */ + if (!*s) return (1); +#endif + /* Get the index */ + i = atoi(buf+2); - /* Advance and Save the name index */ - if (!a_ptr->E_name) a_ptr->E_name = ++a_head->E_name_size; + /* Verify information */ + if (i < error_idx) return (4); - /* Append chars to the name */ - strcpy(E_a_name+ a_head->E_name_size, s); + /* Verify information */ + if (i >= head->info_num) return (2); - /* Advance the index */ - a_head->E_name_size += strlen(s); + /* Save the index */ + error_idx = i; - /* Next... */ - continue; - } -#else - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; + /* Point at the "info" */ + a_ptr = &a_info[i]; - /* Hack -- Verify space */ - if (a_head->name_size + strlen(s) + 8 > fake_name_size) return (7); + /* Ignore everything */ + add_flag(a_ptr->flags, TR_IGNORE_ACID); + add_flag(a_ptr->flags, TR_IGNORE_ELEC); + add_flag(a_ptr->flags, TR_IGNORE_FIRE); + add_flag(a_ptr->flags, TR_IGNORE_COLD); +#ifdef JP + /* Store the name */ + if (!add_name(&a_ptr->name, head, s)) return (7); +#endif + } - /* Advance and Save the name index */ - if (!a_ptr->name) a_ptr->name = ++a_head->name_size; + /* There better be a current a_ptr */ + else if (!a_ptr) return (3); - /* Append chars to the name */ - strcpy(a_name+ a_head->name_size, s); - /* Advance the index */ - a_head->name_size += strlen(s); +#ifdef JP + /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ + /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */ + else if (buf[0] == 'E') + { + /* nothing to do */ + } +#else + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the name */ + if (!add_name(&a_ptr->name, head, s)) return (7); + } #endif - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { + /* Process 'D' for "Description" */ + else if (buf[0] == 'D') + { #ifdef JP - if (buf[2] == '$') - continue; - /* Acquire the text */ - s = buf+2; + if (buf[2] == '$') + return (0); + /* Acquire the text */ + s = buf+2; #else - if (buf[2] != '$') - continue; - /* Acquire the text */ - s = buf+3; + if (buf[2] != '$') + return (0); + /* Acquire the text */ + s = buf+3; #endif - /* Hack -- Verify space */ - if (a_head->text_size + strlen(s) + 8 > fake_text_size) return (7); - - /* Advance and Save the text index */ - if (!a_ptr->text) a_ptr->text = ++a_head->text_size; - - /* Append chars to the name */ - strcpy(a_text + a_head->text_size, s); - - /* Advance the index */ - a_head->text_size += strlen(s); - - /* Next... */ - continue; - } + /* Store the text */ + if (!add_text(&a_ptr->text, head, s, TRUE)) return (7); + } - /* Process 'I' for "Info" (one line only) */ - if (buf[0] == 'I') - { - int tval, sval, pval; + /* Process 'I' for "Info" (one line only) */ + else if (buf[0] == 'I') + { + int tval, sval, pval; - /* Scan for the values */ - if (3 != sscanf(buf+2, "%d:%d:%d", + /* Scan for the values */ + if (3 != sscanf(buf+2, "%d:%d:%d", &tval, &sval, &pval)) return (1); - /* Save the values */ - a_ptr->tval = tval; - a_ptr->sval = sval; - a_ptr->pval = pval; - - /* Next... */ - continue; - } + /* Save the values */ + a_ptr->tval = tval; + a_ptr->sval = sval; + a_ptr->pval = pval; + } - /* Process 'W' for "More Info" (one line only) */ - if (buf[0] == 'W') - { - int level, rarity, wgt; - long cost; + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int level, rarity, wgt; + long cost; - /* Scan for the values */ - if (4 != sscanf(buf+2, "%d:%d:%d:%ld", + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%ld", &level, &rarity, &wgt, &cost)) return (1); - /* Save the values */ - a_ptr->level = level; - a_ptr->rarity = rarity; - a_ptr->weight = wgt; - a_ptr->cost = cost; - - /* Next... */ - continue; - } + /* Save the values */ + a_ptr->level = level; + a_ptr->rarity = rarity; + a_ptr->weight = wgt; + a_ptr->cost = cost; + } - /* Hack -- Process 'P' for "power" and such */ - if (buf[0] == 'P') - { - int ac, hd1, hd2, th, td, ta; + /* Hack -- Process 'P' for "power" and such */ + else if (buf[0] == 'P') + { + int ac, hd1, hd2, th, td, ta; - /* Scan for the values */ - if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", + /* Scan for the values */ + if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", &ac, &hd1, &hd2, &th, &td, &ta)) return (1); - a_ptr->ac = ac; - a_ptr->dd = hd1; - a_ptr->ds = hd2; - a_ptr->to_h = th; - a_ptr->to_d = td; - a_ptr->to_a = ta; - - /* Next... */ - continue; - } + a_ptr->ac = ac; + a_ptr->dd = hd1; + a_ptr->ds = hd2; + a_ptr->to_h = th; + a_ptr->to_d = td; + a_ptr->to_a = ta; + } - /* Hack -- Process 'F' for flags */ - if (buf[0] == 'F') + /* Hack -- Process 'F' for flags */ + else if (buf[0] == 'F') + { + /* Parse every entry textually */ + for (s = buf + 2; *s; ) { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) - { /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + if (*t) + { + *t++ = '\0'; + while ((*t == ' ') || (*t == '|')) t++; + } /* Parse this entry */ - if (0 != grab_one_artifact_flag(a_ptr, s)) return (5); + if (0 != grab_one_artifact_flag(a_ptr, s)) return (5); /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; + s = t; } - - - /* Oops */ - return (6); } - /* Complete the "name" and "text" sizes */ - ++a_head->name_size; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - ++a_head->E_name_size; -#endif - ++a_head->text_size; + /* Oops */ + else return (6); /* Success */ @@ -1812,35 +2325,18 @@ static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what) { int i; - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - e_ptr->flags1 |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) + /* Check flags */ + for (i = 0; i < TR_FLAG_MAX; i++) { - if (streq(what, k_info_flags2[i])) + if (streq(what, k_info_flags[i])) { - e_ptr->flags2 |= (1L << i); + add_flag(e_ptr->flags, i); return (0); } } - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - e_ptr->flags3 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&e_ptr->gen_flags, k_info_gen_flags, what) == 0) + return 0; /* Oops */ #ifdef JP @@ -1860,14 +2356,14 @@ static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what) /* * Initialize the "e_info" array, by parsing an ascii "template" file */ -errr init_e_info_txt(FILE *fp, char *buf) +errr parse_e_info(char *buf, header *head) { int i; char *s, *t; /* Current entry */ - ego_item_type *e_ptr = NULL; + static ego_item_type *e_ptr = NULL; /* Just before the first record */ @@ -1877,243 +2373,148 @@ errr init_e_info_txt(FILE *fp, char *buf) error_line = -1; - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') { - /* Advance the line number */ - error_line++; - - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; - - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); - - - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') - { - /* ignore */ - continue; - } - - - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') - { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); /* Verify that colon */ - if (!s) return (1); + if (!s) return (1); - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* Nuke the colon, advance to the name */ + *s++ = '\0'; #ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); + /* Paranoia -- require a name */ + if (!*s) return (1); #endif - /* Get the index */ - i = atoi(buf+2); + /* Get the index */ + i = atoi(buf+2); - /* Verify information */ - if (i < error_idx) return (4); + /* Verify information */ + if (i < error_idx) return (4); - /* Verify information */ - if (i >= e_head->info_num) return (2); + /* Verify information */ + if (i >= head->info_num) return (2); - /* Save the index */ - error_idx = i; + /* Save the index */ + error_idx = i; - /* Point at the "info" */ - e_ptr = &e_info[i]; + /* Point at the "info" */ + e_ptr = &e_info[i]; #ifdef JP - /* Hack -- Verify space */ - if (e_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!e_ptr->name) e_ptr->name = ++e_head->name_size; - - /* Append chars to the name */ - strcpy(e_name + e_head->name_size, s); - - /* Advance the index */ - e_head->name_size += strlen(s); + /* Store the name */ + if (!add_name(&e_ptr->name, head, s)) return (7); #endif - /* Next... */ - continue; - } + } - /* There better be a current e_ptr */ - if (!e_ptr) return (3); + /* There better be a current e_ptr */ + else if (!e_ptr) return (3); #ifdef JP - /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ - /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */ - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (e_head->E_name_size + strlen(s) + 8 > E_fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!e_ptr->E_name) e_ptr->E_name = ++e_head->E_name_size; - - /* Append chars to the name */ - strcpy(E_e_name+ e_head->E_name_size, s); - - /* Advance the index */ - e_head->E_name_size += strlen(s); - - /* Next... */ - continue; - } + /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ + /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */ + else if (buf[0] == 'E') + { + /* nothing to do */ + } #else - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (e_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!e_ptr->name) e_ptr->name = ++e_head->name_size; - - /* Append chars to the name */ - strcpy(e_name+ e_head->name_size, s); - - /* Advance the index */ - e_head->name_size += strlen(s); + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the name */ + if (!add_name(&e_ptr->name, head, s)) return (7); + } #endif #if 0 - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { - /* Acquire the text */ - s = buf+2; - - /* Hack -- Verify space */ - if (e_head->text_size + strlen(s) + 8 > fake_text_size) return (7); - - /* Advance and Save the text index */ - if (!e_ptr->text) e_ptr->text = ++e_head->text_size; - - /* Append chars to the name */ - strcpy(e_text + e_head->text_size, s); - - /* Advance the index */ - e_head->text_size += strlen(s); + /* Process 'D' for "Description" */ + else if (buf[0] == 'D') + { + /* Acquire the text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the text */ + if (!add_text(&e_ptr->text, head, s, TRUE)) return (7); + } #endif - /* Process 'X' for "Xtra" (one line only) */ - if (buf[0] == 'X') - { - int slot, rating; + /* Process 'X' for "Xtra" (one line only) */ + else if (buf[0] == 'X') + { + int slot, rating; - /* Scan for the values */ - if (2 != sscanf(buf+2, "%d:%d", + /* Scan for the values */ + if (2 != sscanf(buf+2, "%d:%d", &slot, &rating)) return (1); - /* Save the values */ - e_ptr->slot = slot; - e_ptr->rating = rating; - - /* Next... */ - continue; - } + /* Save the values */ + e_ptr->slot = slot; + e_ptr->rating = rating; + } - /* Process 'W' for "More Info" (one line only) */ - if (buf[0] == 'W') - { - int level, rarity, pad2; - long cost; + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int level, rarity, pad2; + long cost; - /* Scan for the values */ - if (4 != sscanf(buf+2, "%d:%d:%d:%ld", + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%ld", &level, &rarity, &pad2, &cost)) return (1); - /* Save the values */ - e_ptr->level = level; - e_ptr->rarity = rarity; - /* e_ptr->weight = wgt; */ - e_ptr->cost = cost; - - /* Next... */ - continue; - } + /* Save the values */ + e_ptr->level = level; + e_ptr->rarity = rarity; + /* e_ptr->weight = wgt; */ + e_ptr->cost = cost; + } - /* Hack -- Process 'C' for "creation" */ - if (buf[0] == 'C') - { - int th, td, ta, pv; + /* Hack -- Process 'C' for "creation" */ + else if (buf[0] == 'C') + { + int th, td, ta, pv; - /* Scan for the values */ - if (4 != sscanf(buf+2, "%d:%d:%d:%d", + /* Scan for the values */ + if (4 != sscanf(buf+2, "%d:%d:%d:%d", &th, &td, &ta, &pv)) return (1); - e_ptr->max_to_h = th; - e_ptr->max_to_d = td; - e_ptr->max_to_a = ta; - e_ptr->max_pval = pv; - - /* Next... */ - continue; - } + e_ptr->max_to_h = th; + e_ptr->max_to_d = td; + e_ptr->max_to_a = ta; + e_ptr->max_pval = pv; + } - /* Hack -- Process 'F' for flags */ - if (buf[0] == 'F') + /* Hack -- Process 'F' for flags */ + else if (buf[0] == 'F') + { + /* Parse every entry textually */ + for (s = buf + 2; *s; ) { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) - { /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + if (*t) + { + *t++ = '\0'; + while ((*t == ' ') || (*t == '|')) t++; + } /* Parse this entry */ - if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5); + if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5); /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; + s = t; } - - /* Oops */ - return (6); } - - /* Complete the "name" and "text" sizes */ - ++e_head->name_size; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - ++e_head->E_name_size; -#endif - ++e_head->text_size; - + /* Oops */ + else return (6); /* Success */ return (0); @@ -2125,67 +2526,26 @@ errr init_e_info_txt(FILE *fp, char *buf) */ static errr grab_one_basic_flag(monster_race *r_ptr, cptr what) { - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - r_ptr->flags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - r_ptr->flags2 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags1, r_info_flags1, what) == 0) + return 0; - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - r_ptr->flags3 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags2, r_info_flags2, what) == 0) + return 0; - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - r_ptr->flags7 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags3, r_info_flags3, what) == 0) + return 0; - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - r_ptr->flags8 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags7, r_info_flags7, what) == 0) + return 0; - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - r_ptr->flags9 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags8, r_info_flags8, what) == 0) + return 0; + + if (grab_one_flag(&r_ptr->flags9, r_info_flags9, what) == 0) + return 0; + + if (grab_one_flag(&r_ptr->flagsr, r_info_flagsr, what) == 0) + return 0; /* Oops */ #ifdef JP @@ -2205,37 +2565,14 @@ static errr grab_one_basic_flag(monster_race *r_ptr, cptr what) */ static errr grab_one_spell_flag(monster_race *r_ptr, cptr what) { - int i; - - /* Scan flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags4[i])) - { - r_ptr->flags4 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags4, r_info_flags4, what) == 0) + return 0; - /* Scan flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags5[i])) - { - r_ptr->flags5 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags5, r_info_flags5, what) == 0) + return 0; - /* Scan flags6 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags6[i])) - { - r_ptr->flags6 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&r_ptr->flags6, r_info_flags6, what) == 0) + return 0; /* Oops */ #ifdef JP @@ -2255,398 +2592,282 @@ static errr grab_one_spell_flag(monster_race *r_ptr, cptr what) /* * Initialize the "r_info" array, by parsing an ascii "template" file */ -errr init_r_info_txt(FILE *fp, char *buf) +errr parse_r_info(char *buf, header *head) { int i; char *s, *t; /* Current entry */ - monster_race *r_ptr = NULL; - - - /* Just before the first record */ - error_idx = -1; - - /* Just before the first line */ - error_line = -1; + static monster_race *r_ptr = NULL; - /* Start the "fake" stuff */ - r_head->name_size = 0; - r_head->text_size = 0; - - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') { - /* Advance the line number */ - error_line++; - - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; - - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); - - - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') - { - /* ignore */ - continue; - } - - - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') - { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); /* Verify that colon */ - if (!s) return (1); + if (!s) return (1); - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* Nuke the colon, advance to the name */ + *s++ = '\0'; #ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); + /* Paranoia -- require a name */ + if (!*s) return (1); #endif - /* Get the index */ - i = atoi(buf+2); + /* Get the index */ + i = atoi(buf+2); - /* Verify information */ - if (i < error_idx) return (4); + /* Verify information */ + if (i < error_idx) return (4); - /* Verify information */ - if (i >= r_head->info_num) return (2); + /* Verify information */ + if (i >= head->info_num) return (2); - /* Save the index */ - error_idx = i; + /* Save the index */ + error_idx = i; - /* Point at the "info" */ - r_ptr = &r_info[i]; + /* Point at the "info" */ + r_ptr = &r_info[i]; #ifdef JP - /* Hack -- Verify space */ - if (r_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!r_ptr->name) r_ptr->name = ++r_head->name_size; - - /* Append chars to the name */ - strcpy(r_name + r_head->name_size, s); - - /* Advance the index */ - r_head->name_size += strlen(s); + /* Store the name */ + if (!add_name(&r_ptr->name, head, s)) return (7); #endif - /* Next... */ - continue; - } + } - /* There better be a current r_ptr */ - if (!r_ptr) return (3); + /* There better be a current r_ptr */ + else if (!r_ptr) return (3); #ifdef JP - /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ - /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */ - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (r_head->E_name_size + strlen(s) + 8 > E_fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!r_ptr->E_name) r_ptr->E_name = ++r_head->E_name_size; - - /* Append chars to the name */ - strcpy(E_r_name+ r_head->E_name_size, s); - - /* Advance the index */ - r_head->E_name_size += strlen(s); + /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà */ + /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */ + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the name */ + if (!add_name(&r_ptr->E_name, head, s)) return (7); + } #else - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (r_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!r_ptr->name) r_ptr->name = ++r_head->name_size; - - /* Append chars to the name */ - strcpy(r_name+ r_head->name_size, s); - - /* Advance the index */ - r_head->name_size += strlen(s); + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the name */ + if (!add_name(&r_ptr->name, head, s)) return (7); + } #endif - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { + /* Process 'D' for "Description" */ + else if (buf[0] == 'D') + { #ifdef JP - if (buf[2] == '$') - continue; - /* Acquire the text */ - s = buf+2; + if (buf[2] == '$') + return (0); + /* Acquire the text */ + s = buf+2; #else - if (buf[2] != '$') - continue; - /* Acquire the text */ - s = buf+3; + if (buf[2] != '$') + return (0); + /* Acquire the text */ + s = buf+3; #endif - /* Hack -- Verify space */ - if (r_head->text_size + strlen(s) + 8 > fake_text_size) return (7); - - /* Advance and Save the text index */ - if (!r_ptr->text) r_ptr->text = ++r_head->text_size; - - /* Append chars to the name */ - strcpy(r_text + r_head->text_size, s); - - /* Advance the index */ - r_head->text_size += strlen(s); - - /* Next... */ - continue; - } - - /* Process 'G' for "Graphics" (one line only) */ - if (buf[0] == 'G') - { - char sym; - int tmp; + /* Store the text */ + if (!add_text(&r_ptr->text, head, s, TRUE)) return (7); + } - /* Paranoia */ - if (!buf[2]) return (1); - if (!buf[3]) return (1); - if (!buf[4]) return (1); + /* Process 'G' for "Graphics" (one line only) */ + else if (buf[0] == 'G') + { + char sym; + byte tmp; - /* Extract the char */ - sym = buf[2]; + /* Paranoia */ + if (buf[1] != ':') return (1); + if (!buf[2]) return (1); + if (buf[3] != ':') return (1); + if (!buf[4]) return (1); - /* Extract the attr */ - tmp = color_char_to_attr(buf[4]); + /* Extract the char */ + sym = buf[2]; - /* Paranoia */ - if (tmp < 0) return (1); + /* Extract the attr */ + tmp = color_char_to_attr(buf[4]); - /* Save the values */ - r_ptr->d_char = sym; - r_ptr->d_attr = tmp; + /* Paranoia */ + if (tmp > 127) return (1); - /* Next... */ - continue; - } + /* Save the values */ + r_ptr->d_char = sym; + r_ptr->d_attr = tmp; + } - /* Process 'I' for "Info" (one line only) */ - if (buf[0] == 'I') - { - int spd, hp1, hp2, aaf, ac, slp; + /* Process 'I' for "Info" (one line only) */ + else if (buf[0] == 'I') + { + int spd, hp1, hp2, aaf, ac, slp; - /* Scan for the other values */ - if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", + /* Scan for the other values */ + if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d", &spd, &hp1, &hp2, &aaf, &ac, &slp)) return (1); - /* Save the values */ - r_ptr->speed = spd; - r_ptr->hdice = hp1; - r_ptr->hside = hp2; - r_ptr->aaf = aaf; - r_ptr->ac = ac; - r_ptr->sleep = slp; - - /* Next... */ - continue; - } + /* Save the values */ + r_ptr->speed = spd; + r_ptr->hdice = MAX(hp1, 1); + r_ptr->hside = MAX(hp2, 1); + r_ptr->aaf = aaf; + r_ptr->ac = ac; + r_ptr->sleep = slp; + } - /* Process 'W' for "More Info" (one line only) */ - if (buf[0] == 'W') - { - int lev, rar, pad; - long exp; - long nextexp; - int nextmon; + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int lev, rar, pad; + long exp; + long nextexp; + int nextmon; - /* Scan for the values */ - if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d", + /* Scan for the values */ + if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d", &lev, &rar, &pad, &exp, &nextexp, &nextmon)) return (1); - /* Save the values */ - r_ptr->level = lev; - r_ptr->rarity = rar; - r_ptr->extra = pad; - r_ptr->mexp = exp; - r_ptr->next_exp = nextexp; - r_ptr->next_r_idx = nextmon; - - /* Next... */ - continue; - } - - /* Process 'B' for "Blows" (up to four lines) */ - if (buf[0] == 'B') - { - int n1, n2; + /* Save the values */ + r_ptr->level = lev; + r_ptr->rarity = rar; + r_ptr->extra = pad; + r_ptr->mexp = exp; + r_ptr->next_exp = nextexp; + r_ptr->next_r_idx = nextmon; + } - /* Find the next empty blow slot (if any) */ - for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break; + /* Process 'B' for "Blows" (up to four lines) */ + else if (buf[0] == 'B') + { + int n1, n2; - /* Oops, no more slots */ - if (i == 4) return (1); + /* Find the next empty blow slot (if any) */ + for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break; - /* Analyze the first field */ - for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */; + /* Oops, no more slots */ + if (i == 4) return (1); - /* Terminate the field (if necessary) */ - if (*t == ':') *t++ = '\0'; + /* Analyze the first field */ + for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */; - /* Analyze the method */ - for (n1 = 0; r_info_blow_method[n1]; n1++) - { - if (streq(s, r_info_blow_method[n1])) break; - } + /* Terminate the field (if necessary) */ + if (*t == ':') *t++ = '\0'; - /* Invalid method */ - if (!r_info_blow_method[n1]) return (1); + /* Analyze the method */ + for (n1 = 0; r_info_blow_method[n1]; n1++) + { + if (streq(s, r_info_blow_method[n1])) break; + } - /* Analyze the second field */ - for (s = t; *t && (*t != ':'); t++) /* loop */; + /* Invalid method */ + if (!r_info_blow_method[n1]) return (1); - /* Terminate the field (if necessary) */ - if (*t == ':') *t++ = '\0'; + /* Analyze the second field */ + for (s = t; *t && (*t != ':'); t++) /* loop */; - /* Analyze effect */ - for (n2 = 0; r_info_blow_effect[n2]; n2++) - { - if (streq(s, r_info_blow_effect[n2])) break; - } + /* Terminate the field (if necessary) */ + if (*t == ':') *t++ = '\0'; - /* Invalid effect */ - if (!r_info_blow_effect[n2]) return (1); + /* Analyze effect */ + for (n2 = 0; r_info_blow_effect[n2]; n2++) + { + if (streq(s, r_info_blow_effect[n2])) break; + } - /* Analyze the third field */ - for (s = t; *t && (*t != 'd'); t++) /* loop */; + /* Invalid effect */ + if (!r_info_blow_effect[n2]) return (1); - /* Terminate the field (if necessary) */ - if (*t == 'd') *t++ = '\0'; + /* Analyze the third field */ + for (s = t; *t && (*t != 'd'); t++) /* loop */; - /* Save the method */ - r_ptr->blow[i].method = n1; + /* Terminate the field (if necessary) */ + if (*t == 'd') *t++ = '\0'; - /* Save the effect */ - r_ptr->blow[i].effect = n2; + /* Save the method */ + r_ptr->blow[i].method = n1; - /* Extract the damage dice and sides */ - r_ptr->blow[i].d_dice = atoi(s); - r_ptr->blow[i].d_side = atoi(t); + /* Save the effect */ + r_ptr->blow[i].effect = n2; - /* Next... */ - continue; - } + /* Extract the damage dice and sides */ + r_ptr->blow[i].d_dice = atoi(s); + r_ptr->blow[i].d_side = atoi(t); + } - /* Process 'F' for "Basic Flags" (multiple lines) */ - if (buf[0] == 'F') + /* Process 'F' for "Basic Flags" (multiple lines) */ + else if (buf[0] == 'F') + { + /* Parse every entry */ + for (s = buf + 2; *s; ) { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + if (*t) + { + *t++ = '\0'; + while (*t == ' ' || *t == '|') t++; + } /* Parse this entry */ - if (0 != grab_one_basic_flag(r_ptr, s)) return (5); + if (0 != grab_one_basic_flag(r_ptr, s)) return (5); /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; + s = t; } + } - /* Process 'S' for "Spell Flags" (multiple lines) */ - if (buf[0] == 'S') + /* Process 'S' for "Spell Flags" (multiple lines) */ + else if (buf[0] == 'S') + { + /* Parse every entry */ + for (s = buf + 2; *s; ) { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + if (*t) + { + *t++ = '\0'; + while ((*t == ' ') || (*t == '|')) t++; + } /* XXX XXX XXX Hack -- Read spell frequency */ - if (1 == sscanf(s, "1_IN_%d", &i)) - { - /* Extract a "frequency" */ - r_ptr->freq_spell = r_ptr->freq_inate = 100 / i; + if (1 == sscanf(s, "1_IN_%d", &i)) + { + /* Extract a "frequency" */ + r_ptr->freq_spell = 100 / i; /* Start at next entry */ - s = t; + s = t; - /* Continue */ - continue; - } + /* Continue */ + continue; + } /* Parse this entry */ - if (0 != grab_one_spell_flag(r_ptr, s)) return (5); + if (0 != grab_one_spell_flag(r_ptr, s)) return (5); /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; + s = t; } - - /* Oops */ - return (6); } + /* Oops */ + else return (6); - /* Complete the "name" and "text" sizes */ - ++r_head->name_size; -#ifdef JP - /* ±Ñ¸ì̾ÍÑ */ - ++r_head->E_name_size; -#endif - ++r_head->text_size; - - - for (i = 1; i < max_r_idx; i++) - { - /* Invert flag WILD_ONLY <-> RF8_DUNGEON */ - r_info[i].flags8 ^= 1L; - - /* WILD_TOO without any other wilderness flags enables all flags */ - if ((r_info[i].flags8 & RF8_WILD_TOO) && !(r_info[i].flags8 & 0x7FFFFFFE)) - r_info[i].flags8 = 0x0463; - } /* Success */ return (0); @@ -2658,23 +2879,14 @@ errr init_r_info_txt(FILE *fp, char *buf) */ static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what) { - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, d_info_flags1[i])) - { - d_ptr->flags1 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->flags1, d_info_flags1, what) == 0) + return 0; /* Oops */ #ifdef JP - msg_format("̤ÃΤΥÀ¥ó¥¸¥ç¥ó¡¦¥Õ¥é¥° '%s'¡£", what); + msg_format("̤ÃΤΥÀ¥ó¥¸¥ç¥ó¡¦¥Õ¥é¥° '%s'¡£", what); #else - msg_format("Unknown dungeon type flag '%s'.", what); + msg_format("Unknown dungeon type flag '%s'.", what); #endif /* Failure */ @@ -2686,67 +2898,26 @@ static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what) */ static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what) { - int i; + if (grab_one_flag(&d_ptr->mflags1, r_info_flags1, what) == 0) + return 0; - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - d_ptr->mflags1 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags2, r_info_flags2, what) == 0) + return 0; - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - d_ptr->mflags2 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags3, r_info_flags3, what) == 0) + return 0; - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - d_ptr->mflags3 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags7, r_info_flags7, what) == 0) + return 0; - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - d_ptr->mflags7 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags8, r_info_flags8, what) == 0) + return 0; - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - d_ptr->mflags8 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags9, r_info_flags9, what) == 0) + return 0; - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - d_ptr->mflags9 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflagsr, r_info_flagsr, what) == 0) + return 0; /* Oops */ #ifdef JP @@ -2764,37 +2935,14 @@ static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what) */ static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what) { - int i; - - /* Scan flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags4[i])) - { - d_ptr->mflags4 |= (1L << i); - return (0); - } - } - - /* Scan flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags5[i])) - { - d_ptr->mflags5 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags4, r_info_flags4, what) == 0) + return 0; - /* Scan flags6 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags6[i])) - { - d_ptr->mflags6 |= (1L << i); - return (0); - } - } + if (grab_one_flag(&d_ptr->mflags5, r_info_flags5, what) == 0) + return 0; + + if (grab_one_flag(&d_ptr->mflags6, r_info_flags6, what) == 0) + return 0; /* Oops */ #ifdef JP @@ -2810,413 +2958,325 @@ static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what) /* * Initialize the "d_info" array, by parsing an ascii "template" file */ -errr init_d_info_txt(FILE *fp, char *buf) +errr parse_d_info(char *buf, header *head) { int i; char *s, *t; /* Current entry */ - dungeon_info_type *d_ptr = NULL; - - - /* Just before the first record */ - error_idx = -1; - - /* Just before the first line */ - error_line = -1; + static dungeon_info_type *d_ptr = NULL; - /* Start the "fake" stuff */ - d_head->name_size = 0; - d_head->text_size = 0; - - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) + /* Process 'N' for "New/Number/Name" */ + if (buf[0] == 'N') { - /* Advance the line number */ - error_line++; - - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; - - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); - - - /* Hack -- Process 'V' for "Version" */ - if (buf[0] == 'V') - { - /* ignore */ - continue; - } - - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') - { - /* Find the colon before the name */ - s = strchr(buf+2, ':'); + /* Find the colon before the name */ + s = my_strchr(buf+2, ':'); - /* Verify that colon */ - if (!s) return (1); + /* Verify that colon */ + if (!s) return (1); - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* Nuke the colon, advance to the name */ + *s++ = '\0'; #ifdef JP - /* Paranoia -- require a name */ - if (!*s) return (1); + /* Paranoia -- require a name */ + if (!*s) return (1); #endif - /* Get the index */ - i = atoi(buf+2); + /* Get the index */ + i = atoi(buf+2); - /* Verify information */ - if (i < error_idx) return (4); + /* Verify information */ + if (i < error_idx) return (4); - /* Verify information */ - if (i >= d_head->info_num) return (2); + /* Verify information */ + if (i >= head->info_num) return (2); - /* Save the index */ - error_idx = i; + /* Save the index */ + error_idx = i; - /* Point at the "info" */ - d_ptr = &d_info[i]; + /* Point at the "info" */ + d_ptr = &d_info[i]; #ifdef JP - /* Hack -- Verify space */ - if (d_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!d_ptr->name) d_ptr->name = ++d_head->name_size; - - /* Append chars to the name */ - strcpy(d_name + d_head->name_size, s); - - /* Advance the index */ - d_head->name_size += strlen(s); + /* Store the name */ + if (!add_name(&d_ptr->name, head, s)) return (7); #endif - /* Next... */ - continue; - } + } #ifdef JP - if (buf[0] == 'E') - continue; + else if (buf[0] == 'E') return (0); #else - if (buf[0] == 'E') - { - /* Acquire the Text */ - s = buf+2; - - /* Hack -- Verify space */ - if (d_head->name_size + strlen(s) + 8 > fake_name_size) return (7); - - /* Advance and Save the name index */ - if (!d_ptr->name) d_ptr->name = ++d_head->name_size; - - /* Append chars to the name */ - strcpy(d_name + d_head->name_size, s); - - /* Advance the index */ - d_head->name_size += strlen(s); + else if (buf[0] == 'E') + { + /* Acquire the Text */ + s = buf+2; - /* Next... */ - continue; - } + /* Store the name */ + if (!add_name(&d_ptr->name, head, s)) return (7); + } #endif - /* Process 'D' for "Description */ - if (buf[0] == 'D') - { + /* Process 'D' for "Description */ + else if (buf[0] == 'D') + { #ifdef JP - if (buf[2] == '$') - continue; - /* Acquire the text */ - s = buf+2; + if (buf[2] == '$') + return (0); + /* Acquire the text */ + s = buf+2; #else - if (buf[2] != '$') - continue; - /* Acquire the text */ - s = buf+3; + if (buf[2] != '$') + return (0); + /* Acquire the text */ + s = buf+3; #endif - /* Hack -- Verify space */ - if (d_head->text_size + strlen(s) + 8 > fake_text_size) return (7); + /* Store the text */ + if (!add_text(&d_ptr->text, head, s, TRUE)) return (7); + } - /* Advance and Save the text index */ - if (!d_ptr->text) d_ptr->text = ++d_head->text_size; + /* Process 'W' for "More Info" (one line only) */ + else if (buf[0] == 'W') + { + int min_lev, max_lev; + int min_plev, mode; + int min_alloc, max_chance; + int obj_good, obj_great; + int pit, nest; + + /* Scan for the values */ + if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x", + &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1); + + /* Save the values */ + d_ptr->mindepth = min_lev; + d_ptr->maxdepth = max_lev; + d_ptr->min_plev = min_plev; + d_ptr->mode = mode; + d_ptr->min_m_alloc_level = min_alloc; + d_ptr->max_m_alloc_chance = max_chance; + d_ptr->obj_good = obj_good; + d_ptr->obj_great = obj_great; + d_ptr->pit = pit; + d_ptr->nest = nest; + } - /* Append chars to the name */ - strcpy(d_text + d_head->text_size, s); + /* Process 'P' for "Place Info" */ + else if (buf[0] == 'P') + { + int dy, dx; - /* Advance the index */ - d_head->text_size += strlen(s); + /* Scan for the values */ + if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1); - /* Next... */ - continue; - } + /* Save the values */ + d_ptr->dy = dy; + d_ptr->dx = dx; + } - /* Process 'W' for "More Info" (one line only) */ - if (buf[0] == 'W') - { - int min_lev, max_lev; - int min_plev, mode; - int min_alloc, max_chance; - int obj_good, obj_great; - int pit, nest; - - /* Scan for the values */ - if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x", - &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1); - - /* Save the values */ - d_ptr->mindepth = min_lev; - d_ptr->maxdepth = max_lev; - d_ptr->min_plev = min_plev; - d_ptr->mode = mode; - d_ptr->min_m_alloc_level = min_alloc; - d_ptr->max_m_alloc_chance = max_chance; - d_ptr->obj_good = obj_good; - d_ptr->obj_great = obj_great; - d_ptr->pit = pit; - d_ptr->nest = nest; - - /* Next... */ - continue; - } + /* Process 'L' for "fLoor type" (one line only) */ + else if (buf[0] == 'L') + { + char *zz[16]; + + /* Scan for the values */ + if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 1, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 1)) return (1); - /* Process 'P' for "Place Info" */ - if (buf[0] == 'P') + /* Save the values */ + for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) { - int dy, dx; + d_ptr->floor[i].feat = f_tag_to_index(zz[i * 2]); + if (d_ptr->floor[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; - /* Scan for the values */ - if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1); + d_ptr->floor[i].percent = atoi(zz[i * 2 + 1]); + } + d_ptr->tunnel_percent = atoi(zz[DUNGEON_FEAT_PROB_NUM * 2]); + } - /* Save the values */ - d_ptr->dy = dy; - d_ptr->dx = dx; + /* Process 'A' for "wAll type" (one line only) */ + else if (buf[0] == 'A') + { + char *zz[16]; - /* Next... */ - continue; - } + /* Scan for the values */ + if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 4, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 4)) return (1); - /* Process 'L' for "fLoor type" (one line only) */ - if (buf[0] == 'L') + /* Save the values */ + for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) { - int f1, f2, f3; - int p1, p2, p3; - int tunnel; - - /* Scan for the values */ - if (7 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d", - &f1, &p1, &f2, &p2, &f3, &p3, &tunnel)) return (1); - - /* Save the values */ - d_ptr->floor1 = f1; - d_ptr->floor_percent1 = p1; - d_ptr->floor2 = f2; - d_ptr->floor_percent2 = p2; - d_ptr->floor3 = f3; - d_ptr->floor_percent3 = p3; - d_ptr->tunnel_percent = tunnel; - - /* Next... */ - continue; - } + d_ptr->fill[i].feat = f_tag_to_index(zz[i * 2]); + if (d_ptr->fill[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; - /* Process 'A' for "wAll type" (one line only) */ - if (buf[0] == 'A') - { - int w1, w2, w3, outer, inner, stream1, stream2; - int p1, p2, p3; - - /* Scan for the values */ - if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - &w1, &p1, &w2, &p2, &w3, &p3, &outer, &inner, &stream1, &stream2)) return (1); - - /* Save the values */ - d_ptr->fill_type1 = w1; - d_ptr->fill_percent1 = p1; - d_ptr->fill_type2 = w2; - d_ptr->fill_percent2 = p2; - d_ptr->fill_type3 = w3; - d_ptr->fill_percent3 = p3; - d_ptr->outer_wall = outer; - d_ptr->inner_wall = inner; - d_ptr->stream1 = stream1; - d_ptr->stream2 = stream2; - - /* Next... */ - continue; + d_ptr->fill[i].percent = atoi(zz[i * 2 + 1]); } - /* Process 'F' for "Dungeon Flags" (multiple lines) */ - if (buf[0] == 'F') - { - int artif = 0, monst = 0; + d_ptr->outer_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2]); + if (d_ptr->outer_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + d_ptr->inner_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 1]); + if (d_ptr->inner_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + d_ptr->stream1 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 2]); + if (d_ptr->stream1 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; + + d_ptr->stream2 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 3]); + if (d_ptr->stream2 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; + } - /* XXX XXX XXX Hack -- Read Final Artifact */ - if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif)) - { - /* Extract a "Final Artifact" */ - d_ptr->final_artifact = artif; + /* Process 'F' for "Dungeon Flags" (multiple lines) */ + else if (buf[0] == 'F') + { + int artif = 0, monst = 0; - /* Start at next entry */ - s = t; + /* Parse every entry */ + for (s = buf + 2; *s; ) + { + /* Find the end of this entry */ + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - /* Continue */ - continue; - } + /* Nuke and skip any dividers */ + if (*t) + { + *t++ = '\0'; + while (*t == ' ' || *t == '|') t++; + } - /* XXX XXX XXX Hack -- Read Final Object */ - if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif)) - { - /* Extract a "Final Artifact" */ - d_ptr->final_object = artif; + /* XXX XXX XXX Hack -- Read Final Artifact */ + if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif)) + { + /* Extract a "Final Artifact" */ + d_ptr->final_artifact = artif; - /* Start at next entry */ - s = t; + /* Start at next entry */ + s = t; - /* Continue */ - continue; - } + /* Continue */ + continue; + } - /* XXX XXX XXX Hack -- Read Artifact Guardian */ - if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) - { - /* Extract a "Artifact Guardian" */ - d_ptr->final_guardian = monst; + /* XXX XXX XXX Hack -- Read Final Object */ + if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif)) + { + /* Extract a "Final Artifact" */ + d_ptr->final_object = artif; - /* Start at next entry */ - s = t; + /* Start at next entry */ + s = t; - /* Continue */ - continue; - } + /* Continue */ + continue; + } - /* XXX XXX XXX Hack -- Read Special Percentage */ - if (1 == sscanf(s, "MONSTER_DIV_%d", &monst)) - { - /* Extract a "Special %" */ - d_ptr->special_div = monst; + /* XXX XXX XXX Hack -- Read Artifact Guardian */ + if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) + { + /* Extract a "Artifact Guardian" */ + d_ptr->final_guardian = monst; - /* Start at next entry */ - s = t; + /* Start at next entry */ + s = t; - /* Continue */ - continue; - } + /* Continue */ + continue; + } - /* Parse this entry */ - if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5); + /* XXX XXX XXX Hack -- Read Special Percentage */ + if (1 == sscanf(s, "MONSTER_DIV_%d", &monst)) + { + /* Extract a "Special %" */ + d_ptr->special_div = monst; - /* Start the next entry */ + /* Start at next entry */ s = t; + + /* Continue */ + continue; } - /* Next... */ - continue; + /* Parse this entry */ + if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5); + + /* Start the next entry */ + s = t; } + } - /* Process 'M' for "Basic Flags" (multiple lines) */ - if (buf[0] == 'M') + /* Process 'M' for "Basic Flags" (multiple lines) */ + else if (buf[0] == 'M') + { + /* Parse every entry */ + for (s = buf + 2; *s; ) { - byte r_char_number = 0, r_char; + /* Find the end of this entry */ + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - /* Parse every entry */ - for (s = buf + 2; *s; ) + /* Nuke and skip any dividers */ + if (*t) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* XXX XXX XXX Hack -- Read monster symbols */ - if (1 == sscanf(s, "R_CHAR_%c", &r_char)) - { - /* Limited to 5 races */ - if(r_char_number >= 5) continue; - - /* Extract a "frequency" */ - d_ptr->r_char[r_char_number++] = r_char; - - /* Start at next entry */ - s = t; + *t++ = '\0'; + while (*t == ' ' || *t == '|') t++; + } - /* Continue */ - continue; - } + /* Hack -- Read monster symbols */ + if (!strncmp(s, "R_CHAR_", 7)) + { + /* Skip "R_CHAR_" */ + s += 7; - /* Parse this entry */ - if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5); + /* Read a string */ + strncpy(d_ptr->r_char, s, sizeof(d_ptr->r_char)); - /* Start the next entry */ + /* Start at next entry */ s = t; + + /* Continue */ + continue; } - /* Next... */ - continue; + /* Parse this entry */ + if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5); + + /* Start the next entry */ + s = t; } + } - /* Process 'S' for "Spell Flags" (multiple lines) */ - if (buf[0] == 'S') + /* Process 'S' for "Spell Flags" (multiple lines) */ + else if (buf[0] == 'S') + { + /* Parse every entry */ + for (s = buf + 2; *s; ) { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + if (*t) + { + *t++ = '\0'; + while ((*t == ' ') || (*t == '|')) t++; + } /* XXX XXX XXX Hack -- Read spell frequency */ - if (1 == sscanf(s, "1_IN_%d", &i)) - { - /* Start at next entry */ - s = t; + if (1 == sscanf(s, "1_IN_%d", &i)) + { + /* Start at next entry */ + s = t; /* Continue */ - continue; - } + continue; + } /* Parse this entry */ - if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5); + if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5); /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; + s = t; } - - /* Oops */ - return (6); } - ++d_head->text_size; + /* Oops */ + else return (6); /* Success */ return (0); @@ -3233,13 +3293,13 @@ static int i = 0; /* Random dungeon grid effects */ -#define RANDOM_NONE 0x00 -#define RANDOM_FEATURE 0x01 -#define RANDOM_MONSTER 0x02 -#define RANDOM_OBJECT 0x04 -#define RANDOM_EGO 0x08 -#define RANDOM_ARTIFACT 0x10 -#define RANDOM_TRAP 0x20 +#define RANDOM_NONE 0x00000000 +#define RANDOM_FEATURE 0x00000001 +#define RANDOM_MONSTER 0x00000002 +#define RANDOM_OBJECT 0x00000004 +#define RANDOM_EGO 0x00000008 +#define RANDOM_ARTIFACT 0x00000010 +#define RANDOM_TRAP 0x00000020 typedef struct dungeon_grid dungeon_grid; @@ -3279,15 +3339,15 @@ static errr parse_line_feature(char *buf) int index = zz[0][0]; /* Reset the info for the letter */ - letter[index].feature = 0; + letter[index].feature = feat_none; letter[index].monster = 0; letter[index].object = 0; letter[index].ego = 0; letter[index].artifact = 0; - letter[index].trap = 0; + letter[index].trap = feat_none; letter[index].cave_info = 0; letter[index].special = 0; - letter[index].random = 0; + letter[index].random = RANDOM_NONE; switch (num) { @@ -3297,19 +3357,14 @@ static errr parse_line_feature(char *buf) /* Fall through */ /* Trap */ case 8: - if (zz[7][0] == '*') + if ((zz[7][0] == '*') && !zz[7][1]) { letter[index].random |= RANDOM_TRAP; - - if (zz[7][1]) - { - zz[7]++; - letter[index].trap = atoi(zz[7]); - } } else { - letter[index].trap = atoi(zz[7]); + letter[index].trap = f_tag_to_index(zz[7]); + if (letter[index].trap < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; } /* Fall through */ /* Artifact */ @@ -3317,12 +3372,7 @@ static errr parse_line_feature(char *buf) if (zz[6][0] == '*') { letter[index].random |= RANDOM_ARTIFACT; - - if (zz[6][1]) - { - zz[6]++; - letter[index].artifact = atoi(zz[6]); - } + if (zz[6][1]) letter[index].artifact = atoi(zz[6] + 1); } else { @@ -3334,12 +3384,7 @@ static errr parse_line_feature(char *buf) if (zz[5][0] == '*') { letter[index].random |= RANDOM_EGO; - - if (zz[5][1]) - { - zz[5]++; - letter[index].ego = atoi(zz[5]); - } + if (zz[5][1]) letter[index].ego = atoi(zz[5] + 1); } else { @@ -3351,12 +3396,7 @@ static errr parse_line_feature(char *buf) if (zz[4][0] == '*') { letter[index].random |= RANDOM_OBJECT; - - if (zz[4][1]) - { - zz[4]++; - letter[index].object = atoi(zz[4]); - } + if (zz[4][1]) letter[index].object = atoi(zz[4] + 1); } else { @@ -3368,11 +3408,12 @@ static errr parse_line_feature(char *buf) if (zz[3][0] == '*') { letter[index].random |= RANDOM_MONSTER; - if (zz[3][1]) - { - zz[3]++; - letter[index].monster = atoi(zz[3]); - } + if (zz[3][1]) letter[index].monster = atoi(zz[3] + 1); + } + else if (zz[3][0] == 'c') + { + if (!zz[3][1]) return PARSE_ERROR_GENERIC; + letter[index].monster = - atoi(zz[3] + 1); } else { @@ -3385,18 +3426,14 @@ static errr parse_line_feature(char *buf) /* Fall through */ /* Feature */ case 2: - if (zz[1][0] == '*') + if ((zz[1][0] == '*') && !zz[1][1]) { letter[index].random |= RANDOM_FEATURE; - if (zz[1][1]) - { - zz[1]++; - letter[index].feature = atoi(zz[1]); - } } else { - letter[index].feature = atoi(zz[1]); + letter[index].feature = f_tag_to_index(zz[1]); + if (letter[index].feature < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG; } break; } @@ -3409,7 +3446,7 @@ static errr parse_line_feature(char *buf) /* - * Process "F:::::::::" -- info for dungeon grid + * Process "B:::..." -- Building definition */ static errr parse_line_building(char *buf) { @@ -3431,7 +3468,7 @@ static errr parse_line_building(char *buf) index = atoi(s); /* Find the colon after the building number */ - s = strchr(s, ':'); + s = my_strchr(s, ':'); /* Verify that colon */ if (!s) return (1); @@ -3547,22 +3584,8 @@ static errr parse_line_building(char *buf) case 'Z': { -#ifdef USE_SCRIPT - if (tokenize(s+2, 2, zz, 0) == 2) - { - /* Index of the action */ - int action_index = atoi(zz[0]); - - /* Name of the action */ - strcpy(building[index].act_script[action_index], zz[1]); - - break; - } - return (1); -#else /* USE_SCRIPT */ /* Ignore scripts */ break; -#endif /* USE_SCRIPT */ } default: @@ -3576,6 +3599,39 @@ static errr parse_line_building(char *buf) /* + * Place the object j_ptr to a grid + */ +static void drop_here(object_type *j_ptr, int y, int x) +{ + cave_type *c_ptr = &cave[y][x]; + object_type *o_ptr; + + /* Get new object */ + s16b o_idx = o_pop(); + + /* Access new object */ + o_ptr = &o_list[o_idx]; + + /* Structure copy */ + object_copy(o_ptr, j_ptr); + + + /* Locate */ + o_ptr->iy = y; + o_ptr->ix = x; + + /* No monster */ + o_ptr->held_m_idx = 0; + + /* Build a stack */ + o_ptr->next_o_idx = c_ptr->o_idx; + + /* Place the object */ + c_ptr->o_idx = o_idx; +} + + +/* * Parse a sub-file of the "extra info" */ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x) @@ -3637,7 +3693,7 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in int artifact_index = letter[idx].artifact; /* Lay down a floor */ - c_ptr->feat = letter[idx].feature; + c_ptr->feat = conv_dungeon_feat(letter[idx].feature); /* Only the features */ if (init_flags & INIT_ONLY_FEATURES) continue; @@ -3650,12 +3706,23 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in { monster_level = base_level + monster_index; - place_monster(*y, *x, TRUE, TRUE); + place_monster(*y, *x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP)); monster_level = base_level; } else if (monster_index) { + int old_cur_num, old_max_num; + bool clone = FALSE; + + if (monster_index < 0) + { + monster_index = -monster_index; + clone = TRUE; + } + old_cur_num = r_info[monster_index].cur_num; + old_max_num = r_info[monster_index].max_num; + /* Make alive again */ if (r_info[monster_index].flags1 & RF1_UNIQUE) { @@ -3664,7 +3731,8 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in } /* Make alive again */ - if (r_info[monster_index].flags7 & RF7_UNIQUE_7) + /* Hack -- Non-unique Nazguls are semi-unique */ + else if (r_info[monster_index].flags7 & RF7_NAZGUL) { if (r_info[monster_index].cur_num == r_info[monster_index].max_num) { @@ -3673,7 +3741,16 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in } /* Place it */ - place_monster_aux(*y, *x, monster_index, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE); + place_monster_aux(0, *y, *x, monster_index, (PM_ALLOW_SLEEP | PM_NO_KAGE)); + if (clone) + { + /* clone */ + m_list[hack_m_idx_ii].smart |= SM_CLONED; + + /* Make alive again for real unique monster */ + r_info[monster_index].cur_num = old_cur_num; + r_info[monster_index].max_num = old_max_num; + } } /* Object (and possible trap) */ @@ -3685,9 +3762,9 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in * Random trap and random treasure defined * 25% chance for trap and 75% chance for object */ - if (rand_int(100) < 75) + if (randint0(100) < 75) { - place_object(*y, *x, FALSE, FALSE); + place_object(*y, *x, 0L); } else { @@ -3701,12 +3778,12 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in object_level = base_level + object_index; /* Create an out of deep object */ - if (rand_int(100) < 75) - place_object(*y, *x, FALSE, FALSE); - else if (rand_int(100) < 80) - place_object(*y, *x, TRUE, FALSE); + if (randint0(100) < 75) + place_object(*y, *x, 0L); + else if (randint0(100) < 80) + place_object(*y, *x, AM_GOOD); else - place_object(*y, *x, TRUE, TRUE); + place_object(*y, *x, AM_GOOD | AM_GREAT); object_level = base_level; } @@ -3715,6 +3792,12 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in { place_trap(*y, *x); } + /* Hidden trap (or door) */ + else if (letter[idx].trap) + { + c_ptr->mimic = c_ptr->feat; + c_ptr->feat = conv_dungeon_feat(letter[idx].trap); + } else if (object_index) { /* Get local object */ @@ -3731,13 +3814,9 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in } /* Apply magic (no messages, no artifacts) */ - apply_magic(o_ptr, base_level, FALSE, TRUE, FALSE, FALSE); - -#ifdef USE_SCRIPT - o_ptr->python = object_create_callback(o_ptr); -#endif /* USE_SCRIPT */ + apply_magic(o_ptr, base_level, AM_NO_FIXED_ART | AM_GOOD); - (void)drop_near(o_ptr, -1, *y, *x); + drop_here(o_ptr, *y, *x); } /* Artifact */ @@ -3745,24 +3824,20 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in { if (a_info[artifact_index].cur_num) { - s16b k_idx = 198; + int k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT); object_type forge; object_type *q_ptr = &forge; object_prep(q_ptr, k_idx); -#ifdef USE_SCRIPT - q_ptr->python = object_create_callback(q_ptr); -#endif /* USE_SCRIPT */ /* Drop it in the dungeon */ - (void)drop_near(q_ptr, -1, *y, *x); + drop_here(q_ptr, *y, *x); } else { /* Create the artifact */ - create_named_art(artifact_index, *y, *x); - - a_info[artifact_index].cur_num = 1; + if (create_named_art(artifact_index, *y, *x)) + a_info[artifact_index].cur_num = 1; } } @@ -3823,7 +3898,7 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in r_ptr->flags1 |= RF1_QUESTOR; a_ptr = &a_info[q_ptr->k_idx]; - a_ptr->flags3 |= TR3_QUESTITEM; + a_ptr->gen_flags |= TRG_QUESTITEM; } return (0); } @@ -3876,17 +3951,9 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in if (*x % SCREEN_WID) panels_x++; cur_wid = panels_x * SCREEN_WID; - /* Choose a panel row */ - max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2; - if (max_panel_rows < 0) max_panel_rows = 0; - - /* Choose a panel col */ - max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2; - if (max_panel_cols < 0) max_panel_cols = 0; - /* Assume illegal panel */ - panel_row = max_panel_rows; - panel_col = max_panel_cols; + panel_row_min = cur_hgt; + panel_col_min = cur_wid; /* Place player in a quest level */ if (p_ptr->inside_quest) @@ -3973,10 +4040,10 @@ static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, in max_e_idx = atoi(zz[1]); } - /* Maximum d_idx */ - else if (zz[0][0] == 'D') + /* Maximum d_idx */ + else if (zz[0][0] == 'D') { - max_d_idx = atoi(zz[1]); + max_d_idx = atoi(zz[1]); } /* Maximum o_idx */ @@ -4097,16 +4164,15 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) /* Function: EQU */ else if (streq(t, "EQU")) { - v = "1"; + v = "0"; if (*s && (f != b2)) { t = process_dungeon_file_expr(&s, &f); } while (*s && (f != b2)) { - p = t; - t = process_dungeon_file_expr(&s, &f); - if (*t && !streq(p, t)) v = "0"; + p = process_dungeon_file_expr(&s, &f); + if (streq(t, p)) v = "1"; } } @@ -4122,7 +4188,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) { p = t; t = process_dungeon_file_expr(&s, &f); - if (*t && (strcmp(p, t) > 0)) v = "0"; + if (*t && atoi(p) > atoi(t)) v = "0"; } } @@ -4138,7 +4204,9 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) { p = t; t = process_dungeon_file_expr(&s, &f); - if (*t && (strcmp(p, t) < 0)) v = "0"; + + /* Compare two numbers instead of string */ + if (*t && atoi(p) < atoi(t)) v = "0"; } } @@ -4162,7 +4230,15 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) else { /* Accept all printables except spaces and brackets */ - while (isprint(*s) && !strchr(" []", *s)) ++s; +#ifdef JP + while (iskanji(*s) || (isprint(*s) && !my_strchr(" []", *s))) + { + if (iskanji(*s)) s++; + s++; + } +#else + while (isprint(*s) && !my_strchr(" []", *s)) ++s; +#endif /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; @@ -4194,7 +4270,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) else if (streq(b+1, "RACE")) { #ifdef JP - v = rp_ptr->E_title; + v = rp_ptr->E_title; #else v = rp_ptr->title; #endif @@ -4204,7 +4280,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) else if (streq(b+1, "CLASS")) { #ifdef JP - v = cp_ptr->E_title; + v = cp_ptr->E_title; #else v = cp_ptr->title; #endif @@ -4216,7 +4292,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) #ifdef JP v = E_realm_names[p_ptr->realm1]; #else - v = realm_names[p_ptr->realm1]; + v = realm_names[p_ptr->realm1]; #endif } @@ -4224,7 +4300,7 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) else if (streq(b+1, "REALM2")) { #ifdef JP - v = E_realm_names[p_ptr->realm2]; + v = E_realm_names[p_ptr->realm2]; #else v = realm_names[p_ptr->realm2]; #endif @@ -4233,7 +4309,22 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) /* Player name */ else if (streq(b+1, "PLAYER")) { - v = player_base; + static char tmp_player_name[32]; + char *pn, *tpn; + for (pn = player_name, tpn = tmp_player_name; *pn; pn++, tpn++) + { +#ifdef JP + if (iskanji(*pn)) + { + *(tpn++) = *(pn++); + *tpn = *pn; + continue; + } +#endif + *tpn = my_strchr(" []", *pn) ? '_' : *pn; + } + *tpn = '\0'; + v = tmp_player_name; } /* Town */ @@ -4333,7 +4424,7 @@ errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax) /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_EDIT, name); + path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, name); /* Open the file */ fp = my_fopen(buf, "r"); @@ -4343,7 +4434,7 @@ errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax) /* Process the file */ - while (0 == my_fgets(fp, buf, 1024)) + while (0 == my_fgets(fp, buf, sizeof(buf))) { /* Count lines */ num++; @@ -4382,18 +4473,6 @@ errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax) /* Apply conditionals */ if (bypass) continue; - - /* Process "%:" */ - if (buf[0] == '%') - { - /* Process that file if allowed */ - (void)process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax); - - /* Continue */ - continue; - } - - /* Process the line */ err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x); @@ -4430,15 +4509,16 @@ msg_format("'%s' +#if 0 void write_r_info_txt(void) { int i, j, z, fc, bc; int dlen; - cptr flags[288]; + cptr flags[32 * 10]; - u32b f_ptr[9]; - cptr *n_ptr[9]; + u32b f_ptr[10]; + cptr *n_ptr[10]; monster_race *r_ptr; @@ -4504,6 +4584,7 @@ void write_r_info_txt(void) f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7; f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8; f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9; + f_ptr[9] = r_ptr->flagsr; n_ptr[9] = r_info_flagsr; /* Write New/Number/Name */ fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name); @@ -4533,14 +4614,14 @@ void write_r_info_txt(void) } /* Extract the flags */ - for (fc = 0, j = 0; j < 96; j++) + for (fc = 0, j = 0; j < 32 * 3; j++) { /* Check this flag */ if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32]; } /* Extract the extra flags */ - for (j = 192; j < 288; j++) + for (j = 32 * 6; j < 32 * 10; j++) { /* Check this flag */ if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32]; @@ -4646,3 +4727,4 @@ void write_r_info_txt(void) fclose(fff); } +#endif