root/trunk/src/init2.c

Revision 156, 39.4 kB (checked in by takkaria, 3 years ago)

Fix #56:

  • Stop squelching items in the pack without choice. Mark items as {squelch} instead of actually being squelched, Ey-style. Auto-mark items as squelch when we find out they're bad (e.g. potions). 'k!' squelches items marked {squelch}. Remove choice of empty chest squelching.
  • Remove ego-item squelching. Remove individual item squelch groups for pseudo-id-able items.
  • Remove item-based autopickup/neverpickup options, and add "Always pickup items matching those in inventory".
  • Rewrite squelch UI using new menus, except for main menu.
  • Simplify quality squelch to give choice of weapons/missiles/armour/lights/etc rather than. Remove "all items" and "just this item" UI junk.
Line 
1 /* File: init2.c */
2
3
4 /*
5  * Copyright (c) 1997 Ben Harrison
6  *
7  * This software may be copied and distributed for educational, research,
8  * and not for profit purposes provided that this copyright and statement
9  * are included in all such copies.  Other copyrights may also apply.
10  */
11
12 #include "angband.h"
13
14 #include "init.h"
15 #include "script.h"
16 #include "cmds.h"
17
18 /*
19  * This file is used to initialize various variables and arrays for the
20  * Angband game.  Note the use of "fd_read()" and "fd_write()" to bypass
21  * the common limitation of "read()" and "write()" to only 32767 bytes
22  * at a time.
23  *
24  * Several of the arrays for Angband are built from "template" files in
25  * the "lib/file" directory, from which quick-load binary "image" files
26  * are constructed whenever they are not present in the "lib/data"
27  * directory, or if those files become obsolete, if we are allowed.
28  *
29  * Warning -- the "ascii" file parsers use a minor hack to collect the
30  * name and text information in a single pass.  Thus, the game will not
31  * be able to load any template file with more than 20K of names or 60K
32  * of text, even though technically, up to 64K should be legal.
33  *
34  * The "init1.c" file is used only to parse the ascii template files,
35  * to create the binary image files.  If you include the binary image
36  * files instead of the ascii template files, then you can undefine
37  * "ALLOW_TEMPLATES", saving about 20K by removing "init1.c".  Note
38  * that the binary image files are extremely system dependant.
39  */
40
41
42
43 /*
44  * Find the default paths to all of our important sub-directories.
45  *
46  * The purpose of each sub-directory is described in "variable.c".
47  *
48  * All of the sub-directories should, by default, be located inside
49  * the main "lib" directory, whose location is very system dependant.
50  *
51  * This function takes a writable buffer, initially containing the
52  * "path" to the "lib" directory, for example, "/pkg/lib/angband/",
53  * or a system dependant string, for example, ":lib:".  The buffer
54  * must be large enough to contain at least 32 more characters.
55  *
56  * Various command line options may allow some of the important
57  * directories to be changed to user-specified directories, most
58  * importantly, the "info" and "user" and "save" directories,
59  * but this is done after this function, see "main.c".
60  *
61  * In general, the initial path should end in the appropriate "PATH_SEP"
62  * string.  All of the "sub-directory" paths (created below or supplied
63  * by the user) will NOT end in the "PATH_SEP" string, see the special
64  * "path_build()" function in "util.c" for more information.
65  *
66  * Hack -- first we free all the strings, since this is known
67  * to succeed even if the strings have not been allocated yet,
68  * as long as the variables start out as "NULL".  This allows
69  * this function to be called multiple times, for example, to
70  * try several base "path" values until a good one is found.
71  */
72 void init_file_paths(const char *path)
73 {
74 #ifdef PRIVATE_USER_PATH
75         char buf[1024];
76         char dirpath[1024];
77 #endif /* PRIVATE_USER_PATH */
78
79         /*** Free everything ***/
80
81         /* Free the main path */
82         string_free(ANGBAND_DIR);
83
84         /* Free the sub-paths */
85         string_free(ANGBAND_DIR_APEX);
86         string_free(ANGBAND_DIR_BONE);
87         string_free(ANGBAND_DIR_DATA);
88         string_free(ANGBAND_DIR_EDIT);
89         string_free(ANGBAND_DIR_FILE);
90         string_free(ANGBAND_DIR_HELP);
91         string_free(ANGBAND_DIR_INFO);
92         string_free(ANGBAND_DIR_SAVE);
93         string_free(ANGBAND_DIR_PREF);
94         string_free(ANGBAND_DIR_USER);
95         string_free(ANGBAND_DIR_XTRA);
96
97
98         /*** Prepare the paths ***/
99
100         /* Save the main directory */
101         ANGBAND_DIR = string_make(path);
102
103         /* Build path names */
104         ANGBAND_DIR_EDIT = string_make(format("%sedit", path));
105         ANGBAND_DIR_FILE = string_make(format("%sfile", path));
106         ANGBAND_DIR_HELP = string_make(format("%shelp", path));
107         ANGBAND_DIR_INFO = string_make(format("%sinfo", path));
108         ANGBAND_DIR_PREF = string_make(format("%spref", path));
109         ANGBAND_DIR_XTRA = string_make(format("%sxtra", path));
110
111
112 #ifdef PRIVATE_USER_PATH
113
114         /* Get an absolute path from the filename, */
115         path_parse(dirpath, sizeof(dirpath), PRIVATE_USER_PATH);
116
117         /* Build the path to the user specific directory */
118         path_build(buf, sizeof(buf), dirpath, VERSION_NAME);
119         ANGBAND_DIR_USER = string_make(buf);
120
121 #else /* PRIVATE_USER_PATH */
122
123         ANGBAND_DIR_USER = string_make(format("%suser", path));
124
125 #endif /* PRIVATE_USER_PATH */
126
127
128 #ifdef USE_PRIVATE_PATHS
129
130         /* Build the path to the user specific sub-directory */
131         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "scores");
132         ANGBAND_DIR_APEX = string_make(buf);
133
134         /* Build the path to the user specific sub-directory */
135         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "bone");
136         ANGBAND_DIR_BONE = string_make(buf);
137
138         /* Build the path to the user specific sub-directory */
139         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "data");
140         ANGBAND_DIR_DATA = string_make(buf);
141
142         /* Build the path to the user specific sub-directory */
143         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "save");
144         ANGBAND_DIR_SAVE = string_make(buf);
145
146 #else /* USE_PRIVATE_PATHS */
147
148         /* Build pathnames */
149         ANGBAND_DIR_APEX = string_make(format("%sapex", path));
150         ANGBAND_DIR_BONE = string_make(format("%sbone", path));
151         ANGBAND_DIR_DATA = string_make(format("%sdata", path));
152         ANGBAND_DIR_SAVE = string_make(format("%ssave", path));
153
154 #endif /* USE_PRIVATE_PATHS */
155 }
156
157
158 #ifdef PRIVATE_USER_PATH
159
160 /*
161  * Create an ".angband/" directory in the users home directory.
162  *
163  * ToDo: Add error handling.
164  * ToDo: Only create the directories when actually writing files.
165  */
166 void create_user_dirs(void)
167 {
168         char dirpath[1024];
169         char subdirpath[1024];
170
171
172         /* Get an absolute path from the filename */
173         path_parse(dirpath, sizeof(dirpath), PRIVATE_USER_PATH);
174
175         /* Create the ~/.angband/ directory */
176         mkdir(dirpath, 0700);
177
178         /* Build the path to the variant-specific sub-directory */
179         path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
180
181         /* Create the directory */
182         mkdir(subdirpath, 0700);
183
184 #ifdef USE_PRIVATE_PATHS
185         /* Build the path to the scores sub-directory */
186         path_build(dirpath, sizeof(dirpath), subdirpath, "scores");
187
188         /* Create the directory */
189         mkdir(dirpath, 0700);
190
191         /* Build the path to the savefile sub-directory */
192         path_build(dirpath, sizeof(dirpath), subdirpath, "bone");
193
194         /* Create the directory */
195         mkdir(dirpath, 0700);
196
197         /* Build the path to the savefile sub-directory */
198         path_build(dirpath, sizeof(dirpath), subdirpath, "data");
199
200         /* Create the directory */
201         mkdir(dirpath, 0700);
202
203         /* Build the path to the savefile sub-directory */
204         path_build(dirpath, sizeof(dirpath), subdirpath, "save");
205
206         /* Create the directory */
207         mkdir(dirpath, 0700);
208 #endif /* USE_PRIVATE_PATHS */
209 }
210
211 #endif /* PRIVATE_USER_PATH */
212
213
214
215 #ifdef ALLOW_TEMPLATES
216
217
218 /*
219  * Hack -- help give useful error messages
220  */
221 int error_idx;
222 int error_line;
223
224
225 /*
226  * Standard error message text
227  */
228 static cptr err_str[PARSE_ERROR_MAX] =
229 {
230         NULL,
231         "parse error",
232         "obsolete file",
233         "missing record header",
234         "non-sequential records",
235         "invalid flag specification",
236         "undefined directive",
237         "out of memory",
238         "value out of bounds",
239         "too few arguments",
240         "too many arguments",
241         "too many allocation entries",
242         "invalid spell frequency",
243         "invalid number of items (0-99)",
244         "too many entries",
245         "vault too big",
246 };
247
248
249 #endif /* ALLOW_TEMPLATES */
250
251
252 /*
253  * File headers
254  */
255 header z_head;
256 header v_head;
257 header f_head;
258 header k_head;
259 header a_head;
260 header e_head;
261 header r_head;
262 header p_head;
263 header c_head;
264 header h_head;
265 header b_head;
266 header g_head;
267 header flavor_head;
268 header s_head;
269
270
271
272 /*** Initialize from binary image files ***/
273
274
275 /*
276  * Initialize a "*_info" array, by parsing a binary "image" file
277  */
278 static errr init_info_raw(int fd, header *head)
279 {
280         header test;
281
282
283         /* Read and verify the header */
284         if (fd_read(fd, (char*)(&test), sizeof(header)) ||
285             (test.v_major != head->v_major) ||
286             (test.v_minor != head->v_minor) ||
287             (test.v_patch != head->v_patch) ||
288             (test.v_extra != head->v_extra) ||
289             (test.info_num != head->info_num) ||
290             (test.info_len != head->info_len) ||
291             (test.head_size != head->head_size) ||
292             (test.info_size != head->info_size))
293         {
294                 /* Error */
295                 return (-1);
296         }
297
298
299         /* Accept the header */
300         COPY(head, &test, header);
301
302
303         /* Allocate the "*_info" array */
304         C_MAKE(head->info_ptr, head->info_size, char);
305
306         /* Read the "*_info" array */
307         fd_read(fd, head->info_ptr, head->info_size);
308
309         if (head->name_size)
310         {
311                 /* Allocate the "*_name" array */
312                 C_MAKE(head->name_ptr, head->name_size, char);
313
314                 /* Read the "*_name" array */
315                 fd_read(fd, head->name_ptr, head->name_size);
316         }
317
318         if (head->text_size)
319         {
320                 /* Allocate the "*_text" array */
321                 C_MAKE(head->text_ptr, head->text_size, char);
322
323                 /* Read the "*_text" array */
324                 fd_read(fd, head->text_ptr, head->text_size);
325         }
326
327         /* Success */
328         return (0);
329 }
330
331
332 /*
333  * Initialize the header of an *_info.raw file.
334  */
335 static void init_header(header *head, int num, int len)
336 {
337         /* Save the "version" */
338         head->v_major = VERSION_MAJOR;
339         head->v_minor = VERSION_MINOR;
340         head->v_patch = VERSION_PATCH;
341         head->v_extra = VERSION_EXTRA;
342
343         /* Save the "record" information */
344         head->info_num = num;
345         head->info_len = len;
346
347         /* Save the size of "*_head" and "*_info" */
348         head->head_size = sizeof(header);
349         head->info_size = head->info_num * head->info_len;
350
351         /* Clear post-parsing evaluation function */
352         head->eval_info_power = NULL;
353        
354         /* Clear the template emission functions */
355         head->emit_info_txt_index = NULL;
356         head->emit_info_txt_always = NULL;
357 }
358
359
360 #ifdef ALLOW_TEMPLATES
361
362 /*
363  * Display a parser error message.
364  */
365 static void display_parse_error(cptr filename, errr err, cptr buf)
366 {
367         cptr oops;
368
369         /* Error string */
370         oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
371
372         /* Oops */
373         msg_format("Error at line %d of '%s.txt'.", error_line, filename);
374         msg_format("Record %d contains a '%s' error.", error_idx, oops);
375         msg_format("Parsing '%s'.", buf);
376         message_flush();
377
378         /* Quit */
379         quit_fmt("Error in '%s.txt' file.", filename);
380 }
381
382 #endif /* ALLOW_TEMPLATES */
383
384
385 /*
386  * Initialize a "*_info" array
387  *
388  * Note that we let each entry have a unique "name" and "text" string,
389  * even if the string happens to be empty (everyone has a unique '\0').
390  */
391 static errr init_info(cptr filename, header *head)
392 {
393         int fd;
394
395         errr err = 1;
396
397         FILE *fp;
398
399 #ifdef ALLOW_TEMPLATES_OUTPUT
400         FILE *fpout;
401 #endif /* ALLOW_TEMPLATES_OUTPUT */
402
403         /* General buffer */
404         char buf[1024];
405
406
407 #ifdef ALLOW_TEMPLATES
408
409         /*** Load the binary image file ***/
410
411         /* Build the filename */
412         path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename));
413
414         /* Attempt to open the "raw" file */
415         fd = fd_open(buf, O_RDONLY);
416
417         /* Process existing "raw" file */
418         if (fd >= 0)
419         {
420 #ifdef CHECK_MODIFICATION_TIME
421
422                 err = check_modification_date(fd, format("%s.txt", filename));
423
424 #endif /* CHECK_MODIFICATION_TIME */
425
426                 /* Attempt to parse the "raw" file */
427                 if (!err)
428                         err = init_info_raw(fd, head);
429
430                 /* Close it */
431                 fd_close(fd);
432         }
433
434         /* Do we have to parse the *.txt file? */
435         if (err)
436         {
437                 /*** Make the fake arrays ***/
438
439                 /* Allocate the "*_info" array */
440                 C_MAKE(head->info_ptr, head->info_size, char);
441
442                 /* MegaHack -- make "fake" arrays */
443                 if (z_info)
444                 {
445                         C_MAKE(head->name_ptr, z_info->fake_name_size, char);
446                         C_MAKE(head->text_ptr, z_info->fake_text_size, char);
447                 }
448
449
450                 /*** Load the ascii template file ***/
451
452                 /* Build the filename */
453                 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename));
454
455                 /* Open the file */
456                 fp = my_fopen(buf, "r");
457
458                 /* Parse it */
459                 if (!fp) quit(format("Cannot open '%s.txt' file.", filename));
460
461                 /* Parse the file */
462                 err = init_info_txt(fp, buf, head, head->parse_info_txt);
463
464                 /* Close it */
465                 my_fclose(fp);
466
467                 /* Errors */
468                 if (err) display_parse_error(filename, err, buf);
469
470                 /* Post processing the data */
471                 if (head->eval_info_power) eval_info(head->eval_info_power, head);
472
473 #ifdef ALLOW_TEMPLATES_OUTPUT
474
475                 /*** Output a 'parsable' ascii template file ***/
476                 if ((head->emit_info_txt_index) || (head->emit_info_txt_always))
477                 {
478                         /* Build the filename */
479                         path_build(buf, 1024, ANGBAND_DIR_EDIT, format("%s.txt", filename));
480
481                         /* Open the file */
482                         fp = my_fopen(buf, "r");
483
484                         /* Parse it */
485                         if (!fp) quit(format("Cannot open '%s.txt' file for re-parsing.", filename));
486
487                         /* Build the filename */
488                         path_build(buf, 1024, ANGBAND_DIR_USER, format("%s.txt", filename));
489
490                         /* Open the file */
491                         fpout = my_fopen(buf, "w");
492
493                         /* Parse it */
494                         if (!fpout) quit(format("Cannot open '%s.txt' file for output.", filename));
495
496                         /* Parse and output the files */
497                         err = emit_info_txt(fpout, fp, buf, head, head->emit_info_txt_index, head->emit_info_txt_always);
498
499                         /* Close both files */
500                         my_fclose(fpout);
501                         my_fclose(fp);
502                 }
503
504 #endif
505
506
507                 /*** Dump the binary image file ***/
508
509                 /* File type is "DATA" */
510                 FILE_TYPE(FILE_TYPE_DATA);
511
512                 /* Build the filename */
513                 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename));
514
515
516                 /* Attempt to open the file */
517                 fd = fd_open(buf, O_RDONLY);
518
519                 /* Failure */
520                 if (fd < 0)
521                 {
522                         int mode = 0644;
523
524                         /* Grab permissions */
525                         safe_setuid_grab();
526
527                         /* Create a new file */
528                         fd = fd_make(buf, mode);
529
530                         /* Drop permissions */
531                         safe_setuid_drop();
532
533                         /* Failure */
534                         if (fd < 0)
535                         {
536                                 /* Complain */
537                                 plog_fmt("Cannot create the '%s' file!", buf);
538
539                                 /* Continue */
540                                 return (0);
541                         }
542                 }
543
544                 /* Close it */
545                 fd_close(fd);
546
547                 /* Grab permissions */
548                 safe_setuid_grab();
549
550                 /* Attempt to create the raw file */
551                 fd = fd_open(buf, O_WRONLY);
552
553                 /* Drop permissions */
554                 safe_setuid_drop();
555
556                 /* Failure */
557                 if (fd < 0)
558                 {
559                         /* Complain */
560                         plog_fmt("Cannot write the '%s' file!", buf);
561
562                         /* Continue */
563                         return (0);
564                 }
565
566                 /* Dump to the file */
567                 if (fd >= 0)
568                 {
569                         /* Dump it */
570                         fd_write(fd, (cptr)head, head->head_size);
571
572                         /* Dump the "*_info" array */
573                         if (head->info_size > 0)
574                                 fd_write(fd, head->info_ptr, head->info_size);
575
576                         /* Dump the "*_name" array */
577                         if (head->name_size > 0)
578                                 fd_write(fd, head->name_ptr, head->name_size);
579
580                         /* Dump the "*_text" array */
581                         if (head->text_size > 0)
582                                 fd_write(fd, head->text_ptr, head->text_size);
583
584                         /* Close */
585                         fd_close(fd);
586                 }
587
588
589                 /*** Kill the fake arrays ***/
590
591                 /* Free the "*_info" array */
592                 KILL(head->info_ptr);
593
594                 /* MegaHack -- Free the "fake" arrays */
595                 if (z_info)
596                 {
597                         KILL(head->name_ptr);
598                         KILL(head->text_ptr);
599                 }
600
601 #endif /* ALLOW_TEMPLATES */
602
603
604                 /*** Load the binary image file ***/
605
606                 /* Build the filename */
607                 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format("%s.raw", filename));
608
609                 /* Attempt to open the "raw" file */
610                 fd = fd_open(buf, O_RDONLY);
611
612                 /* Process existing "raw" file */
613                 if (fd < 0) quit(format("Cannot load '%s.raw' file.", filename));
614
615                 /* Attempt to parse the "raw" file */
616                 err = init_info_raw(fd, head);
617
618                 /* Close it */
619                 fd_close(fd);
620
621                 /* Error */
622                 if (err) quit(format("Cannot parse '%s.raw' file.", filename));
623
624 #ifdef ALLOW_TEMPLATES
625         }
626 #endif /* ALLOW_TEMPLATES */
627
628         /* Success */
629         return (0);
630 }
631
632
633 /*
634  * Free the allocated memory for the info-, name-, and text- arrays.
635  */
636 static errr free_info(header *head)
637 {
638         if (head->info_size)
639                 FREE(head->info_ptr);
640
641         if (head->name_size)
642                 FREE(head->name_ptr);
643
644         if (head->text_size)
645                 FREE(head->text_ptr);
646
647         /* Success */
648         return (0);
649 }
650
651
652 /*
653  * Initialize the "z_info" array
654  */
655 static errr init_z_info(void)
656 {
657         errr err;
658
659         /* Init the header */
660         init_header(&z_head, 1, sizeof(maxima));
661
662 #ifdef ALLOW_TEMPLATES
663
664         /* Save a pointer to the parsing function */
665         z_head.parse_info_txt = parse_z_info;
666
667 #endif /* ALLOW_TEMPLATES */
668
669         err = init_info("limits", &z_head);
670
671         /* Set the global variables */
672         z_info = z_head.info_ptr;
673
674         return (err);
675 }
676
677
678 /*
679  * Initialize the "f_info" array
680  */
681 static errr init_f_info(void)
682 {
683         errr err;
684
685         /* Init the header */
686         init_header(&f_head, z_info->f_max, sizeof(feature_type));
687
688 #ifdef ALLOW_TEMPLATES
689
690         /* Save a pointer to the parsing function */
691         f_head.parse_info_txt = parse_f_info;
692
693 #endif /* ALLOW_TEMPLATES */
694
695         err = init_info("terrain", &f_head);
696
697         /* Set the global variables */
698         f_info = f_head.info_ptr;
699         f_name = f_head.name_ptr;
700         f_text = f_head.text_ptr;
701
702         return (err);
703 }
704
705
706
707 /*
708  * Initialize the "k_info" array
709  */
710 static errr init_k_info(void)
711 {
712         errr err;
713
714         /* Init the header */
715         init_header(&k_head, z_info->k_max, sizeof(object_kind));
716
717 #ifdef ALLOW_TEMPLATES
718
719         /* Save a pointer to the parsing function */
720         k_head.parse_info_txt = parse_k_info;
721
722 #endif /* ALLOW_TEMPLATES */
723
724         err = init_info("object", &k_head);
725
726         /* Set the global variables */
727         k_info = k_head.info_ptr;
728         k_name = k_head.name_ptr;
729         k_text = k_head.text_ptr;
730
731         return (err);
732 }
733
734
735
736 /*
737  * Initialize the "a_info" array
738  */
739 static errr init_a_info(void)
740 {
741         errr err;
742
743         /* Init the header */
744         init_header(&a_head, z_info->a_max, sizeof(artifact_type));
745
746 #ifdef ALLOW_TEMPLATES
747
748         /* Save a pointer to the parsing function */
749         a_head.parse_info_txt = parse_a_info;
750
751 #endif /* ALLOW_TEMPLATES */
752
753         err = init_info("artifact", &a_head);
754
755         /* Set the global variables */
756         a_info = a_head.info_ptr;
757         a_name = a_head.name_ptr;
758         a_text = a_head.text_ptr;
759
760         return (err);
761 }
762
763
764
765 /*
766  * Initialize the "e_info" array
767  */
768 static errr init_e_info(void)
769 {
770         errr err;
771
772         /* Init the header */
773         init_header(&e_head, z_info->e_max, sizeof(ego_item_type));
774
775 #ifdef ALLOW_TEMPLATES
776
777         /* Save a pointer to the parsing function */
778         e_head.parse_info_txt = parse_e_info;
779
780 #endif /* ALLOW_TEMPLATES */
781
782         err = init_info("ego_item", &e_head);
783
784         /* Set the global variables */
785         e_info = e_head.info_ptr;
786         e_name = e_head.name_ptr;
787         e_text = e_head.text_ptr;
788
789         return (err);
790 }
791
792
793
794 /*
795  * Initialize the "r_info" array
796  */
797 static errr init_r_info(void)
798 {
799         errr err;
800
801         /* Init the header */
802         init_header(&r_head, z_info->r_max, sizeof(monster_race));
803
804 #ifdef ALLOW_TEMPLATES
805
806         /* Save a pointer to the parsing function */
807         r_head.parse_info_txt = parse_r_info;
808
809 #ifdef ALLOW_TEMPLATES_PROCESS
810         /* Save a pointer to the evaluate power function*/
811         r_head.eval_info_power = eval_r_power;
812 #endif
813
814 #ifdef ALLOW_TEMPLATES_OUTPUT
815
816         /* Save a pointer to the evaluate power function*/
817         r_head.emit_info_txt_index = emit_r_info_index;
818 #endif /* ALLOW_TEMPLATES_OUTPUT */
819
820 #endif /* ALLOW_TEMPLATES */
821
822         err = init_info("monster", &r_head);
823
824         /* Set the global variables */
825         r_info = r_head.info_ptr;
826         r_name = r_head.name_ptr;
827         r_text = r_head.text_ptr;
828
829         return (err);
830 }
831
832
833
834 /*
835  * Initialize the "v_info" array
836  */
837 static errr init_v_info(void)
838 {
839         errr err;
840
841         /* Init the header */
842         init_header(&v_head, z_info->v_max, sizeof(vault_type));
843
844 #ifdef ALLOW_TEMPLATES
845
846         /* Save a pointer to the parsing function */
847         v_head.parse_info_txt = parse_v_info;
848
849 #endif /* ALLOW_TEMPLATES */
850
851         err = init_info("vault", &v_head);
852
853         /* Set the global variables */
854         v_info = v_head.info_ptr;
855         v_name = v_head.name_ptr;
856         v_text = v_head.text_ptr;
857
858         return (err);
859 }
860
861
862 /*
863  * Initialize the "p_info" array
864  */
865 static errr init_p_info(void)
866 {
867         errr err;
868
869         /* Init the header */
870         init_header(&p_head, z_info->p_max, sizeof(player_race));
871
872 #ifdef ALLOW_TEMPLATES
873
874         /* Save a pointer to the parsing function */
875         p_head.parse_info_txt = parse_p_info;
876
877 #endif /* ALLOW_TEMPLATES */
878
879         err = init_info("p_race", &p_head);
880
881         /* Set the global variables */
882         p_info = p_head.info_ptr;
883         p_name = p_head.name_ptr;
884         p_text = p_head.text_ptr;
885
886         return (err);
887 }
888
889
890 /*
891  * Initialize the "c_info" array
892  */
893 static errr init_c_info(void)
894 {
895         errr err;
896
897         /* Init the header */
898         init_header(&c_head, z_info->c_max, sizeof(player_class));
899
900 #ifdef ALLOW_TEMPLATES
901
902         /* Save a pointer to the parsing function */
903         c_head.parse_info_txt = parse_c_info;
904
905 #endif /* ALLOW_TEMPLATES */
906
907         err = init_info("p_class", &c_head);
908
909         /* Set the global variables */
910         c_info = c_head.info_ptr;
911         c_name = c_head.name_ptr;
912         c_text = c_head.text_ptr;
913
914         return (err);
915 }
916
917
918
919 /*
920  * Initialize the "h_info" array
921  */
922 static errr init_h_info(void)
923 {
924         errr err;
925
926         /* Init the header */
927         init_header(&h_head, z_info->h_max, sizeof(hist_type));
928
929 #ifdef ALLOW_TEMPLATES
930
931         /* Save a pointer to the parsing function */
932         h_head.parse_info_txt = parse_h_info;
933
934 #endif /* ALLOW_TEMPLATES */
935
936         err = init_info("p_hist", &h_head);
937
938         /* Set the global variables */
939         h_info = h_head.info_ptr;
940         h_text = h_head.text_ptr;
941
942         return (err);
943 }
944
945
946
947 /*
948  * Initialize the "b_info" array
949  */
950 static errr init_b_info(void)
951 {
952         errr err;
953
954         /* Init the header */
955         init_header(&b_head, (u16b)(MAX_STORES * z_info->b_max), sizeof(owner_type));
956
957 #ifdef ALLOW_TEMPLATES
958
959         /* Save a pointer to the parsing function */
960         b_head.parse_info_txt = parse_b_info;
961
962 #endif /* ALLOW_TEMPLATES */
963
964         err = init_info("shop_own", &b_head);
965
966         /* Set the global variables */
967         b_info = b_head.info_ptr;
968         b_name = b_head.name_ptr;
969         b_text = b_head.text_ptr;
970
971         return (err);
972 }
973
974
975
976 /*
977  * Initialize the "g_info" array
978  */
979 static errr init_g_info(void)
980 {
981         errr err;
982
983         /* Init the header */
984         init_header(&g_head, (u16b)(z_info->p_max * z_info->p_max), sizeof(byte));
985
986 #ifdef ALLOW_TEMPLATES
987
988         /* Save a pointer to the parsing function */
989         g_head.parse_info_txt = parse_g_info;
990
991 #endif /* ALLOW_TEMPLATES */
992
993         err = init_info("cost_adj", &g_head);
994
995         /* Set the global variables */
996         g_info = g_head.info_ptr;
997         g_name = g_head.name_ptr;
998         g_text = g_head.text_ptr;
999
1000         return (err);
1001 }
1002
1003
1004 /*
1005  * Initialize the "flavor_info" array
1006  */
1007 static errr init_flavor_info(void)
1008 {
1009         errr err;
1010
1011         /* Init the header */
1012         init_header(&flavor_head, z_info->flavor_max, sizeof(flavor_type));
1013
1014 #ifdef ALLOW_TEMPLATES
1015
1016         /* Save a pointer to the parsing function */
1017         flavor_head.parse_info_txt = parse_flavor_info;
1018
1019 #endif /* ALLOW_TEMPLATES */
1020
1021         err = init_info("flavor", &flavor_head);
1022
1023         /* Set the global variables */
1024         flavor_info = flavor_head.info_ptr;
1025         flavor_name = flavor_head.name_ptr;
1026         flavor_text = flavor_head.text_ptr;
1027
1028         return (err);
1029 }
1030
1031
1032
1033 /*
1034  * Initialize the "s_info" array
1035  */
1036 static errr init_s_info(void)
1037 {
1038         errr err;
1039
1040         /* Init the header */
1041         init_header(&s_head, z_info->s_max, sizeof(spell_type));
1042
1043 #ifdef ALLOW_TEMPLATES
1044
1045         /* Save a pointer to the parsing function */
1046         s_head.parse_info_txt = parse_s_info;
1047
1048 #endif /* ALLOW_TEMPLATES */
1049
1050         err = init_info("spell", &s_head);
1051
1052         /* Set the global variables */
1053         s_info = s_head.info_ptr;
1054         s_name = s_head.name_ptr;
1055         s_text = s_head.text_ptr;
1056
1057         return (err);
1058 }
1059
1060 /*
1061  * Initialize the "spell_list" array
1062  */
1063 static void init_books(void)
1064 {
1065         byte realm, sval, snum;
1066         u16b spell;
1067
1068         /* Since not all slots in all books are used, initialize to -1 first */
1069         for (realm = 0; realm < MAX_REALMS; realm++)
1070         {
1071                 for (sval = 0; sval < BOOKS_PER_REALM; sval++)
1072                 {
1073                         for (snum = 0; snum < SPELLS_PER_BOOK; snum++)
1074                         {
1075                                 spell_list[realm][sval][snum] = -1;
1076                         }
1077                 }
1078         }
1079
1080         /* Place each spell in its own book */
1081         for (spell = 0; spell < z_info->s_max; spell++)
1082         {
1083                 /* Get the spell */
1084                 spell_type *s_ptr = &s_info[spell];
1085
1086                 /* Put it in the book */
1087                 spell_list[s_ptr->realm][s_ptr->sval][s_ptr->snum] = spell;
1088         }
1089 }
1090
1091 /*** Initialize others ***/
1092
1093 static void autoinscribe_init(void)
1094 {
1095         if (inscriptions)
1096                 FREE(inscriptions);
1097  
1098         inscriptions = 0;
1099         inscriptions_count = 0;
1100
1101         C_MAKE(inscriptions, AUTOINSCRIPTIONS_MAX, autoinscription);
1102 }
1103
1104
1105 /*
1106  * Initialize some other arrays
1107  */
1108 static errr init_other(void)
1109 {
1110         int i;
1111
1112
1113         /*** Prepare the various "bizarre" arrays ***/
1114
1115         /* Initialize the "macro" package */
1116         (void)macro_init();
1117
1118         /* Initialize the "quark" package */
1119         (void)quarks_init();
1120
1121         /* Initialize squelch things */
1122         autoinscribe_init();
1123
1124         /* Initialize the "message" package */
1125         (void)messages_init();
1126
1127         /*** Prepare grid arrays ***/
1128
1129         /* Array of grids */
1130         C_MAKE(view_g, VIEW_MAX, u16b);
1131
1132         /* Array of grids */
1133         C_MAKE(temp_g, TEMP_MAX, u16b);
1134
1135         /* Hack -- use some memory twice */
1136         temp_y = ((byte*)(temp_g)) + 0;
1137         temp_x = ((byte*)(temp_g)) + TEMP_MAX;
1138
1139
1140         /*** Prepare dungeon arrays ***/
1141
1142         /* Padded into array */
1143         C_MAKE(cave_info, DUNGEON_HGT, byte_256);
1144
1145         /* Feature array */
1146         C_MAKE(cave_feat, DUNGEON_HGT, byte_wid);
1147
1148         /* Entity arrays */
1149         C_MAKE(cave_o_idx, DUNGEON_HGT, s16b_wid);
1150         C_MAKE(cave_m_idx, DUNGEON_HGT, s16b_wid);
1151
1152 #ifdef MONSTER_FLOW
1153
1154         /* Flow arrays */
1155         C_MAKE(cave_cost, DUNGEON_HGT, byte_wid);
1156         C_MAKE(cave_when, DUNGEON_HGT, byte_wid);
1157
1158 #endif /* MONSTER_FLOW */
1159
1160         /*** Prepare "vinfo" array ***/
1161
1162         /* Used by "update_view()" */
1163         (void)vinfo_init();
1164
1165
1166         /*** Prepare entity arrays ***/
1167
1168         /* Objects */
1169         C_MAKE(o_list, z_info->o_max, object_type);
1170
1171         /* Monsters */
1172         C_MAKE(mon_list, z_info->m_max, monster_type);
1173
1174
1175         /*** Prepare lore array ***/
1176
1177         /* Lore */
1178         C_MAKE(l_list, z_info->r_max, monster_lore);
1179
1180
1181         /*** Prepare quest array ***/
1182
1183         /* Quests */
1184         C_MAKE(q_list, MAX_Q_IDX, quest);
1185
1186
1187         /*** Prepare the inventory ***/
1188
1189         /* Allocate it */
1190         C_MAKE(inventory, INVEN_TOTAL, object_type);
1191
1192
1193         /*** Prepare the stores ***/
1194
1195         /* Allocate the stores */
1196         C_MAKE(store, MAX_STORES, store_type);
1197
1198         /* Fill in each store */
1199         for (i = 0; i < MAX_STORES; i++)
1200         {
1201                 int k;
1202
1203                 /* Get the store */
1204                 store_type *st_ptr = &store[i];
1205
1206                 /* Assume full stock */
1207                 st_ptr->stock_size = STORE_INVEN_MAX;
1208
1209                 /* Allocate the stock */
1210                 C_MAKE(st_ptr->stock, st_ptr->stock_size, object_type);
1211
1212                 /* No table for the black market or home */
1213                 if ((i == STORE_B_MARKET) || (i == STORE_HOME)) continue;
1214
1215                 /* Assume full table */
1216                 st_ptr->table_size = STORE_CHOICES;
1217
1218                 /* Allocate the stock */
1219                 C_MAKE(st_ptr->table, st_ptr->table_size, s16b);
1220
1221                 /* Scan the choices */
1222                 for (k = 0; k < STORE_CHOICES; k++)
1223                 {
1224                         int k_idx;
1225
1226                         /* Extract the tval/sval codes */
1227                         int tv = store_choices[i][k][0];
1228                         int sv = store_choices[i][k][1];
1229
1230                         /* Look for it */
1231                         for (k_idx = 1; k_idx < z_info->k_max; k_idx++)
1232                         {
1233                                 object_kind *k_ptr = &k_info[k_idx];
1234
1235                                 /* Found a match */
1236                                 if ((k_ptr->tval == tv) && (k_ptr->sval == sv)) break;
1237                         }
1238
1239                         /* Catch errors */
1240                         if (k_idx == z_info->k_max) continue;
1241
1242                         /* Add that item index to the table */
1243                         st_ptr->table[st_ptr->table_num++] = k_idx;
1244                 }
1245         }
1246
1247
1248         /*** Prepare the options ***/
1249
1250         /* Initialize the options */
1251         for (i = 0; i < OPT_MAX; i++)
1252         {
1253                 /* Default value */
1254                 op_ptr->opt[i] = option_norm[i];
1255         }
1256
1257         /* Initialize the window flags */
1258         for (i = 0; i < ANGBAND_TERM_MAX; i++)
1259         {
1260                 /* Assume no flags */
1261                 op_ptr->window_flag[i] = 0L;
1262         }
1263
1264
1265         /*** Pre-allocate space for the "format()" buffer ***/
1266
1267         /* Hack -- Just call the "format()" function */
1268         (void)format("%s", MAINTAINER);
1269
1270
1271         /* Success */
1272         return (0);
1273 }
1274
1275
1276
1277 /*
1278  * Initialize some other arrays
1279  */
1280 static errr init_alloc(void)
1281 {
1282         int i, j;
1283
1284         object_kind *k_ptr;
1285
1286         monster_race *r_ptr;
1287
1288         ego_item_type *e_ptr;
1289
1290         alloc_entry *table;
1291
1292         s16b num[MAX_DEPTH];
1293
1294         s16b aux[MAX_DEPTH];
1295
1296
1297         /*** Analyze object allocation info ***/
1298
1299         /* Clear the "aux" array */
1300         (void)C_WIPE(aux, MAX_DEPTH, s16b);
1301
1302         /* Clear the "num" array */
1303         (void)C_WIPE(num, MAX_DEPTH, s16b);
1304
1305         /* Size of "alloc_kind_table" */
1306         alloc_kind_size = 0;
1307
1308         /* Scan the objects */
1309         for (i = 1; i < z_info->k_max; i++)
1310         {
1311                 k_ptr = &k_info[i];
1312
1313                 /* Scan allocation pairs */
1314                 for (j = 0; j < 4; j++)
1315                 {
1316                         /* Count the "legal" entries */
1317                         if (k_ptr->chance[j])
1318                         {
1319                                 /* Count the entries */
1320                                 alloc_kind_size++;
1321
1322                                 /* Group by level */
1323                                 num[k_ptr->locale[j]]++;
1324                         }
1325                 }
1326         }
1327
1328         /* Collect the level indexes */
1329         for (i = 1; i < MAX_DEPTH; i++)
1330         {
1331                 /* Group by level */
1332                 num[i] += num[i-1];
1333         }
1334
1335         /* Paranoia */
1336         if (!num[0]) quit("No town objects!");
1337
1338
1339         /*** Initialize object allocation info ***/
1340
1341         /* Allocate the alloc_kind_table */
1342         C_MAKE(alloc_kind_table, alloc_kind_size, alloc_entry);
1343
1344         /* Get the table entry */
1345         table = alloc_kind_table;
1346
1347         /* Scan the objects */
1348         for (i = 1; i < z_info->k_max; i++)
1349         {
1350                 k_ptr = &k_info[i];
1351
1352                 /* Scan allocation pairs */
1353                 for (j = 0; j < 4; j++)
1354                 {
1355                         /* Count the "legal" entries */
1356                         if (k_ptr->chance[j])
1357                         {
1358                                 int p, x, y, z;
1359
1360                                 /* Extract the base level */
1361                                 x = k_ptr->locale[j];
1362
1363                                 /* Extract the base probability */
1364                                 p = (100 / k_ptr->chance[j]);
1365
1366                                 /* Skip entries preceding our locale */
1367                                 y = (x > 0) ? num[x-1] : 0;
1368
1369                                 /* Skip previous entries at this locale */
1370                                 z = y + aux[x];
1371
1372                                 /* Load the entry */
1373                                 table[z].index = i;
1374                                 table[z].level = x;
1375                                 table[z].prob1 = p;
1376                                 table[z].prob2 = p;
1377                                 table[z].prob3 = p;
1378
1379                                 /* Another entry complete for this locale */
1380                                 aux[x]++;
1381                         }
1382                 }
1383         }
1384
1385
1386         /*** Analyze monster allocation info ***/
1387
1388         /* Clear the "aux" array */
1389         (void)C_WIPE(aux, MAX_DEPTH, s16b);
1390
1391         /* Clear the "num" array */
1392         (void)C_WIPE(num, MAX_DEPTH, s16b);
1393
1394         /* Size of "alloc_race_table" */
1395         alloc_race_size = 0;
1396
1397         /* Scan the monsters (not the ghost) */
1398         for (i = 1; i < z_info->r_max - 1; i++)
1399         {
1400                 /* Get the i'th race */
1401                 r_ptr = &r_info[i];
1402
1403                 /* Legal monsters */
1404                 if (r_ptr->rarity)
1405                 {
1406                         /* Count the entries */
1407                         alloc_race_size++;
1408
1409                         /* Group by level */
1410                         num[r_ptr->level]++;
1411                 }
1412         }
1413
1414         /* Collect the level indexes */
1415         for (i = 1; i < MAX_DEPTH; i++)
1416         {
1417                 /* Group by level */
1418                 num[i] += num[i-1];
1419         }
1420
1421         /* Paranoia */
1422         if (!num[0]) quit("No town monsters!");
1423
1424
1425         /*** Initialize monster allocation info ***/
1426
1427         /* Allocate the alloc_race_table */
1428         C_MAKE(alloc_race_table, alloc_race_size, alloc_entry);
1429
1430         /* Get the table entry */
1431         table = alloc_race_table;
1432
1433         /* Scan the monsters (not the ghost) */
1434         for (i = 1; i < z_info->r_max - 1; i++)
1435         {
1436                 /* Get the i'th race */
1437                 r_ptr = &r_info[i];
1438
1439                 /* Count valid pairs */
1440                 if (r_ptr->rarity)
1441                 {
1442                         int p, x, y, z;
1443
1444                         /* Extract the base level */
1445                         x = r_ptr->level;
1446
1447                         /* Extract the base probability */
1448                         p = (100 / r_ptr->rarity);
1449
1450                         /* Skip entries preceding our locale */
1451                         y = (x > 0) ? num[x-1] : 0;
1452
1453                         /* Skip previous entries at this locale */
1454                         z = y + aux[x];
1455
1456                         /* Load the entry */
1457                         table[z].index = i;
1458                         table[z].level = x;
1459                         table[z].prob1 = p;
1460                         table[z].prob2 = p;
1461                         table[z].prob3 = p;
1462
1463                         /* Another entry complete for this locale */
1464                         aux[x]++;
1465                 }
1466         }
1467
1468         /*** Analyze ego_item allocation info ***/
1469
1470         /* Clear the "aux" array */
1471         (void)C_WIPE(aux, MAX_DEPTH, s16b);
1472
1473         /* Clear the "num" array */
1474         (void)C_WIPE(num, MAX_DEPTH, s16b);
1475
1476         /* Size of "alloc_ego_table" */
1477         alloc_ego_size = 0;
1478
1479         /* Scan the ego items */
1480         for (i = 1; i < z_info->e_max; i++)
1481         {
1482                 /* Get the i'th ego item */
1483                 e_ptr = &e_info[i];
1484
1485                 /* Legal items */
1486                 if (e_ptr->rarity)
1487                 {
1488                         /* Count the entries */
1489                         alloc_ego_size++;
1490
1491                         /* Group by level */
1492                         num[e_ptr->level]++;
1493                 }
1494         }
1495
1496         /* Collect the level indexes */
1497         for (i = 1; i < MAX_DEPTH; i++)
1498         {
1499                 /* Group by level */
1500                 num[i] += num[i-1];
1501         }
1502
1503         /*** Initialize ego-item allocation info ***/
1504
1505         /* Allocate the alloc_ego_table */
1506         C_MAKE(alloc_ego_table, alloc_ego_size, alloc_entry);
1507
1508         /* Get the table entry */
1509         table = alloc_ego_table;
1510
1511         /* Scan the ego-items */
1512         for (i = 1; i < z_info->e_max; i++)
1513         {
1514                 /* Get the i'th ego item */
1515                 e_ptr = &e_info[i];
1516
1517                 /* Count valid pairs */
1518                 if (e_ptr->rarity)
1519                 {
1520                         int p, x, y, z;
1521
1522                         /* Extract the base level */
1523                         x = e_ptr->level;
1524
1525                         /* Extract the base probability */
1526                         p = (100 / e_ptr->rarity);
1527
1528                         /* Skip entries preceding our locale */
1529                         y = (x > 0) ? num[x-1] : 0;
1530
1531                         /* Skip previous entries at this locale */
1532                         z = y + aux[x];
1533
1534                         /* Load the entry */
1535                         table[z].index = i;
1536                         table[z].level = x;
1537                         table[z].prob1 = p;
1538                         table[z].prob2 = p;
1539                         table[z].prob3 = p;
1540
1541                         /* Another entry complete for this locale */
1542                         aux[x]++;
1543                 }
1544         }
1545
1546
1547         /* Success */
1548         return (0);
1549 }
1550
1551
1552 /*
1553  * Hack -- take notes on line 23
1554  */
1555 static void note(cptr str)
1556 {
1557         Term_erase(0, 23, 255);
1558         Term_putstr(20, 23, -1, TERM_WHITE, str);
1559         Term_fresh();
1560 }
1561
1562
1563
1564 /*
1565  * Hack -- Explain a broken "lib" folder and quit (see below).
1566  */
1567 static void init_angband_aux(cptr why)
1568 {
1569         quit_fmt("%s\n\n%s", why,
1570                  "The 'lib' directory is probably missing or broken.\n"
1571                  "Perhaps the archive was not extracted correctly.\n"
1572                  "See the 'readme.txt' file for more information.");
1573 }
1574
1575
1576 /*
1577  * Hack -- main Angband initialization entry point
1578  *
1579  * Verify some files, display the "news.txt" file, create
1580  * the high score file, initialize all internal arrays, and
1581  * load the basic "user pref files".
1582  *
1583  * Be very careful to keep track of the order in which things
1584  * are initialized, in particular, the only thing *known* to
1585  * be available when this function is called is the "z-term.c"
1586  * package, and that may not be fully initialized until the
1587  * end of this function, when the default "user pref files"
1588  * are loaded and "Term_xtra(TERM_XTRA_REACT,0)" is called.
1589  *
1590  * Note that this function attempts to verify the "news" file,
1591  * and the game aborts (cleanly) on failure, since without the
1592  * "news" file, it is likely that the "lib" folder has not been
1593  * correctly located.  Otherwise, the news file is displayed for
1594  * the user.
1595  *
1596  * Note that this function attempts to verify (or create) the
1597  * "high score" file, and the game aborts (cleanly) on failure,
1598  * since one of the most common "extraction" failures involves
1599  * failing to extract all sub-directories (even empty ones), such
1600  * as by failing to use the "-d" option of "pkunzip", or failing
1601  * to use the "save empty directories" option with "Compact Pro".
1602  * This error will often be caught by the "high score" creation
1603  * code below, since the "lib/apex" directory, being empty in the
1604  * standard distributions, is most likely to be "lost", making it
1605  * impossible to create the high score file.
1606  *
1607  * Note that various things are initialized by this function,
1608  * including everything that was once done by "init_some_arrays".
1609  *
1610  * This initialization involves the parsing of special files
1611  * in the "lib/data" and sometimes the "lib/edit" directories.
1612  *
1613  * Note that the "template" files are initialized first, since they
1614  * often contain errors.  This means that macros and message recall
1615  * and things like that are not available until after they are done.
1616  *
1617  * We load the default "user pref files" here in case any "color"
1618  * changes are needed before character creation.
1619  *
1620  * Note that the "graf-xxx.prf" file must be loaded separately,
1621  * if needed, in the first (?) pass through "TERM_XTRA_REACT".
1622  */
1623 void init_angband(void)
1624 {
1625         int fd;
1626
1627         int mode = 0644;
1628
1629         FILE *fp;
1630
1631         char buf[1024];
1632
1633
1634         /*** Verify the "news" file ***/
1635
1636         /* Build the filename */
1637         path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "news.txt");
1638
1639         /* Attempt to open the file */
1640         fd = fd_open(buf, O_RDONLY);
1641
1642         /* Failure */
1643         if (fd < 0)
1644         {
1645                 char why[1024];
1646
1647                 /* Message */
1648                 strnfmt(why, sizeof(why), "Cannot access the '%s' file!", buf);
1649
1650                 /* Crash and burn */
1651                 init_angband_aux(why);
1652         }
1653
1654         /* Close it */
1655         fd_close(fd);
1656
1657
1658         /*** Display the "news" file ***/
1659
1660         /* Clear screen */
1661         Term_clear();
1662
1663         /* Build the filename */
1664         path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "news.txt");
1665
1666         /* Open the News file */
1667         fp = my_fopen(buf, "r");
1668
1669         /* Dump */
1670         if (fp)
1671         {
1672                 int i = 0;
1673
1674                 /* Dump the file to the screen */
1675                 while (0 == my_fgets(fp, buf, sizeof(buf)))
1676                 {
1677                         /* Display and advance */
1678                         Term_putstr(0, i++, -1, TERM_WHITE, buf);
1679                 }
1680
1681                 /* Close */
1682                 my_fclose(fp);
1683         }
1684
1685         /* Flush it */
1686         Term_fresh();
1687
1688
1689         /*** Verify (or create) the "high score" file ***/
1690
1691         /* Build the filename */
1692         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");
1693
1694         /* Attempt to open the high score file */
1695         fd = fd_open(buf, O_RDONLY);
1696
1697         /* Failure */
1698         if (fd < 0)
1699         {
1700                 /* File type is "DATA" */
1701                 FILE_TYPE(FILE_TYPE_DATA);
1702
1703                 /* Grab permissions */
1704                 safe_setuid_grab();
1705
1706                 /* Create a new high score file */
1707                 fd = fd_make(buf, mode);
1708
1709                 /* Drop permissions */
1710                 safe_setuid_drop();
1711
1712                 /* Failure */
1713                 if (fd < 0)
1714                 {
1715                         char why[1024];
1716
1717                         /* Message */
1718                         strnfmt(why, sizeof(why), "Cannot create the '%s' file!", buf);
1719
1720                         /* Crash and burn */
1721                         init_angband_aux(why);
1722                 }
1723         }
1724
1725         /* Close it */
1726         fd_close(fd);
1727
1728
1729         /* Initialize the menus */
1730         /* This must occur before preference files are read */
1731         init_cmd4_c();
1732        
1733         /*** Initialize some arrays ***/
1734
1735
1736         /* Initialize size info */
1737         note("[Initializing array sizes...]");
1738         if (init_z_info()) quit("Cannot initialize sizes");
1739
1740         /* Initialize feature info */
1741         note("[Initializing arrays... (features)]");
1742         if (init_f_info()) quit("Cannot initialize features");
1743
1744         /* Initialize object info */
1745         note("[Initializing arrays... (objects)]");
1746         if (init_k_info()) quit("Cannot initialize objects");
1747
1748         /* Initialize artifact info */
1749         note("[Initializing arrays... (artifacts)]");
1750         if (init_a_info()) quit("Cannot initialize artifacts");
1751
1752         /* Initialize ego-item info */
1753         note("[Initializing arrays... (ego-items)]");
1754         if (init_e_info()) quit("Cannot initialize ego-items");
1755
1756         /* Initialize monster info */
1757         note("[Initializing arrays... (monsters)]");
1758         if (init_r_info()) quit("Cannot initialize monsters");
1759
1760         /* Initialize feature info */
1761         note("[Initializing arrays... (vaults)]");
1762         if (init_v_info()) quit("Cannot initialize vaults");
1763
1764         /* Initialize history info */
1765         note("[Initializing arrays... (histories)]");
1766         if (init_h_info()) quit("Cannot initialize histories");
1767
1768         /* Initialize race info */
1769         note("[Initializing arrays... (races)]");
1770         if (init_p_info()) quit("Cannot initialize races");
1771
1772         /* Initialize class info */
1773         note("[Initializing arrays... (classes)]");
1774         if (init_c_info()) quit("Cannot initialize classes");
1775
1776         /* Initialize owner info */
1777         note("[Initializing arrays... (owners)]");
1778         if (init_b_info()) quit("Cannot initialize owners");
1779
1780         /* Initialize price info */
1781         note("[Initializing arrays... (prices)]");
1782         if (init_g_info()) quit("Cannot initialize prices");
1783
1784         /* Initialize flavor info */
1785         note("[Initializing arrays... (flavors)]");
1786         if (init_flavor_info()) quit("Cannot initialize flavors");
1787        
1788         /* Initialize spell info */
1789         note("[Initializing arrays... (spells)]");
1790         if (init_s_info()) quit("Cannot initialize spells");
1791
1792         /* Initialize spellbook info */
1793         note("[Initializing arrays... (spellbooks)]");
1794         init_books();
1795
1796         /* Initialize some other arrays */
1797         note("[Initializing arrays... (other)]");
1798         if (init_other()) quit("Cannot initialize other stuff");
1799
1800         /* Initialize some other arrays */
1801         note("[Initializing arrays... (alloc)]");
1802         if (init_alloc()) quit("Cannot initialize alloc stuff");
1803
1804         /*** Load default user pref files ***/
1805
1806         /* Initialize feature info */
1807         note("[Loading basic user pref file...]");
1808
1809         /* Process that file */
1810         (void)process_pref_file("pref.prf");
1811
1812         /* Done */
1813         note("[Initialization complete]");
1814
1815         /* Sneakily init command list */
1816         cmd_init();
1817 }
1818
1819
1820 void cleanup_angband(void)
1821 {
1822         int i;
1823
1824
1825         /* Free the macros */
1826         macro_free();
1827
1828         /* Free the macro triggers */
1829         macro_trigger_free();
1830
1831         /* Free the allocation tables */
1832         FREE(alloc_ego_table);
1833         FREE(alloc_race_table);
1834         FREE(alloc_kind_table);
1835
1836         if (store)
1837         {
1838                 /* Free the store inventories */
1839                 for (i = 0; i < MAX_STORES; i++)
1840                 {
1841                         /* Get the store */
1842                         store_type *st_ptr = &store[i];
1843
1844                         /* Free the store inventory */
1845                         FREE(st_ptr->stock);
1846                 }
1847         }
1848
1849         /* Free the stores */
1850         FREE(store);
1851
1852         /* Free the player inventory */
1853         FREE(inventory);
1854
1855         /* Free the quest list */
1856         FREE(q_list);
1857
1858         /* Free the lore, monster, and object lists */
1859         FREE(l_list);
1860         FREE(mon_list);
1861         FREE(o_list);
1862
1863 #ifdef MONSTER_FLOW
1864
1865         /* Flow arrays */
1866         FREE(cave_when);
1867         FREE(cave_cost);
1868
1869 #endif /* MONSTER_FLOW */
1870
1871         /* Free the cave */
1872         FREE(cave_o_idx);
1873         FREE(cave_m_idx);
1874         FREE(cave_feat);
1875         FREE(cave_info);
1876
1877         /* Free the "update_view()" array */
1878         FREE(view_g);
1879
1880         /* Free the temp array */
1881         FREE(temp_g);
1882
1883         /* Free the messages */
1884         messages_free();
1885
1886         /* Free the "quarks" */
1887         quarks_free();
1888
1889         /* Free the info, name, and text arrays */
1890         free_info(&flavor_head);
1891         free_info(&g_head);
1892         free_info(&b_head);
1893         free_info(&c_head);
1894         free_info(&p_head);
1895         free_info(&h_head);
1896         free_info(&v_head);
1897         free_info(&r_head);
1898         free_info(&e_head);
1899         free_info(&a_head);
1900         free_info(&k_head);
1901         free_info(&f_head);
1902         free_info(&z_head);
1903         free_info(&s_head);
1904
1905         /* Free the format() buffer */
1906         vformat_kill();
1907
1908         /* Free the directories */
1909         string_free(ANGBAND_DIR);
1910         string_free(ANGBAND_DIR_APEX);
1911         string_free(ANGBAND_DIR_BONE);
1912         string_free(ANGBAND_DIR_DATA);
1913         string_free(ANGBAND_DIR_EDIT);
1914         string_free(ANGBAND_DIR_FILE);
1915         string_free(ANGBAND_DIR_HELP);
1916         string_free(ANGBAND_DIR_INFO);
1917         string_free(ANGBAND_DIR_SAVE);
1918         string_free(ANGBAND_DIR_PREF);
1919         string_free(ANGBAND_DIR_USER);
1920         string_free(ANGBAND_DIR_XTRA);
1921 }
Note: See TracBrowser for help on using the browser.