OSDN Git Service

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