OSDN Git Service

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