OSDN Git Service

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