OSDN Git Service

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