OSDN Git Service

使っていない E_name を全て削除。
[hengbandforosx/hengbandosx.git] / src / init1.c
1 /* File: init1.c */
2
3 /* Purpose: Initialization (part 1) -BEN- */
4
5 #include "angband.h"
6
7
8 #ifdef JP
9 #undef strchr
10 char* _strchr(char* ptr, char ch)
11 {
12   int k_flag = 0;
13
14   for ( ; *ptr != '\0'; ++ptr)
15     if (k_flag == 0) {
16       if (*ptr == ch)
17         return ptr;
18       if (iskanji(*ptr))
19         k_flag = 1;
20     } else
21       k_flag = 0;
22
23   return NULL;
24 }
25 #define strchr _strchr
26 #endif
27 /*
28  * This file is used to initialize various variables and arrays for the
29  * Angband game.  Note the use of "fd_read()" and "fd_write()" to bypass
30  * the common limitation of "read()" and "write()" to only 32767 bytes
31  * at a time.
32  *
33  * Several of the arrays for Angband are built from "template" files in
34  * the "lib/file" directory, from which quick-load binary "image" files
35  * are constructed whenever they are not present in the "lib/data"
36  * directory, or if those files become obsolete, if we are allowed.
37  *
38  * Warning -- the "ascii" file parsers use a minor hack to collect the
39  * name and text information in a single pass.  Thus, the game will not
40  * be able to load any template file with more than 20K of names or 60K
41  * of text, even though technically, up to 64K should be legal.
42  *
43  * Note that if "ALLOW_TEMPLATES" is not defined, then a lot of the code
44  * in this file is compiled out, and the game will not run unless valid
45  * "binary template files" already exist in "lib/data".  Thus, one can
46  * compile Angband with ALLOW_TEMPLATES defined, run once to create the
47  * "*.raw" files in "lib/data", and then quit, and recompile without
48  * defining ALLOW_TEMPLATES, which will both save 20K and prevent people
49  * from changing the ascii template files in potentially dangerous ways.
50  *
51  * The code could actually be removed and placed into a "stand-alone"
52  * program, but that feels a little silly, especially considering some
53  * of the platforms that we currently support.
54  */
55
56 #ifdef ALLOW_TEMPLATES
57
58 #include "init.h"
59
60
61 /*** Helper arrays for parsing ascii template files ***/
62
63 /*
64  * Monster Blow Methods
65  */
66 static cptr r_info_blow_method[] =
67 {
68         "",
69         "HIT",
70         "TOUCH",
71         "PUNCH",
72         "KICK",
73         "CLAW",
74         "BITE",
75         "STING",
76         "SLASH",
77         "BUTT",
78         "CRUSH",
79         "ENGULF",
80         "CHARGE",
81         "CRAWL",
82         "DROOL",
83         "SPIT",
84         "EXPLODE",
85         "GAZE",
86         "WAIL",
87         "SPORE",
88         "XXX4",
89         "BEG",
90         "INSULT",
91         "MOAN",
92         "SHOW",
93         NULL
94 };
95
96
97 /*
98  * Monster Blow Effects
99  */
100 static cptr r_info_blow_effect[] =
101 {
102         "",
103         "HURT",
104         "POISON",
105         "UN_BONUS",
106         "UN_POWER",
107         "EAT_GOLD",
108         "EAT_ITEM",
109         "EAT_FOOD",
110         "EAT_LITE",
111         "ACID",
112         "ELEC",
113         "FIRE",
114         "COLD",
115         "BLIND",
116         "CONFUSE",
117         "TERRIFY",
118         "PARALYZE",
119         "LOSE_STR",
120         "LOSE_INT",
121         "LOSE_WIS",
122         "LOSE_DEX",
123         "LOSE_CON",
124         "LOSE_CHR",
125         "LOSE_ALL",
126         "SHATTER",
127         "EXP_10",
128         "EXP_20",
129         "EXP_40",
130         "EXP_80",
131         "DISEASE",
132         "TIME",
133         "EXP_VAMP",
134         "DR_MANA",
135         "SUPERHURT",
136         NULL
137 };
138
139
140 /*
141  * Monster race flags
142  */
143 static cptr r_info_flags1[] =
144 {
145         "UNIQUE",
146         "QUESTOR",
147         "MALE",
148         "FEMALE",
149         "CHAR_CLEAR",
150         "CHAR_MULTI",
151         "ATTR_CLEAR",
152         "ATTR_MULTI",
153         "FORCE_DEPTH",
154         "FORCE_MAXHP",
155         "FORCE_SLEEP",
156         "FORCE_EXTRA",
157         "FRIEND",
158         "FRIENDS",
159         "ESCORT",
160         "ESCORTS",
161         "NEVER_BLOW",
162         "NEVER_MOVE",
163         "RAND_25",
164         "RAND_50",
165         "ONLY_GOLD",
166         "ONLY_ITEM",
167         "DROP_60",
168         "DROP_90",
169         "DROP_1D2",
170         "DROP_2D2",
171         "DROP_3D2",
172         "DROP_4D2",
173         "DROP_GOOD",
174         "DROP_GREAT",
175         "DROP_USEFUL",
176         "DROP_CHOSEN"
177 };
178
179 /*
180  * Monster race flags
181  */
182 static cptr r_info_flags2[] =
183 {
184         "STUPID",
185         "SMART",
186         "CAN_SPEAK",
187         "REFLECTING",
188         "INVISIBLE",
189         "COLD_BLOOD",
190         "EMPTY_MIND",
191         "WEIRD_MIND",
192         "MULTIPLY",
193         "REGENERATE",
194         "SHAPECHANGER",
195         "ATTR_ANY",
196         "POWERFUL",
197         "ELDRITCH_HORROR",
198         "AURA_FIRE",
199         "AURA_ELEC",
200         "OPEN_DOOR",
201         "BASH_DOOR",
202         "PASS_WALL",
203         "KILL_WALL",
204         "MOVE_BODY",
205         "KILL_BODY",
206         "TAKE_ITEM",
207         "KILL_ITEM",
208         "BRAIN_1",
209         "BRAIN_2",
210         "BRAIN_3",
211         "BRAIN_4",
212         "BRAIN_5",
213         "BRAIN_6",
214         "BRAIN_7",
215         "QUANTUM"
216 };
217
218 /*
219  * Monster race flags
220  */
221 static cptr r_info_flags3[] =
222 {
223         "ORC",
224         "TROLL",
225         "GIANT",
226         "DRAGON",
227         "DEMON",
228         "UNDEAD",
229         "EVIL",
230         "ANIMAL",
231         "AMBERITE",
232         "GOOD",
233         "AURA_COLD",
234         "NONLIVING",
235         "HURT_LITE",
236         "HURT_ROCK",
237         "HURT_FIRE",
238         "HURT_COLD",
239         "IM_ACID",
240         "IM_ELEC",
241         "IM_FIRE",
242         "IM_COLD",
243         "IM_POIS",
244         "RES_TELE",
245         "RES_NETH",
246         "RES_WATE",
247         "RES_PLAS",
248         "RES_NEXU",
249         "RES_DISE",
250         "RES_ALL",
251         "NO_FEAR",
252         "NO_STUN",
253         "NO_CONF",
254         "NO_SLEEP"
255 };
256
257 /*
258  * Monster race flags
259  */
260 static cptr r_info_flags4[] =
261 {
262         "SHRIEK",
263         "XXX1",
264         "DISPEL",
265         "ROCKET",
266         "ARROW_1",
267         "ARROW_2",
268         "ARROW_3",
269         "ARROW_4",
270         "BR_ACID",
271         "BR_ELEC",
272         "BR_FIRE",
273         "BR_COLD",
274         "BR_POIS",
275         "BR_NETH",
276         "BR_LITE",
277         "BR_DARK",
278         "BR_CONF",
279         "BR_SOUN",
280         "BR_CHAO",
281         "BR_DISE",
282         "BR_NEXU",
283         "BR_TIME",
284         "BR_INER",
285         "BR_GRAV",
286         "BR_SHAR",
287         "BR_PLAS",
288         "BR_WALL",
289         "BR_MANA",
290         "BA_NUKE",
291         "BR_NUKE",
292         "BA_CHAO",
293         "BR_DISI",
294 };
295
296 /*
297  * Monster race flags
298  */
299 static cptr r_info_flags5[] =
300 {
301         "BA_ACID",
302         "BA_ELEC",
303         "BA_FIRE",
304         "BA_COLD",
305         "BA_POIS",
306         "BA_NETH",
307         "BA_WATE",
308         "BA_MANA",
309         "BA_DARK",
310         "DRAIN_MANA",
311         "MIND_BLAST",
312         "BRAIN_SMASH",
313         "CAUSE_1",
314         "CAUSE_2",
315         "CAUSE_3",
316         "CAUSE_4",
317         "BO_ACID",
318         "BO_ELEC",
319         "BO_FIRE",
320         "BO_COLD",
321         "BA_LITE",
322         "BO_NETH",
323         "BO_WATE",
324         "BO_MANA",
325         "BO_PLAS",
326         "BO_ICEE",
327         "MISSILE",
328         "SCARE",
329         "BLIND",
330         "CONF",
331         "SLOW",
332         "HOLD"
333 };
334
335 /*
336  * Monster race flags
337  */
338 static cptr r_info_flags6[] =
339 {
340         "HASTE",
341         "HAND_DOOM",
342         "HEAL",
343         "INVULNER",
344         "BLINK",
345         "TPORT",
346         "WORLD",
347         "SPECIAL",
348         "TELE_TO",
349         "TELE_AWAY",
350         "TELE_LEVEL",
351         "PSY_SPEAR",
352         "DARKNESS",
353         "TRAPS",
354         "FORGET",
355         "ANIM_DEAD", /* ToDo: Implement ANIM_DEAD */
356         "S_KIN",
357         "S_CYBER",
358         "S_MONSTER",
359         "S_MONSTERS",
360         "S_ANT",
361         "S_SPIDER",
362         "S_HOUND",
363         "S_HYDRA",
364         "S_ANGEL",
365         "S_DEMON",
366         "S_UNDEAD",
367         "S_DRAGON",
368         "S_HI_UNDEAD",
369         "S_HI_DRAGON",
370         "S_AMBERITES",
371         "S_UNIQUE"
372 };
373
374
375 /*
376  * Monster race flags
377  */
378 static cptr r_info_flags7[] =
379 {
380         "AQUATIC",
381         "CAN_SWIM",
382         "CAN_FLY",
383         "FRIENDLY",
384         "UNIQUE_7",
385         "UNIQUE2",
386         "RIDING",
387         "KAGE",
388         "HAS_LITE_1",
389         "SELF_LITE_1",
390         "HAS_LITE_2",
391         "SELF_LITE_2",
392         "GUARDIAN",
393         "CHAMELEON",
394         "KILL_EXP",
395         "XXX7X15",
396         "XXX7X16",
397         "XXX7X17",
398         "XXX7X18",
399         "XXX7X19",
400         "XXX7X20",
401         "XXX7X21",
402         "XXX7X22",
403         "XXX7X23",
404         "XXX7X24",
405         "XXX7X25",
406         "XXX7X26",
407         "XXX7X27",
408         "XXX7X28",
409         "XXX7X29",
410         "XXX7X30",
411         "XXX7X31",
412 };
413
414 /*
415  * Monster race flags
416  */
417 static cptr r_info_flags8[] =
418 {
419         "WILD_ONLY",
420         "WILD_TOWN",
421         "XXX8X02",
422         "WILD_SHORE",
423         "WILD_OCEAN",
424         "WILD_WASTE",
425         "WILD_WOOD",
426         "WILD_VOLCANO",
427         "XXX8X08",
428         "WILD_MOUNTAIN",
429         "WILD_GRASS",
430         "XXX8X11",
431         "XXX8X12",
432         "XXX8X13",
433         "XXX8X14",
434         "XXX8X15",
435         "XXX8X16",
436         "XXX8X17",
437         "XXX8X18",
438         "XXX8X19",
439         "XXX8X20",
440         "XXX8X21",
441         "XXX8X22",
442         "XXX8X23",
443         "XXX8X24",
444         "XXX8X25",
445         "XXX8X26",
446         "XXX8X27",
447         "XXX8X28",
448         "XXX8X29",
449         "WILD_SWAMP",   /* ToDo: Implement Swamp */
450         "WILD_ALL",
451 };
452
453
454 /*
455  * Monster race flags - Drops
456  */
457 static cptr r_info_flags9[] =
458 {
459         "DROP_CORPSE",
460         "DROP_SKELETON",
461         "EAT_BLIND",
462         "EAT_CONF",
463         "EAT_MANA",
464         "EAT_NEXUS",
465         "EAT_BLINK",
466         "EAT_SLEEP",
467         "EAT_BERSERKER",
468         "EAT_ACIDIC",
469         "EAT_SPEED",
470         "EAT_CURE",
471         "EAT_FIRE_RES",
472         "EAT_COLD_RES",
473         "EAT_ACID_RES",
474         "EAT_ELEC_RES",
475         "EAT_POIS_RES",
476         "EAT_INSANITY",
477         "EAT_DRAIN_EXP",
478         "EAT_POISONOUS",
479         "EAT_GIVE_STR",
480         "EAT_GIVE_INT",
481         "EAT_GIVE_WIS",
482         "EAT_GIVE_DEX",
483         "EAT_GIVE_CON",
484         "EAT_GIVE_CHR",
485         "EAT_LOSE_STR",
486         "EAT_LOSE_INT",
487         "EAT_LOSE_WIS",
488         "EAT_LOSE_DEX",
489         "EAT_LOSE_CON",
490         "EAT_LOSE_CHR",
491         "EAT_DRAIN_MANA",
492 };
493
494
495 /*
496  * Object flags
497  */
498 static cptr k_info_flags1[] =
499 {
500         "STR",
501         "INT",
502         "WIS",
503         "DEX",
504         "CON",
505         "CHR",
506         "MAGIC_MASTERY",
507         "FORCE_WEPON",
508         "STEALTH",
509         "SEARCH",
510         "INFRA",
511         "TUNNEL",
512         "SPEED",
513         "BLOWS",
514         "CHAOTIC",
515         "VAMPIRIC",
516         "SLAY_ANIMAL",
517         "SLAY_EVIL",
518         "SLAY_UNDEAD",
519         "SLAY_DEMON",
520         "SLAY_ORC",
521         "SLAY_TROLL",
522         "SLAY_GIANT",
523         "SLAY_DRAGON",
524         "KILL_DRAGON",
525         "VORPAL",
526         "IMPACT",
527         "BRAND_POIS",
528         "BRAND_ACID",
529         "BRAND_ELEC",
530         "BRAND_FIRE",
531         "BRAND_COLD"
532 };
533
534 /*
535  * Object flags
536  */
537 static cptr k_info_flags2[] =
538 {
539         "SUST_STR",
540         "SUST_INT",
541         "SUST_WIS",
542         "SUST_DEX",
543         "SUST_CON",
544         "SUST_CHR",
545         "RIDING",
546         "XXX2",
547         "IM_ACID",
548         "IM_ELEC",
549         "IM_FIRE",
550         "IM_COLD",
551         "THROW",
552         "REFLECT",
553         "FREE_ACT",
554         "HOLD_LIFE",
555         "RES_ACID",
556         "RES_ELEC",
557         "RES_FIRE",
558         "RES_COLD",
559         "RES_POIS",
560         "RES_FEAR",
561         "RES_LITE",
562         "RES_DARK",
563         "RES_BLIND",
564         "RES_CONF",
565         "RES_SOUND",
566         "RES_SHARDS",
567         "RES_NETHER",
568         "RES_NEXUS",
569         "RES_CHAOS",
570         "RES_DISEN"
571 };
572
573 /*
574  * Object flags
575  */
576 static cptr k_info_flags3[] =
577 {
578         "SH_FIRE",
579         "SH_ELEC",
580         "QUESTITEM",
581         "SH_COLD",
582         "NO_TELE",
583         "NO_MAGIC",
584         "DEC_MANA",
585         "TY_CURSE",
586         "XXX1",
587         "HIDE_TYPE",
588         "SHOW_MODS",
589         "INSTA_ART",
590         "FEATHER",
591         "LITE",
592         "SEE_INVIS",
593         "TELEPATHY",
594         "SLOW_DIGEST",
595         "REGEN",
596         "XTRA_MIGHT",
597         "XTRA_SHOTS",
598         "IGNORE_ACID",
599         "IGNORE_ELEC",
600         "IGNORE_FIRE",
601         "IGNORE_COLD",
602         "ACTIVATE",
603         "DRAIN_EXP",
604         "TELEPORT",
605         "AGGRAVATE",
606         "BLESSED",
607         "CURSED",
608         "HEAVY_CURSE",
609         "PERMA_CURSE"
610 };
611
612
613 /*
614  * Dungeon flags
615  */
616 static cptr d_info_flags1[] =
617 {
618         "WINNER",
619         "MAZE",
620         "SMALLEST",
621         "BEGINNER",
622         "BIG",
623         "NO_DOORS",
624         "WATER_RIVER",
625         "LAVA_RIVER",
626         "WATER_RIVERS",
627         "LAVA_RIVERS",
628         "CAVE",
629         "CAVERN",
630         "NO_UP",
631         "HOT",
632         "COLD",
633         "NO_DOWN",
634         "FORGET",
635         "LAKE_WATER",
636         "LAKE_LAVA",
637         "LAKE_RUBBLE",
638         "LAKE_TREE",
639         "NO_VAULT",
640         "ARENA",
641         "DESTROY",
642         "XXX1",
643         "NO_CAVE",
644         "NO_MAGIC",
645         "NO_MELEE",
646         "CHAMELEON",
647         "DARKNESS",
648         "XXX1",
649         "XXX1"
650 };
651
652
653 /*
654  * Convert a "color letter" into an "actual" color
655  * The colors are: dwsorgbuDWvyRGBU, as shown below
656  */
657 static int color_char_to_attr(char c)
658 {
659         switch (c)
660         {
661                 case 'd': return (TERM_DARK);
662                 case 'w': return (TERM_WHITE);
663                 case 's': return (TERM_SLATE);
664                 case 'o': return (TERM_ORANGE);
665                 case 'r': return (TERM_RED);
666                 case 'g': return (TERM_GREEN);
667                 case 'b': return (TERM_BLUE);
668                 case 'u': return (TERM_UMBER);
669
670                 case 'D': return (TERM_L_DARK);
671                 case 'W': return (TERM_L_WHITE);
672                 case 'v': return (TERM_VIOLET);
673                 case 'y': return (TERM_YELLOW);
674                 case 'R': return (TERM_L_RED);
675                 case 'G': return (TERM_L_GREEN);
676                 case 'B': return (TERM_L_BLUE);
677                 case 'U': return (TERM_L_UMBER);
678         }
679
680         return (-1);
681 }
682
683
684
685 /*** Initialize from ascii template files ***/
686
687
688 /*
689  * Initialize an "*_info" array, by parsing an ascii "template" file
690  */
691 errr init_info_txt(FILE *fp, char *buf, header *head,
692                    parse_info_txt_func parse_info_txt_line)
693 {
694         errr err;
695
696         /* Just before the first record */
697         error_idx = -1;
698
699         /* Just before the first line */
700         error_line = 0;
701
702
703         /* Prepare the "fake" stuff */
704         head->name_size = 0;
705         head->text_size = 0;
706
707         /* Parse */
708         while (0 == my_fgets(fp, buf, 1024))
709         {
710                 /* Advance the line number */
711                 error_line++;
712
713                 /* Skip comments and blank lines */
714                 if (!buf[0] || (buf[0] == '#')) continue;
715
716                 /* Verify correct "colon" format */
717                 if (buf[1] != ':') return (PARSE_ERROR_GENERIC);
718
719
720                 /* Hack -- Process 'V' for "Version" */
721                 if (buf[0] == 'V')
722                 {
723                         /* ignore */
724                         continue;
725                 }
726
727                 /* Parse the line */
728                 if ((err = (*parse_info_txt_line)(buf, head)) != 0)
729                         return (err);
730         }
731
732
733         /* Complete the "name" and "text" sizes */
734         if (head->name_size) head->name_size++;
735         if (head->text_size) head->text_size++;
736
737         /* Success */
738         return (0);
739 }
740
741
742 /*
743  * Initialize the "v_info" array, by parsing an ascii "template" file
744  */
745 errr parse_v_info(char *buf, header *head)
746 {
747         int i;
748         char *s;
749
750         /* Current entry */
751         static vault_type *v_ptr = NULL;
752
753         /* Process 'N' for "New/Number/Name" */
754         if (buf[0] == 'N')
755         {
756                 /* Find the colon before the name */
757                 s = strchr(buf+2, ':');
758
759                 /* Verify that colon */
760                 if (!s) return (1);
761
762                 /* Nuke the colon, advance to the name */
763                 *s++ = '\0';
764
765                 /* Paranoia -- require a name */
766                 if (!*s) return (1);
767
768                 /* Get the index */
769                 i = atoi(buf+2);
770
771                 /* Verify information */
772                 if (i <= error_idx) return (4);
773
774                 /* Verify information */
775                 if (i >= head->info_num) return (2);
776
777                 /* Save the index */
778                 error_idx = i;
779
780                 /* Point at the "info" */
781                 v_ptr = &v_info[i];
782
783                 /* Hack -- Verify space */
784                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
785
786                 /* Advance and Save the name index */
787                 if (!v_ptr->name) v_ptr->name = ++head->name_size;
788
789                 /* Append chars to the name */
790                 strcpy(head->name_ptr + head->name_size, s);
791
792                 /* Advance the index */
793                 head->name_size += strlen(s);
794         }
795
796         /* There better be a current v_ptr */
797         else if (!v_ptr) return (3);
798
799         /* Process 'D' for "Description" */
800         else if (buf[0] == 'D')
801         {
802                 /* Acquire the text */
803                 s = buf+2;
804
805                 /* Hack -- Verify space */
806                 if (head->text_size + strlen(s) + 8 > fake_text_size) return (7);
807
808                 /* Advance and Save the text index */
809                 if (!v_ptr->text) v_ptr->text = ++head->text_size;
810
811                 /* Append chars to the name */
812                 strcpy(head->text_ptr + head->text_size, s);
813
814                 /* Advance the index */
815                 head->text_size += strlen(s);
816
817         }
818
819         /* Process 'X' for "Extra info" (one line only) */
820         else if (buf[0] == 'X')
821         {
822                 int typ, rat, hgt, wid;
823
824                 /* Scan for the values */
825                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
826                         &typ, &rat, &hgt, &wid)) return (1);
827
828                 /* Save the values */
829                 v_ptr->typ = typ;
830                 v_ptr->rat = rat;
831                 v_ptr->hgt = hgt;
832                 v_ptr->wid = wid;
833         }
834
835         /* Oops */
836         else    return (6);
837
838         /* Success */
839         return (0);
840 }
841
842
843
844 /*
845  * Initialize the "s_info" array, by parsing an ascii "template" file
846  */
847 errr parse_s_info(char *buf, header *head)
848 {
849         int i;
850
851         /* Current entry */
852         static skill_table *s_ptr = NULL;
853
854
855         /* Process 'N' for "New/Number/Name" */
856         if (buf[0] == 'N')
857         {
858                 /* Get the index */
859                 i = atoi(buf+2);
860
861                         /* Verify information */
862                 if (i <= error_idx) return (4);
863
864                 /* Verify information */
865                 if (i >= head->info_num) return (2);
866
867                 /* Save the index */
868                 error_idx = i;
869
870                 /* Point at the "info" */
871                 s_ptr = &s_info[i];
872         }
873
874         /* There better be a current s_ptr */
875         else if (!s_ptr) return (3);
876
877         /* Process 'W' for "Weapon exp" */
878         else if (buf[0] == 'W')
879         {
880                 int tval, sval, start, max;
881                 const s16b exp_conv_table[] = { 0, 4000, 6000, 7000, 8000 };
882
883                 /* Scan for the values */
884                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
885                                 &tval, &sval, &start, &max)) return (1);
886
887                 if (start < 0 || start > 4 || max < 0 || max > 4) return (8);
888
889                 /* Save the values */
890                 s_ptr->w_start[tval][sval] = exp_conv_table[start];
891                 s_ptr->w_max[tval][sval] = exp_conv_table[max];
892         }
893
894         /* Process 'S' for "Skill exp" */
895         else if (buf[0] == 'S')
896         {
897                 int num, start, max;
898
899                 /* Scan for the values */
900                 if (3 != sscanf(buf+2, "%d:%d:%d",
901                                 &num, &start, &max)) return (1);
902
903                 if (start < 0 || start > 8000 || max < 0 || max > 8000) return (8);
904
905                 /* Save the values */
906                 s_ptr->s_start[num] = start;
907                 s_ptr->s_max[num] = max;
908         }
909
910
911         /* Oops */
912         else return (6);
913
914         /* Success */
915         return (0);
916 }
917
918
919 /*
920  * Initialize the "m_info" array, by parsing an ascii "template" file
921  */
922 errr parse_m_info(char *buf, header *head)
923 {
924         int i;
925
926         char *s;
927
928         /* Current entry */
929         static player_magic *m_ptr = NULL;
930
931         /* ---Hack--- */
932         static int realm, magic_idx = 0, readable = 0;
933
934
935         /* Process 'N' for "New/Number/Name" */
936         if (buf[0] == 'N')
937         {
938                 /* Get the index */
939                 i = atoi(buf+2);
940
941                         /* Verify information */
942                 if (i <= error_idx) return (4);
943
944                 /* Verify information */
945                 if (i >= head->info_num) return (2);
946
947                 /* Save the index */
948                 error_idx = i;
949
950                 /* Point at the "info" */
951                 m_ptr = &m_info[i];
952         }
953
954         /* There better be a current m_ptr */
955         else if (!m_ptr) return (3);
956
957         /* Process 'I' for "Info" (one line only) */
958         else if (buf[0] == 'I')
959         {
960                 char *book, *stat;
961                 int xtra, type, first, weight;
962
963                 /* Find the colon before the name */
964                 s = strchr(buf+2, ':');
965
966                 /* Verify that colon */
967                 if (!s) return (1);
968
969                 /* Nuke the colon, advance to the name */
970                 *s++ = '\0';
971
972                 book = buf+2;
973
974                 if (streq(book, "SORCERY")) m_ptr->spell_book = TV_SORCERY_BOOK;
975                 else if (streq(book, "LIFE")) m_ptr->spell_book = TV_LIFE_BOOK;
976                 else if (streq(book, "MUSIC")) m_ptr->spell_book = TV_MUSIC_BOOK;
977                 else if (streq(book, "HISSATSU")) m_ptr->spell_book = TV_HISSATSU_BOOK;
978                 else if (streq(book, "NONE")) m_ptr->spell_book = 0;
979                 else return (5);
980
981                 stat = s;
982
983                 /* Find the colon before the name */
984                 s = strchr(s, ':');
985
986                 /* Verify that colon */
987                 if (!s) return (1);
988
989                 /* Nuke the colon, advance to the name */
990                 *s++ = '\0';
991
992                 if (streq(stat, "STR")) m_ptr->spell_stat = A_STR;
993                 else if (streq(stat, "INT")) m_ptr->spell_stat = A_INT;
994                 else if (streq(stat, "WIS")) m_ptr->spell_stat = A_WIS;
995                 else if (streq(stat, "DEX")) m_ptr->spell_stat = A_DEX;
996                 else if (streq(stat, "CON")) m_ptr->spell_stat = A_CON;
997                 else if (streq(stat, "CHR")) m_ptr->spell_stat = A_CHR;
998                 else return (5);
999
1000
1001                 /* Scan for the values */
1002                 if (4 != sscanf(s, "%x:%d:%d:%d",
1003                                 &xtra, &type, &first, &weight)) return (1);
1004
1005                 m_ptr->spell_xtra = xtra;
1006                 m_ptr->spell_type = type;
1007                 m_ptr->spell_first = first;
1008                 m_ptr->spell_weight = weight;
1009         }
1010
1011
1012         /* Process 'R' for "Realm" (one line only) */
1013         else if (buf[0] == 'R')
1014         {
1015                 /* Scan for the values */
1016                 if (2 != sscanf(buf+2, "%d:%d",
1017                                 &realm, &readable)) return (1);
1018
1019                 magic_idx = 0;
1020         }
1021
1022         else if (buf[0] == 'T')
1023         {
1024                 int level, mana, fail, exp;
1025
1026                 if (!readable) return (1);
1027                 /* Scan for the values */
1028                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1029                                 &level, &mana, &fail, &exp)) return (1);
1030
1031                 m_ptr->info[realm][magic_idx].slevel = level;
1032                 m_ptr->info[realm][magic_idx].smana = mana;
1033                 m_ptr->info[realm][magic_idx].sfail = fail;
1034                 m_ptr->info[realm][magic_idx].sexp = exp;
1035                 magic_idx ++;
1036         }
1037
1038
1039         /* Oops */
1040         else return (6);
1041
1042         /* Success */
1043         return (0);
1044 }
1045
1046
1047 /*
1048  * Initialize the "f_info" array, by parsing an ascii "template" file
1049  */
1050 errr parse_f_info(char *buf, header *head)
1051 {
1052         int i;
1053
1054         char *s;
1055
1056         /* Current entry */
1057         static feature_type *f_ptr = NULL;
1058
1059
1060         /* Process 'N' for "New/Number/Name" */
1061         if (buf[0] == 'N')
1062         {
1063                 /* Find the colon before the name */
1064                 s = strchr(buf+2, ':');
1065
1066                         /* Verify that colon */
1067                 if (!s) return (1);
1068
1069                 /* Nuke the colon, advance to the name */
1070                 *s++ = '\0';
1071
1072 #ifdef JP
1073                 /* Paranoia -- require a name */
1074                 if (!*s) return (1);
1075 #endif
1076
1077                 /* Get the index */
1078                 i = atoi(buf+2);
1079
1080                 /* Verify information */
1081                 if (i <= error_idx) return (4);
1082
1083                 /* Verify information */
1084                 if (i >= head->info_num) return (2);
1085
1086                 /* Save the index */
1087                 error_idx = i;
1088
1089                 /* Point at the "info" */
1090                 f_ptr = &f_info[i];
1091
1092 #ifdef JP
1093                 /* Hack -- Verify space */
1094                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1095
1096                 /* Advance and Save the name index */
1097                 if (!f_ptr->name) f_ptr->name = ++head->name_size;
1098
1099                 /* Append chars to the name */
1100                 strcpy(head->name_ptr + head->name_size, s);
1101
1102                 /* Advance the index */
1103                 head->name_size += strlen(s);
1104 #endif
1105                 /* Default "mimic" */
1106                 f_ptr->mimic = i;
1107         }
1108
1109         /* There better be a current f_ptr */
1110         else if (!f_ptr) return (3);
1111
1112 #ifdef JP
1113         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1114         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
1115         else if (buf[0] == 'E')
1116         {
1117                 /* nothing to do */
1118         }
1119 #else
1120         else if (buf[0] == 'E')
1121         {
1122                 /* Acquire the Text */
1123                 s = buf+2;
1124
1125                 /* Hack -- Verify space */
1126                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1127
1128                 /* Advance and Save the name index */
1129                 if (!f_ptr->name) f_ptr->name = ++head->name_size;
1130
1131                 /* Append chars to the name */
1132                 strcpy(head->name_ptr + head->name_size, s);
1133
1134                 /* Advance the index */
1135                 head->name_size += strlen(s);
1136         }
1137 #endif
1138
1139 #if 0
1140
1141         /* Process 'D' for "Description" */
1142         else if (buf[0] == 'D')
1143         {
1144                 /* Acquire the text */
1145                 s = buf+2;
1146
1147                         /* Hack -- Verify space */
1148                 if (f_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
1149
1150                 /* Advance and Save the text index */
1151                 if (!f_ptr->text) f_ptr->text = ++f_head->text_size;
1152
1153                 /* Append chars to the name */
1154                 strcpy(f_text + f_head->text_size, s);
1155
1156                 /* Advance the index */
1157                 f_head->text_size += strlen(s);
1158
1159         }
1160
1161 #endif
1162
1163
1164         /* Process 'M' for "Mimic" (one line only) */
1165         else if (buf[0] == 'M')
1166         {
1167                 int mimic;
1168
1169                 /* Scan for the values */
1170                 if (1 != sscanf(buf+2, "%d",
1171                                 &mimic)) return (1);
1172
1173                 /* Save the values */
1174                 f_ptr->mimic = mimic;
1175
1176         }
1177
1178
1179         /* Process 'G' for "Graphics" (one line only) */
1180         else if (buf[0] == 'G')
1181         {
1182                 int tmp;
1183
1184                 /* Paranoia */
1185                 if (!buf[2]) return (1);
1186                 if (!buf[3]) return (1);
1187                 if (!buf[4]) return (1);
1188
1189                 /* Extract the color */
1190                 tmp = color_char_to_attr(buf[4]);
1191
1192                 /* Paranoia */
1193                 if (tmp < 0) return (1);
1194
1195                 /* Save the values */
1196                 f_ptr->d_attr = tmp;
1197                 f_ptr->d_char = buf[2];
1198
1199         }
1200
1201         /* Oops */
1202         else    return (6);
1203
1204         /* Success */
1205         return (0);
1206 }
1207
1208
1209 /*
1210  * Grab one flag in an object_kind from a textual string
1211  */
1212 static errr grab_one_kind_flag(object_kind *k_ptr, cptr what)
1213 {
1214         int i;
1215
1216         /* Check flags1 */
1217         for (i = 0; i < 32; i++)
1218         {
1219                 if (streq(what, k_info_flags1[i]))
1220                 {
1221                         k_ptr->flags1 |= (1L << i);
1222                         return (0);
1223                 }
1224         }
1225
1226         /* Check flags2 */
1227         for (i = 0; i < 32; i++)
1228         {
1229                 if (streq(what, k_info_flags2[i]))
1230                 {
1231                         k_ptr->flags2 |= (1L << i);
1232                         return (0);
1233                 }
1234         }
1235
1236         /* Check flags3 */
1237         for (i = 0; i < 32; i++)
1238         {
1239                 if (streq(what, k_info_flags3[i]))
1240                 {
1241                         k_ptr->flags3 |= (1L << i);
1242                         return (0);
1243                 }
1244         }
1245
1246         /* Oops */
1247 #ifdef JP
1248         msg_format("̤ÃΤΥ¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1249 #else
1250         msg_format("Unknown object flag '%s'.", what);
1251 #endif
1252
1253
1254         /* Error */
1255         return (1);
1256 }
1257
1258
1259 /*
1260  * Initialize the "k_info" array, by parsing an ascii "template" file
1261  */
1262 errr parse_k_info(char *buf, header *head)
1263 {
1264         int i;
1265
1266         char *s, *t;
1267
1268         /* Current entry */
1269         static object_kind *k_ptr = NULL;
1270
1271
1272         /* Process 'N' for "New/Number/Name" */
1273         if (buf[0] == 'N')
1274         {
1275                 /* Find the colon before the name */
1276                 s = strchr(buf+2, ':');
1277
1278                         /* Verify that colon */
1279                 if (!s) return (1);
1280
1281                 /* Nuke the colon, advance to the name */
1282                 *s++ = '\0';
1283
1284 #ifdef JP
1285                 /* Paranoia -- require a name */
1286                 if (!*s) return (1);
1287 #endif
1288                 /* Get the index */
1289                 i = atoi(buf+2);
1290
1291                 /* Verify information */
1292                 if (i <= error_idx) return (4);
1293
1294                 /* Verify information */
1295                 if (i >= head->info_num) return (2);
1296
1297                 /* Save the index */
1298                 error_idx = i;
1299
1300                 /* Point at the "info" */
1301                 k_ptr = &k_info[i];
1302
1303 #ifdef JP
1304                 /* Hack -- Verify space */
1305                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1306
1307                 /* Advance and Save the name index */
1308                 if (!k_ptr->name) k_ptr->name = ++head->name_size;
1309
1310                 /* Append chars to the name */
1311                 strcpy(head->name_ptr + head->name_size, s);
1312
1313                 /* Advance the index */
1314                 head->name_size += strlen(s);
1315 #endif
1316         }
1317
1318         /* There better be a current k_ptr */
1319         else if (!k_ptr) return (3);
1320
1321
1322 #ifdef JP
1323         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1324         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
1325         else if (buf[0] == 'E')
1326         {
1327                 /* nothing to do */
1328         }
1329 #else
1330         else if (buf[0] == 'E')
1331         {
1332                 /* Acquire the Text */
1333                 s = buf+2;
1334
1335                         /* Hack -- Verify space */
1336                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1337
1338                 /* Advance and Save the name index */
1339                 if (!k_ptr->name) k_ptr->name = ++head->name_size;
1340
1341                 /* Append chars to the name */
1342                 strcpy(head->name_ptr + head->name_size, s);
1343
1344                 /* Advance the index */
1345                 head->name_size += strlen(s);
1346         }
1347 #endif
1348 #if 0
1349
1350         /* Process 'D' for "Description" */
1351         else if (buf[0] == 'D')
1352         {
1353                 /* Acquire the text */
1354                 s = buf+2;
1355
1356                         /* Hack -- Verify space */
1357                 if (k_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
1358
1359                 /* Advance and Save the text index */
1360                 if (!k_ptr->text) k_ptr->text = ++k_head->text_size;
1361
1362                 /* Append chars to the name */
1363                 strcpy(k_text + k_head->text_size, s);
1364
1365                 /* Advance the index */
1366                 k_head->text_size += strlen(s);
1367         }
1368
1369 #endif
1370
1371
1372         /* Process 'G' for "Graphics" (one line only) */
1373         else if (buf[0] == 'G')
1374         {
1375                 char sym;
1376                 int tmp;
1377
1378                 /* Paranoia */
1379                 if (!buf[2]) return (1);
1380                 if (!buf[3]) return (1);
1381                 if (!buf[4]) return (1);
1382
1383                 /* Extract the char */
1384                 sym = buf[2];
1385
1386                 /* Extract the attr */
1387                 tmp = color_char_to_attr(buf[4]);
1388
1389                 /* Paranoia */
1390                 if (tmp < 0) return (1);
1391
1392                 /* Save the values */
1393                 k_ptr->d_attr = tmp;
1394                 k_ptr->d_char = sym;
1395         }
1396
1397         /* Process 'I' for "Info" (one line only) */
1398         else if (buf[0] == 'I')
1399         {
1400                 int tval, sval, pval;
1401
1402                 /* Scan for the values */
1403                 if (3 != sscanf(buf+2, "%d:%d:%d",
1404                                 &tval, &sval, &pval)) return (1);
1405
1406                 /* Save the values */
1407                 k_ptr->tval = tval;
1408                 k_ptr->sval = sval;
1409                 k_ptr->pval = pval;
1410         }
1411
1412         /* Process 'W' for "More Info" (one line only) */
1413         else if (buf[0] == 'W')
1414         {
1415                 int level, extra, wgt;
1416                 long cost;
1417
1418                 /* Scan for the values */
1419                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1420                                 &level, &extra, &wgt, &cost)) return (1);
1421
1422                 /* Save the values */
1423                 k_ptr->level = level;
1424                 k_ptr->extra = extra;
1425                 k_ptr->weight = wgt;
1426                 k_ptr->cost = cost;
1427         }
1428
1429         /* Process 'A' for "Allocation" (one line only) */
1430         else if (buf[0] == 'A')
1431         {
1432                 int i;
1433
1434                 /* XXX XXX XXX Simply read each number following a colon */
1435                 for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i)
1436                 {
1437                                 /* Default chance */
1438                         k_ptr->chance[i] = 1;
1439
1440                                 /* Store the attack damage index */
1441                         k_ptr->locale[i] = atoi(s+1);
1442
1443                                 /* Find the slash */
1444                         t = strchr(s+1, '/');
1445
1446                                 /* Find the next colon */
1447                         s = strchr(s+1, ':');
1448
1449                                 /* If the slash is "nearby", use it */
1450                         if (t && (!s || t < s))
1451                         {
1452                                 int chance = atoi(t+1);
1453                                 if (chance > 0) k_ptr->chance[i] = chance;
1454                         }
1455                 }
1456         }
1457
1458         /* Hack -- Process 'P' for "power" and such */
1459         else if (buf[0] == 'P')
1460         {
1461                 int ac, hd1, hd2, th, td, ta;
1462
1463                 /* Scan for the values */
1464                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
1465                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
1466
1467                 k_ptr->ac = ac;
1468                 k_ptr->dd = hd1;
1469                 k_ptr->ds = hd2;
1470                 k_ptr->to_h = th;
1471                 k_ptr->to_d = td;
1472                 k_ptr->to_a =  ta;
1473         }
1474
1475         /* Hack -- Process 'F' for flags */
1476         else if (buf[0] == 'F')
1477         {
1478                 /* Parse every entry textually */
1479                 for (s = buf + 2; *s; )
1480                 {
1481                                 /* Find the end of this entry */
1482                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1483
1484                                 /* Nuke and skip any dividers */
1485                         if (*t)
1486                         {
1487                                 *t++ = '\0';
1488                                 while (*t == ' ' || *t == '|') t++;
1489                         }
1490
1491                                 /* Parse this entry */
1492                         if (0 != grab_one_kind_flag(k_ptr, s)) return (5);
1493
1494                                 /* Start the next entry */
1495                         s = t;
1496                 }
1497         }
1498
1499
1500         /* Oops */
1501         else return (6);
1502
1503
1504         /* Success */
1505         return (0);
1506 }
1507
1508
1509 /*
1510  * Grab one flag in an artifact_type from a textual string
1511  */
1512 static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what)
1513 {
1514         int i;
1515
1516         /* Check flags1 */
1517         for (i = 0; i < 32; i++)
1518         {
1519                 if (streq(what, k_info_flags1[i]))
1520                 {
1521                         a_ptr->flags1 |= (1L << i);
1522                         return (0);
1523                 }
1524         }
1525
1526         /* Check flags2 */
1527         for (i = 0; i < 32; i++)
1528         {
1529                 if (streq(what, k_info_flags2[i]))
1530                 {
1531                         a_ptr->flags2 |= (1L << i);
1532                         return (0);
1533                 }
1534         }
1535
1536         /* Check flags3 */
1537         for (i = 0; i < 32; i++)
1538         {
1539                 if (streq(what, k_info_flags3[i]))
1540                 {
1541                         a_ptr->flags3 |= (1L << i);
1542                         return (0);
1543                 }
1544         }
1545
1546         /* Oops */
1547 #ifdef JP
1548         msg_format("̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1549 #else
1550         msg_format("Unknown artifact flag '%s'.", what);
1551 #endif
1552
1553
1554         /* Error */
1555         return (1);
1556 }
1557
1558
1559
1560
1561 /*
1562  * Initialize the "a_info" array, by parsing an ascii "template" file
1563  */
1564 errr parse_a_info(char *buf, header *head)
1565 {
1566         int i;
1567
1568         char *s, *t;
1569
1570         /* Current entry */
1571         static artifact_type *a_ptr = NULL;
1572
1573
1574         /* Process 'N' for "New/Number/Name" */
1575         if (buf[0] == 'N')
1576         {
1577                 /* Find the colon before the name */
1578                 s = strchr(buf+2, ':');
1579
1580                         /* Verify that colon */
1581                 if (!s) return (1);
1582
1583                 /* Nuke the colon, advance to the name */
1584                 *s++ = '\0';
1585 #ifdef JP
1586                 /* Paranoia -- require a name */
1587                 if (!*s) return (1);
1588 #endif
1589                 /* Get the index */
1590                 i = atoi(buf+2);
1591
1592                 /* Verify information */
1593                 if (i < error_idx) return (4);
1594
1595                 /* Verify information */
1596                 if (i >= head->info_num) return (2);
1597
1598                 /* Save the index */
1599                 error_idx = i;
1600
1601                 /* Point at the "info" */
1602                 a_ptr = &a_info[i];
1603
1604                 /* Ignore everything */
1605                 a_ptr->flags3 |= (TR3_IGNORE_ACID);
1606                 a_ptr->flags3 |= (TR3_IGNORE_ELEC);
1607                 a_ptr->flags3 |= (TR3_IGNORE_FIRE);
1608                 a_ptr->flags3 |= (TR3_IGNORE_COLD);
1609 #ifdef JP
1610                 /* Hack -- Verify space */
1611                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1612
1613                 /* Advance and Save the name index */
1614                 if (!a_ptr->name) a_ptr->name = ++head->name_size;
1615
1616                 /* Append chars to the name */
1617                 strcpy(head->name_ptr + head->name_size, s);
1618
1619                 /* Advance the index */
1620                 head->name_size += strlen(s);
1621 #endif
1622         }
1623
1624         /* There better be a current a_ptr */
1625         else if (!a_ptr) return (3);
1626
1627
1628 #ifdef JP
1629         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1630         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
1631         else if (buf[0] == 'E')
1632         {
1633                 /* nothing to do */
1634         }
1635 #else
1636         else if (buf[0] == 'E')
1637         {
1638                 /* Acquire the Text */
1639                 s = buf+2;
1640
1641                         /* Hack -- Verify space */
1642                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1643
1644                 /* Advance and Save the name index */
1645                 if (!a_ptr->name) a_ptr->name = ++head->name_size;
1646
1647                 /* Append chars to the name */
1648                 strcpy(head->name_ptr + head->name_size, s);
1649
1650                 /* Advance the index */
1651                 head->name_size += strlen(s);
1652         }
1653 #endif
1654
1655         /* Process 'D' for "Description" */
1656         else if (buf[0] == 'D')
1657         {
1658 #ifdef JP
1659                 if (buf[2] == '$')
1660                         return (0);
1661                 /* Acquire the text */
1662                 s = buf+2;
1663 #else
1664                 if (buf[2] != '$')
1665                         return (0);
1666                 /* Acquire the text */
1667                 s = buf+3;
1668 #endif
1669
1670                 /* Hack -- Verify space */
1671                 if (head->text_size + strlen(s) + 8 > fake_text_size) return (7);
1672
1673                 /* Advance and Save the text index */
1674                 if (!a_ptr->text) a_ptr->text = ++head->text_size;
1675
1676                 /* Append chars to the name */
1677                 strcpy(head->text_ptr + head->text_size, s);
1678
1679                 /* Advance the index */
1680                 head->text_size += strlen(s);
1681         }
1682
1683
1684         /* Process 'I' for "Info" (one line only) */
1685         else if (buf[0] == 'I')
1686         {
1687                 int tval, sval, pval;
1688
1689                 /* Scan for the values */
1690                 if (3 != sscanf(buf+2, "%d:%d:%d",
1691                                 &tval, &sval, &pval)) return (1);
1692
1693                 /* Save the values */
1694                 a_ptr->tval = tval;
1695                 a_ptr->sval = sval;
1696                 a_ptr->pval = pval;
1697         }
1698
1699         /* Process 'W' for "More Info" (one line only) */
1700         else if (buf[0] == 'W')
1701         {
1702                 int level, rarity, wgt;
1703                 long cost;
1704
1705                 /* Scan for the values */
1706                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1707                                 &level, &rarity, &wgt, &cost)) return (1);
1708
1709                 /* Save the values */
1710                 a_ptr->level = level;
1711                 a_ptr->rarity = rarity;
1712                 a_ptr->weight = wgt;
1713                 a_ptr->cost = cost;
1714         }
1715
1716         /* Hack -- Process 'P' for "power" and such */
1717         else if (buf[0] == 'P')
1718         {
1719                 int ac, hd1, hd2, th, td, ta;
1720
1721                 /* Scan for the values */
1722                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
1723                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
1724
1725                 a_ptr->ac = ac;
1726                 a_ptr->dd = hd1;
1727                 a_ptr->ds = hd2;
1728                 a_ptr->to_h = th;
1729                 a_ptr->to_d = td;
1730                 a_ptr->to_a =  ta;
1731         }
1732
1733         /* Hack -- Process 'F' for flags */
1734         else if (buf[0] == 'F')
1735         {
1736                 /* Parse every entry textually */
1737                 for (s = buf + 2; *s; )
1738                 {
1739                                 /* Find the end of this entry */
1740                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1741
1742                                 /* Nuke and skip any dividers */
1743                         if (*t)
1744                         {
1745                                 *t++ = '\0';
1746                                 while ((*t == ' ') || (*t == '|')) t++;
1747                         }
1748
1749                                 /* Parse this entry */
1750                         if (0 != grab_one_artifact_flag(a_ptr, s)) return (5);
1751
1752                                 /* Start the next entry */
1753                         s = t;
1754                 }
1755         }
1756
1757
1758         /* Oops */
1759         else return (6);
1760
1761
1762         /* Success */
1763         return (0);
1764 }
1765
1766
1767 /*
1768  * Grab one flag in a ego-item_type from a textual string
1769  */
1770 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what)
1771 {
1772         int i;
1773
1774         /* Check flags1 */
1775         for (i = 0; i < 32; i++)
1776         {
1777                 if (streq(what, k_info_flags1[i]))
1778                 {
1779                         e_ptr->flags1 |= (1L << i);
1780                         return (0);
1781                 }
1782         }
1783
1784         /* Check flags2 */
1785         for (i = 0; i < 32; i++)
1786         {
1787                 if (streq(what, k_info_flags2[i]))
1788                 {
1789                         e_ptr->flags2 |= (1L << i);
1790                         return (0);
1791                 }
1792         }
1793
1794         /* Check flags3 */
1795         for (i = 0; i < 32; i++)
1796         {
1797                 if (streq(what, k_info_flags3[i]))
1798                 {
1799                         e_ptr->flags3 |= (1L << i);
1800                         return (0);
1801                 }
1802         }
1803
1804         /* Oops */
1805 #ifdef JP
1806         msg_format("̤ÃΤÎ̾¤Î¤¢¤ë¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1807 #else
1808         msg_format("Unknown ego-item flag '%s'.", what);
1809 #endif
1810
1811
1812         /* Error */
1813         return (1);
1814 }
1815
1816
1817
1818
1819 /*
1820  * Initialize the "e_info" array, by parsing an ascii "template" file
1821  */
1822 errr parse_e_info(char *buf, header *head)
1823 {
1824         int i;
1825
1826         char *s, *t;
1827
1828         /* Current entry */
1829         static ego_item_type *e_ptr = NULL;
1830
1831
1832         /* Just before the first record */
1833         error_idx = -1;
1834
1835         /* Just before the first line */
1836         error_line = -1;
1837
1838
1839         /* Process 'N' for "New/Number/Name" */
1840         if (buf[0] == 'N')
1841         {
1842                 /* Find the colon before the name */
1843                 s = strchr(buf+2, ':');
1844
1845                         /* Verify that colon */
1846                 if (!s) return (1);
1847
1848                 /* Nuke the colon, advance to the name */
1849                 *s++ = '\0';
1850 #ifdef JP
1851                 /* Paranoia -- require a name */
1852                 if (!*s) return (1);
1853 #endif
1854                 /* Get the index */
1855                 i = atoi(buf+2);
1856
1857                 /* Verify information */
1858                 if (i < error_idx) return (4);
1859
1860                 /* Verify information */
1861                 if (i >= head->info_num) return (2);
1862
1863                 /* Save the index */
1864                 error_idx = i;
1865
1866                 /* Point at the "info" */
1867                 e_ptr = &e_info[i];
1868 #ifdef JP
1869                 /* Hack -- Verify space */
1870                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1871
1872                 /* Advance and Save the name index */
1873                 if (!e_ptr->name) e_ptr->name = ++head->name_size;
1874
1875                 /* Append chars to the name */
1876                 strcpy(head->name_ptr + head->name_size, s);
1877
1878                 /* Advance the index */
1879                 head->name_size += strlen(s);
1880 #endif
1881         }
1882
1883         /* There better be a current e_ptr */
1884         else if (!e_ptr) return (3);
1885
1886
1887 #ifdef JP
1888         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1889         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
1890         else if (buf[0] == 'E')
1891         {
1892                 /* nothing to do */
1893         }
1894 #else
1895         else if (buf[0] == 'E')
1896         {
1897                 /* Acquire the Text */
1898                 s = buf+2;
1899
1900                         /* Hack -- Verify space */
1901                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
1902
1903                 /* Advance and Save the name index */
1904                 if (!e_ptr->name) e_ptr->name = ++head->name_size;
1905
1906                 /* Append chars to the name */
1907                 strcpy(head->name_ptr + head->name_size, s);
1908
1909                 /* Advance the index */
1910                 head->name_size += strlen(s);
1911         }
1912 #endif
1913 #if 0
1914
1915         /* Process 'D' for "Description" */
1916         else if (buf[0] == 'D')
1917         {
1918                 /* Acquire the text */
1919                 s = buf+2;
1920
1921                         /* Hack -- Verify space */
1922                 if (e_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
1923
1924                 /* Advance and Save the text index */
1925                 if (!e_ptr->text) e_ptr->text = ++e_head->text_size;
1926
1927                 /* Append chars to the name */
1928                 strcpy(e_text + e_head->text_size, s);
1929
1930                 /* Advance the index */
1931                 e_head->text_size += strlen(s);
1932         }
1933
1934 #endif
1935
1936         /* Process 'X' for "Xtra" (one line only) */
1937         else if (buf[0] == 'X')
1938         {
1939                 int slot, rating;
1940
1941                 /* Scan for the values */
1942                 if (2 != sscanf(buf+2, "%d:%d",
1943                                 &slot, &rating)) return (1);
1944
1945                 /* Save the values */
1946                 e_ptr->slot = slot;
1947                 e_ptr->rating = rating;
1948         }
1949
1950         /* Process 'W' for "More Info" (one line only) */
1951         else if (buf[0] == 'W')
1952         {
1953                 int level, rarity, pad2;
1954                 long cost;
1955
1956                 /* Scan for the values */
1957                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1958                                 &level, &rarity, &pad2, &cost)) return (1);
1959
1960                 /* Save the values */
1961                 e_ptr->level = level;
1962                 e_ptr->rarity = rarity;
1963                 /* e_ptr->weight = wgt; */
1964                 e_ptr->cost = cost;
1965         }
1966
1967         /* Hack -- Process 'C' for "creation" */
1968         else if (buf[0] == 'C')
1969         {
1970                 int th, td, ta, pv;
1971
1972                 /* Scan for the values */
1973                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1974                                 &th, &td, &ta, &pv)) return (1);
1975
1976                 e_ptr->max_to_h = th;
1977                 e_ptr->max_to_d = td;
1978                 e_ptr->max_to_a = ta;
1979                 e_ptr->max_pval = pv;
1980         }
1981
1982         /* Hack -- Process 'F' for flags */
1983         else if (buf[0] == 'F')
1984         {
1985                 /* Parse every entry textually */
1986                 for (s = buf + 2; *s; )
1987                 {
1988                                 /* Find the end of this entry */
1989                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1990
1991                                 /* Nuke and skip any dividers */
1992                         if (*t)
1993                         {
1994                                 *t++ = '\0';
1995                                 while ((*t == ' ') || (*t == '|')) t++;
1996                         }
1997
1998                                 /* Parse this entry */
1999                         if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5);
2000
2001                                 /* Start the next entry */
2002                         s = t;
2003                 }
2004         }
2005
2006         /* Oops */
2007         else return (6);
2008
2009         /* Success */
2010         return (0);
2011 }
2012
2013
2014 /*
2015  * Grab one (basic) flag in a monster_race from a textual string
2016  */
2017 static errr grab_one_basic_flag(monster_race *r_ptr, cptr what)
2018 {
2019         int i;
2020
2021         /* Scan flags1 */
2022         for (i = 0; i < 32; i++)
2023         {
2024                 if (streq(what, r_info_flags1[i]))
2025                 {
2026                         r_ptr->flags1 |= (1L << i);
2027                         return (0);
2028                 }
2029         }
2030
2031         /* Scan flags2 */
2032         for (i = 0; i < 32; i++)
2033         {
2034                 if (streq(what, r_info_flags2[i]))
2035                 {
2036                         r_ptr->flags2 |= (1L << i);
2037                         return (0);
2038                 }
2039         }
2040
2041         /* Scan flags3 */
2042         for (i = 0; i < 32; i++)
2043         {
2044                 if (streq(what, r_info_flags3[i]))
2045                 {
2046                         r_ptr->flags3 |= (1L << i);
2047                         return (0);
2048                 }
2049         }
2050
2051         /* Scan flags7 */
2052         for (i = 0; i < 32; i++)
2053         {
2054                 if (streq(what, r_info_flags7[i]))
2055                 {
2056                         r_ptr->flags7 |= (1L << i);
2057                         return (0);
2058                 }
2059         }
2060
2061         /* Scan flags8 */
2062         for (i = 0; i < 32; i++)
2063         {
2064                 if (streq(what, r_info_flags8[i]))
2065                 {
2066                         r_ptr->flags8 |= (1L << i);
2067                         return (0);
2068                 }
2069         }
2070
2071         /* Scan flags9 */
2072         for (i = 0; i < 32; i++)
2073         {
2074                 if (streq(what, r_info_flags9[i]))
2075                 {
2076                         r_ptr->flags9 |= (1L << i);
2077                         return (0);
2078                 }
2079         }
2080
2081         /* Oops */
2082 #ifdef JP
2083         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2084 #else
2085         msg_format("Unknown monster flag '%s'.", what);
2086 #endif
2087
2088
2089         /* Failure */
2090         return (1);
2091 }
2092
2093
2094 /*
2095  * Grab one (spell) flag in a monster_race from a textual string
2096  */
2097 static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
2098 {
2099         int i;
2100
2101         /* Scan flags4 */
2102         for (i = 0; i < 32; i++)
2103         {
2104                 if (streq(what, r_info_flags4[i]))
2105                 {
2106                         r_ptr->flags4 |= (1L << i);
2107                         return (0);
2108                 }
2109         }
2110
2111         /* Scan flags5 */
2112         for (i = 0; i < 32; i++)
2113         {
2114                 if (streq(what, r_info_flags5[i]))
2115                 {
2116                         r_ptr->flags5 |= (1L << i);
2117                         return (0);
2118                 }
2119         }
2120
2121         /* Scan flags6 */
2122         for (i = 0; i < 32; i++)
2123         {
2124                 if (streq(what, r_info_flags6[i]))
2125                 {
2126                         r_ptr->flags6 |= (1L << i);
2127                         return (0);
2128                 }
2129         }
2130
2131         /* Oops */
2132 #ifdef JP
2133         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2134 #else
2135         msg_format("Unknown monster flag '%s'.", what);
2136 #endif
2137
2138
2139         /* Failure */
2140         return (1);
2141 }
2142
2143
2144
2145
2146 /*
2147  * Initialize the "r_info" array, by parsing an ascii "template" file
2148  */
2149 errr parse_r_info(char *buf, header *head)
2150 {
2151         int i;
2152
2153         char *s, *t;
2154
2155         /* Current entry */
2156         static monster_race *r_ptr = NULL;
2157
2158
2159         /* Process 'N' for "New/Number/Name" */
2160         if (buf[0] == 'N')
2161         {
2162                 /* Find the colon before the name */
2163                 s = strchr(buf+2, ':');
2164
2165                         /* Verify that colon */
2166                 if (!s) return (1);
2167
2168                 /* Nuke the colon, advance to the name */
2169                 *s++ = '\0';
2170 #ifdef JP
2171                 /* Paranoia -- require a name */
2172                 if (!*s) return (1);
2173 #endif
2174                 /* Get the index */
2175                 i = atoi(buf+2);
2176
2177                 /* Verify information */
2178                 if (i < error_idx) return (4);
2179
2180                 /* Verify information */
2181                 if (i >= head->info_num) return (2);
2182
2183                 /* Save the index */
2184                 error_idx = i;
2185
2186                 /* Point at the "info" */
2187                 r_ptr = &r_info[i];
2188 #ifdef JP
2189                 /* Hack -- Verify space */
2190                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
2191
2192                 /* Advance and Save the name index */
2193                 if (!r_ptr->name) r_ptr->name = ++head->name_size;
2194
2195                 /* Append chars to the name */
2196                 strcpy(head->name_ptr + head->name_size, s);
2197
2198                 /* Advance the index */
2199                 head->name_size += strlen(s);
2200 #endif
2201         }
2202
2203         /* There better be a current r_ptr */
2204         else if (!r_ptr) return (3);
2205
2206
2207 #ifdef JP
2208         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2209         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
2210         else if (buf[0] == 'E')
2211         {
2212                 /* Acquire the Text */
2213                 s = buf+2;
2214
2215                         /* Hack -- Verify space */
2216                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
2217
2218                 /* Advance and Save the name index */
2219                 if (!r_ptr->E_name) r_ptr->E_name = ++head->name_size;
2220
2221                 /* Append chars to the name */
2222                 strcpy(head->name_ptr + head->name_size, s);
2223
2224                 /* Advance the index */
2225                 head->name_size += strlen(s);
2226         }
2227 #else
2228         else if (buf[0] == 'E')
2229         {
2230                 /* Acquire the Text */
2231                 s = buf+2;
2232
2233                         /* Hack -- Verify space */
2234                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
2235
2236                 /* Advance and Save the name index */
2237                 if (!r_ptr->name) r_ptr->name = ++head->name_size;
2238
2239                 /* Append chars to the name */
2240                 strcpy(head->name_ptr + head->name_size, s);
2241
2242                 /* Advance the index */
2243                 head->name_size += strlen(s);
2244         }
2245 #endif
2246         /* Process 'D' for "Description" */
2247         else if (buf[0] == 'D')
2248         {
2249 #ifdef JP
2250                 if (buf[2] == '$')
2251                         return (0);
2252                 /* Acquire the text */
2253                 s = buf+2;
2254 #else
2255                 if (buf[2] != '$')
2256                         return (0);
2257                 /* Acquire the text */
2258                 s = buf+3;
2259 #endif
2260
2261                 /* Hack -- Verify space */
2262                 if (head->text_size + strlen(s) + 8 > fake_text_size) return (7);
2263
2264                 /* Advance and Save the text index */
2265                 if (!r_ptr->text) r_ptr->text = ++head->text_size;
2266
2267                 /* Append chars to the name */
2268                 strcpy(head->text_ptr + head->text_size, s);
2269
2270                 /* Advance the index */
2271                 head->text_size += strlen(s);
2272         }
2273
2274         /* Process 'G' for "Graphics" (one line only) */
2275         else if (buf[0] == 'G')
2276         {
2277                 char sym;
2278                 int tmp;
2279
2280                 /* Paranoia */
2281                 if (!buf[2]) return (1);
2282                 if (!buf[3]) return (1);
2283                 if (!buf[4]) return (1);
2284
2285                 /* Extract the char */
2286                 sym = buf[2];
2287
2288                 /* Extract the attr */
2289                 tmp = color_char_to_attr(buf[4]);
2290
2291                 /* Paranoia */
2292                 if (tmp < 0) return (1);
2293
2294                 /* Save the values */
2295                 r_ptr->d_char = sym;
2296                 r_ptr->d_attr = tmp;
2297         }
2298
2299         /* Process 'I' for "Info" (one line only) */
2300         else if (buf[0] == 'I')
2301         {
2302                 int spd, hp1, hp2, aaf, ac, slp;
2303
2304                 /* Scan for the other values */
2305                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2306                                 &spd, &hp1, &hp2, &aaf, &ac, &slp)) return (1);
2307
2308                 /* Save the values */
2309                 r_ptr->speed = spd;
2310                 r_ptr->hdice = hp1;
2311                 r_ptr->hside = hp2;
2312                 r_ptr->aaf = aaf;
2313                 r_ptr->ac = ac;
2314                 r_ptr->sleep = slp;
2315         }
2316
2317         /* Process 'W' for "More Info" (one line only) */
2318         else if (buf[0] == 'W')
2319         {
2320                 int lev, rar, pad;
2321                 long exp;
2322                 long nextexp;
2323                 int nextmon;
2324
2325                 /* Scan for the values */
2326                 if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d",
2327                                 &lev, &rar, &pad, &exp, &nextexp, &nextmon)) return (1);
2328
2329                 /* Save the values */
2330                 r_ptr->level = lev;
2331                 r_ptr->rarity = rar;
2332                 r_ptr->extra = pad;
2333                 r_ptr->mexp = exp;
2334                 r_ptr->next_exp = nextexp;
2335                 r_ptr->next_r_idx = nextmon;
2336         }
2337
2338         /* Process 'B' for "Blows" (up to four lines) */
2339         else if (buf[0] == 'B')
2340         {
2341                 int n1, n2;
2342
2343                 /* Find the next empty blow slot (if any) */
2344                 for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break;
2345
2346                 /* Oops, no more slots */
2347                 if (i == 4) return (1);
2348
2349                 /* Analyze the first field */
2350                 for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
2351
2352                 /* Terminate the field (if necessary) */
2353                 if (*t == ':') *t++ = '\0';
2354
2355                 /* Analyze the method */
2356                 for (n1 = 0; r_info_blow_method[n1]; n1++)
2357                 {
2358                         if (streq(s, r_info_blow_method[n1])) break;
2359                 }
2360
2361                 /* Invalid method */
2362                 if (!r_info_blow_method[n1]) return (1);
2363
2364                 /* Analyze the second field */
2365                 for (s = t; *t && (*t != ':'); t++) /* loop */;
2366
2367                 /* Terminate the field (if necessary) */
2368                 if (*t == ':') *t++ = '\0';
2369
2370                 /* Analyze effect */
2371                 for (n2 = 0; r_info_blow_effect[n2]; n2++)
2372                 {
2373                         if (streq(s, r_info_blow_effect[n2])) break;
2374                 }
2375
2376                 /* Invalid effect */
2377                 if (!r_info_blow_effect[n2]) return (1);
2378
2379                 /* Analyze the third field */
2380                 for (s = t; *t && (*t != 'd'); t++) /* loop */;
2381
2382                 /* Terminate the field (if necessary) */
2383                 if (*t == 'd') *t++ = '\0';
2384
2385                 /* Save the method */
2386                 r_ptr->blow[i].method = n1;
2387
2388                 /* Save the effect */
2389                 r_ptr->blow[i].effect = n2;
2390
2391                 /* Extract the damage dice and sides */
2392                 r_ptr->blow[i].d_dice = atoi(s);
2393                 r_ptr->blow[i].d_side = atoi(t);
2394         }
2395
2396         /* Process 'F' for "Basic Flags" (multiple lines) */
2397         else if (buf[0] == 'F')
2398         {
2399                 /* Parse every entry */
2400                 for (s = buf + 2; *s; )
2401                 {
2402                                 /* Find the end of this entry */
2403                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2404
2405                                 /* Nuke and skip any dividers */
2406                         if (*t)
2407                         {
2408                                 *t++ = '\0';
2409                                 while (*t == ' ' || *t == '|') t++;
2410                         }
2411
2412                                 /* Parse this entry */
2413                         if (0 != grab_one_basic_flag(r_ptr, s)) return (5);
2414
2415                                 /* Start the next entry */
2416                         s = t;
2417                 }
2418         }
2419
2420         /* Process 'S' for "Spell Flags" (multiple lines) */
2421         else if (buf[0] == 'S')
2422         {
2423                 /* Parse every entry */
2424                 for (s = buf + 2; *s; )
2425                 {
2426                                 /* Find the end of this entry */
2427                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2428
2429                                 /* Nuke and skip any dividers */
2430                         if (*t)
2431                         {
2432                                 *t++ = '\0';
2433                                 while ((*t == ' ') || (*t == '|')) t++;
2434                         }
2435
2436                                 /* XXX XXX XXX Hack -- Read spell frequency */
2437                         if (1 == sscanf(s, "1_IN_%d", &i))
2438                         {
2439                                 /* Extract a "frequency" */
2440                                 r_ptr->freq_spell = r_ptr->freq_inate = 100 / i;
2441
2442                                         /* Start at next entry */
2443                                 s = t;
2444
2445                                 /* Continue */
2446                                 continue;
2447                         }
2448
2449                                 /* Parse this entry */
2450                         if (0 != grab_one_spell_flag(r_ptr, s)) return (5);
2451
2452                                 /* Start the next entry */
2453                         s = t;
2454                 }
2455         }
2456
2457         /* Oops */
2458         else return (6);
2459
2460
2461         /* Success */
2462         return (0);
2463 }
2464
2465
2466 /*
2467  * Grab one flag for a dungeon type from a textual string
2468  */
2469 static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what)
2470 {
2471         int i;
2472
2473         /* Scan flags1 */
2474         for (i = 0; i < 32; i++)
2475         {
2476                 if (streq(what, d_info_flags1[i]))
2477                 {
2478                         d_ptr->flags1 |= (1L << i);
2479                         return (0);
2480                 }
2481         }
2482
2483         /* Oops */
2484 #ifdef JP
2485         msg_format("̤ÃΤΥÀ¥ó¥¸¥ç¥ó¡¦¥Õ¥é¥° '%s'¡£", what);
2486 #else
2487         msg_format("Unknown dungeon type flag '%s'.", what);
2488 #endif
2489
2490         /* Failure */
2491         return (1);
2492 }
2493
2494 /*
2495  * Grab one (basic) flag in a monster_race from a textual string
2496  */
2497 static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what)
2498 {
2499         int i;
2500
2501         /* Scan flags1 */
2502         for (i = 0; i < 32; i++)
2503         {
2504                 if (streq(what, r_info_flags1[i]))
2505                 {
2506                         d_ptr->mflags1 |= (1L << i);
2507                         return (0);
2508                 }
2509         }
2510
2511         /* Scan flags2 */
2512         for (i = 0; i < 32; i++)
2513         {
2514                 if (streq(what, r_info_flags2[i]))
2515                 {
2516                         d_ptr->mflags2 |= (1L << i);
2517                         return (0);
2518                 }
2519         }
2520
2521         /* Scan flags3 */
2522         for (i = 0; i < 32; i++)
2523         {
2524                 if (streq(what, r_info_flags3[i]))
2525                 {
2526                         d_ptr->mflags3 |= (1L << i);
2527                         return (0);
2528                 }
2529         }
2530
2531         /* Scan flags7 */
2532         for (i = 0; i < 32; i++)
2533         {
2534                 if (streq(what, r_info_flags7[i]))
2535                 {
2536                         d_ptr->mflags7 |= (1L << i);
2537                         return (0);
2538                 }
2539         }
2540
2541         /* Scan flags8 */
2542         for (i = 0; i < 32; i++)
2543         {
2544                 if (streq(what, r_info_flags8[i]))
2545                 {
2546                         d_ptr->mflags8 |= (1L << i);
2547                         return (0);
2548                 }
2549         }
2550
2551         /* Scan flags9 */
2552         for (i = 0; i < 32; i++)
2553         {
2554                 if (streq(what, r_info_flags9[i]))
2555                 {
2556                         d_ptr->mflags9 |= (1L << i);
2557                         return (0);
2558                 }
2559         }
2560
2561         /* Oops */
2562 #ifdef JP
2563         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2564 #else
2565         msg_format("Unknown monster flag '%s'.", what);
2566 #endif
2567         /* Failure */
2568         return (1);
2569 }
2570
2571
2572 /*
2573  * Grab one (spell) flag in a monster_race from a textual string
2574  */
2575 static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what)
2576 {
2577         int i;
2578
2579         /* Scan flags4 */
2580         for (i = 0; i < 32; i++)
2581         {
2582                 if (streq(what, r_info_flags4[i]))
2583                 {
2584                         d_ptr->mflags4 |= (1L << i);
2585                         return (0);
2586                 }
2587         }
2588
2589         /* Scan flags5 */
2590         for (i = 0; i < 32; i++)
2591         {
2592                 if (streq(what, r_info_flags5[i]))
2593                 {
2594                         d_ptr->mflags5 |= (1L << i);
2595                         return (0);
2596                 }
2597         }
2598
2599         /* Scan flags6 */
2600         for (i = 0; i < 32; i++)
2601         {
2602                 if (streq(what, r_info_flags6[i]))
2603                 {
2604                         d_ptr->mflags6 |= (1L << i);
2605                         return (0);
2606                 }
2607         }
2608
2609         /* Oops */
2610 #ifdef JP
2611         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2612 #else
2613         msg_format("Unknown monster flag '%s'.", what);
2614 #endif
2615
2616         /* Failure */
2617         return (1);
2618 }
2619
2620 /*
2621  * Initialize the "d_info" array, by parsing an ascii "template" file
2622  */
2623 errr parse_d_info(char *buf, header *head)
2624 {
2625         int i;
2626
2627         char *s, *t;
2628
2629         /* Current entry */
2630         static dungeon_info_type *d_ptr = NULL;
2631
2632
2633         /* Process 'N' for "New/Number/Name" */
2634         if (buf[0] == 'N')
2635         {
2636                 /* Find the colon before the name */
2637                 s = strchr(buf+2, ':');
2638
2639                 /* Verify that colon */
2640                 if (!s) return (1);
2641
2642                 /* Nuke the colon, advance to the name */
2643                 *s++ = '\0';
2644 #ifdef JP
2645                 /* Paranoia -- require a name */
2646                 if (!*s) return (1);
2647 #endif
2648                 /* Get the index */
2649                 i = atoi(buf+2);
2650
2651                 /* Verify information */
2652                 if (i < error_idx) return (4);
2653
2654                 /* Verify information */
2655                 if (i >= head->info_num) return (2);
2656
2657                 /* Save the index */
2658                 error_idx = i;
2659
2660                 /* Point at the "info" */
2661                 d_ptr = &d_info[i];
2662 #ifdef JP
2663                 /* Hack -- Verify space */
2664                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
2665
2666                 /* Advance and Save the name index */
2667                 if (!d_ptr->name) d_ptr->name = ++head->name_size;
2668
2669                 /* Append chars to the name */
2670                 strcpy(head->name_ptr + head->name_size, s);
2671
2672                 /* Advance the index */
2673                 head->name_size += strlen(s);
2674 #endif
2675         }
2676
2677 #ifdef JP
2678         else if (buf[0] == 'E') return (0);
2679 #else
2680         else if (buf[0] == 'E')
2681         {
2682                 /* Acquire the Text */
2683                 s = buf+2;
2684
2685                 /* Hack -- Verify space */
2686                 if (head->name_size + strlen(s) + 8 > fake_name_size) return (7);
2687
2688                 /* Advance and Save the name index */
2689                 if (!d_ptr->name) d_ptr->name = ++head->name_size;
2690
2691                 /* Append chars to the name */
2692                 strcpy(head->name_ptr + head->name_size, s);
2693
2694                 /* Advance the index */
2695                 head->name_size += strlen(s);
2696         }
2697 #endif
2698
2699         /* Process 'D' for "Description */
2700         else if (buf[0] == 'D')
2701         {
2702 #ifdef JP
2703                 if (buf[2] == '$')
2704                         return (0);
2705                 /* Acquire the text */
2706                 s = buf+2;
2707 #else
2708                 if (buf[2] != '$')
2709                         return (0);
2710                 /* Acquire the text */
2711                 s = buf+3;
2712 #endif
2713
2714                 /* Hack -- Verify space */
2715                 if (head->text_size + strlen(s) + 8 > fake_text_size) return (7);
2716
2717                 /* Advance and Save the text index */
2718                 if (!d_ptr->text) d_ptr->text = ++head->text_size;
2719
2720                 /* Append chars to the name */
2721                 strcpy(d_text + head->text_size, s);
2722
2723                 /* Advance the index */
2724                 head->text_size += strlen(s);
2725         }
2726
2727         /* Process 'W' for "More Info" (one line only) */
2728         else if (buf[0] == 'W')
2729         {
2730                 int min_lev, max_lev;
2731                 int min_plev, mode;
2732                 int min_alloc, max_chance;
2733                 int obj_good, obj_great;
2734                 int pit, nest;
2735
2736                 /* Scan for the values */
2737                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x",
2738                                  &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1);
2739
2740                 /* Save the values */
2741                 d_ptr->mindepth = min_lev;
2742                 d_ptr->maxdepth = max_lev;
2743                 d_ptr->min_plev = min_plev;
2744                 d_ptr->mode = mode;
2745                 d_ptr->min_m_alloc_level = min_alloc;
2746                 d_ptr->max_m_alloc_chance = max_chance;
2747                 d_ptr->obj_good = obj_good;
2748                 d_ptr->obj_great = obj_great;
2749                 d_ptr->pit = pit;
2750                 d_ptr->nest = nest;
2751         }
2752
2753         /* Process 'P' for "Place Info" */
2754         else if (buf[0] == 'P')
2755         {
2756                 int dy, dx;
2757
2758                 /* Scan for the values */
2759                 if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1);
2760
2761                 /* Save the values */
2762                 d_ptr->dy = dy;
2763                 d_ptr->dx = dx;
2764         }
2765
2766         /* Process 'L' for "fLoor type" (one line only) */
2767         else if (buf[0] == 'L')
2768         {
2769                 int f1, f2, f3;
2770                 int p1, p2, p3;
2771                 int tunnel;
2772
2773                 /* Scan for the values */
2774                 if (7 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d",
2775                                 &f1, &p1, &f2, &p2, &f3, &p3, &tunnel)) return (1);
2776
2777                 /* Save the values */
2778                 d_ptr->floor1 = f1;
2779                 d_ptr->floor_percent1 = p1;
2780                 d_ptr->floor2 = f2;
2781                 d_ptr->floor_percent2 = p2;
2782                 d_ptr->floor3 = f3;
2783                 d_ptr->floor_percent3 = p3;
2784                 d_ptr->tunnel_percent = tunnel;
2785         }
2786
2787         /* Process 'A' for "wAll type" (one line only) */
2788         else if (buf[0] == 'A')
2789         {
2790                 int w1, w2, w3, outer, inner, stream1, stream2;
2791                 int p1, p2, p3;
2792
2793                 /* Scan for the values */
2794                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
2795                                  &w1, &p1, &w2, &p2, &w3, &p3, &outer, &inner, &stream1, &stream2)) return (1);
2796
2797                 /* Save the values */
2798                 d_ptr->fill_type1 = w1;
2799                 d_ptr->fill_percent1 = p1;
2800                 d_ptr->fill_type2 = w2;
2801                 d_ptr->fill_percent2 = p2;
2802                 d_ptr->fill_type3 = w3;
2803                 d_ptr->fill_percent3 = p3;
2804                 d_ptr->outer_wall = outer;
2805                 d_ptr->inner_wall = inner;
2806                 d_ptr->stream1 = stream1;
2807                 d_ptr->stream2 = stream2;
2808         }
2809
2810         /* Process 'F' for "Dungeon Flags" (multiple lines) */
2811         else if (buf[0] == 'F')
2812         {
2813                 int artif = 0, monst = 0;
2814
2815                 /* Parse every entry */
2816                 for (s = buf + 2; *s; )
2817                 {
2818                                 /* Find the end of this entry */
2819                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2820
2821                                 /* Nuke and skip any dividers */
2822                         if (*t)
2823                         {
2824                                 *t++ = '\0';
2825                                 while (*t == ' ' || *t == '|') t++;
2826                         }
2827
2828                                 /* XXX XXX XXX Hack -- Read Final Artifact */
2829                         if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif))
2830                         {
2831                                 /* Extract a "Final Artifact" */
2832                                 d_ptr->final_artifact = artif;
2833
2834                                 /* Start at next entry */
2835                                 s = t;
2836
2837                                 /* Continue */
2838                                 continue;
2839                         }
2840
2841                                 /* XXX XXX XXX Hack -- Read Final Object */
2842                         if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif))
2843                         {
2844                                 /* Extract a "Final Artifact" */
2845                                 d_ptr->final_object = artif;
2846
2847                                 /* Start at next entry */
2848                                 s = t;
2849
2850                                 /* Continue */
2851                                 continue;
2852                         }
2853
2854                                 /* XXX XXX XXX Hack -- Read Artifact Guardian */
2855                         if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst))
2856                         {
2857                                 /* Extract a "Artifact Guardian" */
2858                                 d_ptr->final_guardian = monst;
2859
2860                                 /* Start at next entry */
2861                                 s = t;
2862
2863                                 /* Continue */
2864                                 continue;
2865                         }
2866
2867                                 /* XXX XXX XXX Hack -- Read Special Percentage */
2868                         if (1 == sscanf(s, "MONSTER_DIV_%d", &monst))
2869                         {
2870                                 /* Extract a "Special %" */
2871                                 d_ptr->special_div = monst;
2872
2873                                 /* Start at next entry */
2874                                 s = t;
2875
2876                                 /* Continue */
2877                                 continue;
2878                         }
2879
2880                                 /* Parse this entry */
2881                         if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5);
2882
2883                                 /* Start the next entry */
2884                         s = t;
2885                 }
2886         }
2887
2888         /* Process 'M' for "Basic Flags" (multiple lines) */
2889         else if (buf[0] == 'M')
2890         {
2891                 byte r_char_number = 0, r_char;
2892
2893                 /* Parse every entry */
2894                 for (s = buf + 2; *s; )
2895                 {
2896                                 /* Find the end of this entry */
2897                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2898
2899                                 /* Nuke and skip any dividers */
2900                         if (*t)
2901                         {
2902                                 *t++ = '\0';
2903                                 while (*t == ' ' || *t == '|') t++;
2904                         }
2905
2906                                 /* XXX XXX XXX Hack -- Read monster symbols */
2907                         if (1 == sscanf(s, "R_CHAR_%c", &r_char))
2908                         {
2909                                 /* Limited to 5 races */
2910                                 if(r_char_number >= 5) continue;
2911
2912                                 /* Extract a "frequency" */
2913                                 d_ptr->r_char[r_char_number++] = r_char;
2914
2915                                 /* Start at next entry */
2916                                 s = t;
2917
2918                                 /* Continue */
2919                                 continue;
2920                         }
2921
2922                                 /* Parse this entry */
2923                         if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5);
2924
2925                                 /* Start the next entry */
2926                         s = t;
2927                 }
2928         }
2929
2930         /* Process 'S' for "Spell Flags" (multiple lines) */
2931         else if (buf[0] == 'S')
2932         {
2933                 /* Parse every entry */
2934                 for (s = buf + 2; *s; )
2935                 {
2936                                 /* Find the end of this entry */
2937                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2938
2939                                 /* Nuke and skip any dividers */
2940                         if (*t)
2941                         {
2942                                 *t++ = '\0';
2943                                 while ((*t == ' ') || (*t == '|')) t++;
2944                         }
2945
2946                                 /* XXX XXX XXX Hack -- Read spell frequency */
2947                         if (1 == sscanf(s, "1_IN_%d", &i))
2948                         {
2949                                 /* Start at next entry */
2950                                 s = t;
2951
2952                                         /* Continue */
2953                                 continue;
2954                         }
2955
2956                                 /* Parse this entry */
2957                         if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5);
2958
2959                                 /* Start the next entry */
2960                         s = t;
2961                 }
2962         }
2963
2964         /* Oops */
2965         else return (6);
2966
2967         /* Success */
2968         return (0);
2969 }
2970
2971
2972 #else   /* ALLOW_TEMPLATES */
2973
2974 #ifdef MACINTOSH
2975 static int i = 0;
2976 #endif
2977
2978 #endif  /* ALLOW_TEMPLATES */
2979
2980
2981 /* Random dungeon grid effects */
2982 #define RANDOM_NONE         0x00
2983 #define RANDOM_FEATURE      0x01
2984 #define RANDOM_MONSTER      0x02
2985 #define RANDOM_OBJECT       0x04
2986 #define RANDOM_EGO          0x08
2987 #define RANDOM_ARTIFACT     0x10
2988 #define RANDOM_TRAP         0x20
2989
2990
2991 typedef struct dungeon_grid dungeon_grid;
2992
2993 struct dungeon_grid
2994 {
2995         int             feature;                /* Terrain feature */
2996         int             monster;                /* Monster */
2997         int             object;                 /* Object */
2998         int             ego;                    /* Ego-Item */
2999         int             artifact;               /* Artifact */
3000         int             trap;                   /* Trap */
3001         int             cave_info;              /* Flags for CAVE_MARK, CAVE_GLOW, CAVE_ICKY, CAVE_ROOM */
3002         int             special;                /* Reserved for special terrain info */
3003         int             random;                 /* Number of the random effect */
3004 };
3005
3006
3007 static dungeon_grid letter[255];
3008
3009
3010 /*
3011  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3012  */
3013 static errr parse_line_feature(char *buf)
3014 {
3015         int num;
3016         char *zz[9];
3017
3018
3019         if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3020
3021         /* Tokenize the line */
3022         if ((num = tokenize(buf+2, 9, zz, 0)) > 1)
3023         {
3024                 /* Letter to assign */
3025                 int index = zz[0][0];
3026
3027                 /* Reset the info for the letter */
3028                 letter[index].feature = 0;
3029                 letter[index].monster = 0;
3030                 letter[index].object = 0;
3031                 letter[index].ego = 0;
3032                 letter[index].artifact = 0;
3033                 letter[index].trap = 0;
3034                 letter[index].cave_info = 0;
3035                 letter[index].special = 0;
3036                 letter[index].random = 0;
3037
3038                 switch (num)
3039                 {
3040                         /* Special */
3041                         case 9:
3042                                 letter[index].special = atoi(zz[8]);
3043                                 /* Fall through */
3044                         /* Trap */
3045                         case 8:
3046                                 if (zz[7][0] == '*')
3047                                 {
3048                                         letter[index].random |= RANDOM_TRAP;
3049
3050                                         if (zz[7][1])
3051                                         {
3052                                                 zz[7]++;
3053                                                 letter[index].trap = atoi(zz[7]);
3054                                         }
3055                                 }
3056                                 else
3057                                 {
3058                                         letter[index].trap = atoi(zz[7]);
3059                                 }
3060                                 /* Fall through */
3061                         /* Artifact */
3062                         case 7:
3063                                 if (zz[6][0] == '*')
3064                                 {
3065                                         letter[index].random |= RANDOM_ARTIFACT;
3066
3067                                         if (zz[6][1])
3068                                         {
3069                                                 zz[6]++;
3070                                                 letter[index].artifact = atoi(zz[6]);
3071                                         }
3072                                 }
3073                                 else
3074                                 {
3075                                         letter[index].artifact = atoi(zz[6]);
3076                                 }
3077                                 /* Fall through */
3078                         /* Ego-item */
3079                         case 6:
3080                                 if (zz[5][0] == '*')
3081                                 {
3082                                         letter[index].random |= RANDOM_EGO;
3083
3084                                         if (zz[5][1])
3085                                         {
3086                                                 zz[5]++;
3087                                                 letter[index].ego = atoi(zz[5]);
3088                                         }
3089                                 }
3090                                 else
3091                                 {
3092                                         letter[index].ego = atoi(zz[5]);
3093                                 }
3094                                 /* Fall through */
3095                         /* Object */
3096                         case 5:
3097                                 if (zz[4][0] == '*')
3098                                 {
3099                                         letter[index].random |= RANDOM_OBJECT;
3100
3101                                         if (zz[4][1])
3102                                         {
3103                                                 zz[4]++;
3104                                                 letter[index].object = atoi(zz[4]);
3105                                         }
3106                                 }
3107                                 else
3108                                 {
3109                                         letter[index].object = atoi(zz[4]);
3110                                 }
3111                                 /* Fall through */
3112                         /* Monster */
3113                         case 4:
3114                                 if (zz[3][0] == '*')
3115                                 {
3116                                         letter[index].random |= RANDOM_MONSTER;
3117                                         if (zz[3][1])
3118                                         {
3119                                                 zz[3]++;
3120                                                 letter[index].monster = atoi(zz[3]);
3121                                         }
3122                                 }
3123                                 else
3124                                 {
3125                                         letter[index].monster = atoi(zz[3]);
3126                                 }
3127                                 /* Fall through */
3128                         /* Cave info */
3129                         case 3:
3130                                 letter[index].cave_info = atoi(zz[2]);
3131                                 /* Fall through */
3132                         /* Feature */
3133                         case 2:
3134                                 if (zz[1][0] == '*')
3135                                 {
3136                                         letter[index].random |= RANDOM_FEATURE;
3137                                         if (zz[1][1])
3138                                         {
3139                                                 zz[1]++;
3140                                                 letter[index].feature = atoi(zz[1]);
3141                                         }
3142                                 }
3143                                 else
3144                                 {
3145                                         letter[index].feature = atoi(zz[1]);
3146                                 }
3147                                 break;
3148                 }
3149
3150                 return (0);
3151         }
3152
3153         return (1);
3154 }
3155
3156
3157 /*
3158  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3159  */
3160 static errr parse_line_building(char *buf)
3161 {
3162         int i;
3163         char *zz[37];
3164         int index;
3165         char *s;
3166
3167 #ifdef JP
3168         if (buf[2] == '$')
3169                 return 0;
3170         s = buf + 2;
3171 #else
3172         if (buf[2] != '$')
3173                 return 0;
3174         s = buf + 3;
3175 #endif
3176         /* Get the building number */
3177         index = atoi(s);
3178
3179         /* Find the colon after the building number */
3180         s = strchr(s, ':');
3181
3182         /* Verify that colon */
3183         if (!s) return (1);
3184
3185         /* Nuke the colon, advance to the sub-index */
3186         *s++ = '\0';
3187
3188         /* Paranoia -- require a sub-index */
3189         if (!*s) return (1);
3190
3191         /* Building definition sub-index */
3192         switch (s[0])
3193         {
3194                 /* Building name, owner, race */
3195                 case 'N':
3196                 {
3197                         if (tokenize(s + 2, 3, zz, 0) == 3)
3198                         {
3199                                 /* Name of the building */
3200                                 strcpy(building[index].name, zz[0]);
3201
3202                                 /* Name of the owner */
3203                                 strcpy(building[index].owner_name, zz[1]);
3204
3205                                 /* Race of the owner */
3206                                 strcpy(building[index].owner_race, zz[2]);
3207
3208                                 break;
3209                         }
3210
3211                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3212                 }
3213
3214                 /* Building Action */
3215                 case 'A':
3216                 {
3217                         if (tokenize(s + 2, 8, zz, 0) >= 7)
3218                         {
3219                                 /* Index of the action */
3220                                 int action_index = atoi(zz[0]);
3221
3222                                 /* Name of the action */
3223                                 strcpy(building[index].act_names[action_index], zz[1]);
3224
3225                                 /* Cost of the action for members */
3226                                 building[index].member_costs[action_index] = atoi(zz[2]);
3227
3228                                 /* Cost of the action for non-members */
3229                                 building[index].other_costs[action_index] = atoi(zz[3]);
3230
3231                                 /* Letter assigned to the action */
3232                                 building[index].letters[action_index] = zz[4][0];
3233
3234                                 /* Action code */
3235                                 building[index].actions[action_index] = atoi(zz[5]);
3236
3237                                 /* Action restriction */
3238                                 building[index].action_restr[action_index] = atoi(zz[6]);
3239
3240                                 break;
3241                         }
3242
3243                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3244                 }
3245
3246                 /* Building Classes */
3247                 case 'C':
3248                 {
3249                         if (tokenize(s + 2, MAX_CLASS, zz, 0) == MAX_CLASS)
3250                         {
3251                                 for (i = 0; i < MAX_CLASS; i++)
3252                                 {
3253                                         building[index].member_class[i] = atoi(zz[i]);
3254                                 }
3255
3256                                 break;
3257                         }
3258
3259                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3260                 }
3261
3262                 /* Building Races */
3263                 case 'R':
3264                 {
3265                         if (tokenize(s+2, MAX_RACES, zz, 0) == MAX_RACES)
3266                         {
3267                                 for (i = 0; i < MAX_RACES; i++)
3268                                 {
3269                                         building[index].member_race[i] = atoi(zz[i]);
3270                                 }
3271
3272                                 break;
3273                         }
3274
3275                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3276                 }
3277
3278                 /* Building Realms */
3279                 case 'M':
3280                 {
3281                         if (tokenize(s+2, MAX_MAGIC, zz, 0) == MAX_MAGIC)
3282                         {
3283                                 for (i = 0; i < MAX_MAGIC; i++)
3284                                 {
3285                                         building[index].member_realm[i+1] = atoi(zz[i]);
3286                                 }
3287
3288                                 break;
3289                         }
3290
3291                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3292                 }
3293
3294                 case 'Z':
3295                 {
3296 #ifdef USE_SCRIPT
3297                         if (tokenize(s+2, 2, zz, 0) == 2)
3298                         {
3299                                 /* Index of the action */
3300                                 int action_index = atoi(zz[0]);
3301
3302                                 /* Name of the action */
3303                                 strcpy(building[index].act_script[action_index], zz[1]);
3304
3305                                 break;
3306                         }
3307                         return (1);
3308 #else /* USE_SCRIPT */
3309                         /* Ignore scripts */
3310                         break;
3311 #endif /* USE_SCRIPT */
3312                 }
3313
3314                 default:
3315                 {
3316                         return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
3317                 }
3318         }
3319
3320         return (0);
3321 }
3322
3323
3324 /*
3325  * Parse a sub-file of the "extra info"
3326  */
3327 static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
3328 {
3329         int i;
3330
3331         char *zz[33];
3332
3333
3334         /* Skip "empty" lines */
3335         if (!buf[0]) return (0);
3336
3337         /* Skip "blank" lines */
3338         if (isspace(buf[0])) return (0);
3339
3340         /* Skip comments */
3341         if (buf[0] == '#') return (0);
3342
3343         /* Require "?:*" format */
3344         if (buf[1] != ':') return (1);
3345
3346
3347         /* Process "%:<fname>" */
3348         if (buf[0] == '%')
3349         {
3350                 /* Attempt to Process the given file */
3351                 return (process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax));
3352         }
3353
3354         /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
3355         if (buf[0] == 'F')
3356         {
3357                 return parse_line_feature(buf);
3358         }
3359
3360         /* Process "D:<dungeon>" -- info for the cave grids */
3361         else if (buf[0] == 'D')
3362         {
3363                 object_type object_type_body;
3364
3365                 /* Acquire the text */
3366                 char *s = buf + 2;
3367
3368                 /* Length of the text */
3369                 int len = strlen(s);
3370
3371                 if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3372
3373                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
3374                 {
3375                         /* Access the grid */
3376                         cave_type *c_ptr = &cave[*y][*x];
3377
3378                         int idx = s[0];
3379
3380                         int object_index = letter[idx].object;
3381                         int monster_index = letter[idx].monster;
3382                         int random = letter[idx].random;
3383                         int artifact_index = letter[idx].artifact;
3384
3385                         /* Lay down a floor */
3386                         c_ptr->feat = letter[idx].feature;
3387
3388                         /* Only the features */
3389                         if (init_flags & INIT_ONLY_FEATURES) continue;
3390
3391                         /* Cave info */
3392                         c_ptr->info = letter[idx].cave_info;
3393
3394                         /* Create a monster */
3395                         if (random & RANDOM_MONSTER)
3396                         {
3397                                 monster_level = base_level + monster_index;
3398
3399                                 place_monster(*y, *x, TRUE, TRUE);
3400
3401                                 monster_level = base_level;
3402                         }
3403                         else if (monster_index)
3404                         {
3405                                 /* Make alive again */
3406                                 if (r_info[monster_index].flags1 & RF1_UNIQUE)
3407                                 {
3408                                         r_info[monster_index].cur_num = 0;
3409                                         r_info[monster_index].max_num = 1;
3410                                 }
3411
3412                                 /* Make alive again */
3413                                 if (r_info[monster_index].flags7 & RF7_UNIQUE_7)
3414                                 {
3415                                         if (r_info[monster_index].cur_num == r_info[monster_index].max_num)
3416                                         {
3417                                                 r_info[monster_index].max_num++;
3418                                         }
3419                                 }
3420
3421                                 /* Place it */
3422                                 place_monster_aux(*y, *x, monster_index, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE);
3423                         }
3424
3425                         /* Object (and possible trap) */
3426                         if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP))
3427                         {
3428                                 object_level = base_level + object_index;
3429
3430                                 /*
3431                                  * Random trap and random treasure defined
3432                                  * 25% chance for trap and 75% chance for object
3433                                  */
3434                                 if (rand_int(100) < 75)
3435                                 {
3436                                         place_object(*y, *x, FALSE, FALSE);
3437                                 }
3438                                 else
3439                                 {
3440                                         place_trap(*y, *x);
3441                                 }
3442
3443                                 object_level = base_level;
3444                         }
3445                         else if (random & RANDOM_OBJECT)
3446                         {
3447                                 object_level = base_level + object_index;
3448
3449                                 /* Create an out of deep object */
3450                                 if (rand_int(100) < 75)
3451                                         place_object(*y, *x, FALSE, FALSE);
3452                                 else if (rand_int(100) < 80)
3453                                         place_object(*y, *x, TRUE, FALSE);
3454                                 else
3455                                         place_object(*y, *x, TRUE, TRUE);
3456
3457                                 object_level = base_level;
3458                         }
3459                         /* Random trap */
3460                         else if (random & RANDOM_TRAP)
3461                         {
3462                                 place_trap(*y, *x);
3463                         }
3464                         else if (object_index)
3465                         {
3466                                 /* Get local object */
3467                                 object_type *o_ptr = &object_type_body;
3468
3469                                 /* Create the item */
3470                                 object_prep(o_ptr, object_index);
3471
3472                                 if (o_ptr->tval == TV_GOLD)
3473                                 {
3474                                         coin_type = object_index - OBJ_GOLD_LIST;
3475                                         make_gold(o_ptr);
3476                                         coin_type = 0;
3477                                 }
3478
3479                                 /* Apply magic (no messages, no artifacts) */
3480                                 apply_magic(o_ptr, base_level, FALSE, TRUE, FALSE, FALSE);
3481
3482 #ifdef USE_SCRIPT
3483                                 o_ptr->python = object_create_callback(o_ptr);
3484 #endif /* USE_SCRIPT */
3485
3486                                 (void)drop_near(o_ptr, -1, *y, *x);
3487                         }
3488
3489                         /* Artifact */
3490                         if (artifact_index)
3491                         {
3492                                 if (a_info[artifact_index].cur_num)
3493                                 {
3494                                         s16b k_idx = 198;
3495                                         object_type forge;
3496                                         object_type *q_ptr = &forge;
3497
3498                                         object_prep(q_ptr, k_idx);
3499 #ifdef USE_SCRIPT
3500                                         q_ptr->python = object_create_callback(q_ptr);
3501 #endif /* USE_SCRIPT */
3502
3503                                         /* Drop it in the dungeon */
3504                                         (void)drop_near(q_ptr, -1, *y, *x);
3505                                 }
3506                                 else
3507                                 {
3508                                         /* Create the artifact */
3509                                         create_named_art(artifact_index, *y, *x);
3510
3511                                         a_info[artifact_index].cur_num = 1;
3512                                 }
3513                         }
3514
3515                         /* Terrain special */
3516                         c_ptr->special = letter[idx].special;
3517                 }
3518
3519                 (*y)++;
3520
3521                 return (0);
3522         }
3523
3524         /* Process "Q:<number>:<command>:... -- quest info */
3525         else if (buf[0] == 'Q')
3526         {
3527                 int num;
3528                 quest_type *q_ptr;
3529 #ifdef JP
3530                 if (buf[2] == '$')
3531                         return 0;
3532                 num = tokenize(buf + 2, 33, zz, 0);
3533 #else
3534                 if (buf[2] != '$')
3535                         return 0;
3536                 num = tokenize(buf + 3, 33, zz, 0);
3537 #endif
3538
3539                 /* Have we enough parameters? */
3540                 if (num < 3) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3541
3542                 /* Get the quest */
3543                 q_ptr = &(quest[atoi(zz[0])]);
3544
3545                 /* Process "Q:<q_index>:Q:<type>:<num_mon>:<cur_num>:<max_num>:<level>:<r_idx>:<k_idx>:<flags>" -- quest info */
3546                 if (zz[1][0] == 'Q')
3547                 {
3548                         if (init_flags & INIT_ASSIGN)
3549                         {
3550                                 monster_race *r_ptr;
3551                                 artifact_type *a_ptr;
3552
3553                                 if (num < 9) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3554
3555                                 q_ptr->type    = atoi(zz[2]);
3556                                 q_ptr->num_mon = atoi(zz[3]);
3557                                 q_ptr->cur_num = atoi(zz[4]);
3558                                 q_ptr->max_num = atoi(zz[5]);
3559                                 q_ptr->level   = atoi(zz[6]);
3560                                 q_ptr->r_idx   = atoi(zz[7]);
3561                                 q_ptr->k_idx   = atoi(zz[8]);
3562                                 q_ptr->dungeon = atoi(zz[9]);
3563
3564                                 if (num > 10)
3565                                         q_ptr->flags  = atoi(zz[10]);
3566
3567                                 r_ptr = &r_info[q_ptr->r_idx];
3568                                 if (r_ptr->flags1 & RF1_UNIQUE)
3569                                         r_ptr->flags1 |= RF1_QUESTOR;
3570
3571                                 a_ptr = &a_info[q_ptr->k_idx];
3572                                 a_ptr->flags3 |= TR3_QUESTITEM;
3573                         }
3574                         return (0);
3575                 }
3576
3577                 /* Process "Q:<q_index>:N:<name>" -- quest name */
3578                 else if (zz[1][0] == 'N')
3579                 {
3580                         if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT))
3581                         {
3582                                 strcpy(q_ptr->name, zz[2]);
3583                         }
3584
3585                         return (0);
3586                 }
3587
3588                 /* Process "Q:<q_index>:T:<text>" -- quest description line */
3589                 else if (zz[1][0] == 'T')
3590                 {
3591                         if (init_flags & INIT_SHOW_TEXT)
3592                         {
3593                                 strcpy(quest_text[quest_text_line], zz[2]);
3594                                 quest_text_line++;
3595                         }
3596
3597                         return (0);
3598                 }
3599         }
3600
3601         /* Process "W:<command>: ..." -- info for the wilderness */
3602         else if (buf[0] == 'W')
3603         {
3604                 return parse_line_wilderness(buf, ymin, xmin, ymax, xmax, y, x);
3605         }
3606
3607         /* Process "P:<y>:<x>" -- player position */
3608         else if (buf[0] == 'P')
3609         {
3610                 if (init_flags & INIT_CREATE_DUNGEON)
3611                 {
3612                         if (tokenize(buf + 2, 2, zz, 0) == 2)
3613                         {
3614                                 int panels_x, panels_y;
3615
3616                                 /* Hack - Set the dungeon size */
3617                                 panels_y = (*y / SCREEN_HGT);
3618                                 if (*y % SCREEN_HGT) panels_y++;
3619                                 cur_hgt = panels_y * SCREEN_HGT;
3620
3621                                 panels_x = (*x / SCREEN_WID);
3622                                 if (*x % SCREEN_WID) panels_x++;
3623                                 cur_wid = panels_x * SCREEN_WID;
3624
3625                                 /* Choose a panel row */
3626                                 max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
3627                                 if (max_panel_rows < 0) max_panel_rows = 0;
3628
3629                                 /* Choose a panel col */
3630                                 max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;
3631                                 if (max_panel_cols < 0) max_panel_cols = 0;
3632
3633                                 /* Assume illegal panel */
3634                                 panel_row = max_panel_rows;
3635                                 panel_col = max_panel_cols;
3636
3637                                 /* Place player in a quest level */
3638                                 if (p_ptr->inside_quest)
3639                                 {
3640                                         int y, x;
3641
3642                                         /* Delete the monster (if any) */
3643                                         delete_monster(py, px);
3644
3645                                         y = atoi(zz[0]);
3646                                         x = atoi(zz[1]);
3647
3648                                         py = y;
3649                                         px = x;
3650                                 }
3651                                 /* Place player in the town */
3652                                 else if (!p_ptr->oldpx && !p_ptr->oldpy)
3653                                 {
3654                                         p_ptr->oldpy = atoi(zz[0]);
3655                                         p_ptr->oldpx = atoi(zz[1]);
3656                                 }
3657                         }
3658                 }
3659
3660                 return (0);
3661         }
3662
3663         /* Process "B:<Index>:<Command>:..." -- Building definition */
3664         else if (buf[0] == 'B')
3665         {
3666                 return parse_line_building(buf);
3667         }
3668
3669         /* Process "M:<type>:<maximum>" -- set maximum values */
3670         else if (buf[0] == 'M')
3671         {
3672                 if (tokenize(buf+2, 2, zz, 0) == 2)
3673                 {
3674                         /* Maximum towns */
3675                         if (zz[0][0] == 'T')
3676                         {
3677                                 max_towns = atoi(zz[1]);
3678                         }
3679
3680                         /* Maximum quests */
3681                         else if (zz[0][0] == 'Q')
3682                         {
3683                                 max_quests = atoi(zz[1]);
3684                         }
3685
3686                         /* Maximum r_idx */
3687                         else if (zz[0][0] == 'R')
3688                         {
3689                                 max_r_idx = atoi(zz[1]);
3690                         }
3691
3692                         /* Maximum k_idx */
3693                         else if (zz[0][0] == 'K')
3694                         {
3695                                 max_k_idx = atoi(zz[1]);
3696                         }
3697
3698                         /* Maximum v_idx */
3699                         else if (zz[0][0] == 'V')
3700                         {
3701                                 max_v_idx = atoi(zz[1]);
3702                         }
3703
3704                         /* Maximum f_idx */
3705                         else if (zz[0][0] == 'F')
3706                         {
3707                                 max_f_idx = atoi(zz[1]);
3708                         }
3709
3710                         /* Maximum a_idx */
3711                         else if (zz[0][0] == 'A')
3712                         {
3713                                 max_a_idx = atoi(zz[1]);
3714                         }
3715
3716                         /* Maximum e_idx */
3717                         else if (zz[0][0] == 'E')
3718                         {
3719                                 max_e_idx = atoi(zz[1]);
3720                         }
3721
3722                         /* Maximum d_idx */
3723                         else if (zz[0][0] == 'D')
3724                         {
3725                                 max_d_idx = atoi(zz[1]); 
3726                         }
3727
3728                         /* Maximum o_idx */
3729                         else if (zz[0][0] == 'O')
3730                         {
3731                                 max_o_idx = atoi(zz[1]);
3732                         }
3733
3734                         /* Maximum m_idx */
3735                         else if (zz[0][0] == 'M')
3736                         {
3737                                 max_m_idx = atoi(zz[1]);
3738                         }
3739
3740                         /* Wilderness size */
3741                         else if (zz[0][0] == 'W')
3742                         {
3743                                 /* Maximum wild_x_size */
3744                                 if (zz[0][1] == 'X')
3745                                         max_wild_x = atoi(zz[1]);
3746                                 /* Maximum wild_y_size */
3747                                 if (zz[0][1] == 'Y')
3748                                         max_wild_y = atoi(zz[1]);
3749                         }
3750
3751                         return (0);
3752                 }
3753         }
3754
3755
3756         /* Failure */
3757         return (1);
3758 }
3759
3760
3761 static char tmp[8];
3762 static cptr variant = "ZANGBAND";
3763
3764
3765 /*
3766  * Helper function for "process_dungeon_file()"
3767  */
3768 static cptr process_dungeon_file_expr(char **sp, char *fp)
3769 {
3770         cptr v;
3771
3772         char *b;
3773         char *s;
3774
3775         char b1 = '[';
3776         char b2 = ']';
3777
3778         char f = ' ';
3779
3780         /* Initial */
3781         s = (*sp);
3782
3783         /* Skip spaces */
3784         while (isspace(*s)) s++;
3785
3786         /* Save start */
3787         b = s;
3788
3789         /* Default */
3790         v = "?o?o?";
3791
3792         /* Analyze */
3793         if (*s == b1)
3794         {
3795                 const char *p;
3796                 const char *t;
3797
3798                 /* Skip b1 */
3799                 s++;
3800
3801                 /* First */
3802                 t = process_dungeon_file_expr(&s, &f);
3803
3804                 /* Oops */
3805                 if (!*t)
3806                 {
3807                         /* Nothing */
3808                 }
3809
3810                 /* Function: IOR */
3811                 else if (streq(t, "IOR"))
3812                 {
3813                         v = "0";
3814                         while (*s && (f != b2))
3815                         {
3816                                 t = process_dungeon_file_expr(&s, &f);
3817                                 if (*t && !streq(t, "0")) v = "1";
3818                         }
3819                 }
3820
3821                 /* Function: AND */
3822                 else if (streq(t, "AND"))
3823                 {
3824                         v = "1";
3825                         while (*s && (f != b2))
3826                         {
3827                                 t = process_dungeon_file_expr(&s, &f);
3828                                 if (*t && streq(t, "0")) v = "0";
3829                         }
3830                 }
3831
3832                 /* Function: NOT */
3833                 else if (streq(t, "NOT"))
3834                 {
3835                         v = "1";
3836                         while (*s && (f != b2))
3837                         {
3838                                 t = process_dungeon_file_expr(&s, &f);
3839                                 if (*t && streq(t, "1")) v = "0";
3840                         }
3841                 }
3842
3843                 /* Function: EQU */
3844                 else if (streq(t, "EQU"))
3845                 {
3846                         v = "1";
3847                         if (*s && (f != b2))
3848                         {
3849                                 t = process_dungeon_file_expr(&s, &f);
3850                         }
3851                         while (*s && (f != b2))
3852                         {
3853                                 p = t;
3854                                 t = process_dungeon_file_expr(&s, &f);
3855                                 if (*t && !streq(p, t)) v = "0";
3856                         }
3857                 }
3858
3859                 /* Function: LEQ */
3860                 else if (streq(t, "LEQ"))
3861                 {
3862                         v = "1";
3863                         if (*s && (f != b2))
3864                         {
3865                                 t = process_dungeon_file_expr(&s, &f);
3866                         }
3867                         while (*s && (f != b2))
3868                         {
3869                                 p = t;
3870                                 t = process_dungeon_file_expr(&s, &f);
3871                                 if (*t && (strcmp(p, t) > 0)) v = "0";
3872                         }
3873                 }
3874
3875                 /* Function: GEQ */
3876                 else if (streq(t, "GEQ"))
3877                 {
3878                         v = "1";
3879                         if (*s && (f != b2))
3880                         {
3881                                 t = process_dungeon_file_expr(&s, &f);
3882                         }
3883                         while (*s && (f != b2))
3884                         {
3885                                 p = t;
3886                                 t = process_dungeon_file_expr(&s, &f);
3887                                 if (*t && (strcmp(p, t) < 0)) v = "0";
3888                         }
3889                 }
3890
3891                 /* Oops */
3892                 else
3893                 {
3894                         while (*s && (f != b2))
3895                         {
3896                                 t = process_dungeon_file_expr(&s, &f);
3897                         }
3898                 }
3899
3900                 /* Verify ending */
3901                 if (f != b2) v = "?x?x?";
3902
3903                 /* Extract final and Terminate */
3904                 if ((f = *s) != '\0') *s++ = '\0';
3905         }
3906
3907         /* Other */
3908         else
3909         {
3910                 /* Accept all printables except spaces and brackets */
3911                 while (isprint(*s) && !strchr(" []", *s)) ++s;
3912
3913                 /* Extract final and Terminate */
3914                 if ((f = *s) != '\0') *s++ = '\0';
3915
3916                 /* Variable */
3917                 if (*b == '$')
3918                 {
3919                         /* System */
3920                         if (streq(b+1, "SYS"))
3921                         {
3922                                 v = ANGBAND_SYS;
3923                         }
3924
3925                         /* Graphics */
3926                         else if (streq(b+1, "GRAF"))
3927                         {
3928                                 v = ANGBAND_GRAF;
3929                         }
3930
3931                         else if (streq(b+1, "MONOCHROME"))
3932                         {
3933                                 if (arg_monochrome)
3934                                         v = "ON";
3935                                 else
3936                                         v = "OFF";
3937                         }
3938
3939                         /* Race */
3940                         else if (streq(b+1, "RACE"))
3941                         {
3942 #ifdef JP
3943                                 v = rp_ptr->E_title;
3944 #else
3945                                 v = rp_ptr->title;
3946 #endif
3947                         }
3948
3949                         /* Class */
3950                         else if (streq(b+1, "CLASS"))
3951                         {
3952 #ifdef JP
3953                                 v = cp_ptr->E_title;
3954 #else
3955                                 v = cp_ptr->title;
3956 #endif
3957                         }
3958
3959                         /* First realm */
3960                         else if (streq(b+1, "REALM1"))
3961                         {
3962 #ifdef JP
3963                                 v = E_realm_names[p_ptr->realm1];
3964 #else
3965                                 v = realm_names[p_ptr->realm1];
3966 #endif
3967                         }
3968
3969                         /* Second realm */
3970                         else if (streq(b+1, "REALM2"))
3971                         {
3972 #ifdef JP
3973                                 v = E_realm_names[p_ptr->realm2];
3974 #else
3975                                 v = realm_names[p_ptr->realm2];
3976 #endif
3977                         }
3978
3979                         /* Player name */
3980                         else if (streq(b+1, "PLAYER"))
3981                         {
3982                                 v = player_base;
3983                         }
3984
3985                         /* Town */
3986                         else if (streq(b+1, "TOWN"))
3987                         {
3988                                 sprintf(tmp, "%d", p_ptr->town_num);
3989                                 v = tmp;
3990                         }
3991
3992                         /* Level */
3993                         else if (streq(b+1, "LEVEL"))
3994                         {
3995                                 sprintf(tmp, "%d", p_ptr->lev);
3996                                 v = tmp;
3997                         }
3998
3999                         /* Current quest number */
4000                         else if (streq(b+1, "QUEST_NUMBER"))
4001                         {
4002                                 sprintf(tmp, "%d", p_ptr->inside_quest);
4003                                 v = tmp;
4004                         }
4005
4006                         /* Number of last quest */
4007                         else if (streq(b+1, "LEAVING_QUEST"))
4008                         {
4009                                 sprintf(tmp, "%d", leaving_quest);
4010                                 v = tmp;
4011                         }
4012
4013                         /* Quest status */
4014                         else if (prefix(b+1, "QUEST"))
4015                         {
4016                                 /* "QUEST" uses a special parameter to determine the number of the quest */
4017                                 sprintf(tmp, "%d", quest[atoi(b+6)].status);
4018                                 v = tmp;
4019                         }
4020
4021                         /* Random */
4022                         else if (prefix(b+1, "RANDOM"))
4023                         {
4024                                 /* "RANDOM" uses a special parameter to determine the number of the quest */
4025                                 sprintf(tmp, "%d", (int)(seed_town%atoi(b+7)));
4026                                 v = tmp;
4027                         }
4028
4029                         /* Variant name */
4030                         else if (streq(b+1, "VARIANT"))
4031                         {
4032                                 v = variant;
4033                         }
4034
4035                         /* Wilderness */
4036                         else if (streq(b+1, "WILDERNESS"))
4037                         {
4038                                 if (vanilla_town)
4039                                         sprintf(tmp, "NONE");
4040                                 else if (lite_town)
4041                                         sprintf(tmp, "LITE");
4042                                 else
4043                                         sprintf(tmp, "NORMAL");
4044                                 v = tmp;
4045                         }
4046                 }
4047
4048                 /* Constant */
4049                 else
4050                 {
4051                         v = b;
4052                 }
4053         }
4054
4055         /* Save */
4056         (*fp) = f;
4057
4058         /* Save */
4059         (*sp) = s;
4060
4061         /* Result */
4062         return (v);
4063 }
4064
4065
4066 errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax)
4067 {
4068         FILE *fp;
4069
4070         char buf[1024];
4071
4072         int num = -1;
4073
4074         errr err = 0;
4075
4076         bool bypass = FALSE;
4077
4078         int x = xmin, y = ymin;
4079
4080
4081         /* Build the filename */
4082         path_build(buf, 1024, ANGBAND_DIR_EDIT, name);
4083
4084         /* Open the file */
4085         fp = my_fopen(buf, "r");
4086
4087         /* No such file */
4088         if (!fp) return (-1);
4089
4090
4091         /* Process the file */
4092         while (0 == my_fgets(fp, buf, 1024))
4093         {
4094                 /* Count lines */
4095                 num++;
4096
4097
4098                 /* Skip "empty" lines */
4099                 if (!buf[0]) continue;
4100
4101                 /* Skip "blank" lines */
4102                 if (isspace(buf[0])) continue;
4103
4104                 /* Skip comments */
4105                 if (buf[0] == '#') continue;
4106
4107
4108                 /* Process "?:<expr>" */
4109                 if ((buf[0] == '?') && (buf[1] == ':'))
4110                 {
4111                         char f;
4112                         cptr v;
4113                         char *s;
4114
4115                         /* Start */
4116                         s = buf + 2;
4117
4118                         /* Parse the expr */
4119                         v = process_dungeon_file_expr(&s, &f);
4120
4121                         /* Set flag */
4122                         bypass = (streq(v, "0") ? TRUE : FALSE);
4123
4124                         /* Continue */
4125                         continue;
4126                 }
4127
4128                 /* Apply conditionals */
4129                 if (bypass) continue;
4130
4131
4132                 /* Process "%:<file>" */
4133                 if (buf[0] == '%')
4134                 {
4135                         /* Process that file if allowed */
4136                         (void)process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax);
4137
4138                         /* Continue */
4139                         continue;
4140                 }
4141
4142
4143                 /* Process the line */
4144                 err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x);
4145
4146                 /* Oops */
4147                 if (err) break;
4148         }
4149
4150         /* Errors */
4151         if (err)
4152         {
4153                 cptr oops;
4154
4155                 /* Error string */
4156                 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
4157
4158                 /* Oops */
4159                 msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
4160 #ifdef JP
4161 msg_format("'%s'¤ò²òÀÏÃæ¡£", buf);
4162 #else
4163                 msg_format("Parsing '%s'.", buf);
4164 #endif
4165
4166                 msg_print(NULL);
4167         }
4168
4169
4170         /* Close the file */
4171         my_fclose(fp);
4172
4173         /* Result */
4174         return (err);
4175 }
4176
4177
4178
4179 #if 0
4180 void write_r_info_txt(void)
4181 {
4182         int i, j, z, fc, bc;
4183         int dlen;
4184
4185         cptr flags[288];
4186
4187         u32b f_ptr[9];
4188         cptr *n_ptr[9];
4189
4190         monster_race *r_ptr;
4191
4192         monster_blow *b_ptr;
4193
4194         FILE *fff = fopen("output.txt", "wt");
4195
4196         cptr desc;
4197
4198         int mode = -1;
4199
4200         if (!fff) return;
4201
4202         fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");
4203
4204         fprintf(fff, "# Version stamp (required)\n\n");
4205
4206         /* Write Version */
4207         fprintf(fff, "V:%d.%d.%d\n\n\n", r_head->v_major, r_head->v_minor, r_head->v_patch);
4208
4209         /* Write a note */
4210         fprintf(fff, "##### The Player #####\n\n");
4211
4212         for (z = -1; z < alloc_race_size; z++)
4213         {
4214                 /* Output the monsters in order */
4215                 i = (z >= 0) ? alloc_race_table[z].index : 0;
4216
4217                 /* Acquire the monster */
4218                 r_ptr = &r_info[i];
4219
4220                 /* Ignore empty monsters */
4221                 if (!strlen(r_name + r_ptr->name)) continue;
4222
4223                 /* Ignore useless monsters */
4224                 if (i && !r_ptr->speed) continue;
4225
4226                 /* Write a note if necessary */
4227                 if (i && (!r_ptr->level != !mode))
4228                 {
4229                         /* Note the town */
4230                         if (!r_ptr->level)
4231                         {
4232                                 fprintf(fff, "\n##### Town monsters #####\n\n");
4233                         }
4234                         /* Note the dungeon */
4235                         else
4236                         {
4237                                 fprintf(fff, "\n##### Normal monsters #####\n\n");
4238                         }
4239
4240                         /* Record the change */
4241                         mode = r_ptr->level;
4242                 }
4243
4244                 /* Acquire the flags */
4245                 f_ptr[0] = r_ptr->flags1; n_ptr[0] = r_info_flags1;
4246                 f_ptr[1] = r_ptr->flags2; n_ptr[1] = r_info_flags2;
4247                 f_ptr[2] = r_ptr->flags3; n_ptr[2] = r_info_flags3;
4248                 f_ptr[3] = r_ptr->flags4; n_ptr[3] = r_info_flags4;
4249                 f_ptr[4] = r_ptr->flags5; n_ptr[4] = r_info_flags5;
4250                 f_ptr[5] = r_ptr->flags6; n_ptr[5] = r_info_flags6;
4251                 f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7;
4252                 f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8;
4253                 f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9;
4254
4255                 /* Write New/Number/Name */
4256                 fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name);
4257
4258                 /* Write Graphic */
4259                 fprintf(fff, "G:%c:%c\n", r_ptr->d_char, color_char[r_ptr->d_attr]);
4260
4261                 /* Write Information */
4262                 fprintf(fff, "I:%d:%dd%d:%d:%d:%d\n", r_ptr->speed, r_ptr->hdice, r_ptr->hside,
4263                                                                                                                   r_ptr->aaf, r_ptr->ac, r_ptr->sleep);
4264
4265                 /* Write more information */
4266                 fprintf(fff, "W:%d:%d:%d:%ld\n", r_ptr->level, r_ptr->rarity, r_ptr->extra, r_ptr->mexp);
4267
4268                 /* Write Blows */
4269                 for(j = 0; j < 4; j++)
4270                 {
4271                         b_ptr = &(r_ptr->blow[j]);
4272
4273                         /* Stop when done */
4274                         if (!b_ptr->method) break;
4275
4276                         /* Write the blows */
4277                         fprintf(fff, "B:%s:%s:%dd%d\n", r_info_blow_method[b_ptr->method],
4278                                                                                                           r_info_blow_effect[b_ptr->effect],
4279                                                                                                           b_ptr->d_dice, b_ptr->d_side);
4280                 }
4281
4282                 /* Extract the flags */
4283                 for (fc = 0, j = 0; j < 96; j++)
4284                 {
4285                         /* Check this flag */
4286                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4287                 }
4288
4289                 /* Extract the extra flags */
4290                 for (j = 192; j < 288; j++)
4291                 {
4292                         /* Check this flag */
4293                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4294                 }
4295
4296                 /* Write the flags */
4297                 for (j = 0; j < fc;)
4298                 {
4299                         char buf[160];
4300
4301                         /* Start the line */
4302                         sprintf(buf, "F:");
4303
4304                         for (bc = 0; (bc < 60) && (j < fc); j++)
4305                         {
4306                                 char t[80];
4307
4308                                 /* Format the flag */
4309                                 sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4310
4311                                 /* Add it to the buffer */
4312                                 strcat(buf, t);
4313
4314                                 /* Note the length */
4315                                 bc += strlen(t);
4316                         }
4317
4318                         /* Done with this line; write it */
4319                         fprintf(fff, "%s\n", buf);
4320                 }
4321
4322                 /* Write Spells if applicable */
4323                 if (r_ptr->freq_spell)
4324                 {
4325                         /* Write the frequency */
4326                         fprintf(fff, "S:1_IN_%d | \n", 100 / r_ptr->freq_spell);
4327
4328                         /* Extract the spell flags */
4329                         for (fc = 0, j = 96; j < 192; j++)
4330                         {
4331                                 /* Check this flag */
4332                                 if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4333                         }
4334
4335                         /* Write the flags */
4336                         for (j = 0; j < fc;)
4337                         {
4338                                 char buf[160], *t;
4339
4340                                 /* Start the line */
4341                                 sprintf(buf, "S:");
4342
4343                                 for (bc = 0, t = buf + 2; (bc < 60) && (j < fc); j++)
4344                                 {
4345                                         int tlen;
4346
4347                                         /* Format the flag */
4348                                         sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4349
4350                                         tlen = strlen(t);
4351
4352                                         /* Note the length */
4353                                         bc += tlen;
4354
4355                                         /* Advance */
4356                                         t += tlen;
4357                                 }
4358
4359                                 /* Done with this line; write it */
4360                                 fprintf(fff, "%s\n", buf);
4361                         }
4362                 }
4363
4364                 /* Acquire the description */
4365                 desc = r_text + r_ptr->text;
4366                 dlen = strlen(desc);
4367
4368                 /* Write Description */
4369                 for (j = 0; j < dlen;)
4370                 {
4371                         char buf[160], *t;
4372
4373                         /* Start the line */
4374                         sprintf(buf, "D:");
4375
4376                         for (bc = 0, t = buf + 2; ((bc < 60) || !isspace(desc[j])) && (j < dlen); j++, bc++, t++)
4377                         {
4378                                 *t = desc[j];
4379                         }
4380
4381                         /* Terminate it */
4382                         *t = '\0';
4383
4384                         /* Done with this line; write it */
4385                         fprintf(fff, "%s\n", buf);
4386                 }
4387
4388                 /* Space between entries */
4389                 fprintf(fff, "\n");
4390         }
4391
4392         /* Done */
4393         fclose(fff);
4394 }
4395
4396 #endif