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         "BRAIN_7",
211         "QUANTUM"
212 };
213
214 /*
215  * Monster race flags
216  */
217 static cptr r_info_flags3[] =
218 {
219         "ORC",
220         "TROLL",
221         "GIANT",
222         "DRAGON",
223         "DEMON",
224         "UNDEAD",
225         "EVIL",
226         "ANIMAL",
227         "AMBERITE",
228         "GOOD",
229         "AURA_COLD",
230         "NONLIVING",
231         "HURT_LITE",
232         "HURT_ROCK",
233         "HURT_FIRE",
234         "HURT_COLD",
235         "IM_ACID",
236         "IM_ELEC",
237         "IM_FIRE",
238         "IM_COLD",
239         "IM_POIS",
240         "RES_TELE",
241         "RES_NETH",
242         "RES_WATE",
243         "RES_PLAS",
244         "RES_NEXU",
245         "RES_DISE",
246         "RES_ALL",
247         "NO_FEAR",
248         "NO_STUN",
249         "NO_CONF",
250         "NO_SLEEP"
251 };
252
253 /*
254  * Monster race flags
255  */
256 static cptr r_info_flags4[] =
257 {
258         "SHRIEK",
259         "XXX1",
260         "DISPEL",
261         "ROCKET",
262         "SHOOT",
263         "XXX2",
264         "XXX3",
265         "XXX4",
266         "BR_ACID",
267         "BR_ELEC",
268         "BR_FIRE",
269         "BR_COLD",
270         "BR_POIS",
271         "BR_NETH",
272         "BR_LITE",
273         "BR_DARK",
274         "BR_CONF",
275         "BR_SOUN",
276         "BR_CHAO",
277         "BR_DISE",
278         "BR_NEXU",
279         "BR_TIME",
280         "BR_INER",
281         "BR_GRAV",
282         "BR_SHAR",
283         "BR_PLAS",
284         "BR_WALL",
285         "BR_MANA",
286         "BA_NUKE",
287         "BR_NUKE",
288         "BA_CHAO",
289         "BR_DISI",
290 };
291
292 /*
293  * Monster race flags
294  */
295 static cptr r_info_flags5[] =
296 {
297         "BA_ACID",
298         "BA_ELEC",
299         "BA_FIRE",
300         "BA_COLD",
301         "BA_POIS",
302         "BA_NETH",
303         "BA_WATE",
304         "BA_MANA",
305         "BA_DARK",
306         "DRAIN_MANA",
307         "MIND_BLAST",
308         "BRAIN_SMASH",
309         "CAUSE_1",
310         "CAUSE_2",
311         "CAUSE_3",
312         "CAUSE_4",
313         "BO_ACID",
314         "BO_ELEC",
315         "BO_FIRE",
316         "BO_COLD",
317         "BA_LITE",
318         "BO_NETH",
319         "BO_WATE",
320         "BO_MANA",
321         "BO_PLAS",
322         "BO_ICEE",
323         "MISSILE",
324         "SCARE",
325         "BLIND",
326         "CONF",
327         "SLOW",
328         "HOLD"
329 };
330
331 /*
332  * Monster race flags
333  */
334 static cptr r_info_flags6[] =
335 {
336         "HASTE",
337         "HAND_DOOM",
338         "HEAL",
339         "INVULNER",
340         "BLINK",
341         "TPORT",
342         "WORLD",
343         "SPECIAL",
344         "TELE_TO",
345         "TELE_AWAY",
346         "TELE_LEVEL",
347         "PSY_SPEAR",
348         "DARKNESS",
349         "TRAPS",
350         "FORGET",
351         "ANIM_DEAD", /* ToDo: Implement ANIM_DEAD */
352         "S_KIN",
353         "S_CYBER",
354         "S_MONSTER",
355         "S_MONSTERS",
356         "S_ANT",
357         "S_SPIDER",
358         "S_HOUND",
359         "S_HYDRA",
360         "S_ANGEL",
361         "S_DEMON",
362         "S_UNDEAD",
363         "S_DRAGON",
364         "S_HI_UNDEAD",
365         "S_HI_DRAGON",
366         "S_AMBERITES",
367         "S_UNIQUE"
368 };
369
370
371 /*
372  * Monster race flags
373  */
374 static cptr r_info_flags7[] =
375 {
376         "AQUATIC",
377         "CAN_SWIM",
378         "CAN_FLY",
379         "FRIENDLY",
380         "UNIQUE_7",
381         "UNIQUE2",
382         "RIDING",
383         "KAGE",
384         "HAS_LITE_1",
385         "SELF_LITE_1",
386         "HAS_LITE_2",
387         "SELF_LITE_2",
388         "GUARDIAN",
389         "CHAMELEON",
390         "KILL_EXP",
391         "XXX7X15",
392         "XXX7X16",
393         "XXX7X17",
394         "XXX7X18",
395         "XXX7X19",
396         "XXX7X20",
397         "XXX7X21",
398         "XXX7X22",
399         "XXX7X23",
400         "XXX7X24",
401         "XXX7X25",
402         "XXX7X26",
403         "XXX7X27",
404         "XXX7X28",
405         "XXX7X29",
406         "XXX7X30",
407         "XXX7X31",
408 };
409
410 /*
411  * Monster race flags
412  */
413 static cptr r_info_flags8[] =
414 {
415         "WILD_ONLY",
416         "WILD_TOWN",
417         "XXX8X02",
418         "WILD_SHORE",
419         "WILD_OCEAN",
420         "WILD_WASTE",
421         "WILD_WOOD",
422         "WILD_VOLCANO",
423         "XXX8X08",
424         "WILD_MOUNTAIN",
425         "WILD_GRASS",
426         "XXX8X11",
427         "XXX8X12",
428         "XXX8X13",
429         "XXX8X14",
430         "XXX8X15",
431         "XXX8X16",
432         "XXX8X17",
433         "XXX8X18",
434         "XXX8X19",
435         "XXX8X20",
436         "XXX8X21",
437         "XXX8X22",
438         "XXX8X23",
439         "XXX8X24",
440         "XXX8X25",
441         "XXX8X26",
442         "XXX8X27",
443         "XXX8X28",
444         "XXX8X29",
445         "WILD_SWAMP",   /* ToDo: Implement Swamp */
446         "WILD_ALL",
447 };
448
449
450 /*
451  * Monster race flags - Drops
452  */
453 static cptr r_info_flags9[] =
454 {
455         "DROP_CORPSE",
456         "DROP_SKELETON",
457         "EAT_BLIND",
458         "EAT_CONF",
459         "EAT_MANA",
460         "EAT_NEXUS",
461         "EAT_BLINK",
462         "EAT_SLEEP",
463         "EAT_BERSERKER",
464         "EAT_ACIDIC",
465         "EAT_SPEED",
466         "EAT_CURE",
467         "EAT_FIRE_RES",
468         "EAT_COLD_RES",
469         "EAT_ACID_RES",
470         "EAT_ELEC_RES",
471         "EAT_POIS_RES",
472         "EAT_INSANITY",
473         "EAT_DRAIN_EXP",
474         "EAT_POISONOUS",
475         "EAT_GIVE_STR",
476         "EAT_GIVE_INT",
477         "EAT_GIVE_WIS",
478         "EAT_GIVE_DEX",
479         "EAT_GIVE_CON",
480         "EAT_GIVE_CHR",
481         "EAT_LOSE_STR",
482         "EAT_LOSE_INT",
483         "EAT_LOSE_WIS",
484         "EAT_LOSE_DEX",
485         "EAT_LOSE_CON",
486         "EAT_LOSE_CHR",
487         "EAT_DRAIN_MANA",
488 };
489
490
491 /*
492  * Object flags
493  */
494 static cptr k_info_flags1[] =
495 {
496         "STR",
497         "INT",
498         "WIS",
499         "DEX",
500         "CON",
501         "CHR",
502         "MAGIC_MASTERY",
503         "FORCE_WEAPON",
504         "STEALTH",
505         "SEARCH",
506         "INFRA",
507         "TUNNEL",
508         "SPEED",
509         "BLOWS",
510         "CHAOTIC",
511         "VAMPIRIC",
512         "SLAY_ANIMAL",
513         "SLAY_EVIL",
514         "SLAY_UNDEAD",
515         "SLAY_DEMON",
516         "SLAY_ORC",
517         "SLAY_TROLL",
518         "SLAY_GIANT",
519         "SLAY_DRAGON",
520         "KILL_DRAGON",
521         "VORPAL",
522         "IMPACT",
523         "BRAND_POIS",
524         "BRAND_ACID",
525         "BRAND_ELEC",
526         "BRAND_FIRE",
527         "BRAND_COLD"
528 };
529
530 /*
531  * Object flags
532  */
533 static cptr k_info_flags2[] =
534 {
535         "SUST_STR",
536         "SUST_INT",
537         "SUST_WIS",
538         "SUST_DEX",
539         "SUST_CON",
540         "SUST_CHR",
541         "RIDING",
542         "XXX2",
543         "IM_ACID",
544         "IM_ELEC",
545         "IM_FIRE",
546         "IM_COLD",
547         "THROW",
548         "REFLECT",
549         "FREE_ACT",
550         "HOLD_LIFE",
551         "RES_ACID",
552         "RES_ELEC",
553         "RES_FIRE",
554         "RES_COLD",
555         "RES_POIS",
556         "RES_FEAR",
557         "RES_LITE",
558         "RES_DARK",
559         "RES_BLIND",
560         "RES_CONF",
561         "RES_SOUND",
562         "RES_SHARDS",
563         "RES_NETHER",
564         "RES_NEXUS",
565         "RES_CHAOS",
566         "RES_DISEN"
567 };
568
569 /*
570  * Object flags
571  */
572 static cptr k_info_flags3[] =
573 {
574         "SH_FIRE",
575         "SH_ELEC",
576         "XXX1",
577         "SH_COLD",
578         "NO_TELE",
579         "NO_MAGIC",
580         "DEC_MANA",
581         "TY_CURSE",
582         "WARNING",
583         "HIDE_TYPE",
584         "SHOW_MODS",
585         "XXX2",
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 static int 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                 int 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 #if 0
1387
1388         /* Process 'D' for "Description" */
1389         else if (buf[0] == 'D')
1390         {
1391                 /* Acquire the text */
1392                 s = buf+2;
1393
1394                 /* Store the text */
1395                 if (!add_text(&k_ptr->text, head, s)) return (7);
1396         }
1397
1398 #endif
1399
1400
1401         /* Process 'G' for "Graphics" (one line only) */
1402         else if (buf[0] == 'G')
1403         {
1404                 char sym;
1405                 int tmp;
1406
1407                 /* Paranoia */
1408                 if (!buf[2]) return (1);
1409                 if (!buf[3]) return (1);
1410                 if (!buf[4]) return (1);
1411
1412                 /* Extract the char */
1413                 sym = buf[2];
1414
1415                 /* Extract the attr */
1416                 tmp = color_char_to_attr(buf[4]);
1417
1418                 /* Paranoia */
1419                 if (tmp < 0) return (1);
1420
1421                 /* Save the values */
1422                 k_ptr->d_attr = tmp;
1423                 k_ptr->d_char = sym;
1424         }
1425
1426         /* Process 'I' for "Info" (one line only) */
1427         else if (buf[0] == 'I')
1428         {
1429                 int tval, sval, pval;
1430
1431                 /* Scan for the values */
1432                 if (3 != sscanf(buf+2, "%d:%d:%d",
1433                                 &tval, &sval, &pval)) return (1);
1434
1435                 /* Save the values */
1436                 k_ptr->tval = tval;
1437                 k_ptr->sval = sval;
1438                 k_ptr->pval = pval;
1439         }
1440
1441         /* Process 'W' for "More Info" (one line only) */
1442         else if (buf[0] == 'W')
1443         {
1444                 int level, extra, wgt;
1445                 long cost;
1446
1447                 /* Scan for the values */
1448                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1449                                 &level, &extra, &wgt, &cost)) return (1);
1450
1451                 /* Save the values */
1452                 k_ptr->level = level;
1453                 k_ptr->extra = extra;
1454                 k_ptr->weight = wgt;
1455                 k_ptr->cost = cost;
1456         }
1457
1458         /* Process 'A' for "Allocation" (one line only) */
1459         else if (buf[0] == 'A')
1460         {
1461                 int i;
1462
1463                 /* XXX XXX XXX Simply read each number following a colon */
1464                 for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i)
1465                 {
1466                                 /* Default chance */
1467                         k_ptr->chance[i] = 1;
1468
1469                                 /* Store the attack damage index */
1470                         k_ptr->locale[i] = atoi(s+1);
1471
1472                                 /* Find the slash */
1473                         t = strchr(s+1, '/');
1474
1475                                 /* Find the next colon */
1476                         s = strchr(s+1, ':');
1477
1478                                 /* If the slash is "nearby", use it */
1479                         if (t && (!s || t < s))
1480                         {
1481                                 int chance = atoi(t+1);
1482                                 if (chance > 0) k_ptr->chance[i] = chance;
1483                         }
1484                 }
1485         }
1486
1487         /* Hack -- Process 'P' for "power" and such */
1488         else if (buf[0] == 'P')
1489         {
1490                 int ac, hd1, hd2, th, td, ta;
1491
1492                 /* Scan for the values */
1493                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
1494                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
1495
1496                 k_ptr->ac = ac;
1497                 k_ptr->dd = hd1;
1498                 k_ptr->ds = hd2;
1499                 k_ptr->to_h = th;
1500                 k_ptr->to_d = td;
1501                 k_ptr->to_a =  ta;
1502         }
1503
1504         /* Hack -- Process 'F' for flags */
1505         else if (buf[0] == 'F')
1506         {
1507                 /* Parse every entry textually */
1508                 for (s = buf + 2; *s; )
1509                 {
1510                                 /* Find the end of this entry */
1511                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1512
1513                                 /* Nuke and skip any dividers */
1514                         if (*t)
1515                         {
1516                                 *t++ = '\0';
1517                                 while (*t == ' ' || *t == '|') t++;
1518                         }
1519
1520                                 /* Parse this entry */
1521                         if (0 != grab_one_kind_flag(k_ptr, s)) return (5);
1522
1523                                 /* Start the next entry */
1524                         s = t;
1525                 }
1526         }
1527
1528
1529         /* Oops */
1530         else return (6);
1531
1532
1533         /* Success */
1534         return (0);
1535 }
1536
1537
1538 /*
1539  * Grab one flag in an artifact_type from a textual string
1540  */
1541 static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what)
1542 {
1543         int i;
1544
1545         /* Check flags1 */
1546         for (i = 0; i < 32; i++)
1547         {
1548                 if (streq(what, k_info_flags1[i]))
1549                 {
1550                         a_ptr->flags1 |= (1L << i);
1551                         return (0);
1552                 }
1553         }
1554
1555         /* Check flags2 */
1556         for (i = 0; i < 32; i++)
1557         {
1558                 if (streq(what, k_info_flags2[i]))
1559                 {
1560                         a_ptr->flags2 |= (1L << i);
1561                         return (0);
1562                 }
1563         }
1564
1565         /* Check flags3 */
1566         for (i = 0; i < 32; i++)
1567         {
1568                 if (streq(what, k_info_flags3[i]))
1569                 {
1570                         a_ptr->flags3 |= (1L << i);
1571                         return (0);
1572                 }
1573         }
1574
1575         /* Check gen_flags */
1576         for (i = 0; i < 32; i++)
1577         {
1578                 if (streq(what, k_info_gen_flags[i]))
1579                 {
1580                         a_ptr->gen_flags |= (1L << i);
1581                         return (0);
1582                 }
1583         }
1584
1585         /* Oops */
1586 #ifdef JP
1587         msg_format("̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1588 #else
1589         msg_format("Unknown artifact flag '%s'.", what);
1590 #endif
1591
1592
1593         /* Error */
1594         return (1);
1595 }
1596
1597
1598
1599
1600 /*
1601  * Initialize the "a_info" array, by parsing an ascii "template" file
1602  */
1603 errr parse_a_info(char *buf, header *head)
1604 {
1605         int i;
1606
1607         char *s, *t;
1608
1609         /* Current entry */
1610         static artifact_type *a_ptr = NULL;
1611
1612
1613         /* Process 'N' for "New/Number/Name" */
1614         if (buf[0] == 'N')
1615         {
1616                 /* Find the colon before the name */
1617                 s = strchr(buf+2, ':');
1618
1619                         /* Verify that colon */
1620                 if (!s) return (1);
1621
1622                 /* Nuke the colon, advance to the name */
1623                 *s++ = '\0';
1624 #ifdef JP
1625                 /* Paranoia -- require a name */
1626                 if (!*s) return (1);
1627 #endif
1628                 /* Get the index */
1629                 i = atoi(buf+2);
1630
1631                 /* Verify information */
1632                 if (i < error_idx) return (4);
1633
1634                 /* Verify information */
1635                 if (i >= head->info_num) return (2);
1636
1637                 /* Save the index */
1638                 error_idx = i;
1639
1640                 /* Point at the "info" */
1641                 a_ptr = &a_info[i];
1642
1643                 /* Ignore everything */
1644                 a_ptr->flags3 |= (TR3_IGNORE_ACID);
1645                 a_ptr->flags3 |= (TR3_IGNORE_ELEC);
1646                 a_ptr->flags3 |= (TR3_IGNORE_FIRE);
1647                 a_ptr->flags3 |= (TR3_IGNORE_COLD);
1648 #ifdef JP
1649                 /* Store the name */
1650                 if (!add_name(&a_ptr->name, head, s)) return (7);
1651 #endif
1652         }
1653
1654         /* There better be a current a_ptr */
1655         else if (!a_ptr) return (3);
1656
1657
1658 #ifdef JP
1659         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1660         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
1661         else if (buf[0] == 'E')
1662         {
1663                 /* nothing to do */
1664         }
1665 #else
1666         else if (buf[0] == 'E')
1667         {
1668                 /* Acquire the Text */
1669                 s = buf+2;
1670
1671                 /* Store the name */
1672                 if (!add_name(&a_ptr->name, head, s)) return (7);
1673         }
1674 #endif
1675
1676         /* Process 'D' for "Description" */
1677         else if (buf[0] == 'D')
1678         {
1679 #ifdef JP
1680                 if (buf[2] == '$')
1681                         return (0);
1682                 /* Acquire the text */
1683                 s = buf+2;
1684 #else
1685                 if (buf[2] != '$')
1686                         return (0);
1687                 /* Acquire the text */
1688                 s = buf+3;
1689 #endif
1690
1691                 /* Store the text */
1692                 if (!add_text(&a_ptr->text, head, s)) return (7);
1693         }
1694
1695
1696         /* Process 'I' for "Info" (one line only) */
1697         else if (buf[0] == 'I')
1698         {
1699                 int tval, sval, pval;
1700
1701                 /* Scan for the values */
1702                 if (3 != sscanf(buf+2, "%d:%d:%d",
1703                                 &tval, &sval, &pval)) return (1);
1704
1705                 /* Save the values */
1706                 a_ptr->tval = tval;
1707                 a_ptr->sval = sval;
1708                 a_ptr->pval = pval;
1709         }
1710
1711         /* Process 'W' for "More Info" (one line only) */
1712         else if (buf[0] == 'W')
1713         {
1714                 int level, rarity, wgt;
1715                 long cost;
1716
1717                 /* Scan for the values */
1718                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1719                                 &level, &rarity, &wgt, &cost)) return (1);
1720
1721                 /* Save the values */
1722                 a_ptr->level = level;
1723                 a_ptr->rarity = rarity;
1724                 a_ptr->weight = wgt;
1725                 a_ptr->cost = cost;
1726         }
1727
1728         /* Hack -- Process 'P' for "power" and such */
1729         else if (buf[0] == 'P')
1730         {
1731                 int ac, hd1, hd2, th, td, ta;
1732
1733                 /* Scan for the values */
1734                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
1735                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
1736
1737                 a_ptr->ac = ac;
1738                 a_ptr->dd = hd1;
1739                 a_ptr->ds = hd2;
1740                 a_ptr->to_h = th;
1741                 a_ptr->to_d = td;
1742                 a_ptr->to_a =  ta;
1743         }
1744
1745         /* Hack -- Process 'F' for flags */
1746         else if (buf[0] == 'F')
1747         {
1748                 /* Parse every entry textually */
1749                 for (s = buf + 2; *s; )
1750                 {
1751                                 /* Find the end of this entry */
1752                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1753
1754                                 /* Nuke and skip any dividers */
1755                         if (*t)
1756                         {
1757                                 *t++ = '\0';
1758                                 while ((*t == ' ') || (*t == '|')) t++;
1759                         }
1760
1761                                 /* Parse this entry */
1762                         if (0 != grab_one_artifact_flag(a_ptr, s)) return (5);
1763
1764                                 /* Start the next entry */
1765                         s = t;
1766                 }
1767         }
1768
1769
1770         /* Oops */
1771         else return (6);
1772
1773
1774         /* Success */
1775         return (0);
1776 }
1777
1778
1779 /*
1780  * Grab one flag in a ego-item_type from a textual string
1781  */
1782 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what)
1783 {
1784         int i;
1785
1786         /* Check flags1 */
1787         for (i = 0; i < 32; i++)
1788         {
1789                 if (streq(what, k_info_flags1[i]))
1790                 {
1791                         e_ptr->flags1 |= (1L << i);
1792                         return (0);
1793                 }
1794         }
1795
1796         /* Check flags2 */
1797         for (i = 0; i < 32; i++)
1798         {
1799                 if (streq(what, k_info_flags2[i]))
1800                 {
1801                         e_ptr->flags2 |= (1L << i);
1802                         return (0);
1803                 }
1804         }
1805
1806         /* Check flags3 */
1807         for (i = 0; i < 32; i++)
1808         {
1809                 if (streq(what, k_info_flags3[i]))
1810                 {
1811                         e_ptr->flags3 |= (1L << i);
1812                         return (0);
1813                 }
1814         }
1815         
1816         /* Check gen_flags */
1817         for (i = 0; i < 32; i++)
1818         {
1819                 if (streq(what, k_info_gen_flags[i]))
1820                 {
1821                         e_ptr->gen_flags |= (1L << i);
1822                         return (0);
1823                 }
1824         }
1825
1826 /* Oops */
1827 #ifdef JP
1828         msg_format("̤ÃΤÎ̾¤Î¤¢¤ë¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1829 #else
1830         msg_format("Unknown ego-item flag '%s'.", what);
1831 #endif
1832
1833
1834         /* Error */
1835         return (1);
1836 }
1837
1838
1839
1840
1841 /*
1842  * Initialize the "e_info" array, by parsing an ascii "template" file
1843  */
1844 errr parse_e_info(char *buf, header *head)
1845 {
1846         int i;
1847
1848         char *s, *t;
1849
1850         /* Current entry */
1851         static ego_item_type *e_ptr = NULL;
1852
1853
1854         /* Just before the first record */
1855         error_idx = -1;
1856
1857         /* Just before the first line */
1858         error_line = -1;
1859
1860
1861         /* Process 'N' for "New/Number/Name" */
1862         if (buf[0] == 'N')
1863         {
1864                 /* Find the colon before the name */
1865                 s = strchr(buf+2, ':');
1866
1867                         /* Verify that colon */
1868                 if (!s) return (1);
1869
1870                 /* Nuke the colon, advance to the name */
1871                 *s++ = '\0';
1872 #ifdef JP
1873                 /* Paranoia -- require a name */
1874                 if (!*s) return (1);
1875 #endif
1876                 /* Get the index */
1877                 i = atoi(buf+2);
1878
1879                 /* Verify information */
1880                 if (i < error_idx) return (4);
1881
1882                 /* Verify information */
1883                 if (i >= head->info_num) return (2);
1884
1885                 /* Save the index */
1886                 error_idx = i;
1887
1888                 /* Point at the "info" */
1889                 e_ptr = &e_info[i];
1890 #ifdef JP
1891                 /* Store the name */
1892                 if (!add_name(&e_ptr->name, head, s)) return (7);
1893 #endif
1894         }
1895
1896         /* There better be a current e_ptr */
1897         else if (!e_ptr) return (3);
1898
1899
1900 #ifdef JP
1901         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
1902         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
1903         else if (buf[0] == 'E')
1904         {
1905                 /* nothing to do */
1906         }
1907 #else
1908         else if (buf[0] == 'E')
1909         {
1910                 /* Acquire the Text */
1911                 s = buf+2;
1912
1913                 /* Store the name */
1914                 if (!add_name(&e_ptr->name, head, s)) return (7);
1915         }
1916 #endif
1917 #if 0
1918
1919         /* Process 'D' for "Description" */
1920         else if (buf[0] == 'D')
1921         {
1922                 /* Acquire the text */
1923                 s = buf+2;
1924
1925                 /* Store the text */
1926                 if (!add_text(&e_ptr->text, head, s)) return (7);
1927         }
1928
1929 #endif
1930
1931         /* Process 'X' for "Xtra" (one line only) */
1932         else if (buf[0] == 'X')
1933         {
1934                 int slot, rating;
1935
1936                 /* Scan for the values */
1937                 if (2 != sscanf(buf+2, "%d:%d",
1938                                 &slot, &rating)) return (1);
1939
1940                 /* Save the values */
1941                 e_ptr->slot = slot;
1942                 e_ptr->rating = rating;
1943         }
1944
1945         /* Process 'W' for "More Info" (one line only) */
1946         else if (buf[0] == 'W')
1947         {
1948                 int level, rarity, pad2;
1949                 long cost;
1950
1951                 /* Scan for the values */
1952                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
1953                                 &level, &rarity, &pad2, &cost)) return (1);
1954
1955                 /* Save the values */
1956                 e_ptr->level = level;
1957                 e_ptr->rarity = rarity;
1958                 /* e_ptr->weight = wgt; */
1959                 e_ptr->cost = cost;
1960         }
1961
1962         /* Hack -- Process 'C' for "creation" */
1963         else if (buf[0] == 'C')
1964         {
1965                 int th, td, ta, pv;
1966
1967                 /* Scan for the values */
1968                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1969                                 &th, &td, &ta, &pv)) return (1);
1970
1971                 e_ptr->max_to_h = th;
1972                 e_ptr->max_to_d = td;
1973                 e_ptr->max_to_a = ta;
1974                 e_ptr->max_pval = pv;
1975         }
1976
1977         /* Hack -- Process 'F' for flags */
1978         else if (buf[0] == 'F')
1979         {
1980                 /* Parse every entry textually */
1981                 for (s = buf + 2; *s; )
1982                 {
1983                                 /* Find the end of this entry */
1984                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1985
1986                                 /* Nuke and skip any dividers */
1987                         if (*t)
1988                         {
1989                                 *t++ = '\0';
1990                                 while ((*t == ' ') || (*t == '|')) t++;
1991                         }
1992
1993                                 /* Parse this entry */
1994                         if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5);
1995
1996                                 /* Start the next entry */
1997                         s = t;
1998                 }
1999         }
2000
2001         /* Oops */
2002         else return (6);
2003
2004         /* Success */
2005         return (0);
2006 }
2007
2008
2009 /*
2010  * Grab one (basic) flag in a monster_race from a textual string
2011  */
2012 static errr grab_one_basic_flag(monster_race *r_ptr, cptr what)
2013 {
2014         int i;
2015
2016         /* Scan flags1 */
2017         for (i = 0; i < 32; i++)
2018         {
2019                 if (streq(what, r_info_flags1[i]))
2020                 {
2021                         r_ptr->flags1 |= (1L << i);
2022                         return (0);
2023                 }
2024         }
2025
2026         /* Scan flags2 */
2027         for (i = 0; i < 32; i++)
2028         {
2029                 if (streq(what, r_info_flags2[i]))
2030                 {
2031                         r_ptr->flags2 |= (1L << i);
2032                         return (0);
2033                 }
2034         }
2035
2036         /* Scan flags3 */
2037         for (i = 0; i < 32; i++)
2038         {
2039                 if (streq(what, r_info_flags3[i]))
2040                 {
2041                         r_ptr->flags3 |= (1L << i);
2042                         return (0);
2043                 }
2044         }
2045
2046         /* Scan flags7 */
2047         for (i = 0; i < 32; i++)
2048         {
2049                 if (streq(what, r_info_flags7[i]))
2050                 {
2051                         r_ptr->flags7 |= (1L << i);
2052                         return (0);
2053                 }
2054         }
2055
2056         /* Scan flags8 */
2057         for (i = 0; i < 32; i++)
2058         {
2059                 if (streq(what, r_info_flags8[i]))
2060                 {
2061                         r_ptr->flags8 |= (1L << i);
2062                         return (0);
2063                 }
2064         }
2065
2066         /* Scan flags9 */
2067         for (i = 0; i < 32; i++)
2068         {
2069                 if (streq(what, r_info_flags9[i]))
2070                 {
2071                         r_ptr->flags9 |= (1L << i);
2072                         return (0);
2073                 }
2074         }
2075
2076         /* Oops */
2077 #ifdef JP
2078         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2079 #else
2080         msg_format("Unknown monster flag '%s'.", what);
2081 #endif
2082
2083
2084         /* Failure */
2085         return (1);
2086 }
2087
2088
2089 /*
2090  * Grab one (spell) flag in a monster_race from a textual string
2091  */
2092 static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
2093 {
2094         int i;
2095
2096         /* Scan flags4 */
2097         for (i = 0; i < 32; i++)
2098         {
2099                 if (streq(what, r_info_flags4[i]))
2100                 {
2101                         r_ptr->flags4 |= (1L << i);
2102                         return (0);
2103                 }
2104         }
2105
2106         /* Scan flags5 */
2107         for (i = 0; i < 32; i++)
2108         {
2109                 if (streq(what, r_info_flags5[i]))
2110                 {
2111                         r_ptr->flags5 |= (1L << i);
2112                         return (0);
2113                 }
2114         }
2115
2116         /* Scan flags6 */
2117         for (i = 0; i < 32; i++)
2118         {
2119                 if (streq(what, r_info_flags6[i]))
2120                 {
2121                         r_ptr->flags6 |= (1L << i);
2122                         return (0);
2123                 }
2124         }
2125
2126         /* Oops */
2127 #ifdef JP
2128         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2129 #else
2130         msg_format("Unknown monster flag '%s'.", what);
2131 #endif
2132
2133
2134         /* Failure */
2135         return (1);
2136 }
2137
2138
2139
2140
2141 /*
2142  * Initialize the "r_info" array, by parsing an ascii "template" file
2143  */
2144 errr parse_r_info(char *buf, header *head)
2145 {
2146         int i;
2147
2148         char *s, *t;
2149
2150         /* Current entry */
2151         static monster_race *r_ptr = NULL;
2152
2153
2154         /* Process 'N' for "New/Number/Name" */
2155         if (buf[0] == 'N')
2156         {
2157                 /* Find the colon before the name */
2158                 s = strchr(buf+2, ':');
2159
2160                         /* Verify that colon */
2161                 if (!s) return (1);
2162
2163                 /* Nuke the colon, advance to the name */
2164                 *s++ = '\0';
2165 #ifdef JP
2166                 /* Paranoia -- require a name */
2167                 if (!*s) return (1);
2168 #endif
2169                 /* Get the index */
2170                 i = atoi(buf+2);
2171
2172                 /* Verify information */
2173                 if (i < error_idx) return (4);
2174
2175                 /* Verify information */
2176                 if (i >= head->info_num) return (2);
2177
2178                 /* Save the index */
2179                 error_idx = i;
2180
2181                 /* Point at the "info" */
2182                 r_ptr = &r_info[i];
2183 #ifdef JP
2184                 /* Store the name */
2185                 if (!add_name(&r_ptr->name, head, s)) return (7);
2186 #endif
2187         }
2188
2189         /* There better be a current r_ptr */
2190         else if (!r_ptr) return (3);
2191
2192
2193 #ifdef JP
2194         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2195         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
2196         else if (buf[0] == 'E')
2197         {
2198                 /* Acquire the Text */
2199                 s = buf+2;
2200
2201                 /* Store the name */
2202                 if (!add_name(&r_ptr->E_name, head, s)) return (7);
2203         }
2204 #else
2205         else if (buf[0] == 'E')
2206         {
2207                 /* Acquire the Text */
2208                 s = buf+2;
2209
2210                 /* Store the name */
2211                 if (!add_name(&r_ptr->name, head, s)) return (7);
2212         }
2213 #endif
2214         /* Process 'D' for "Description" */
2215         else if (buf[0] == 'D')
2216         {
2217 #ifdef JP
2218                 if (buf[2] == '$')
2219                         return (0);
2220                 /* Acquire the text */
2221                 s = buf+2;
2222 #else
2223                 if (buf[2] != '$')
2224                         return (0);
2225                 /* Acquire the text */
2226                 s = buf+3;
2227 #endif
2228
2229                 /* Store the text */
2230                 if (!add_text(&r_ptr->text, head, s)) return (7);
2231         }
2232
2233         /* Process 'G' for "Graphics" (one line only) */
2234         else if (buf[0] == 'G')
2235         {
2236                 char sym;
2237                 int tmp;
2238
2239                 /* Paranoia */
2240                 if (!buf[2]) return (1);
2241                 if (!buf[3]) return (1);
2242                 if (!buf[4]) return (1);
2243
2244                 /* Extract the char */
2245                 sym = buf[2];
2246
2247                 /* Extract the attr */
2248                 tmp = color_char_to_attr(buf[4]);
2249
2250                 /* Paranoia */
2251                 if (tmp < 0) return (1);
2252
2253                 /* Save the values */
2254                 r_ptr->d_char = sym;
2255                 r_ptr->d_attr = tmp;
2256         }
2257
2258         /* Process 'I' for "Info" (one line only) */
2259         else if (buf[0] == 'I')
2260         {
2261                 int spd, hp1, hp2, aaf, ac, slp;
2262
2263                 /* Scan for the other values */
2264                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2265                                 &spd, &hp1, &hp2, &aaf, &ac, &slp)) return (1);
2266
2267                 /* Save the values */
2268                 r_ptr->speed = spd;
2269                 r_ptr->hdice = hp1;
2270                 r_ptr->hside = hp2;
2271                 r_ptr->aaf = aaf;
2272                 r_ptr->ac = ac;
2273                 r_ptr->sleep = slp;
2274         }
2275
2276         /* Process 'W' for "More Info" (one line only) */
2277         else if (buf[0] == 'W')
2278         {
2279                 int lev, rar, pad;
2280                 long exp;
2281                 long nextexp;
2282                 int nextmon;
2283
2284                 /* Scan for the values */
2285                 if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d",
2286                                 &lev, &rar, &pad, &exp, &nextexp, &nextmon)) return (1);
2287
2288                 /* Save the values */
2289                 r_ptr->level = lev;
2290                 r_ptr->rarity = rar;
2291                 r_ptr->extra = pad;
2292                 r_ptr->mexp = exp;
2293                 r_ptr->next_exp = nextexp;
2294                 r_ptr->next_r_idx = nextmon;
2295         }
2296
2297         /* Process 'B' for "Blows" (up to four lines) */
2298         else if (buf[0] == 'B')
2299         {
2300                 int n1, n2;
2301
2302                 /* Find the next empty blow slot (if any) */
2303                 for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break;
2304
2305                 /* Oops, no more slots */
2306                 if (i == 4) return (1);
2307
2308                 /* Analyze the first field */
2309                 for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
2310
2311                 /* Terminate the field (if necessary) */
2312                 if (*t == ':') *t++ = '\0';
2313
2314                 /* Analyze the method */
2315                 for (n1 = 0; r_info_blow_method[n1]; n1++)
2316                 {
2317                         if (streq(s, r_info_blow_method[n1])) break;
2318                 }
2319
2320                 /* Invalid method */
2321                 if (!r_info_blow_method[n1]) return (1);
2322
2323                 /* Analyze the second field */
2324                 for (s = t; *t && (*t != ':'); t++) /* loop */;
2325
2326                 /* Terminate the field (if necessary) */
2327                 if (*t == ':') *t++ = '\0';
2328
2329                 /* Analyze effect */
2330                 for (n2 = 0; r_info_blow_effect[n2]; n2++)
2331                 {
2332                         if (streq(s, r_info_blow_effect[n2])) break;
2333                 }
2334
2335                 /* Invalid effect */
2336                 if (!r_info_blow_effect[n2]) return (1);
2337
2338                 /* Analyze the third field */
2339                 for (s = t; *t && (*t != 'd'); t++) /* loop */;
2340
2341                 /* Terminate the field (if necessary) */
2342                 if (*t == 'd') *t++ = '\0';
2343
2344                 /* Save the method */
2345                 r_ptr->blow[i].method = n1;
2346
2347                 /* Save the effect */
2348                 r_ptr->blow[i].effect = n2;
2349
2350                 /* Extract the damage dice and sides */
2351                 r_ptr->blow[i].d_dice = atoi(s);
2352                 r_ptr->blow[i].d_side = atoi(t);
2353         }
2354
2355         /* Process 'F' for "Basic Flags" (multiple lines) */
2356         else if (buf[0] == 'F')
2357         {
2358                 /* Parse every entry */
2359                 for (s = buf + 2; *s; )
2360                 {
2361                                 /* Find the end of this entry */
2362                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2363
2364                                 /* Nuke and skip any dividers */
2365                         if (*t)
2366                         {
2367                                 *t++ = '\0';
2368                                 while (*t == ' ' || *t == '|') t++;
2369                         }
2370
2371                                 /* Parse this entry */
2372                         if (0 != grab_one_basic_flag(r_ptr, s)) return (5);
2373
2374                                 /* Start the next entry */
2375                         s = t;
2376                 }
2377         }
2378
2379         /* Process 'S' for "Spell Flags" (multiple lines) */
2380         else if (buf[0] == 'S')
2381         {
2382                 /* Parse every entry */
2383                 for (s = buf + 2; *s; )
2384                 {
2385                                 /* Find the end of this entry */
2386                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2387
2388                                 /* Nuke and skip any dividers */
2389                         if (*t)
2390                         {
2391                                 *t++ = '\0';
2392                                 while ((*t == ' ') || (*t == '|')) t++;
2393                         }
2394
2395                                 /* XXX XXX XXX Hack -- Read spell frequency */
2396                         if (1 == sscanf(s, "1_IN_%d", &i))
2397                         {
2398                                 /* Extract a "frequency" */
2399                                 r_ptr->freq_spell = r_ptr->freq_inate = 100 / i;
2400
2401                                         /* Start at next entry */
2402                                 s = t;
2403
2404                                 /* Continue */
2405                                 continue;
2406                         }
2407
2408                                 /* Parse this entry */
2409                         if (0 != grab_one_spell_flag(r_ptr, s)) return (5);
2410
2411                                 /* Start the next entry */
2412                         s = t;
2413                 }
2414         }
2415
2416         /* Oops */
2417         else return (6);
2418
2419
2420         /* Success */
2421         return (0);
2422 }
2423
2424
2425 /*
2426  * Grab one flag for a dungeon type from a textual string
2427  */
2428 static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what)
2429 {
2430         int i;
2431
2432         /* Scan flags1 */
2433         for (i = 0; i < 32; i++)
2434         {
2435                 if (streq(what, d_info_flags1[i]))
2436                 {
2437                         d_ptr->flags1 |= (1L << i);
2438                         return (0);
2439                 }
2440         }
2441
2442         /* Oops */
2443 #ifdef JP
2444         msg_format("̤ÃΤΥÀ¥ó¥¸¥ç¥ó¡¦¥Õ¥é¥° '%s'¡£", what);
2445 #else
2446         msg_format("Unknown dungeon type flag '%s'.", what);
2447 #endif
2448
2449         /* Failure */
2450         return (1);
2451 }
2452
2453 /*
2454  * Grab one (basic) flag in a monster_race from a textual string
2455  */
2456 static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what)
2457 {
2458         int i;
2459
2460         /* Scan flags1 */
2461         for (i = 0; i < 32; i++)
2462         {
2463                 if (streq(what, r_info_flags1[i]))
2464                 {
2465                         d_ptr->mflags1 |= (1L << i);
2466                         return (0);
2467                 }
2468         }
2469
2470         /* Scan flags2 */
2471         for (i = 0; i < 32; i++)
2472         {
2473                 if (streq(what, r_info_flags2[i]))
2474                 {
2475                         d_ptr->mflags2 |= (1L << i);
2476                         return (0);
2477                 }
2478         }
2479
2480         /* Scan flags3 */
2481         for (i = 0; i < 32; i++)
2482         {
2483                 if (streq(what, r_info_flags3[i]))
2484                 {
2485                         d_ptr->mflags3 |= (1L << i);
2486                         return (0);
2487                 }
2488         }
2489
2490         /* Scan flags7 */
2491         for (i = 0; i < 32; i++)
2492         {
2493                 if (streq(what, r_info_flags7[i]))
2494                 {
2495                         d_ptr->mflags7 |= (1L << i);
2496                         return (0);
2497                 }
2498         }
2499
2500         /* Scan flags8 */
2501         for (i = 0; i < 32; i++)
2502         {
2503                 if (streq(what, r_info_flags8[i]))
2504                 {
2505                         d_ptr->mflags8 |= (1L << i);
2506                         return (0);
2507                 }
2508         }
2509
2510         /* Scan flags9 */
2511         for (i = 0; i < 32; i++)
2512         {
2513                 if (streq(what, r_info_flags9[i]))
2514                 {
2515                         d_ptr->mflags9 |= (1L << i);
2516                         return (0);
2517                 }
2518         }
2519
2520         /* Oops */
2521 #ifdef JP
2522         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2523 #else
2524         msg_format("Unknown monster flag '%s'.", what);
2525 #endif
2526         /* Failure */
2527         return (1);
2528 }
2529
2530
2531 /*
2532  * Grab one (spell) flag in a monster_race from a textual string
2533  */
2534 static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what)
2535 {
2536         int i;
2537
2538         /* Scan flags4 */
2539         for (i = 0; i < 32; i++)
2540         {
2541                 if (streq(what, r_info_flags4[i]))
2542                 {
2543                         d_ptr->mflags4 |= (1L << i);
2544                         return (0);
2545                 }
2546         }
2547
2548         /* Scan flags5 */
2549         for (i = 0; i < 32; i++)
2550         {
2551                 if (streq(what, r_info_flags5[i]))
2552                 {
2553                         d_ptr->mflags5 |= (1L << i);
2554                         return (0);
2555                 }
2556         }
2557
2558         /* Scan flags6 */
2559         for (i = 0; i < 32; i++)
2560         {
2561                 if (streq(what, r_info_flags6[i]))
2562                 {
2563                         d_ptr->mflags6 |= (1L << i);
2564                         return (0);
2565                 }
2566         }
2567
2568         /* Oops */
2569 #ifdef JP
2570         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2571 #else
2572         msg_format("Unknown monster flag '%s'.", what);
2573 #endif
2574
2575         /* Failure */
2576         return (1);
2577 }
2578
2579 /*
2580  * Initialize the "d_info" array, by parsing an ascii "template" file
2581  */
2582 errr parse_d_info(char *buf, header *head)
2583 {
2584         int i;
2585
2586         char *s, *t;
2587
2588         /* Current entry */
2589         static dungeon_info_type *d_ptr = NULL;
2590
2591
2592         /* Process 'N' for "New/Number/Name" */
2593         if (buf[0] == 'N')
2594         {
2595                 /* Find the colon before the name */
2596                 s = strchr(buf+2, ':');
2597
2598                 /* Verify that colon */
2599                 if (!s) return (1);
2600
2601                 /* Nuke the colon, advance to the name */
2602                 *s++ = '\0';
2603 #ifdef JP
2604                 /* Paranoia -- require a name */
2605                 if (!*s) return (1);
2606 #endif
2607                 /* Get the index */
2608                 i = atoi(buf+2);
2609
2610                 /* Verify information */
2611                 if (i < error_idx) return (4);
2612
2613                 /* Verify information */
2614                 if (i >= head->info_num) return (2);
2615
2616                 /* Save the index */
2617                 error_idx = i;
2618
2619                 /* Point at the "info" */
2620                 d_ptr = &d_info[i];
2621 #ifdef JP
2622                 /* Store the name */
2623                 if (!add_name(&d_ptr->name, head, s)) return (7);
2624 #endif
2625         }
2626
2627 #ifdef JP
2628         else if (buf[0] == 'E') return (0);
2629 #else
2630         else if (buf[0] == 'E')
2631         {
2632                 /* Acquire the Text */
2633                 s = buf+2;
2634
2635                 /* Store the name */
2636                 if (!add_name(&d_ptr->name, head, s)) return (7);
2637         }
2638 #endif
2639
2640         /* Process 'D' for "Description */
2641         else if (buf[0] == 'D')
2642         {
2643 #ifdef JP
2644                 if (buf[2] == '$')
2645                         return (0);
2646                 /* Acquire the text */
2647                 s = buf+2;
2648 #else
2649                 if (buf[2] != '$')
2650                         return (0);
2651                 /* Acquire the text */
2652                 s = buf+3;
2653 #endif
2654
2655                 /* Store the text */
2656                 if (!add_text(&d_ptr->text, head, s)) return (7);
2657         }
2658
2659         /* Process 'W' for "More Info" (one line only) */
2660         else if (buf[0] == 'W')
2661         {
2662                 int min_lev, max_lev;
2663                 int min_plev, mode;
2664                 int min_alloc, max_chance;
2665                 int obj_good, obj_great;
2666                 int pit, nest;
2667
2668                 /* Scan for the values */
2669                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x",
2670                                  &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1);
2671
2672                 /* Save the values */
2673                 d_ptr->mindepth = min_lev;
2674                 d_ptr->maxdepth = max_lev;
2675                 d_ptr->min_plev = min_plev;
2676                 d_ptr->mode = mode;
2677                 d_ptr->min_m_alloc_level = min_alloc;
2678                 d_ptr->max_m_alloc_chance = max_chance;
2679                 d_ptr->obj_good = obj_good;
2680                 d_ptr->obj_great = obj_great;
2681                 d_ptr->pit = pit;
2682                 d_ptr->nest = nest;
2683         }
2684
2685         /* Process 'P' for "Place Info" */
2686         else if (buf[0] == 'P')
2687         {
2688                 int dy, dx;
2689
2690                 /* Scan for the values */
2691                 if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1);
2692
2693                 /* Save the values */
2694                 d_ptr->dy = dy;
2695                 d_ptr->dx = dx;
2696         }
2697
2698         /* Process 'L' for "fLoor type" (one line only) */
2699         else if (buf[0] == 'L')
2700         {
2701                 int f1, f2, f3;
2702                 int p1, p2, p3;
2703                 int tunnel;
2704
2705                 /* Scan for the values */
2706                 if (7 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d",
2707                                 &f1, &p1, &f2, &p2, &f3, &p3, &tunnel)) return (1);
2708
2709                 /* Save the values */
2710                 d_ptr->floor1 = f1;
2711                 d_ptr->floor_percent1 = p1;
2712                 d_ptr->floor2 = f2;
2713                 d_ptr->floor_percent2 = p2;
2714                 d_ptr->floor3 = f3;
2715                 d_ptr->floor_percent3 = p3;
2716                 d_ptr->tunnel_percent = tunnel;
2717         }
2718
2719         /* Process 'A' for "wAll type" (one line only) */
2720         else if (buf[0] == 'A')
2721         {
2722                 int w1, w2, w3, outer, inner, stream1, stream2;
2723                 int p1, p2, p3;
2724
2725                 /* Scan for the values */
2726                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
2727                                  &w1, &p1, &w2, &p2, &w3, &p3, &outer, &inner, &stream1, &stream2)) return (1);
2728
2729                 /* Save the values */
2730                 d_ptr->fill_type1 = w1;
2731                 d_ptr->fill_percent1 = p1;
2732                 d_ptr->fill_type2 = w2;
2733                 d_ptr->fill_percent2 = p2;
2734                 d_ptr->fill_type3 = w3;
2735                 d_ptr->fill_percent3 = p3;
2736                 d_ptr->outer_wall = outer;
2737                 d_ptr->inner_wall = inner;
2738                 d_ptr->stream1 = stream1;
2739                 d_ptr->stream2 = stream2;
2740         }
2741
2742         /* Process 'F' for "Dungeon Flags" (multiple lines) */
2743         else if (buf[0] == 'F')
2744         {
2745                 int artif = 0, monst = 0;
2746
2747                 /* Parse every entry */
2748                 for (s = buf + 2; *s; )
2749                 {
2750                                 /* Find the end of this entry */
2751                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2752
2753                                 /* Nuke and skip any dividers */
2754                         if (*t)
2755                         {
2756                                 *t++ = '\0';
2757                                 while (*t == ' ' || *t == '|') t++;
2758                         }
2759
2760                                 /* XXX XXX XXX Hack -- Read Final Artifact */
2761                         if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif))
2762                         {
2763                                 /* Extract a "Final Artifact" */
2764                                 d_ptr->final_artifact = artif;
2765
2766                                 /* Start at next entry */
2767                                 s = t;
2768
2769                                 /* Continue */
2770                                 continue;
2771                         }
2772
2773                                 /* XXX XXX XXX Hack -- Read Final Object */
2774                         if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif))
2775                         {
2776                                 /* Extract a "Final Artifact" */
2777                                 d_ptr->final_object = artif;
2778
2779                                 /* Start at next entry */
2780                                 s = t;
2781
2782                                 /* Continue */
2783                                 continue;
2784                         }
2785
2786                                 /* XXX XXX XXX Hack -- Read Artifact Guardian */
2787                         if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst))
2788                         {
2789                                 /* Extract a "Artifact Guardian" */
2790                                 d_ptr->final_guardian = monst;
2791
2792                                 /* Start at next entry */
2793                                 s = t;
2794
2795                                 /* Continue */
2796                                 continue;
2797                         }
2798
2799                                 /* XXX XXX XXX Hack -- Read Special Percentage */
2800                         if (1 == sscanf(s, "MONSTER_DIV_%d", &monst))
2801                         {
2802                                 /* Extract a "Special %" */
2803                                 d_ptr->special_div = monst;
2804
2805                                 /* Start at next entry */
2806                                 s = t;
2807
2808                                 /* Continue */
2809                                 continue;
2810                         }
2811
2812                                 /* Parse this entry */
2813                         if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5);
2814
2815                                 /* Start the next entry */
2816                         s = t;
2817                 }
2818         }
2819
2820         /* Process 'M' for "Basic Flags" (multiple lines) */
2821         else if (buf[0] == 'M')
2822         {
2823                 byte r_char_number = 0, r_char;
2824
2825                 /* Parse every entry */
2826                 for (s = buf + 2; *s; )
2827                 {
2828                                 /* Find the end of this entry */
2829                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2830
2831                                 /* Nuke and skip any dividers */
2832                         if (*t)
2833                         {
2834                                 *t++ = '\0';
2835                                 while (*t == ' ' || *t == '|') t++;
2836                         }
2837
2838                                 /* XXX XXX XXX Hack -- Read monster symbols */
2839                         if (1 == sscanf(s, "R_CHAR_%c", &r_char))
2840                         {
2841                                 /* Limited to 5 races */
2842                                 if(r_char_number >= 5) continue;
2843
2844                                 /* Extract a "frequency" */
2845                                 d_ptr->r_char[r_char_number++] = r_char;
2846
2847                                 /* Start at next entry */
2848                                 s = t;
2849
2850                                 /* Continue */
2851                                 continue;
2852                         }
2853
2854                                 /* Parse this entry */
2855                         if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5);
2856
2857                                 /* Start the next entry */
2858                         s = t;
2859                 }
2860         }
2861
2862         /* Process 'S' for "Spell Flags" (multiple lines) */
2863         else if (buf[0] == 'S')
2864         {
2865                 /* Parse every entry */
2866                 for (s = buf + 2; *s; )
2867                 {
2868                                 /* Find the end of this entry */
2869                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2870
2871                                 /* Nuke and skip any dividers */
2872                         if (*t)
2873                         {
2874                                 *t++ = '\0';
2875                                 while ((*t == ' ') || (*t == '|')) t++;
2876                         }
2877
2878                                 /* XXX XXX XXX Hack -- Read spell frequency */
2879                         if (1 == sscanf(s, "1_IN_%d", &i))
2880                         {
2881                                 /* Start at next entry */
2882                                 s = t;
2883
2884                                         /* Continue */
2885                                 continue;
2886                         }
2887
2888                                 /* Parse this entry */
2889                         if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5);
2890
2891                                 /* Start the next entry */
2892                         s = t;
2893                 }
2894         }
2895
2896         /* Oops */
2897         else return (6);
2898
2899         /* Success */
2900         return (0);
2901 }
2902
2903
2904 #else   /* ALLOW_TEMPLATES */
2905
2906 #ifdef MACINTOSH
2907 static int i = 0;
2908 #endif
2909
2910 #endif  /* ALLOW_TEMPLATES */
2911
2912
2913 /* Random dungeon grid effects */
2914 #define RANDOM_NONE         0x00
2915 #define RANDOM_FEATURE      0x01
2916 #define RANDOM_MONSTER      0x02
2917 #define RANDOM_OBJECT       0x04
2918 #define RANDOM_EGO          0x08
2919 #define RANDOM_ARTIFACT     0x10
2920 #define RANDOM_TRAP         0x20
2921
2922
2923 typedef struct dungeon_grid dungeon_grid;
2924
2925 struct dungeon_grid
2926 {
2927         int             feature;                /* Terrain feature */
2928         int             monster;                /* Monster */
2929         int             object;                 /* Object */
2930         int             ego;                    /* Ego-Item */
2931         int             artifact;               /* Artifact */
2932         int             trap;                   /* Trap */
2933         int             cave_info;              /* Flags for CAVE_MARK, CAVE_GLOW, CAVE_ICKY, CAVE_ROOM */
2934         int             special;                /* Reserved for special terrain info */
2935         int             random;                 /* Number of the random effect */
2936 };
2937
2938
2939 static dungeon_grid letter[255];
2940
2941
2942 /*
2943  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
2944  */
2945 static errr parse_line_feature(char *buf)
2946 {
2947         int num;
2948         char *zz[9];
2949
2950
2951         if (init_flags & INIT_ONLY_BUILDINGS) return (0);
2952
2953         /* Tokenize the line */
2954         if ((num = tokenize(buf+2, 9, zz, 0)) > 1)
2955         {
2956                 /* Letter to assign */
2957                 int index = zz[0][0];
2958
2959                 /* Reset the info for the letter */
2960                 letter[index].feature = 0;
2961                 letter[index].monster = 0;
2962                 letter[index].object = 0;
2963                 letter[index].ego = 0;
2964                 letter[index].artifact = 0;
2965                 letter[index].trap = 0;
2966                 letter[index].cave_info = 0;
2967                 letter[index].special = 0;
2968                 letter[index].random = 0;
2969
2970                 switch (num)
2971                 {
2972                         /* Special */
2973                         case 9:
2974                                 letter[index].special = atoi(zz[8]);
2975                                 /* Fall through */
2976                         /* Trap */
2977                         case 8:
2978                                 if (zz[7][0] == '*')
2979                                 {
2980                                         letter[index].random |= RANDOM_TRAP;
2981
2982                                         if (zz[7][1])
2983                                         {
2984                                                 zz[7]++;
2985                                                 letter[index].trap = atoi(zz[7]);
2986                                         }
2987                                 }
2988                                 else
2989                                 {
2990                                         letter[index].trap = atoi(zz[7]);
2991                                 }
2992                                 /* Fall through */
2993                         /* Artifact */
2994                         case 7:
2995                                 if (zz[6][0] == '*')
2996                                 {
2997                                         letter[index].random |= RANDOM_ARTIFACT;
2998
2999                                         if (zz[6][1])
3000                                         {
3001                                                 zz[6]++;
3002                                                 letter[index].artifact = atoi(zz[6]);
3003                                         }
3004                                 }
3005                                 else
3006                                 {
3007                                         letter[index].artifact = atoi(zz[6]);
3008                                 }
3009                                 /* Fall through */
3010                         /* Ego-item */
3011                         case 6:
3012                                 if (zz[5][0] == '*')
3013                                 {
3014                                         letter[index].random |= RANDOM_EGO;
3015
3016                                         if (zz[5][1])
3017                                         {
3018                                                 zz[5]++;
3019                                                 letter[index].ego = atoi(zz[5]);
3020                                         }
3021                                 }
3022                                 else
3023                                 {
3024                                         letter[index].ego = atoi(zz[5]);
3025                                 }
3026                                 /* Fall through */
3027                         /* Object */
3028                         case 5:
3029                                 if (zz[4][0] == '*')
3030                                 {
3031                                         letter[index].random |= RANDOM_OBJECT;
3032
3033                                         if (zz[4][1])
3034                                         {
3035                                                 zz[4]++;
3036                                                 letter[index].object = atoi(zz[4]);
3037                                         }
3038                                 }
3039                                 else
3040                                 {
3041                                         letter[index].object = atoi(zz[4]);
3042                                 }
3043                                 /* Fall through */
3044                         /* Monster */
3045                         case 4:
3046                                 if (zz[3][0] == '*')
3047                                 {
3048                                         letter[index].random |= RANDOM_MONSTER;
3049                                         if (zz[3][1])
3050                                         {
3051                                                 zz[3]++;
3052                                                 letter[index].monster = atoi(zz[3]);
3053                                         }
3054                                 }
3055                                 else if (zz[3][0] == 'c')
3056                                 {
3057                                         letter[index].monster = - atoi(zz[3]+1);
3058                                 }
3059                                 else
3060                                 {
3061                                         letter[index].monster = atoi(zz[3]);
3062                                 }
3063                                 /* Fall through */
3064                         /* Cave info */
3065                         case 3:
3066                                 letter[index].cave_info = atoi(zz[2]);
3067                                 /* Fall through */
3068                         /* Feature */
3069                         case 2:
3070                                 if (zz[1][0] == '*')
3071                                 {
3072                                         letter[index].random |= RANDOM_FEATURE;
3073                                         if (zz[1][1])
3074                                         {
3075                                                 zz[1]++;
3076                                                 letter[index].feature = atoi(zz[1]);
3077                                         }
3078                                 }
3079                                 else
3080                                 {
3081                                         letter[index].feature = atoi(zz[1]);
3082                                 }
3083                                 break;
3084                 }
3085
3086                 return (0);
3087         }
3088
3089         return (1);
3090 }
3091
3092
3093 /*
3094  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3095  */
3096 static errr parse_line_building(char *buf)
3097 {
3098         int i;
3099         char *zz[37];
3100         int index;
3101         char *s;
3102
3103 #ifdef JP
3104         if (buf[2] == '$')
3105                 return 0;
3106         s = buf + 2;
3107 #else
3108         if (buf[2] != '$')
3109                 return 0;
3110         s = buf + 3;
3111 #endif
3112         /* Get the building number */
3113         index = atoi(s);
3114
3115         /* Find the colon after the building number */
3116         s = strchr(s, ':');
3117
3118         /* Verify that colon */
3119         if (!s) return (1);
3120
3121         /* Nuke the colon, advance to the sub-index */
3122         *s++ = '\0';
3123
3124         /* Paranoia -- require a sub-index */
3125         if (!*s) return (1);
3126
3127         /* Building definition sub-index */
3128         switch (s[0])
3129         {
3130                 /* Building name, owner, race */
3131                 case 'N':
3132                 {
3133                         if (tokenize(s + 2, 3, zz, 0) == 3)
3134                         {
3135                                 /* Name of the building */
3136                                 strcpy(building[index].name, zz[0]);
3137
3138                                 /* Name of the owner */
3139                                 strcpy(building[index].owner_name, zz[1]);
3140
3141                                 /* Race of the owner */
3142                                 strcpy(building[index].owner_race, zz[2]);
3143
3144                                 break;
3145                         }
3146
3147                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3148                 }
3149
3150                 /* Building Action */
3151                 case 'A':
3152                 {
3153                         if (tokenize(s + 2, 8, zz, 0) >= 7)
3154                         {
3155                                 /* Index of the action */
3156                                 int action_index = atoi(zz[0]);
3157
3158                                 /* Name of the action */
3159                                 strcpy(building[index].act_names[action_index], zz[1]);
3160
3161                                 /* Cost of the action for members */
3162                                 building[index].member_costs[action_index] = atoi(zz[2]);
3163
3164                                 /* Cost of the action for non-members */
3165                                 building[index].other_costs[action_index] = atoi(zz[3]);
3166
3167                                 /* Letter assigned to the action */
3168                                 building[index].letters[action_index] = zz[4][0];
3169
3170                                 /* Action code */
3171                                 building[index].actions[action_index] = atoi(zz[5]);
3172
3173                                 /* Action restriction */
3174                                 building[index].action_restr[action_index] = atoi(zz[6]);
3175
3176                                 break;
3177                         }
3178
3179                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3180                 }
3181
3182                 /* Building Classes */
3183                 case 'C':
3184                 {
3185                         if (tokenize(s + 2, MAX_CLASS, zz, 0) == MAX_CLASS)
3186                         {
3187                                 for (i = 0; i < MAX_CLASS; i++)
3188                                 {
3189                                         building[index].member_class[i] = atoi(zz[i]);
3190                                 }
3191
3192                                 break;
3193                         }
3194
3195                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3196                 }
3197
3198                 /* Building Races */
3199                 case 'R':
3200                 {
3201                         if (tokenize(s+2, MAX_RACES, zz, 0) == MAX_RACES)
3202                         {
3203                                 for (i = 0; i < MAX_RACES; i++)
3204                                 {
3205                                         building[index].member_race[i] = atoi(zz[i]);
3206                                 }
3207
3208                                 break;
3209                         }
3210
3211                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3212                 }
3213
3214                 /* Building Realms */
3215                 case 'M':
3216                 {
3217                         if (tokenize(s+2, MAX_MAGIC, zz, 0) == MAX_MAGIC)
3218                         {
3219                                 for (i = 0; i < MAX_MAGIC; i++)
3220                                 {
3221                                         building[index].member_realm[i+1] = atoi(zz[i]);
3222                                 }
3223
3224                                 break;
3225                         }
3226
3227                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3228                 }
3229
3230                 case 'Z':
3231                 {
3232                         /* Ignore scripts */
3233                         break;
3234                 }
3235
3236                 default:
3237                 {
3238                         return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
3239                 }
3240         }
3241
3242         return (0);
3243 }
3244
3245
3246 /*
3247  * Parse a sub-file of the "extra info"
3248  */
3249 static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
3250 {
3251         int i;
3252
3253         char *zz[33];
3254
3255
3256         /* Skip "empty" lines */
3257         if (!buf[0]) return (0);
3258
3259         /* Skip "blank" lines */
3260         if (isspace(buf[0])) return (0);
3261
3262         /* Skip comments */
3263         if (buf[0] == '#') return (0);
3264
3265         /* Require "?:*" format */
3266         if (buf[1] != ':') return (1);
3267
3268
3269         /* Process "%:<fname>" */
3270         if (buf[0] == '%')
3271         {
3272                 /* Attempt to Process the given file */
3273                 return (process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax));
3274         }
3275
3276         /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
3277         if (buf[0] == 'F')
3278         {
3279                 return parse_line_feature(buf);
3280         }
3281
3282         /* Process "D:<dungeon>" -- info for the cave grids */
3283         else if (buf[0] == 'D')
3284         {
3285                 object_type object_type_body;
3286
3287                 /* Acquire the text */
3288                 char *s = buf + 2;
3289
3290                 /* Length of the text */
3291                 int len = strlen(s);
3292
3293                 if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3294
3295                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
3296                 {
3297                         /* Access the grid */
3298                         cave_type *c_ptr = &cave[*y][*x];
3299
3300                         int idx = s[0];
3301
3302                         int object_index = letter[idx].object;
3303                         int monster_index = letter[idx].monster;
3304                         int random = letter[idx].random;
3305                         int artifact_index = letter[idx].artifact;
3306
3307                         /* Lay down a floor */
3308                         c_ptr->feat = letter[idx].feature;
3309
3310                         /* Only the features */
3311                         if (init_flags & INIT_ONLY_FEATURES) continue;
3312
3313                         /* Cave info */
3314                         c_ptr->info = letter[idx].cave_info;
3315
3316                         /* Create a monster */
3317                         if (random & RANDOM_MONSTER)
3318                         {
3319                                 monster_level = base_level + monster_index;
3320
3321                                 place_monster(*y, *x, TRUE, TRUE);
3322
3323                                 monster_level = base_level;
3324                         }
3325                         else if (monster_index)
3326                         {
3327                                 int old_cur_num, old_max_num;
3328                                 bool clone = FALSE;
3329
3330                                 if (monster_index < 0)
3331                                 {
3332                                         monster_index = -monster_index;
3333                                         clone = TRUE;
3334                                 }
3335                                 old_cur_num = r_info[monster_index].cur_num;
3336                                 old_max_num = r_info[monster_index].max_num;
3337
3338                                 /* Make alive again */
3339                                 if (r_info[monster_index].flags1 & RF1_UNIQUE)
3340                                 {
3341                                         r_info[monster_index].cur_num = 0;
3342                                         r_info[monster_index].max_num = 1;
3343                                 }
3344
3345                                 /* Make alive again */
3346                                 if (r_info[monster_index].flags7 & RF7_UNIQUE_7)
3347                                 {
3348                                         if (r_info[monster_index].cur_num == r_info[monster_index].max_num)
3349                                         {
3350                                                 r_info[monster_index].max_num++;
3351                                         }
3352                                 }
3353
3354                                 /* Place it */
3355                                 place_monster_aux(*y, *x, monster_index, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE);
3356                                 if (clone)
3357                                 {
3358                                         /* clone */
3359                                         m_list[hack_m_idx_ii].smart |= SM_CLONED;
3360
3361                                         /* Make alive again for real unique monster */
3362                                         r_info[monster_index].cur_num = old_cur_num;
3363                                         r_info[monster_index].max_num = old_max_num;
3364                                 }
3365                         }
3366
3367                         /* Object (and possible trap) */
3368                         if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP))
3369                         {
3370                                 object_level = base_level + object_index;
3371
3372                                 /*
3373                                  * Random trap and random treasure defined
3374                                  * 25% chance for trap and 75% chance for object
3375                                  */
3376                                 if (randint0(100) < 75)
3377                                 {
3378                                         place_object(*y, *x, FALSE, FALSE);
3379                                 }
3380                                 else
3381                                 {
3382                                         place_trap(*y, *x);
3383                                 }
3384
3385                                 object_level = base_level;
3386                         }
3387                         else if (random & RANDOM_OBJECT)
3388                         {
3389                                 object_level = base_level + object_index;
3390
3391                                 /* Create an out of deep object */
3392                                 if (randint0(100) < 75)
3393                                         place_object(*y, *x, FALSE, FALSE);
3394                                 else if (randint0(100) < 80)
3395                                         place_object(*y, *x, TRUE, FALSE);
3396                                 else
3397                                         place_object(*y, *x, TRUE, TRUE);
3398
3399                                 object_level = base_level;
3400                         }
3401                         /* Random trap */
3402                         else if (random & RANDOM_TRAP)
3403                         {
3404                                 place_trap(*y, *x);
3405                         }
3406                         else if (object_index)
3407                         {
3408                                 /* Get local object */
3409                                 object_type *o_ptr = &object_type_body;
3410
3411                                 /* Create the item */
3412                                 object_prep(o_ptr, object_index);
3413
3414                                 if (o_ptr->tval == TV_GOLD)
3415                                 {
3416                                         coin_type = object_index - OBJ_GOLD_LIST;
3417                                         make_gold(o_ptr);
3418                                         coin_type = 0;
3419                                 }
3420
3421                                 /* Apply magic (no messages, no artifacts) */
3422                                 apply_magic(o_ptr, base_level, FALSE, TRUE, FALSE, FALSE);
3423
3424                                 (void)drop_near(o_ptr, -1, *y, *x);
3425                         }
3426
3427                         /* Artifact */
3428                         if (artifact_index)
3429                         {
3430                                 if (a_info[artifact_index].cur_num)
3431                                 {
3432                                         int k_idx = 198;
3433                                         object_type forge;
3434                                         object_type *q_ptr = &forge;
3435
3436                                         object_prep(q_ptr, k_idx);
3437
3438                                         /* Drop it in the dungeon */
3439                                         (void)drop_near(q_ptr, -1, *y, *x);
3440                                 }
3441                                 else
3442                                 {
3443                                         /* Create the artifact */
3444                                         create_named_art(artifact_index, *y, *x);
3445
3446                                         a_info[artifact_index].cur_num = 1;
3447                                 }
3448                         }
3449
3450                         /* Terrain special */
3451                         c_ptr->special = letter[idx].special;
3452                 }
3453
3454                 (*y)++;
3455
3456                 return (0);
3457         }
3458
3459         /* Process "Q:<number>:<command>:... -- quest info */
3460         else if (buf[0] == 'Q')
3461         {
3462                 int num;
3463                 quest_type *q_ptr;
3464 #ifdef JP
3465                 if (buf[2] == '$')
3466                         return 0;
3467                 num = tokenize(buf + 2, 33, zz, 0);
3468 #else
3469                 if (buf[2] != '$')
3470                         return 0;
3471                 num = tokenize(buf + 3, 33, zz, 0);
3472 #endif
3473
3474                 /* Have we enough parameters? */
3475                 if (num < 3) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3476
3477                 /* Get the quest */
3478                 q_ptr = &(quest[atoi(zz[0])]);
3479
3480                 /* Process "Q:<q_index>:Q:<type>:<num_mon>:<cur_num>:<max_num>:<level>:<r_idx>:<k_idx>:<flags>" -- quest info */
3481                 if (zz[1][0] == 'Q')
3482                 {
3483                         if (init_flags & INIT_ASSIGN)
3484                         {
3485                                 monster_race *r_ptr;
3486                                 artifact_type *a_ptr;
3487
3488                                 if (num < 9) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3489
3490                                 q_ptr->type    = atoi(zz[2]);
3491                                 q_ptr->num_mon = atoi(zz[3]);
3492                                 q_ptr->cur_num = atoi(zz[4]);
3493                                 q_ptr->max_num = atoi(zz[5]);
3494                                 q_ptr->level   = atoi(zz[6]);
3495                                 q_ptr->r_idx   = atoi(zz[7]);
3496                                 q_ptr->k_idx   = atoi(zz[8]);
3497                                 q_ptr->dungeon = atoi(zz[9]);
3498
3499                                 if (num > 10)
3500                                         q_ptr->flags  = atoi(zz[10]);
3501
3502                                 r_ptr = &r_info[q_ptr->r_idx];
3503                                 if (r_ptr->flags1 & RF1_UNIQUE)
3504                                         r_ptr->flags1 |= RF1_QUESTOR;
3505
3506                                 a_ptr = &a_info[q_ptr->k_idx];
3507                                 a_ptr->gen_flags |= TRG_QUESTITEM;
3508                         }
3509                         return (0);
3510                 }
3511
3512                 /* Process "Q:<q_index>:N:<name>" -- quest name */
3513                 else if (zz[1][0] == 'N')
3514                 {
3515                         if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT))
3516                         {
3517                                 strcpy(q_ptr->name, zz[2]);
3518                         }
3519
3520                         return (0);
3521                 }
3522
3523                 /* Process "Q:<q_index>:T:<text>" -- quest description line */
3524                 else if (zz[1][0] == 'T')
3525                 {
3526                         if (init_flags & INIT_SHOW_TEXT)
3527                         {
3528                                 strcpy(quest_text[quest_text_line], zz[2]);
3529                                 quest_text_line++;
3530                         }
3531
3532                         return (0);
3533                 }
3534         }
3535
3536         /* Process "W:<command>: ..." -- info for the wilderness */
3537         else if (buf[0] == 'W')
3538         {
3539                 return parse_line_wilderness(buf, ymin, xmin, ymax, xmax, y, x);
3540         }
3541
3542         /* Process "P:<y>:<x>" -- player position */
3543         else if (buf[0] == 'P')
3544         {
3545                 if (init_flags & INIT_CREATE_DUNGEON)
3546                 {
3547                         if (tokenize(buf + 2, 2, zz, 0) == 2)
3548                         {
3549                                 int panels_x, panels_y;
3550
3551                                 /* Hack - Set the dungeon size */
3552                                 panels_y = (*y / SCREEN_HGT);
3553                                 if (*y % SCREEN_HGT) panels_y++;
3554                                 cur_hgt = panels_y * SCREEN_HGT;
3555
3556                                 panels_x = (*x / SCREEN_WID);
3557                                 if (*x % SCREEN_WID) panels_x++;
3558                                 cur_wid = panels_x * SCREEN_WID;
3559
3560                                 /* Assume illegal panel */
3561                                 panel_row_min = cur_hgt;
3562                                 panel_col_min = cur_wid;
3563
3564                                 /* Place player in a quest level */
3565                                 if (p_ptr->inside_quest)
3566                                 {
3567                                         int y, x;
3568
3569                                         /* Delete the monster (if any) */
3570                                         delete_monster(py, px);
3571
3572                                         y = atoi(zz[0]);
3573                                         x = atoi(zz[1]);
3574
3575                                         py = y;
3576                                         px = x;
3577                                 }
3578                                 /* Place player in the town */
3579                                 else if (!p_ptr->oldpx && !p_ptr->oldpy)
3580                                 {
3581                                         p_ptr->oldpy = atoi(zz[0]);
3582                                         p_ptr->oldpx = atoi(zz[1]);
3583                                 }
3584                         }
3585                 }
3586
3587                 return (0);
3588         }
3589
3590         /* Process "B:<Index>:<Command>:..." -- Building definition */
3591         else if (buf[0] == 'B')
3592         {
3593                 return parse_line_building(buf);
3594         }
3595
3596         /* Process "M:<type>:<maximum>" -- set maximum values */
3597         else if (buf[0] == 'M')
3598         {
3599                 if (tokenize(buf+2, 2, zz, 0) == 2)
3600                 {
3601                         /* Maximum towns */
3602                         if (zz[0][0] == 'T')
3603                         {
3604                                 max_towns = atoi(zz[1]);
3605                         }
3606
3607                         /* Maximum quests */
3608                         else if (zz[0][0] == 'Q')
3609                         {
3610                                 max_quests = atoi(zz[1]);
3611                         }
3612
3613                         /* Maximum r_idx */
3614                         else if (zz[0][0] == 'R')
3615                         {
3616                                 max_r_idx = atoi(zz[1]);
3617                         }
3618
3619                         /* Maximum k_idx */
3620                         else if (zz[0][0] == 'K')
3621                         {
3622                                 max_k_idx = atoi(zz[1]);
3623                         }
3624
3625                         /* Maximum v_idx */
3626                         else if (zz[0][0] == 'V')
3627                         {
3628                                 max_v_idx = atoi(zz[1]);
3629                         }
3630
3631                         /* Maximum f_idx */
3632                         else if (zz[0][0] == 'F')
3633                         {
3634                                 max_f_idx = atoi(zz[1]);
3635                         }
3636
3637                         /* Maximum a_idx */
3638                         else if (zz[0][0] == 'A')
3639                         {
3640                                 max_a_idx = atoi(zz[1]);
3641                         }
3642
3643                         /* Maximum e_idx */
3644                         else if (zz[0][0] == 'E')
3645                         {
3646                                 max_e_idx = atoi(zz[1]);
3647                         }
3648
3649                         /* Maximum d_idx */
3650                         else if (zz[0][0] == 'D')
3651                         {
3652                                 max_d_idx = atoi(zz[1]); 
3653                         }
3654
3655                         /* Maximum o_idx */
3656                         else if (zz[0][0] == 'O')
3657                         {
3658                                 max_o_idx = atoi(zz[1]);
3659                         }
3660
3661                         /* Maximum m_idx */
3662                         else if (zz[0][0] == 'M')
3663                         {
3664                                 max_m_idx = atoi(zz[1]);
3665                         }
3666
3667                         /* Wilderness size */
3668                         else if (zz[0][0] == 'W')
3669                         {
3670                                 /* Maximum wild_x_size */
3671                                 if (zz[0][1] == 'X')
3672                                         max_wild_x = atoi(zz[1]);
3673                                 /* Maximum wild_y_size */
3674                                 if (zz[0][1] == 'Y')
3675                                         max_wild_y = atoi(zz[1]);
3676                         }
3677
3678                         return (0);
3679                 }
3680         }
3681
3682
3683         /* Failure */
3684         return (1);
3685 }
3686
3687
3688 static char tmp[8];
3689 static cptr variant = "ZANGBAND";
3690
3691
3692 /*
3693  * Helper function for "process_dungeon_file()"
3694  */
3695 static cptr process_dungeon_file_expr(char **sp, char *fp)
3696 {
3697         cptr v;
3698
3699         char *b;
3700         char *s;
3701
3702         char b1 = '[';
3703         char b2 = ']';
3704
3705         char f = ' ';
3706
3707         /* Initial */
3708         s = (*sp);
3709
3710         /* Skip spaces */
3711         while (isspace(*s)) s++;
3712
3713         /* Save start */
3714         b = s;
3715
3716         /* Default */
3717         v = "?o?o?";
3718
3719         /* Analyze */
3720         if (*s == b1)
3721         {
3722                 const char *p;
3723                 const char *t;
3724
3725                 /* Skip b1 */
3726                 s++;
3727
3728                 /* First */
3729                 t = process_dungeon_file_expr(&s, &f);
3730
3731                 /* Oops */
3732                 if (!*t)
3733                 {
3734                         /* Nothing */
3735                 }
3736
3737                 /* Function: IOR */
3738                 else if (streq(t, "IOR"))
3739                 {
3740                         v = "0";
3741                         while (*s && (f != b2))
3742                         {
3743                                 t = process_dungeon_file_expr(&s, &f);
3744                                 if (*t && !streq(t, "0")) v = "1";
3745                         }
3746                 }
3747
3748                 /* Function: AND */
3749                 else if (streq(t, "AND"))
3750                 {
3751                         v = "1";
3752                         while (*s && (f != b2))
3753                         {
3754                                 t = process_dungeon_file_expr(&s, &f);
3755                                 if (*t && streq(t, "0")) v = "0";
3756                         }
3757                 }
3758
3759                 /* Function: NOT */
3760                 else if (streq(t, "NOT"))
3761                 {
3762                         v = "1";
3763                         while (*s && (f != b2))
3764                         {
3765                                 t = process_dungeon_file_expr(&s, &f);
3766                                 if (*t && streq(t, "1")) v = "0";
3767                         }
3768                 }
3769
3770                 /* Function: EQU */
3771                 else if (streq(t, "EQU"))
3772                 {
3773                         v = "1";
3774                         if (*s && (f != b2))
3775                         {
3776                                 t = process_dungeon_file_expr(&s, &f);
3777                         }
3778                         while (*s && (f != b2))
3779                         {
3780                                 p = t;
3781                                 t = process_dungeon_file_expr(&s, &f);
3782                                 if (*t && !streq(p, t)) v = "0";
3783                         }
3784                 }
3785
3786                 /* Function: LEQ */
3787                 else if (streq(t, "LEQ"))
3788                 {
3789                         v = "1";
3790                         if (*s && (f != b2))
3791                         {
3792                                 t = process_dungeon_file_expr(&s, &f);
3793                         }
3794                         while (*s && (f != b2))
3795                         {
3796                                 p = t;
3797                                 t = process_dungeon_file_expr(&s, &f);
3798                                 if (*t && (strcmp(p, t) > 0)) v = "0";
3799                         }
3800                 }
3801
3802                 /* Function: GEQ */
3803                 else if (streq(t, "GEQ"))
3804                 {
3805                         v = "1";
3806                         if (*s && (f != b2))
3807                         {
3808                                 t = process_dungeon_file_expr(&s, &f);
3809                         }
3810                         while (*s && (f != b2))
3811                         {
3812                                 p = t;
3813                                 t = process_dungeon_file_expr(&s, &f);
3814                                 if (*t && (strcmp(p, t) < 0)) v = "0";
3815                         }
3816                 }
3817
3818                 /* Oops */
3819                 else
3820                 {
3821                         while (*s && (f != b2))
3822                         {
3823                                 t = process_dungeon_file_expr(&s, &f);
3824                         }
3825                 }
3826
3827                 /* Verify ending */
3828                 if (f != b2) v = "?x?x?";
3829
3830                 /* Extract final and Terminate */
3831                 if ((f = *s) != '\0') *s++ = '\0';
3832         }
3833
3834         /* Other */
3835         else
3836         {
3837                 /* Accept all printables except spaces and brackets */
3838                 while (isprint(*s) && !strchr(" []", *s)) ++s;
3839
3840                 /* Extract final and Terminate */
3841                 if ((f = *s) != '\0') *s++ = '\0';
3842
3843                 /* Variable */
3844                 if (*b == '$')
3845                 {
3846                         /* System */
3847                         if (streq(b+1, "SYS"))
3848                         {
3849                                 v = ANGBAND_SYS;
3850                         }
3851
3852                         /* Graphics */
3853                         else if (streq(b+1, "GRAF"))
3854                         {
3855                                 v = ANGBAND_GRAF;
3856                         }
3857
3858                         else if (streq(b+1, "MONOCHROME"))
3859                         {
3860                                 if (arg_monochrome)
3861                                         v = "ON";
3862                                 else
3863                                         v = "OFF";
3864                         }
3865
3866                         /* Race */
3867                         else if (streq(b+1, "RACE"))
3868                         {
3869 #ifdef JP
3870                                 v = rp_ptr->E_title;
3871 #else
3872                                 v = rp_ptr->title;
3873 #endif
3874                         }
3875
3876                         /* Class */
3877                         else if (streq(b+1, "CLASS"))
3878                         {
3879 #ifdef JP
3880                                 v = cp_ptr->E_title;
3881 #else
3882                                 v = cp_ptr->title;
3883 #endif
3884                         }
3885
3886                         /* First realm */
3887                         else if (streq(b+1, "REALM1"))
3888                         {
3889 #ifdef JP
3890                                 v = E_realm_names[p_ptr->realm1];
3891 #else
3892                                 v = realm_names[p_ptr->realm1];
3893 #endif
3894                         }
3895
3896                         /* Second realm */
3897                         else if (streq(b+1, "REALM2"))
3898                         {
3899 #ifdef JP
3900                                 v = E_realm_names[p_ptr->realm2];
3901 #else
3902                                 v = realm_names[p_ptr->realm2];
3903 #endif
3904                         }
3905
3906                         /* Player name */
3907                         else if (streq(b+1, "PLAYER"))
3908                         {
3909                                 v = player_base;
3910                         }
3911
3912                         /* Town */
3913                         else if (streq(b+1, "TOWN"))
3914                         {
3915                                 sprintf(tmp, "%d", p_ptr->town_num);
3916                                 v = tmp;
3917                         }
3918
3919                         /* Level */
3920                         else if (streq(b+1, "LEVEL"))
3921                         {
3922                                 sprintf(tmp, "%d", p_ptr->lev);
3923                                 v = tmp;
3924                         }
3925
3926                         /* Current quest number */
3927                         else if (streq(b+1, "QUEST_NUMBER"))
3928                         {
3929                                 sprintf(tmp, "%d", p_ptr->inside_quest);
3930                                 v = tmp;
3931                         }
3932
3933                         /* Number of last quest */
3934                         else if (streq(b+1, "LEAVING_QUEST"))
3935                         {
3936                                 sprintf(tmp, "%d", leaving_quest);
3937                                 v = tmp;
3938                         }
3939
3940                         /* Quest status */
3941                         else if (prefix(b+1, "QUEST"))
3942                         {
3943                                 /* "QUEST" uses a special parameter to determine the number of the quest */
3944                                 sprintf(tmp, "%d", quest[atoi(b+6)].status);
3945                                 v = tmp;
3946                         }
3947
3948                         /* Random */
3949                         else if (prefix(b+1, "RANDOM"))
3950                         {
3951                                 /* "RANDOM" uses a special parameter to determine the number of the quest */
3952                                 sprintf(tmp, "%d", (int)(seed_town%atoi(b+7)));
3953                                 v = tmp;
3954                         }
3955
3956                         /* Variant name */
3957                         else if (streq(b+1, "VARIANT"))
3958                         {
3959                                 v = variant;
3960                         }
3961
3962                         /* Wilderness */
3963                         else if (streq(b+1, "WILDERNESS"))
3964                         {
3965                                 if (vanilla_town)
3966                                         sprintf(tmp, "NONE");
3967                                 else if (lite_town)
3968                                         sprintf(tmp, "LITE");
3969                                 else
3970                                         sprintf(tmp, "NORMAL");
3971                                 v = tmp;
3972                         }
3973                 }
3974
3975                 /* Constant */
3976                 else
3977                 {
3978                         v = b;
3979                 }
3980         }
3981
3982         /* Save */
3983         (*fp) = f;
3984
3985         /* Save */
3986         (*sp) = s;
3987
3988         /* Result */
3989         return (v);
3990 }
3991
3992
3993 errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax)
3994 {
3995         FILE *fp;
3996
3997         char buf[1024];
3998
3999         int num = -1;
4000
4001         errr err = 0;
4002
4003         bool bypass = FALSE;
4004
4005         int x = xmin, y = ymin;
4006
4007
4008         /* Build the filename */
4009         path_build(buf, 1024, ANGBAND_DIR_EDIT, name);
4010
4011         /* Open the file */
4012         fp = my_fopen(buf, "r");
4013
4014         /* No such file */
4015         if (!fp) return (-1);
4016
4017
4018         /* Process the file */
4019         while (0 == my_fgets(fp, buf, 1024))
4020         {
4021                 /* Count lines */
4022                 num++;
4023
4024
4025                 /* Skip "empty" lines */
4026                 if (!buf[0]) continue;
4027
4028                 /* Skip "blank" lines */
4029                 if (isspace(buf[0])) continue;
4030
4031                 /* Skip comments */
4032                 if (buf[0] == '#') continue;
4033
4034
4035                 /* Process "?:<expr>" */
4036                 if ((buf[0] == '?') && (buf[1] == ':'))
4037                 {
4038                         char f;
4039                         cptr v;
4040                         char *s;
4041
4042                         /* Start */
4043                         s = buf + 2;
4044
4045                         /* Parse the expr */
4046                         v = process_dungeon_file_expr(&s, &f);
4047
4048                         /* Set flag */
4049                         bypass = (streq(v, "0") ? TRUE : FALSE);
4050
4051                         /* Continue */
4052                         continue;
4053                 }
4054
4055                 /* Apply conditionals */
4056                 if (bypass) continue;
4057
4058
4059                 /* Process "%:<file>" */
4060                 if (buf[0] == '%')
4061                 {
4062                         /* Process that file if allowed */
4063                         (void)process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax);
4064
4065                         /* Continue */
4066                         continue;
4067                 }
4068
4069
4070                 /* Process the line */
4071                 err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x);
4072
4073                 /* Oops */
4074                 if (err) break;
4075         }
4076
4077         /* Errors */
4078         if (err)
4079         {
4080                 cptr oops;
4081
4082                 /* Error string */
4083                 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
4084
4085                 /* Oops */
4086                 msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
4087 #ifdef JP
4088 msg_format("'%s'¤ò²òÀÏÃæ¡£", buf);
4089 #else
4090                 msg_format("Parsing '%s'.", buf);
4091 #endif
4092
4093                 msg_print(NULL);
4094         }
4095
4096
4097         /* Close the file */
4098         my_fclose(fp);
4099
4100         /* Result */
4101         return (err);
4102 }
4103
4104
4105
4106 #if 0
4107 void write_r_info_txt(void)
4108 {
4109         int i, j, z, fc, bc;
4110         int dlen;
4111
4112         cptr flags[288];
4113
4114         u32b f_ptr[9];
4115         cptr *n_ptr[9];
4116
4117         monster_race *r_ptr;
4118
4119         monster_blow *b_ptr;
4120
4121         FILE *fff = fopen("output.txt", "wt");
4122
4123         cptr desc;
4124
4125         int mode = -1;
4126
4127         if (!fff) return;
4128
4129         fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");
4130
4131         fprintf(fff, "# Version stamp (required)\n\n");
4132
4133         /* Write Version */
4134         fprintf(fff, "V:%d.%d.%d\n\n\n", r_head->v_major, r_head->v_minor, r_head->v_patch);
4135
4136         /* Write a note */
4137         fprintf(fff, "##### The Player #####\n\n");
4138
4139         for (z = -1; z < alloc_race_size; z++)
4140         {
4141                 /* Output the monsters in order */
4142                 i = (z >= 0) ? alloc_race_table[z].index : 0;
4143
4144                 /* Acquire the monster */
4145                 r_ptr = &r_info[i];
4146
4147                 /* Ignore empty monsters */
4148                 if (!strlen(r_name + r_ptr->name)) continue;
4149
4150                 /* Ignore useless monsters */
4151                 if (i && !r_ptr->speed) continue;
4152
4153                 /* Write a note if necessary */
4154                 if (i && (!r_ptr->level != !mode))
4155                 {
4156                         /* Note the town */
4157                         if (!r_ptr->level)
4158                         {
4159                                 fprintf(fff, "\n##### Town monsters #####\n\n");
4160                         }
4161                         /* Note the dungeon */
4162                         else
4163                         {
4164                                 fprintf(fff, "\n##### Normal monsters #####\n\n");
4165                         }
4166
4167                         /* Record the change */
4168                         mode = r_ptr->level;
4169                 }
4170
4171                 /* Acquire the flags */
4172                 f_ptr[0] = r_ptr->flags1; n_ptr[0] = r_info_flags1;
4173                 f_ptr[1] = r_ptr->flags2; n_ptr[1] = r_info_flags2;
4174                 f_ptr[2] = r_ptr->flags3; n_ptr[2] = r_info_flags3;
4175                 f_ptr[3] = r_ptr->flags4; n_ptr[3] = r_info_flags4;
4176                 f_ptr[4] = r_ptr->flags5; n_ptr[4] = r_info_flags5;
4177                 f_ptr[5] = r_ptr->flags6; n_ptr[5] = r_info_flags6;
4178                 f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7;
4179                 f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8;
4180                 f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9;
4181
4182                 /* Write New/Number/Name */
4183                 fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name);
4184
4185                 /* Write Graphic */
4186                 fprintf(fff, "G:%c:%c\n", r_ptr->d_char, color_char[r_ptr->d_attr]);
4187
4188                 /* Write Information */
4189                 fprintf(fff, "I:%d:%dd%d:%d:%d:%d\n", r_ptr->speed, r_ptr->hdice, r_ptr->hside,
4190                                                                                                                   r_ptr->aaf, r_ptr->ac, r_ptr->sleep);
4191
4192                 /* Write more information */
4193                 fprintf(fff, "W:%d:%d:%d:%ld\n", r_ptr->level, r_ptr->rarity, r_ptr->extra, r_ptr->mexp);
4194
4195                 /* Write Blows */
4196                 for(j = 0; j < 4; j++)
4197                 {
4198                         b_ptr = &(r_ptr->blow[j]);
4199
4200                         /* Stop when done */
4201                         if (!b_ptr->method) break;
4202
4203                         /* Write the blows */
4204                         fprintf(fff, "B:%s:%s:%dd%d\n", r_info_blow_method[b_ptr->method],
4205                                                                                                           r_info_blow_effect[b_ptr->effect],
4206                                                                                                           b_ptr->d_dice, b_ptr->d_side);
4207                 }
4208
4209                 /* Extract the flags */
4210                 for (fc = 0, j = 0; j < 96; j++)
4211                 {
4212                         /* Check this flag */
4213                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4214                 }
4215
4216                 /* Extract the extra flags */
4217                 for (j = 192; j < 288; j++)
4218                 {
4219                         /* Check this flag */
4220                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4221                 }
4222
4223                 /* Write the flags */
4224                 for (j = 0; j < fc;)
4225                 {
4226                         char buf[160];
4227
4228                         /* Start the line */
4229                         sprintf(buf, "F:");
4230
4231                         for (bc = 0; (bc < 60) && (j < fc); j++)
4232                         {
4233                                 char t[80];
4234
4235                                 /* Format the flag */
4236                                 sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4237
4238                                 /* Add it to the buffer */
4239                                 strcat(buf, t);
4240
4241                                 /* Note the length */
4242                                 bc += strlen(t);
4243                         }
4244
4245                         /* Done with this line; write it */
4246                         fprintf(fff, "%s\n", buf);
4247                 }
4248
4249                 /* Write Spells if applicable */
4250                 if (r_ptr->freq_spell)
4251                 {
4252                         /* Write the frequency */
4253                         fprintf(fff, "S:1_IN_%d | \n", 100 / r_ptr->freq_spell);
4254
4255                         /* Extract the spell flags */
4256                         for (fc = 0, j = 96; j < 192; j++)
4257                         {
4258                                 /* Check this flag */
4259                                 if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4260                         }
4261
4262                         /* Write the flags */
4263                         for (j = 0; j < fc;)
4264                         {
4265                                 char buf[160], *t;
4266
4267                                 /* Start the line */
4268                                 sprintf(buf, "S:");
4269
4270                                 for (bc = 0, t = buf + 2; (bc < 60) && (j < fc); j++)
4271                                 {
4272                                         int tlen;
4273
4274                                         /* Format the flag */
4275                                         sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4276
4277                                         tlen = strlen(t);
4278
4279                                         /* Note the length */
4280                                         bc += tlen;
4281
4282                                         /* Advance */
4283                                         t += tlen;
4284                                 }
4285
4286                                 /* Done with this line; write it */
4287                                 fprintf(fff, "%s\n", buf);
4288                         }
4289                 }
4290
4291                 /* Acquire the description */
4292                 desc = r_text + r_ptr->text;
4293                 dlen = strlen(desc);
4294
4295                 /* Write Description */
4296                 for (j = 0; j < dlen;)
4297                 {
4298                         char buf[160], *t;
4299
4300                         /* Start the line */
4301                         sprintf(buf, "D:");
4302
4303                         for (bc = 0, t = buf + 2; ((bc < 60) || !isspace(desc[j])) && (j < dlen); j++, bc++, t++)
4304                         {
4305                                 *t = desc[j];
4306                         }
4307
4308                         /* Terminate it */
4309                         *t = '\0';
4310
4311                         /* Done with this line; write it */
4312                         fprintf(fff, "%s\n", buf);
4313                 }
4314
4315                 /* Space between entries */
4316                 fprintf(fff, "\n");
4317         }
4318
4319         /* Done */
4320         fclose(fff);
4321 }
4322
4323 #endif