/* File: init2.c */ /* Purpose: Initialization (part 2) -BEN- */ #include "angband.h" /* * 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 * the common limitation of "read()" and "write()" to only 32767 bytes * at a time. * * Several of the arrays for Angband are built from "template" files in * the "lib/file" directory, from which quick-load binary "image" files * are constructed whenever they are not present in the "lib/data" * directory, or if those files become obsolete, if we are allowed. * * Warning -- the "ascii" file parsers use a minor hack to collect the * name and text information in a single pass. Thus, the game will not * be able to load any template file with more than 20K of names or 60K * of text, even though technically, up to 64K should be legal. * * The "init1.c" file is used only to parse the ascii template files, * to create the binary image files. If you include the binary image * files instead of the ascii template files, then you can undefine * "ALLOW_TEMPLATES", saving about 20K by removing "init1.c". Note * that the binary image files are extremely system dependant. */ /* * Find the default paths to all of our important sub-directories. * * The purpose of each sub-directory is described in "variable.c". * * All of the sub-directories should, by default, be located inside * the main "lib" directory, whose location is very system dependant. * * This function takes a writable buffer, initially containing the * "path" to the "lib" directory, for example, "/pkg/lib/angband/", * or a system dependant string, for example, ":lib:". The buffer * must be large enough to contain at least 32 more characters. * * Various command line options may allow some of the important * directories to be changed to user-specified directories, most * importantly, the "info" and "user" and "save" directories, * but this is done after this function, see "main.c". * * In general, the initial path should end in the appropriate * "PATH_SEP" string. All of the "sub-directory" paths created * below will also end in the "PATH_SEP" string, and, in general, * any replacement paths specified by the user should do the same. * * Mega-Hack -- support fat raw files under NEXTSTEP, using * a special "system prefix" for all the "lib/data" files. * This will cause the "lib/data" directory to hold one set * of "raw" files for each relevant platform, when necessary, * and still hold the "normal" files if no platform is known. * * Hack -- first we free all the strings, since this is known * to succeed even if the strings have not been allocated yet. */ void init_file_paths(char *path) { char *tail; /*** Free everything ***/ /* Free the main path */ string_free(ANGBAND_DIR); /* Free the sub-paths */ string_free(ANGBAND_DIR_APEX); string_free(ANGBAND_DIR_BONE); string_free(ANGBAND_DIR_DATA); string_free(ANGBAND_DIR_EDIT); string_free(ANGBAND_DIR_FILE); string_free(ANGBAND_DIR_HELP); string_free(ANGBAND_DIR_INFO); string_free(ANGBAND_DIR_SAVE); string_free(ANGBAND_DIR_USER); string_free(ANGBAND_DIR_XTRA); /*** Prepare the "path" ***/ /* Hack -- save the main directory */ ANGBAND_DIR = string_make(path); /* Prepare to append to the Base Path */ tail = path + strlen(path); #ifdef VM /*** Use "flat" paths with VM/ESA ***/ /* Use "blank" path names */ ANGBAND_DIR_APEX = string_make(""); ANGBAND_DIR_BONE = string_make(""); ANGBAND_DIR_DATA = string_make(""); ANGBAND_DIR_EDIT = string_make(""); ANGBAND_DIR_FILE = string_make(""); ANGBAND_DIR_HELP = string_make(""); ANGBAND_DIR_INFO = string_make(""); ANGBAND_DIR_SAVE = string_make(""); ANGBAND_DIR_USER = string_make(""); ANGBAND_DIR_XTRA = string_make(""); #else /* VM */ /*** Build the sub-directory names ***/ /* Build a path name */ sprintf(tail, "apex%s", PATH_SEP); ANGBAND_DIR_APEX = string_make(path); /* Build a path name */ sprintf(tail, "bone%s", PATH_SEP); ANGBAND_DIR_BONE = string_make(path); /* Build a path name */ sprintf(tail, "data%s", PATH_SEP); ANGBAND_DIR_DATA = string_make(path); /* Build a path name */ sprintf(tail, "edit%s", PATH_SEP); ANGBAND_DIR_EDIT = string_make(path); /* Build a path name */ sprintf(tail, "file%s", PATH_SEP); ANGBAND_DIR_FILE = string_make(path); /* Build a path name */ sprintf(tail, "help%s", PATH_SEP); ANGBAND_DIR_HELP = string_make(path); /* Build a path name */ sprintf(tail, "info%s", PATH_SEP); ANGBAND_DIR_INFO = string_make(path); /* Build a path name */ sprintf(tail, "save%s", PATH_SEP); ANGBAND_DIR_SAVE = string_make(path); /* Build a path name */ sprintf(tail, "user%s", PATH_SEP); ANGBAND_DIR_USER = string_make(path); /* Build a path name */ sprintf(tail, "xtra%s", PATH_SEP); ANGBAND_DIR_XTRA = string_make(path); #endif /* VM */ #ifdef NeXT /* Allow "fat binary" usage with NeXT */ if (TRUE) { cptr next = ""; # if defined(m68k) next = "m68k."; # endif # if defined(i386) next = "i386."; # endif # if defined(sparc) next = "sparc."; # endif # if defined(hppa) next = "hppa."; # endif /* Forget the old path name */ string_free(ANGBAND_DIR_DATA); /* Build a new path name */ sprintf(tail, "data%s%s", PATH_SEP, next); ANGBAND_DIR_DATA = string_make(path); } #endif /* NeXT */ } /* * Hack -- Explain a broken "lib" folder and quit (see below). * * XXX XXX XXX This function is "messy" because various things * may or may not be initialized, but the "plog()" and "quit()" * functions are "supposed" to work under any conditions. */ static void show_news_aux(cptr why) { /* Why */ plog(why); /* Explain */ plog("The 'lib' directory is probably missing or broken."); /* More details */ plog("Perhaps the archive was not extracted correctly."); /* Explain */ plog("See the 'README' file for more information."); /* Quit with error */ quit("Fatal Error."); } /* * Hack -- verify some files, and display the "news.txt" file * * This function is often called before "init_some_arrays()", * but after the "term.c" package has been initialized, so * be aware that many functions will not be "usable" yet. * * Note that this function attempts to verify the "news" file, * and the game aborts (cleanly) on failure. * * Note that this function attempts to verify (or create) the * "high score" file, and the game aborts (cleanly) on failure. * * Note that one of the most common "extraction" errors involves * failing to extract all sub-directories (even empty ones), such * as by failing to use the "-d" option of "pkunzip", or failing * to use the "save empty directories" option with "Compact Pro". * This error will often be caught by the "high score" creation * code below, since the "lib/apex" directory, being empty in the * standard distributions, is most likely to be "lost", making it * impossible to create the high score file. */ void show_news(void) { int fd = -1; int mode = 0644; FILE *fp; char buf[1024]; /*** Verify the "news" file ***/ /* Access the "news.txt" file */ strcpy(buf, ANGBAND_DIR_FILE); strcat(buf, "news.txt"); /* Attempt to open the file */ fd = fd_open(buf, O_RDONLY); /* Failure */ if (fd < 0) { char why[1024]; /* Message */ sprintf(why, "Cannot access the '%s' file!", buf); /* Crash and burn */ show_news_aux(why); } /* Close it */ (void)fd_close(fd); /*** Display the "news" file ***/ /* Clear the screen */ clear_screen(); /* Access the "news" file */ strcpy(buf, ANGBAND_DIR_FILE); strcat(buf, "news.txt"); /* Open the News file */ fp = my_fopen(buf, "r"); /* Dump */ if (fp) { int i = 0; /* Dump the file to the screen */ while (0 == my_fgets(fp, buf, 1024)) { /* Display and advance */ put_str(buf, i++, 0); } /* Close */ my_fclose(fp); } /* Flush it */ Term_fresh(); /*** Verify (or create) the "high score" file ***/ /* Access the high score file */ strcpy(buf, ANGBAND_DIR_APEX); strcat(buf, "scores.raw"); /* Attempt to open the high score file */ fd = fd_open(buf, O_RDONLY); /* Failure */ if (fd < 0) { #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Create a new high score file */ fd = fd_make(buf, mode); /* Failure */ if (fd < 0) { char why[1024]; /* Message */ sprintf(why, "Cannot create the '%s' file!", buf); /* Crash and burn */ show_news_aux(why); } } /* Close it */ (void)fd_close(fd); } /* * Hack -- take notes on line 23 */ static void note(cptr str) { Term_erase(0, 23, 80, 1); Term_putstr(20, 23, -1, TERM_WHITE, str); Term_fresh(); } #ifdef ALLOW_TEMPLATES /* * Hack -- help give useful error messages */ s16b error_idx; s16b error_line; /* * Hack -- help initialize the fake "name" and "text" arrays when * parsing an "ascii" template file. */ u16b fake_name_size; u16b fake_text_size; /* * Standard error message text */ static cptr err_str[8] = { NULL, "parse error", "obsolete file", "missing record header", "non-sequential records", "invalid flag specification", "undefined directive", "out of memory" }; #endif /*** Initialize from binary image files ***/ /* * Initialize the "f_info" array, by parsing a binary "image" file */ static errr init_f_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != f_head->v_major) || (test.v_minor != f_head->v_minor) || (test.v_patch != f_head->v_patch) || (test.v_extra != f_head->v_extra) || (test.info_num != f_head->info_num) || (test.info_len != f_head->info_len) || (test.head_size != f_head->head_size) || (test.info_size != f_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*f_head) = test; /* Allocate the "f_info" array */ C_MAKE(f_info, f_head->info_num, feature_type); /* Read the "f_info" array */ fd_read(fd, (char*)(f_info), f_head->info_size); /* Allocate the "f_name" array */ C_MAKE(f_name, f_head->name_size, char); /* Read the "f_name" array */ fd_read(fd, (char*)(f_name), f_head->name_size); #ifndef DELAY_LOAD_F_TEXT /* Allocate the "f_text" array */ C_MAKE(f_text, f_head->text_size, char); /* Read the "f_text" array */ fd_read(fd, (char*)(f_text), f_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "f_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_f_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the header ***/ /* Allocate the "header" */ MAKE(f_head, header); /* Save the "version" */ f_head->v_major = VERSION_MAJOR; f_head->v_minor = VERSION_MINOR; f_head->v_patch = VERSION_PATCH; f_head->v_extra = VERSION_TYPE; /* Save the "record" information */ f_head->info_num = MAX_F_IDX; f_head->info_len = sizeof(feature_type); /* Save the size of "f_head" and "f_info" */ f_head->head_size = sizeof(header); f_head->info_size = f_head->info_num * f_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "f_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "f_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_f_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'f_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Fake the size of "f_name" and "f_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "f_info" array */ C_MAKE(f_info, f_head->info_num, feature_type); /* Hack -- make "fake" arrays */ C_MAKE(f_name, fake_name_size, char); C_MAKE(f_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "f_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "f_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'f_info.txt' file."); /* Parse the file */ err = init_f_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'f_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'f_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "f_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "f_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(f_head), f_head->head_size); /* Dump the "f_info" array */ fd_write(fd, (char*)(f_info), f_head->info_size); /* Dump the "f_name" array */ fd_write(fd, (char*)(f_name), f_head->name_size); /* Dump the "f_text" array */ fd_write(fd, (char*)(f_text), f_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "f_info" array */ C_KILL(f_info, f_head->info_num, feature_type); /* Hack -- Free the "fake" arrays */ C_KILL(f_name, fake_name_size, char); C_KILL(f_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "f_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "f_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot load 'f_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_f_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'f_info.raw' file."); /* Success */ return (0); } /* * Initialize the "k_info" array, by parsing a binary "image" file */ static errr init_k_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != k_head->v_major) || (test.v_minor != k_head->v_minor) || (test.v_patch != k_head->v_patch) || (test.v_extra != k_head->v_extra) || (test.info_num != k_head->info_num) || (test.info_len != k_head->info_len) || (test.head_size != k_head->head_size) || (test.info_size != k_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*k_head) = test; /* Allocate the "k_info" array */ C_MAKE(k_info, k_head->info_num, object_kind); /* Read the "k_info" array */ fd_read(fd, (char*)(k_info), k_head->info_size); /* Allocate the "k_name" array */ C_MAKE(k_name, k_head->name_size, char); /* Read the "k_name" array */ fd_read(fd, (char*)(k_name), k_head->name_size); #ifndef DELAY_LOAD_K_TEXT /* Allocate the "k_text" array */ C_MAKE(k_text, k_head->text_size, char); /* Read the "k_text" array */ fd_read(fd, (char*)(k_text), k_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "k_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_k_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the header ***/ /* Allocate the "header" */ MAKE(k_head, header); /* Save the "version" */ k_head->v_major = VERSION_MAJOR; k_head->v_minor = VERSION_MINOR; k_head->v_patch = VERSION_PATCH; k_head->v_extra = VERSION_TYPE; /* Save the "record" information */ k_head->info_num = MAX_K_IDX; k_head->info_len = sizeof(object_kind); /* Save the size of "k_head" and "k_info" */ k_head->head_size = sizeof(header); k_head->info_size = k_head->info_num * k_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "k_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "k_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_k_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'k_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Fake the size of "k_name" and "k_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "k_info" array */ C_MAKE(k_info, k_head->info_num, object_kind); /* Hack -- make "fake" arrays */ C_MAKE(k_name, fake_name_size, char); C_MAKE(k_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "k_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "k_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'k_info.txt' file."); /* Parse the file */ err = init_k_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'k_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'k_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "k_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "k_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(k_head), k_head->head_size); /* Dump the "k_info" array */ fd_write(fd, (char*)(k_info), k_head->info_size); /* Dump the "k_name" array */ fd_write(fd, (char*)(k_name), k_head->name_size); /* Dump the "k_text" array */ fd_write(fd, (char*)(k_text), k_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "k_info" array */ C_KILL(k_info, k_head->info_num, object_kind); /* Hack -- Free the "fake" arrays */ C_KILL(k_name, fake_name_size, char); C_KILL(k_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "k_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "k_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot load 'k_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_k_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'k_info.raw' file."); /* Success */ return (0); } /* * Initialize the "a_info" array, by parsing a binary "image" file */ static errr init_a_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != a_head->v_major) || (test.v_minor != a_head->v_minor) || (test.v_patch != a_head->v_patch) || (test.v_extra != a_head->v_extra) || (test.info_num != a_head->info_num) || (test.info_len != a_head->info_len) || (test.head_size != a_head->head_size) || (test.info_size != a_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*a_head) = test; /* Allocate the "a_info" array */ C_MAKE(a_info, a_head->info_num, artifact_type); /* Read the "a_info" array */ fd_read(fd, (char*)(a_info), a_head->info_size); /* Allocate the "a_name" array */ C_MAKE(a_name, a_head->name_size, char); /* Read the "a_name" array */ fd_read(fd, (char*)(a_name), a_head->name_size); #ifndef DELAY_LOAD_A_TEXT /* Allocate the "a_text" array */ C_MAKE(a_text, a_head->text_size, char); /* Read the "a_text" array */ fd_read(fd, (char*)(a_text), a_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "a_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_a_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the "header" ***/ /* Allocate the "header" */ MAKE(a_head, header); /* Save the "version" */ a_head->v_major = VERSION_MAJOR; a_head->v_minor = VERSION_MINOR; a_head->v_patch = VERSION_PATCH; a_head->v_extra = VERSION_TYPE; /* Save the "record" information */ a_head->info_num = MAX_A_IDX; a_head->info_len = sizeof(artifact_type); /* Save the size of "a_head" and "a_info" */ a_head->head_size = sizeof(header); a_head->info_size = a_head->info_num * a_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "a_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "a_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_a_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'a_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Fake the size of "a_name" and "a_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "a_info" array */ C_MAKE(a_info, a_head->info_num, artifact_type); /* Hack -- make "fake" arrays */ C_MAKE(a_name, fake_name_size, char); C_MAKE(a_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "a_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "a_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'a_info.txt' file."); /* Parse the file */ err = init_a_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'a_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'a_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "a_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "a_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(a_head), a_head->head_size); /* Dump the "a_info" array */ fd_write(fd, (char*)(a_info), a_head->info_size); /* Dump the "a_name" array */ fd_write(fd, (char*)(a_name), a_head->name_size); /* Dump the "a_text" array */ fd_write(fd, (char*)(a_text), a_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "a_info" array */ C_KILL(a_info, a_head->info_num, artifact_type); /* Hack -- Free the "fake" arrays */ C_KILL(a_name, fake_name_size, char); C_KILL(a_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "a_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "a_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot open 'a_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_a_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'a_info.raw' file."); /* Success */ return (0); } /* * Initialize the "e_info" array, by parsing a binary "image" file */ static errr init_e_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != e_head->v_major) || (test.v_minor != e_head->v_minor) || (test.v_patch != e_head->v_patch) || (test.v_extra != e_head->v_extra) || (test.info_num != e_head->info_num) || (test.info_len != e_head->info_len) || (test.head_size != e_head->head_size) || (test.info_size != e_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*e_head) = test; /* Allocate the "e_info" array */ C_MAKE(e_info, e_head->info_num, ego_item_type); /* Read the "e_info" array */ fd_read(fd, (char*)(e_info), e_head->info_size); /* Allocate the "e_name" array */ C_MAKE(e_name, e_head->name_size, char); /* Read the "e_name" array */ fd_read(fd, (char*)(e_name), e_head->name_size); #ifndef DELAY_LOAD_E_TEXT /* Allocate the "e_text" array */ C_MAKE(e_text, e_head->text_size, char); /* Read the "e_text" array */ fd_read(fd, (char*)(e_text), e_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "e_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_e_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the "header" ***/ /* Allocate the "header" */ MAKE(e_head, header); /* Save the "version" */ e_head->v_major = VERSION_MAJOR; e_head->v_minor = VERSION_MINOR; e_head->v_patch = VERSION_PATCH; e_head->v_extra = VERSION_TYPE; /* Save the "record" information */ e_head->info_num = MAX_E_IDX; e_head->info_len = sizeof(ego_item_type); /* Save the size of "e_head" and "e_info" */ e_head->head_size = sizeof(header); e_head->info_size = e_head->info_num * e_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "e_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "e_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_e_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'e_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Fake the size of "e_name" and "e_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "e_info" array */ C_MAKE(e_info, e_head->info_num, ego_item_type); /* Hack -- make "fake" arrays */ C_MAKE(e_name, fake_name_size, char); C_MAKE(e_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "e_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "e_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'e_info.txt' file."); /* Parse the file */ err = init_e_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'e_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'e_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "e_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "e_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(e_head), e_head->head_size); /* Dump the "e_info" array */ fd_write(fd, (char*)(e_info), e_head->info_size); /* Dump the "e_name" array */ fd_write(fd, (char*)(e_name), e_head->name_size); /* Dump the "e_text" array */ fd_write(fd, (char*)(e_text), e_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "e_info" array */ C_KILL(e_info, e_head->info_num, ego_item_type); /* Hack -- Free the "fake" arrays */ C_KILL(e_name, fake_name_size, char); C_KILL(e_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "e_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "e_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot load 'e_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_e_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'e_info.raw' file."); /* Success */ return (0); } /* * Initialize the "r_info" array, by parsing a binary "image" file */ static errr init_r_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != r_head->v_major) || (test.v_minor != r_head->v_minor) || (test.v_patch != r_head->v_patch) || (test.v_extra != r_head->v_extra) || (test.info_num != r_head->info_num) || (test.info_len != r_head->info_len) || (test.head_size != r_head->head_size) || (test.info_size != r_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*r_head) = test; /* Allocate the "r_info" array */ C_MAKE(r_info, r_head->info_num, monster_race); /* Read the "r_info" array */ fd_read(fd, (char*)(r_info), r_head->info_size); /* Allocate the "r_name" array */ C_MAKE(r_name, r_head->name_size, char); /* Read the "r_name" array */ fd_read(fd, (char*)(r_name), r_head->name_size); #ifndef DELAY_LOAD_R_TEXT /* Allocate the "r_text" array */ C_MAKE(r_text, r_head->text_size, char); /* Read the "r_text" array */ fd_read(fd, (char*)(r_text), r_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "r_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_r_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the header ***/ /* Allocate the "header" */ MAKE(r_head, header); /* Save the "version" */ r_head->v_major = VERSION_MAJOR; r_head->v_minor = VERSION_MINOR; r_head->v_patch = VERSION_PATCH; r_head->v_extra = VERSION_TYPE; /* Save the "record" information */ r_head->info_num = MAX_R_IDX; r_head->info_len = sizeof(monster_race); /* Save the size of "r_head" and "r_info" */ r_head->head_size = sizeof(header); r_head->info_size = r_head->info_num * r_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "r_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "r_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_r_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'r_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Assume the size of "r_name" and "r_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "r_info" array */ C_MAKE(r_info, r_head->info_num, monster_race); /* Hack -- make "fake" arrays */ C_MAKE(r_name, fake_name_size, char); C_MAKE(r_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "r_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "r_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'r_info.txt' file."); /* Parse the file */ err = init_r_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'r_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'r_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "r_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "r_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(r_head), r_head->head_size); /* Dump the "r_info" array */ fd_write(fd, (char*)(r_info), r_head->info_size); /* Dump the "r_name" array */ fd_write(fd, (char*)(r_name), r_head->name_size); /* Dump the "r_text" array */ fd_write(fd, (char*)(r_text), r_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "r_info" array */ C_KILL(r_info, r_head->info_num, monster_race); /* Hack -- Free the "fake" arrays */ C_KILL(r_name, fake_name_size, char); C_KILL(r_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "r_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "r_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot load 'r_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_r_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'r_info.raw' file."); /* Success */ return (0); } /* * Initialize the "v_info" array, by parsing a binary "image" file */ static errr init_v_info_raw(int fd) { header test; /* Read and Verify the header */ if (fd_read(fd, (char*)(&test), sizeof(header)) || (test.v_major != v_head->v_major) || (test.v_minor != v_head->v_minor) || (test.v_patch != v_head->v_patch) || (test.v_extra != v_head->v_extra) || (test.info_num != v_head->info_num) || (test.info_len != v_head->info_len) || (test.head_size != v_head->head_size) || (test.info_size != v_head->info_size)) { /* Error */ return (-1); } /* Accept the header */ (*v_head) = test; /* Allocate the "v_info" array */ C_MAKE(v_info, v_head->info_num, vault_type); /* Read the "v_info" array */ fd_read(fd, (char*)(v_info), v_head->info_size); /* Allocate the "v_name" array */ C_MAKE(v_name, v_head->name_size, char); /* Read the "v_name" array */ fd_read(fd, (char*)(v_name), v_head->name_size); #ifndef DELAY_LOAD_V_TEXT /* Allocate the "v_text" array */ C_MAKE(v_text, v_head->text_size, char); /* Read the "v_text" array */ fd_read(fd, (char*)(v_text), v_head->text_size); #endif /* Success */ return (0); } /* * Initialize the "v_info" array * * Note that we let each entry have a unique "name" and "text" string, * even if the string happens to be empty (everyone has a unique '\0'). */ static errr init_v_info(void) { int fd; int mode = 0644; errr err; FILE *fp; /* General buffer */ char buf[1024]; /*** Make the header ***/ /* Allocate the "header" */ MAKE(v_head, header); /* Save the "version" */ v_head->v_major = VERSION_MAJOR; v_head->v_minor = VERSION_MINOR; v_head->v_patch = VERSION_PATCH; v_head->v_extra = VERSION_TYPE; /* Save the "record" information */ v_head->info_num = MAX_V_IDX; v_head->info_len = sizeof(feature_type); /* Save the size of "v_head" and "v_info" */ v_head->head_size = sizeof(header); v_head->info_size = v_head->info_num * v_head->info_len; #ifdef ALLOW_TEMPLATES /*** Load the binary image file ***/ /* Access the "v_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "v_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd >= 0) { /* Attempt to parse the "raw" file */ err = init_v_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Success */ if (!err) return (0); /* Information */ msg_print("Ignoring obsolete/defective 'v_info.raw' file."); msg_print(NULL); } /*** Make the fake arrays ***/ /* Fake the size of "v_name" and "v_text" */ fake_name_size = 20 * 1024L; fake_text_size = 60 * 1024L; /* Allocate the "k_info" array */ C_MAKE(v_info, v_head->info_num, vault_type); /* Hack -- make "fake" arrays */ C_MAKE(v_name, fake_name_size, char); C_MAKE(v_text, fake_text_size, char); /*** Load the ascii template file ***/ /* Access the "v_info.txt" file */ strcpy(buf, ANGBAND_DIR_EDIT); strcat(buf, "v_info.txt"); /* Open the file */ fp = my_fopen(buf, "r"); /* Parse it */ if (!fp) quit("Cannot open 'v_info.txt' file."); /* Parse the file */ err = init_v_info_txt(fp, buf); /* Close it */ my_fclose(fp); /* Errors */ if (err) { cptr oops; /* Error string */ oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown"); /* Oops */ msg_format("Error %d at line %d of 'v_info.txt'.", err, error_line); msg_format("Record %d contains a '%s' error.", error_idx, oops); msg_format("Parsing '%s'.", buf); msg_print(NULL); /* Quit */ quit("Error in 'v_info.txt' file."); } /*** Dump the binary image file ***/ #if defined(MACINTOSH) && !defined(applec) /* Global -- "data file" */ _feate = 'DATA'; #endif /* Access the "v_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "v_info.raw"); /* Attempt to create the raw file */ fd = fd_make(buf, mode); /* Dump to the file */ if (fd >= 0) { /* Dump it */ fd_write(fd, (char*)(v_head), v_head->head_size); /* Dump the "v_info" array */ fd_write(fd, (char*)(v_info), v_head->info_size); /* Dump the "v_name" array */ fd_write(fd, (char*)(v_name), v_head->name_size); /* Dump the "v_text" array */ fd_write(fd, (char*)(v_text), v_head->text_size); /* Close */ (void)fd_close(fd); } /*** Kill the fake arrays ***/ /* Free the "v_info" array */ C_KILL(v_info, v_head->info_num, vault_type); /* Hack -- Free the "fake" arrays */ C_KILL(v_name, fake_name_size, char); C_KILL(v_text, fake_text_size, char); /* Forget the array sizes */ fake_name_size = 0; fake_text_size = 0; #endif /* ALLOW_TEMPLATES */ /*** Load the binary image file ***/ /* Access the "v_info.raw" file */ strcpy(buf, ANGBAND_DIR_DATA); strcat(buf, "v_info.raw"); /* Attempt to open the "raw" file */ fd = fd_open(buf, O_RDONLY); /* Process existing "raw" file */ if (fd < 0) quit("Cannot load 'v_info.raw' file."); /* Attempt to parse the "raw" file */ err = init_v_info_raw(fd); /* Close it */ (void)fd_close(fd); /* Error */ if (err) quit("Cannot parse 'v_info.raw' file."); /* Success */ return (0); } /*** Initialize others ***/ /* * Hack -- Objects sold in the stores -- by tval/sval pair. */ static byte store_table[MAX_STORES-2][STORE_CHOICES][2] = { { /* General Store */ { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_RATION }, { TV_FOOD, SV_FOOD_BISCUIT }, { TV_FOOD, SV_FOOD_JERKY }, { TV_FOOD, SV_FOOD_PINT_OF_WINE }, { TV_FOOD, SV_FOOD_PINT_OF_ALE }, { TV_DIGGING, SV_SHOVEL }, { TV_DIGGING, SV_PICK }, { TV_CLOAK, SV_CLOAK }, { TV_CLOAK, SV_CLOAK }, { TV_CLOAK, SV_CLOAK }, { TV_CLOAK, SV_CLOAK }, { TV_POTION, SV_POTION_WATER }, { TV_POTION, SV_POTION_WATER }, { TV_POTION, SV_POTION_WATER }, { TV_POTION, SV_POTION_APPLE_JUICE }, { TV_LITE, SV_LITE_TORCH }, { TV_LITE, SV_LITE_TORCH }, { TV_LITE, SV_LITE_TORCH }, { TV_LITE, SV_LITE_TORCH }, { TV_LITE, SV_LITE_LANTERN }, { TV_LITE, SV_LITE_LANTERN }, { TV_FLASK, 0 }, { TV_FLASK, 0 }, { TV_FLASK, 0 }, { TV_FLASK, 0 }, { TV_FLASK, 0 }, { TV_FLASK, 0 } }, { /* Armory */ { TV_BOOTS, SV_PAIR_OF_SOFT_LEATHER_BOOTS }, { TV_BOOTS, SV_PAIR_OF_SOFT_LEATHER_BOOTS }, { TV_BOOTS, SV_PAIR_OF_HARD_LEATHER_BOOTS }, { TV_BOOTS, SV_PAIR_OF_HARD_LEATHER_BOOTS }, { TV_HELM, SV_HARD_LEATHER_CAP }, { TV_HELM, SV_HARD_LEATHER_CAP }, { TV_HELM, SV_METAL_CAP }, { TV_HELM, SV_IRON_HELM }, { TV_SOFT_ARMOR, SV_ROBE }, { TV_SOFT_ARMOR, SV_ROBE }, { TV_SOFT_ARMOR, SV_SOFT_LEATHER_ARMOR }, { TV_SOFT_ARMOR, SV_SOFT_LEATHER_ARMOR }, { TV_SOFT_ARMOR, SV_HARD_LEATHER_ARMOR }, { TV_SOFT_ARMOR, SV_HARD_LEATHER_ARMOR }, { TV_SOFT_ARMOR, SV_HARD_STUDDED_LEATHER }, { TV_SOFT_ARMOR, SV_LEATHER_SCALE_MAIL }, { TV_SOFT_ARMOR, SV_LEATHER_SCALE_MAIL }, { TV_HARD_ARMOR, SV_METAL_SCALE_MAIL }, { TV_HARD_ARMOR, SV_CHAIN_MAIL }, { TV_HARD_ARMOR, SV_CHAIN_MAIL }, { TV_HARD_ARMOR, SV_AUGMENTED_CHAIN_MAIL }, { TV_HARD_ARMOR, SV_BAR_CHAIN_MAIL }, { TV_HARD_ARMOR, SV_METAL_BRIGANDINE_ARMOR }, { TV_HARD_ARMOR, SV_DOUBLE_CHAIN_MAIL }, { TV_GLOVES, SV_SET_OF_LEATHER_GLOVES }, { TV_GLOVES, SV_SET_OF_LEATHER_GLOVES }, { TV_GLOVES, SV_SET_OF_GAUNTLETS }, { TV_SHIELD, SV_SMALL_LEATHER_SHIELD }, { TV_SHIELD, SV_SMALL_LEATHER_SHIELD }, { TV_SHIELD, SV_LARGE_LEATHER_SHIELD }, { TV_SHIELD, SV_SMALL_METAL_SHIELD } }, { /* Weaponsmith */ { TV_SWORD, SV_DAGGER }, { TV_SWORD, SV_MAIN_GAUCHE }, { TV_SWORD, SV_RAPIER }, { TV_SWORD, SV_SMALL_SWORD }, { TV_SWORD, SV_SHORT_SWORD }, { TV_SWORD, SV_SABRE }, { TV_SWORD, SV_CUTLASS }, { TV_SWORD, SV_TULWAR }, { TV_SWORD, SV_BROAD_SWORD }, { TV_SWORD, SV_LONG_SWORD }, { TV_SWORD, SV_SCIMITAR }, { TV_SWORD, SV_KATANA }, { TV_SWORD, SV_BASTARD_SWORD }, { TV_POLEARM, SV_SPEAR }, { TV_POLEARM, SV_AWL_PIKE }, { TV_POLEARM, SV_TRIDENT }, { TV_POLEARM, SV_PIKE }, { TV_POLEARM, SV_BEAKED_AXE }, { TV_POLEARM, SV_BROAD_AXE }, { TV_POLEARM, SV_LANCE }, { TV_POLEARM, SV_BATTLE_AXE }, { TV_HAFTED, SV_WHIP }, { TV_BOW, SV_SLING }, { TV_BOW, SV_SHORT_BOW }, { TV_BOW, SV_LONG_BOW }, { TV_BOW, SV_LIGHT_XBOW }, { TV_SHOT, SV_AMMO_LIGHT }, { TV_SHOT, SV_AMMO_NORMAL }, { TV_ARROW, SV_AMMO_NORMAL }, { TV_ARROW, SV_AMMO_NORMAL }, { TV_BOLT, SV_AMMO_NORMAL }, { TV_BOLT, SV_AMMO_NORMAL }, }, { /* Temple */ { TV_HAFTED, SV_WHIP }, { TV_HAFTED, SV_QUARTERSTAFF }, { TV_HAFTED, SV_MACE }, { TV_HAFTED, SV_BALL_AND_CHAIN }, { TV_HAFTED, SV_WAR_HAMMER }, { TV_HAFTED, SV_LUCERN_HAMMER }, { TV_HAFTED, SV_MORNING_STAR }, { TV_HAFTED, SV_FLAIL }, { TV_HAFTED, SV_LEAD_FILLED_MACE }, { TV_SCROLL, SV_SCROLL_REMOVE_CURSE }, { TV_SCROLL, SV_SCROLL_BLESSING }, { TV_SCROLL, SV_SCROLL_HOLY_CHANT }, { TV_POTION, SV_POTION_BOLDNESS }, { TV_POTION, SV_POTION_HEROISM }, { TV_POTION, SV_POTION_CURE_LIGHT }, { TV_POTION, SV_POTION_CURE_SERIOUS }, { TV_POTION, SV_POTION_CURE_SERIOUS }, { TV_POTION, SV_POTION_CURE_CRITICAL }, { TV_POTION, SV_POTION_CURE_CRITICAL }, { TV_POTION, SV_POTION_RESTORE_EXP }, { TV_POTION, SV_POTION_RESTORE_EXP }, { TV_POTION, SV_POTION_RESTORE_EXP }, { TV_PRAYER_BOOK, 0 }, { TV_PRAYER_BOOK, 0 }, { TV_PRAYER_BOOK, 0 }, { TV_PRAYER_BOOK, 0 }, { TV_PRAYER_BOOK, 1 }, { TV_PRAYER_BOOK, 1 }, { TV_PRAYER_BOOK, 1 }, { TV_PRAYER_BOOK, 2 }, { TV_PRAYER_BOOK, 2 }, { TV_PRAYER_BOOK, 3 } }, { /* Alchemy shop */ { TV_SCROLL, SV_SCROLL_ENCHANT_WEAPON_TO_HIT }, { TV_SCROLL, SV_SCROLL_ENCHANT_WEAPON_TO_DAM }, { TV_SCROLL, SV_SCROLL_ENCHANT_ARMOR }, { TV_SCROLL, SV_SCROLL_IDENTIFY }, { TV_SCROLL, SV_SCROLL_IDENTIFY }, { TV_SCROLL, SV_SCROLL_IDENTIFY }, { TV_SCROLL, SV_SCROLL_IDENTIFY }, { TV_SCROLL, SV_SCROLL_LIGHT }, { TV_SCROLL, SV_SCROLL_PHASE_DOOR }, { TV_SCROLL, SV_SCROLL_PHASE_DOOR }, { TV_SCROLL, SV_SCROLL_PHASE_DOOR }, { TV_SCROLL, SV_SCROLL_MONSTER_CONFUSION }, { TV_SCROLL, SV_SCROLL_MAPPING }, { TV_SCROLL, SV_SCROLL_DETECT_GOLD }, { TV_SCROLL, SV_SCROLL_DETECT_ITEM }, { TV_SCROLL, SV_SCROLL_DETECT_TRAP }, { TV_SCROLL, SV_SCROLL_DETECT_DOOR }, { TV_SCROLL, SV_SCROLL_DETECT_INVIS }, { TV_SCROLL, SV_SCROLL_RECHARGING }, { TV_SCROLL, SV_SCROLL_SATISFY_HUNGER }, { TV_SCROLL, SV_SCROLL_WORD_OF_RECALL }, { TV_SCROLL, SV_SCROLL_WORD_OF_RECALL }, { TV_SCROLL, SV_SCROLL_WORD_OF_RECALL }, { TV_SCROLL, SV_SCROLL_WORD_OF_RECALL }, { TV_POTION, SV_POTION_RESIST_HEAT }, { TV_POTION, SV_POTION_RESIST_COLD }, { TV_POTION, SV_POTION_RES_STR }, { TV_POTION, SV_POTION_RES_INT }, { TV_POTION, SV_POTION_RES_WIS }, { TV_POTION, SV_POTION_RES_DEX }, { TV_POTION, SV_POTION_RES_CON }, { TV_POTION, SV_POTION_RES_CHR } }, { /* Magic-User store */ { TV_RING, SV_RING_SEARCHING }, { TV_RING, SV_RING_FEATHER_FALL }, { TV_RING, SV_RING_PROTECTION }, { TV_AMULET, SV_AMULET_CHARISMA }, { TV_AMULET, SV_AMULET_SLOW_DIGEST }, { TV_AMULET, SV_AMULET_RESIST_ACID }, { TV_WAND, SV_WAND_SLOW_MONSTER }, { TV_WAND, SV_WAND_CONFUSE_MONSTER }, { TV_WAND, SV_WAND_SLEEP_MONSTER }, { TV_WAND, SV_WAND_MAGIC_MISSILE }, { TV_WAND, SV_WAND_STINKING_CLOUD }, { TV_WAND, SV_WAND_WONDER }, { TV_STAFF, SV_STAFF_LITE }, { TV_STAFF, SV_STAFF_MAPPING }, { TV_STAFF, SV_STAFF_DETECT_TRAP }, { TV_STAFF, SV_STAFF_DETECT_DOOR }, { TV_STAFF, SV_STAFF_DETECT_GOLD }, { TV_STAFF, SV_STAFF_DETECT_ITEM }, { TV_STAFF, SV_STAFF_DETECT_INVIS }, { TV_STAFF, SV_STAFF_DETECT_EVIL }, { TV_STAFF, SV_STAFF_TELEPORTATION }, { TV_STAFF, SV_STAFF_IDENTIFY }, { TV_MAGIC_BOOK, 0 }, { TV_MAGIC_BOOK, 0 }, { TV_MAGIC_BOOK, 0 }, { TV_MAGIC_BOOK, 0 }, { TV_MAGIC_BOOK, 1 }, { TV_MAGIC_BOOK, 1 }, { TV_MAGIC_BOOK, 1 }, { TV_MAGIC_BOOK, 2 }, { TV_MAGIC_BOOK, 2 }, { TV_MAGIC_BOOK, 3 } } }; /* * Initialize some other arrays */ static errr init_other(void) { int i, j, k; object_kind *k_ptr; monster_race *r_ptr; s16b aux[256]; /*** Prepare the "dungeon" information ***/ /* Allocate and Wipe the object list */ C_MAKE(i_list, MAX_I_IDX, object_type); /* Allocate and Wipe the monster list */ C_MAKE(m_list, MAX_M_IDX, monster_type); /* Allocate and wipe each line of the cave */ for (i = 0; i < MAX_HGT; i++) { /* Allocate one row of the cave */ C_MAKE(cave[i], MAX_WID, cave_type); } /*** Prepare the various "bizarre" arrays ***/ /* Macro variables */ C_MAKE(macro__pat, MACRO_MAX, cptr); C_MAKE(macro__act, MACRO_MAX, cptr); C_MAKE(macro__cmd, MACRO_MAX, bool); /* Macro action buffer */ C_MAKE(macro__buf, 1024, char); /* Quark variables */ C_MAKE(quark__str, QUARK_MAX, cptr); /* Message variables */ C_MAKE(message__ptr, MESSAGE_MAX, u16b); C_MAKE(message__buf, MESSAGE_BUF, char); /* Hack -- No messages yet */ message__tail = MESSAGE_BUF; /*** Prepare the Player inventory ***/ /* Allocate it */ C_MAKE(inventory, INVEN_TOTAL, object_type); /*** Prepare the Object Kind Allocator ***/ /* Clear the aux array */ C_WIPE(&aux, MAX_DEPTH, s16b); /* Make the index */ C_MAKE(alloc_kind_index, MAX_DEPTH, s16b); /* Scan all of the objects */ for (i = 1; i < MAX_K_IDX; i++) { /* Get the i'th object */ k_ptr = &k_info[i]; /* Scan all of the locale/chance pairs */ for (j = 0; j < 4; j++) { /* Count valid pairs */ if (k_ptr->chance[j] && (k_ptr->locale[j] < MAX_DEPTH)) { /* Count the total entries */ alloc_kind_size++; /* Count the entries at each level */ alloc_kind_index[k_ptr->locale[j]]++; } } } /* Combine the "alloc_kind_index" entries */ for (i = 1; i < MAX_DEPTH; i++) { alloc_kind_index[i] += alloc_kind_index[i-1]; } /* Allocate the table */ C_MAKE(alloc_kind_table, alloc_kind_size, kind_entry); /* Initialize the table */ for (i = 1; i < MAX_K_IDX; i++) { /* Get the i'th object */ k_ptr = &k_info[i]; /* Scan all of the locale/chance pairs */ for (j = 0; j < 4; j++) { /* Count valid pairs */ if (k_ptr->chance[j] && (k_ptr->locale[j] < MAX_DEPTH)) { int r, x, y, z; /* Extract the chance/locale */ r = k_ptr->chance[j]; x = k_ptr->locale[j]; /* Skip entries preceding our locale */ y = (x > 0) ? alloc_kind_index[x-1] : 0; /* Skip previous entries at this locale */ z = y + aux[x]; /* Load the table entry */ alloc_kind_table[z].k_idx = i; alloc_kind_table[z].locale = x; alloc_kind_table[z].chance = r; /* Another entry complete for this locale */ aux[x]++; } } } /* Paranoia */ if (!alloc_kind_index[0]) quit("No town objects!"); /*** Prepare the Monster Race Allocator ***/ /* Clear the aux array */ C_WIPE(&aux, MAX_DEPTH, s16b); /* Allocate and clear the index */ C_MAKE(alloc_race_index, MAX_DEPTH, s16b); /* Scan the monsters (not the ghost) */ for (i = 1; i < MAX_R_IDX - 1; i++) { /* Get the i'th race */ r_ptr = &r_info[i]; /* Process "real" monsters */ if (r_ptr->rarity && (r_ptr->level < MAX_DEPTH)) { /* Count the total entries */ alloc_race_size++; /* Count the entries at each level */ alloc_race_index[r_ptr->level]++; } } /* Combine the "alloc_race_index" entries */ for (i = 1; i < MAX_DEPTH; i++) { alloc_race_index[i] += alloc_race_index[i-1]; } /* Allocate the alloc_race_table */ C_MAKE(alloc_race_table, alloc_race_size, race_entry); /* Scan the monsters (not the ghost) */ for (i = 1; i < MAX_R_IDX - 1; i++) { /* Get the i'th race */ r_ptr = &r_info[i]; /* Count valid pairs */ if (r_ptr->rarity && (r_ptr->level < MAX_DEPTH)) { int r, x, y, z; /* Extract the level/rarity */ x = r_ptr->level; r = r_ptr->rarity; /* Skip entries preceding our locale */ y = (x > 0) ? alloc_race_index[x-1] : 0; /* Skip previous entries at this locale */ z = y + aux[x]; /* Load the table entry */ alloc_race_table[z].r_idx = i; alloc_race_table[z].locale = x; alloc_race_table[z].chance = r; /* Another entry complete for this locale */ aux[x]++; } } /* Paranoia */ if (!alloc_race_index[0]) quit("No town monsters!"); /*** Prepare the Stores ***/ /* Allocate the stores */ C_MAKE(store, MAX_STORES, store_type); /* Fill in each store */ for (i = 0; i < MAX_STORES; i++) { /* Access the store */ store_type *st_ptr = &store[i]; /* Assume full stock */ st_ptr->stock_size = STORE_INVEN_MAX; /* Allocate the stock */ C_MAKE(st_ptr->stock, st_ptr->stock_size, object_type); /* No table for the black market or home */ if ((i == 6) || (i == 7)) continue; /* Assume full table */ st_ptr->table_size = STORE_CHOICES; /* Allocate the stock */ C_MAKE(st_ptr->table, st_ptr->table_size, s16b); /* Scan the choices */ for (k = 0; k < STORE_CHOICES; k++) { int k_idx; /* Extract the tval/sval codes */ int tv = store_table[i][k][0]; int sv = store_table[i][k][1]; /* Look for it */ for (k_idx = 1; k_idx < MAX_K_IDX; k_idx++) { object_kind *k_ptr = &k_info[k_idx]; /* Found a match */ if ((k_ptr->tval == tv) && (k_ptr->sval == sv)) break; } /* Catch errors */ if (k_idx == MAX_K_IDX) continue; /* Add that item index to the table */ st_ptr->table[st_ptr->table_num++] = k_idx; } } /*** Pre-allocate the basic "auto-inscriptions" ***/ /* The "basic" feelings */ quark_add("cursed"); quark_add("broken"); quark_add("average"); quark_add("good"); /* The "extra" feelings */ quark_add("excellent"); quark_add("worthless"); quark_add("special"); quark_add("terrible"); /* Some extra strings */ quark_add("uncursed"); quark_add("on sale"); /*** Set the "default" options ***/ /* Scan the options */ for (i = 0; options[i].o_desc; i++) { /* Set the "default" options */ if (options[i].o_var) (*options[i].o_var) = options[i].o_norm; } /*** Pre-allocate space for the "format()" buffer ***/ /* Hack -- Just call the "format()" function */ format("%s (%s).", "Matt Craighead", MAINTAINER); /*** Pre-allocate space for save/restore screen ***/ /* Save the screen */ Term_save(); /* Save the screen (embedded) */ Term_save(); /* Restore the screen (embedded) */ Term_load(); /* Restore the screen */ Term_load(); /* Success */ return (0); } /* * Initialize various Angband variables and arrays. * * This initialization involves the parsing of special files * in the "lib/data" and sometimes the "lib/edit" directories. * * Note that the "template" files are initialized first, since they * often contain errors. This means that macros and message recall * and things like that are not available until after they are done. */ void init_some_arrays(void) { /* Initialize feature info */ note("[Initializing arrays... (features)]"); if (init_f_info()) quit("Cannot initialize features"); /* Initialize object info */ note("[Initializing arrays... (objects)]"); if (init_k_info()) quit("Cannot initialize objects"); /* Initialize artifact info */ note("[Initializing arrays... (artifacts)]"); if (init_a_info()) quit("Cannot initialize artifacts"); /* Initialize ego-item info */ note("[Initializing arrays... (ego-items)]"); if (init_e_info()) quit("Cannot initialize ego-items"); /* Initialize monster info */ note("[Initializing arrays... (monsters)]"); if (init_r_info()) quit("Cannot initialize monsters"); /* Initialize feature info */ note("[Initializing arrays... (vaults)]"); if (init_v_info()) quit("Cannot initialize vaults"); /* Initialize some other arrays */ note("[Initializing arrays...]"); if (init_other()) quit("Cannot initialize arrays"); /* Hack -- all done */ note("[Initializing arrays... done]"); }