OSDN Git Service

fake_{text,name}_sizeの変数をわざわざ使わずに、FAKE_{NAME,TEXT}_SIZEの定数を直接使うようにした。
[hengband/hengband.git] / src / init1.c
1 /* File: init1.c */
2
3 /* Purpose: Initialization (part 1) -BEN- */
4
5 #include "angband.h"
6
7
8 #ifdef JP
9 #undef strchr
10 char* _strchr(char* ptr, char ch)
11 {
12   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
2993                                 {
2994                                         letter[index].monster = atoi(zz[3]);
2995                                 }
2996                                 /* Fall through */
2997                         /* Cave info */
2998                         case 3:
2999                                 letter[index].cave_info = atoi(zz[2]);
3000                                 /* Fall through */
3001                         /* Feature */
3002                         case 2:
3003                                 if (zz[1][0] == '*')
3004                                 {
3005                                         letter[index].random |= RANDOM_FEATURE;
3006                                         if (zz[1][1])
3007                                         {
3008                                                 zz[1]++;
3009                                                 letter[index].feature = atoi(zz[1]);
3010                                         }
3011                                 }
3012                                 else
3013                                 {
3014                                         letter[index].feature = atoi(zz[1]);
3015                                 }
3016                                 break;
3017                 }
3018
3019                 return (0);
3020         }
3021
3022         return (1);
3023 }
3024
3025
3026 /*
3027  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3028  */
3029 static errr parse_line_building(char *buf)
3030 {
3031         int i;
3032         char *zz[37];
3033         int index;
3034         char *s;
3035
3036 #ifdef JP
3037         if (buf[2] == '$')
3038                 return 0;
3039         s = buf + 2;
3040 #else
3041         if (buf[2] != '$')
3042                 return 0;
3043         s = buf + 3;
3044 #endif
3045         /* Get the building number */
3046         index = atoi(s);
3047
3048         /* Find the colon after the building number */
3049         s = strchr(s, ':');
3050
3051         /* Verify that colon */
3052         if (!s) return (1);
3053
3054         /* Nuke the colon, advance to the sub-index */
3055         *s++ = '\0';
3056
3057         /* Paranoia -- require a sub-index */
3058         if (!*s) return (1);
3059
3060         /* Building definition sub-index */
3061         switch (s[0])
3062         {
3063                 /* Building name, owner, race */
3064                 case 'N':
3065                 {
3066                         if (tokenize(s + 2, 3, zz, 0) == 3)
3067                         {
3068                                 /* Name of the building */
3069                                 strcpy(building[index].name, zz[0]);
3070
3071                                 /* Name of the owner */
3072                                 strcpy(building[index].owner_name, zz[1]);
3073
3074                                 /* Race of the owner */
3075                                 strcpy(building[index].owner_race, zz[2]);
3076
3077                                 break;
3078                         }
3079
3080                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3081                 }
3082
3083                 /* Building Action */
3084                 case 'A':
3085                 {
3086                         if (tokenize(s + 2, 8, zz, 0) >= 7)
3087                         {
3088                                 /* Index of the action */
3089                                 int action_index = atoi(zz[0]);
3090
3091                                 /* Name of the action */
3092                                 strcpy(building[index].act_names[action_index], zz[1]);
3093
3094                                 /* Cost of the action for members */
3095                                 building[index].member_costs[action_index] = atoi(zz[2]);
3096
3097                                 /* Cost of the action for non-members */
3098                                 building[index].other_costs[action_index] = atoi(zz[3]);
3099
3100                                 /* Letter assigned to the action */
3101                                 building[index].letters[action_index] = zz[4][0];
3102
3103                                 /* Action code */
3104                                 building[index].actions[action_index] = atoi(zz[5]);
3105
3106                                 /* Action restriction */
3107                                 building[index].action_restr[action_index] = atoi(zz[6]);
3108
3109                                 break;
3110                         }
3111
3112                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3113                 }
3114
3115                 /* Building Classes */
3116                 case 'C':
3117                 {
3118                         if (tokenize(s + 2, MAX_CLASS, zz, 0) == MAX_CLASS)
3119                         {
3120                                 for (i = 0; i < MAX_CLASS; i++)
3121                                 {
3122                                         building[index].member_class[i] = atoi(zz[i]);
3123                                 }
3124
3125                                 break;
3126                         }
3127
3128                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3129                 }
3130
3131                 /* Building Races */
3132                 case 'R':
3133                 {
3134                         if (tokenize(s+2, MAX_RACES, zz, 0) == MAX_RACES)
3135                         {
3136                                 for (i = 0; i < MAX_RACES; i++)
3137                                 {
3138                                         building[index].member_race[i] = atoi(zz[i]);
3139                                 }
3140
3141                                 break;
3142                         }
3143
3144                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3145                 }
3146
3147                 /* Building Realms */
3148                 case 'M':
3149                 {
3150                         if (tokenize(s+2, MAX_MAGIC, zz, 0) == MAX_MAGIC)
3151                         {
3152                                 for (i = 0; i < MAX_MAGIC; i++)
3153                                 {
3154                                         building[index].member_realm[i+1] = atoi(zz[i]);
3155                                 }
3156
3157                                 break;
3158                         }
3159
3160                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3161                 }
3162
3163                 case 'Z':
3164                 {
3165 #ifdef USE_SCRIPT
3166                         if (tokenize(s+2, 2, zz, 0) == 2)
3167                         {
3168                                 /* Index of the action */
3169                                 int action_index = atoi(zz[0]);
3170
3171                                 /* Name of the action */
3172                                 strcpy(building[index].act_script[action_index], zz[1]);
3173
3174                                 break;
3175                         }
3176                         return (1);
3177 #else /* USE_SCRIPT */
3178                         /* Ignore scripts */
3179                         break;
3180 #endif /* USE_SCRIPT */
3181                 }
3182
3183                 default:
3184                 {
3185                         return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
3186                 }
3187         }
3188
3189         return (0);
3190 }
3191
3192
3193 /*
3194  * Parse a sub-file of the "extra info"
3195  */
3196 static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
3197 {
3198         int i;
3199
3200         char *zz[33];
3201
3202
3203         /* Skip "empty" lines */
3204         if (!buf[0]) return (0);
3205
3206         /* Skip "blank" lines */
3207         if (isspace(buf[0])) return (0);
3208
3209         /* Skip comments */
3210         if (buf[0] == '#') return (0);
3211
3212         /* Require "?:*" format */
3213         if (buf[1] != ':') return (1);
3214
3215
3216         /* Process "%:<fname>" */
3217         if (buf[0] == '%')
3218         {
3219                 /* Attempt to Process the given file */
3220                 return (process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax));
3221         }
3222
3223         /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
3224         if (buf[0] == 'F')
3225         {
3226                 return parse_line_feature(buf);
3227         }
3228
3229         /* Process "D:<dungeon>" -- info for the cave grids */
3230         else if (buf[0] == 'D')
3231         {
3232                 object_type object_type_body;
3233
3234                 /* Acquire the text */
3235                 char *s = buf + 2;
3236
3237                 /* Length of the text */
3238                 int len = strlen(s);
3239
3240                 if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3241
3242                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
3243                 {
3244                         /* Access the grid */
3245                         cave_type *c_ptr = &cave[*y][*x];
3246
3247                         int idx = s[0];
3248
3249                         int object_index = letter[idx].object;
3250                         int monster_index = letter[idx].monster;
3251                         int random = letter[idx].random;
3252                         int artifact_index = letter[idx].artifact;
3253
3254                         /* Lay down a floor */
3255                         c_ptr->feat = letter[idx].feature;
3256
3257                         /* Only the features */
3258                         if (init_flags & INIT_ONLY_FEATURES) continue;
3259
3260                         /* Cave info */
3261                         c_ptr->info = letter[idx].cave_info;
3262
3263                         /* Create a monster */
3264                         if (random & RANDOM_MONSTER)
3265                         {
3266                                 monster_level = base_level + monster_index;
3267
3268                                 place_monster(*y, *x, TRUE, TRUE);
3269
3270                                 monster_level = base_level;
3271                         }
3272                         else if (monster_index)
3273                         {
3274                                 /* Make alive again */
3275                                 if (r_info[monster_index].flags1 & RF1_UNIQUE)
3276                                 {
3277                                         r_info[monster_index].cur_num = 0;
3278                                         r_info[monster_index].max_num = 1;
3279                                 }
3280
3281                                 /* Make alive again */
3282                                 if (r_info[monster_index].flags7 & RF7_UNIQUE_7)
3283                                 {
3284                                         if (r_info[monster_index].cur_num == r_info[monster_index].max_num)
3285                                         {
3286                                                 r_info[monster_index].max_num++;
3287                                         }
3288                                 }
3289
3290                                 /* Place it */
3291                                 place_monster_aux(*y, *x, monster_index, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE);
3292                         }
3293
3294                         /* Object (and possible trap) */
3295                         if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP))
3296                         {
3297                                 object_level = base_level + object_index;
3298
3299                                 /*
3300                                  * Random trap and random treasure defined
3301                                  * 25% chance for trap and 75% chance for object
3302                                  */
3303                                 if (rand_int(100) < 75)
3304                                 {
3305                                         place_object(*y, *x, FALSE, FALSE);
3306                                 }
3307                                 else
3308                                 {
3309                                         place_trap(*y, *x);
3310                                 }
3311
3312                                 object_level = base_level;
3313                         }
3314                         else if (random & RANDOM_OBJECT)
3315                         {
3316                                 object_level = base_level + object_index;
3317
3318                                 /* Create an out of deep object */
3319                                 if (rand_int(100) < 75)
3320                                         place_object(*y, *x, FALSE, FALSE);
3321                                 else if (rand_int(100) < 80)
3322                                         place_object(*y, *x, TRUE, FALSE);
3323                                 else
3324                                         place_object(*y, *x, TRUE, TRUE);
3325
3326                                 object_level = base_level;
3327                         }
3328                         /* Random trap */
3329                         else if (random & RANDOM_TRAP)
3330                         {
3331                                 place_trap(*y, *x);
3332                         }
3333                         else if (object_index)
3334                         {
3335                                 /* Get local object */
3336                                 object_type *o_ptr = &object_type_body;
3337
3338                                 /* Create the item */
3339                                 object_prep(o_ptr, object_index);
3340
3341                                 if (o_ptr->tval == TV_GOLD)
3342                                 {
3343                                         coin_type = object_index - OBJ_GOLD_LIST;
3344                                         make_gold(o_ptr);
3345                                         coin_type = 0;
3346                                 }
3347
3348                                 /* Apply magic (no messages, no artifacts) */
3349                                 apply_magic(o_ptr, base_level, FALSE, TRUE, FALSE, FALSE);
3350
3351 #ifdef USE_SCRIPT
3352                                 o_ptr->python = object_create_callback(o_ptr);
3353 #endif /* USE_SCRIPT */
3354
3355                                 (void)drop_near(o_ptr, -1, *y, *x);
3356                         }
3357
3358                         /* Artifact */
3359                         if (artifact_index)
3360                         {
3361                                 if (a_info[artifact_index].cur_num)
3362                                 {
3363                                         s16b k_idx = 198;
3364                                         object_type forge;
3365                                         object_type *q_ptr = &forge;
3366
3367                                         object_prep(q_ptr, k_idx);
3368 #ifdef USE_SCRIPT
3369                                         q_ptr->python = object_create_callback(q_ptr);
3370 #endif /* USE_SCRIPT */
3371
3372                                         /* Drop it in the dungeon */
3373                                         (void)drop_near(q_ptr, -1, *y, *x);
3374                                 }
3375                                 else
3376                                 {
3377                                         /* Create the artifact */
3378                                         create_named_art(artifact_index, *y, *x);
3379
3380                                         a_info[artifact_index].cur_num = 1;
3381                                 }
3382                         }
3383
3384                         /* Terrain special */
3385                         c_ptr->special = letter[idx].special;
3386                 }
3387
3388                 (*y)++;
3389
3390                 return (0);
3391         }
3392
3393         /* Process "Q:<number>:<command>:... -- quest info */
3394         else if (buf[0] == 'Q')
3395         {
3396                 int num;
3397                 quest_type *q_ptr;
3398 #ifdef JP
3399                 if (buf[2] == '$')
3400                         return 0;
3401                 num = tokenize(buf + 2, 33, zz, 0);
3402 #else
3403                 if (buf[2] != '$')
3404                         return 0;
3405                 num = tokenize(buf + 3, 33, zz, 0);
3406 #endif
3407
3408                 /* Have we enough parameters? */
3409                 if (num < 3) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3410
3411                 /* Get the quest */
3412                 q_ptr = &(quest[atoi(zz[0])]);
3413
3414                 /* Process "Q:<q_index>:Q:<type>:<num_mon>:<cur_num>:<max_num>:<level>:<r_idx>:<k_idx>:<flags>" -- quest info */
3415                 if (zz[1][0] == 'Q')
3416                 {
3417                         if (init_flags & INIT_ASSIGN)
3418                         {
3419                                 monster_race *r_ptr;
3420                                 artifact_type *a_ptr;
3421
3422                                 if (num < 9) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3423
3424                                 q_ptr->type    = atoi(zz[2]);
3425                                 q_ptr->num_mon = atoi(zz[3]);
3426                                 q_ptr->cur_num = atoi(zz[4]);
3427                                 q_ptr->max_num = atoi(zz[5]);
3428                                 q_ptr->level   = atoi(zz[6]);
3429                                 q_ptr->r_idx   = atoi(zz[7]);
3430                                 q_ptr->k_idx   = atoi(zz[8]);
3431                                 q_ptr->dungeon = atoi(zz[9]);
3432
3433                                 if (num > 10)
3434                                         q_ptr->flags  = atoi(zz[10]);
3435
3436                                 r_ptr = &r_info[q_ptr->r_idx];
3437                                 if (r_ptr->flags1 & RF1_UNIQUE)
3438                                         r_ptr->flags1 |= RF1_QUESTOR;
3439
3440                                 a_ptr = &a_info[q_ptr->k_idx];
3441                                 a_ptr->flags3 |= TR3_QUESTITEM;
3442                         }
3443                         return (0);
3444                 }
3445
3446                 /* Process "Q:<q_index>:N:<name>" -- quest name */
3447                 else if (zz[1][0] == 'N')
3448                 {
3449                         if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT))
3450                         {
3451                                 strcpy(q_ptr->name, zz[2]);
3452                         }
3453
3454                         return (0);
3455                 }
3456
3457                 /* Process "Q:<q_index>:T:<text>" -- quest description line */
3458                 else if (zz[1][0] == 'T')
3459                 {
3460                         if (init_flags & INIT_SHOW_TEXT)
3461                         {
3462                                 strcpy(quest_text[quest_text_line], zz[2]);
3463                                 quest_text_line++;
3464                         }
3465
3466                         return (0);
3467                 }
3468         }
3469
3470         /* Process "W:<command>: ..." -- info for the wilderness */
3471         else if (buf[0] == 'W')
3472         {
3473                 return parse_line_wilderness(buf, ymin, xmin, ymax, xmax, y, x);
3474         }
3475
3476         /* Process "P:<y>:<x>" -- player position */
3477         else if (buf[0] == 'P')
3478         {
3479                 if (init_flags & INIT_CREATE_DUNGEON)
3480                 {
3481                         if (tokenize(buf + 2, 2, zz, 0) == 2)
3482                         {
3483                                 int panels_x, panels_y;
3484
3485                                 /* Hack - Set the dungeon size */
3486                                 panels_y = (*y / SCREEN_HGT);
3487                                 if (*y % SCREEN_HGT) panels_y++;
3488                                 cur_hgt = panels_y * SCREEN_HGT;
3489
3490                                 panels_x = (*x / SCREEN_WID);
3491                                 if (*x % SCREEN_WID) panels_x++;
3492                                 cur_wid = panels_x * SCREEN_WID;
3493
3494                                 /* Choose a panel row */
3495                                 max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
3496                                 if (max_panel_rows < 0) max_panel_rows = 0;
3497
3498                                 /* Choose a panel col */
3499                                 max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;
3500                                 if (max_panel_cols < 0) max_panel_cols = 0;
3501
3502                                 /* Assume illegal panel */
3503                                 panel_row = max_panel_rows;
3504                                 panel_col = max_panel_cols;
3505
3506                                 /* Place player in a quest level */
3507                                 if (p_ptr->inside_quest)
3508                                 {
3509                                         int y, x;
3510
3511                                         /* Delete the monster (if any) */
3512                                         delete_monster(py, px);
3513
3514                                         y = atoi(zz[0]);
3515                                         x = atoi(zz[1]);
3516
3517                                         py = y;
3518                                         px = x;
3519                                 }
3520                                 /* Place player in the town */
3521                                 else if (!p_ptr->oldpx && !p_ptr->oldpy)
3522                                 {
3523                                         p_ptr->oldpy = atoi(zz[0]);
3524                                         p_ptr->oldpx = atoi(zz[1]);
3525                                 }
3526                         }
3527                 }
3528
3529                 return (0);
3530         }
3531
3532         /* Process "B:<Index>:<Command>:..." -- Building definition */
3533         else if (buf[0] == 'B')
3534         {
3535                 return parse_line_building(buf);
3536         }
3537
3538         /* Process "M:<type>:<maximum>" -- set maximum values */
3539         else if (buf[0] == 'M')
3540         {
3541                 if (tokenize(buf+2, 2, zz, 0) == 2)
3542                 {
3543                         /* Maximum towns */
3544                         if (zz[0][0] == 'T')
3545                         {
3546                                 max_towns = atoi(zz[1]);
3547                         }
3548
3549                         /* Maximum quests */
3550                         else if (zz[0][0] == 'Q')
3551                         {
3552                                 max_quests = atoi(zz[1]);
3553                         }
3554
3555                         /* Maximum r_idx */
3556                         else if (zz[0][0] == 'R')
3557                         {
3558                                 max_r_idx = atoi(zz[1]);
3559                         }
3560
3561                         /* Maximum k_idx */
3562                         else if (zz[0][0] == 'K')
3563                         {
3564                                 max_k_idx = atoi(zz[1]);
3565                         }
3566
3567                         /* Maximum v_idx */
3568                         else if (zz[0][0] == 'V')
3569                         {
3570                                 max_v_idx = atoi(zz[1]);
3571                         }
3572
3573                         /* Maximum f_idx */
3574                         else if (zz[0][0] == 'F')
3575                         {
3576                                 max_f_idx = atoi(zz[1]);
3577                         }
3578
3579                         /* Maximum a_idx */
3580                         else if (zz[0][0] == 'A')
3581                         {
3582                                 max_a_idx = atoi(zz[1]);
3583                         }
3584
3585                         /* Maximum e_idx */
3586                         else if (zz[0][0] == 'E')
3587                         {
3588                                 max_e_idx = atoi(zz[1]);
3589                         }
3590
3591                         /* Maximum d_idx */
3592                         else if (zz[0][0] == 'D')
3593                         {
3594                                 max_d_idx = atoi(zz[1]); 
3595                         }
3596
3597                         /* Maximum o_idx */
3598                         else if (zz[0][0] == 'O')
3599                         {
3600                                 max_o_idx = atoi(zz[1]);
3601                         }
3602
3603                         /* Maximum m_idx */
3604                         else if (zz[0][0] == 'M')
3605                         {
3606                                 max_m_idx = atoi(zz[1]);
3607                         }
3608
3609                         /* Wilderness size */
3610                         else if (zz[0][0] == 'W')
3611                         {
3612                                 /* Maximum wild_x_size */
3613                                 if (zz[0][1] == 'X')
3614                                         max_wild_x = atoi(zz[1]);
3615                                 /* Maximum wild_y_size */
3616                                 if (zz[0][1] == 'Y')
3617                                         max_wild_y = atoi(zz[1]);
3618                         }
3619
3620                         return (0);
3621                 }
3622         }
3623
3624
3625         /* Failure */
3626         return (1);
3627 }
3628
3629
3630 static char tmp[8];
3631 static cptr variant = "ZANGBAND";
3632
3633
3634 /*
3635  * Helper function for "process_dungeon_file()"
3636  */
3637 static cptr process_dungeon_file_expr(char **sp, char *fp)
3638 {
3639         cptr v;
3640
3641         char *b;
3642         char *s;
3643
3644         char b1 = '[';
3645         char b2 = ']';
3646
3647         char f = ' ';
3648
3649         /* Initial */
3650         s = (*sp);
3651
3652         /* Skip spaces */
3653         while (isspace(*s)) s++;
3654
3655         /* Save start */
3656         b = s;
3657
3658         /* Default */
3659         v = "?o?o?";
3660
3661         /* Analyze */
3662         if (*s == b1)
3663         {
3664                 const char *p;
3665                 const char *t;
3666
3667                 /* Skip b1 */
3668                 s++;
3669
3670                 /* First */
3671                 t = process_dungeon_file_expr(&s, &f);
3672
3673                 /* Oops */
3674                 if (!*t)
3675                 {
3676                         /* Nothing */
3677                 }
3678
3679                 /* Function: IOR */
3680                 else if (streq(t, "IOR"))
3681                 {
3682                         v = "0";
3683                         while (*s && (f != b2))
3684                         {
3685                                 t = process_dungeon_file_expr(&s, &f);
3686                                 if (*t && !streq(t, "0")) v = "1";
3687                         }
3688                 }
3689
3690                 /* Function: AND */
3691                 else if (streq(t, "AND"))
3692                 {
3693                         v = "1";
3694                         while (*s && (f != b2))
3695                         {
3696                                 t = process_dungeon_file_expr(&s, &f);
3697                                 if (*t && streq(t, "0")) v = "0";
3698                         }
3699                 }
3700
3701                 /* Function: NOT */
3702                 else if (streq(t, "NOT"))
3703                 {
3704                         v = "1";
3705                         while (*s && (f != b2))
3706                         {
3707                                 t = process_dungeon_file_expr(&s, &f);
3708                                 if (*t && streq(t, "1")) v = "0";
3709                         }
3710                 }
3711
3712                 /* Function: EQU */
3713                 else if (streq(t, "EQU"))
3714                 {
3715                         v = "1";
3716                         if (*s && (f != b2))
3717                         {
3718                                 t = process_dungeon_file_expr(&s, &f);
3719                         }
3720                         while (*s && (f != b2))
3721                         {
3722                                 p = t;
3723                                 t = process_dungeon_file_expr(&s, &f);
3724                                 if (*t && !streq(p, t)) v = "0";
3725                         }
3726                 }
3727
3728                 /* Function: LEQ */
3729                 else if (streq(t, "LEQ"))
3730                 {
3731                         v = "1";
3732                         if (*s && (f != b2))
3733                         {
3734                                 t = process_dungeon_file_expr(&s, &f);
3735                         }
3736                         while (*s && (f != b2))
3737                         {
3738                                 p = t;
3739                                 t = process_dungeon_file_expr(&s, &f);
3740                                 if (*t && (strcmp(p, t) > 0)) v = "0";
3741                         }
3742                 }
3743
3744                 /* Function: GEQ */
3745                 else if (streq(t, "GEQ"))
3746                 {
3747                         v = "1";
3748                         if (*s && (f != b2))
3749                         {
3750                                 t = process_dungeon_file_expr(&s, &f);
3751                         }
3752                         while (*s && (f != b2))
3753                         {
3754                                 p = t;
3755                                 t = process_dungeon_file_expr(&s, &f);
3756                                 if (*t && (strcmp(p, t) < 0)) v = "0";
3757                         }
3758                 }
3759
3760                 /* Oops */
3761                 else
3762                 {
3763                         while (*s && (f != b2))
3764                         {
3765                                 t = process_dungeon_file_expr(&s, &f);
3766                         }
3767                 }
3768
3769                 /* Verify ending */
3770                 if (f != b2) v = "?x?x?";
3771
3772                 /* Extract final and Terminate */
3773                 if ((f = *s) != '\0') *s++ = '\0';
3774         }
3775
3776         /* Other */
3777         else
3778         {
3779                 /* Accept all printables except spaces and brackets */
3780                 while (isprint(*s) && !strchr(" []", *s)) ++s;
3781
3782                 /* Extract final and Terminate */
3783                 if ((f = *s) != '\0') *s++ = '\0';
3784
3785                 /* Variable */
3786                 if (*b == '$')
3787                 {
3788                         /* System */
3789                         if (streq(b+1, "SYS"))
3790                         {
3791                                 v = ANGBAND_SYS;
3792                         }
3793
3794                         /* Graphics */
3795                         else if (streq(b+1, "GRAF"))
3796                         {
3797                                 v = ANGBAND_GRAF;
3798                         }
3799
3800                         else if (streq(b+1, "MONOCHROME"))
3801                         {
3802                                 if (arg_monochrome)
3803                                         v = "ON";
3804                                 else
3805                                         v = "OFF";
3806                         }
3807
3808                         /* Race */
3809                         else if (streq(b+1, "RACE"))
3810                         {
3811 #ifdef JP
3812                                 v = rp_ptr->E_title;
3813 #else
3814                                 v = rp_ptr->title;
3815 #endif
3816                         }
3817
3818                         /* Class */
3819                         else if (streq(b+1, "CLASS"))
3820                         {
3821 #ifdef JP
3822                                 v = cp_ptr->E_title;
3823 #else
3824                                 v = cp_ptr->title;
3825 #endif
3826                         }
3827
3828                         /* First realm */
3829                         else if (streq(b+1, "REALM1"))
3830                         {
3831 #ifdef JP
3832                                 v = E_realm_names[p_ptr->realm1];
3833 #else
3834                                 v = realm_names[p_ptr->realm1];
3835 #endif
3836                         }
3837
3838                         /* Second realm */
3839                         else if (streq(b+1, "REALM2"))
3840                         {
3841 #ifdef JP
3842                                 v = E_realm_names[p_ptr->realm2];
3843 #else
3844                                 v = realm_names[p_ptr->realm2];
3845 #endif
3846                         }
3847
3848                         /* Player name */
3849                         else if (streq(b+1, "PLAYER"))
3850                         {
3851                                 v = player_base;
3852                         }
3853
3854                         /* Town */
3855                         else if (streq(b+1, "TOWN"))
3856                         {
3857                                 sprintf(tmp, "%d", p_ptr->town_num);
3858                                 v = tmp;
3859                         }
3860
3861                         /* Level */
3862                         else if (streq(b+1, "LEVEL"))
3863                         {
3864                                 sprintf(tmp, "%d", p_ptr->lev);
3865                                 v = tmp;
3866                         }
3867
3868                         /* Current quest number */
3869                         else if (streq(b+1, "QUEST_NUMBER"))
3870                         {
3871                                 sprintf(tmp, "%d", p_ptr->inside_quest);
3872                                 v = tmp;
3873                         }
3874
3875                         /* Number of last quest */
3876                         else if (streq(b+1, "LEAVING_QUEST"))
3877                         {
3878                                 sprintf(tmp, "%d", leaving_quest);
3879                                 v = tmp;
3880                         }
3881
3882                         /* Quest status */
3883                         else if (prefix(b+1, "QUEST"))
3884                         {
3885                                 /* "QUEST" uses a special parameter to determine the number of the quest */
3886                                 sprintf(tmp, "%d", quest[atoi(b+6)].status);
3887                                 v = tmp;
3888                         }
3889
3890                         /* Random */
3891                         else if (prefix(b+1, "RANDOM"))
3892                         {
3893                                 /* "RANDOM" uses a special parameter to determine the number of the quest */
3894                                 sprintf(tmp, "%d", (int)(seed_town%atoi(b+7)));
3895                                 v = tmp;
3896                         }
3897
3898                         /* Variant name */
3899                         else if (streq(b+1, "VARIANT"))
3900                         {
3901                                 v = variant;
3902                         }
3903
3904                         /* Wilderness */
3905                         else if (streq(b+1, "WILDERNESS"))
3906                         {
3907                                 if (vanilla_town)
3908                                         sprintf(tmp, "NONE");
3909                                 else if (lite_town)
3910                                         sprintf(tmp, "LITE");
3911                                 else
3912                                         sprintf(tmp, "NORMAL");
3913                                 v = tmp;
3914                         }
3915                 }
3916
3917                 /* Constant */
3918                 else
3919                 {
3920                         v = b;
3921                 }
3922         }
3923
3924         /* Save */
3925         (*fp) = f;
3926
3927         /* Save */
3928         (*sp) = s;
3929
3930         /* Result */
3931         return (v);
3932 }
3933
3934
3935 errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax)
3936 {
3937         FILE *fp;
3938
3939         char buf[1024];
3940
3941         int num = -1;
3942
3943         errr err = 0;
3944
3945         bool bypass = FALSE;
3946
3947         int x = xmin, y = ymin;
3948
3949
3950         /* Build the filename */
3951         path_build(buf, 1024, ANGBAND_DIR_EDIT, name);
3952
3953         /* Open the file */
3954         fp = my_fopen(buf, "r");
3955
3956         /* No such file */
3957         if (!fp) return (-1);
3958
3959
3960         /* Process the file */
3961         while (0 == my_fgets(fp, buf, 1024))
3962         {
3963                 /* Count lines */
3964                 num++;
3965
3966
3967                 /* Skip "empty" lines */
3968                 if (!buf[0]) continue;
3969
3970                 /* Skip "blank" lines */
3971                 if (isspace(buf[0])) continue;
3972
3973                 /* Skip comments */
3974                 if (buf[0] == '#') continue;
3975
3976
3977                 /* Process "?:<expr>" */
3978                 if ((buf[0] == '?') && (buf[1] == ':'))
3979                 {
3980                         char f;
3981                         cptr v;
3982                         char *s;
3983
3984                         /* Start */
3985                         s = buf + 2;
3986
3987                         /* Parse the expr */
3988                         v = process_dungeon_file_expr(&s, &f);
3989
3990                         /* Set flag */
3991                         bypass = (streq(v, "0") ? TRUE : FALSE);
3992
3993                         /* Continue */
3994                         continue;
3995                 }
3996
3997                 /* Apply conditionals */
3998                 if (bypass) continue;
3999
4000
4001                 /* Process "%:<file>" */
4002                 if (buf[0] == '%')
4003                 {
4004                         /* Process that file if allowed */
4005                         (void)process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax);
4006
4007                         /* Continue */
4008                         continue;
4009                 }
4010
4011
4012                 /* Process the line */
4013                 err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x);
4014
4015                 /* Oops */
4016                 if (err) break;
4017         }
4018
4019         /* Errors */
4020         if (err)
4021         {
4022                 cptr oops;
4023
4024                 /* Error string */
4025                 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
4026
4027                 /* Oops */
4028                 msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
4029 #ifdef JP
4030 msg_format("'%s'¤ò²òÀÏÃæ¡£", buf);
4031 #else
4032                 msg_format("Parsing '%s'.", buf);
4033 #endif
4034
4035                 msg_print(NULL);
4036         }
4037
4038
4039         /* Close the file */
4040         my_fclose(fp);
4041
4042         /* Result */
4043         return (err);
4044 }
4045
4046
4047
4048 #if 0
4049 void write_r_info_txt(void)
4050 {
4051         int i, j, z, fc, bc;
4052         int dlen;
4053
4054         cptr flags[288];
4055
4056         u32b f_ptr[9];
4057         cptr *n_ptr[9];
4058
4059         monster_race *r_ptr;
4060
4061         monster_blow *b_ptr;
4062
4063         FILE *fff = fopen("output.txt", "wt");
4064
4065         cptr desc;
4066
4067         int mode = -1;
4068
4069         if (!fff) return;
4070
4071         fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");
4072
4073         fprintf(fff, "# Version stamp (required)\n\n");
4074
4075         /* Write Version */
4076         fprintf(fff, "V:%d.%d.%d\n\n\n", r_head->v_major, r_head->v_minor, r_head->v_patch);
4077
4078         /* Write a note */
4079         fprintf(fff, "##### The Player #####\n\n");
4080
4081         for (z = -1; z < alloc_race_size; z++)
4082         {
4083                 /* Output the monsters in order */
4084                 i = (z >= 0) ? alloc_race_table[z].index : 0;
4085
4086                 /* Acquire the monster */
4087                 r_ptr = &r_info[i];
4088
4089                 /* Ignore empty monsters */
4090                 if (!strlen(r_name + r_ptr->name)) continue;
4091
4092                 /* Ignore useless monsters */
4093                 if (i && !r_ptr->speed) continue;
4094
4095                 /* Write a note if necessary */
4096                 if (i && (!r_ptr->level != !mode))
4097                 {
4098                         /* Note the town */
4099                         if (!r_ptr->level)
4100                         {
4101                                 fprintf(fff, "\n##### Town monsters #####\n\n");
4102                         }
4103                         /* Note the dungeon */
4104                         else
4105                         {
4106                                 fprintf(fff, "\n##### Normal monsters #####\n\n");
4107                         }
4108
4109                         /* Record the change */
4110                         mode = r_ptr->level;
4111                 }
4112
4113                 /* Acquire the flags */
4114                 f_ptr[0] = r_ptr->flags1; n_ptr[0] = r_info_flags1;
4115                 f_ptr[1] = r_ptr->flags2; n_ptr[1] = r_info_flags2;
4116                 f_ptr[2] = r_ptr->flags3; n_ptr[2] = r_info_flags3;
4117                 f_ptr[3] = r_ptr->flags4; n_ptr[3] = r_info_flags4;
4118                 f_ptr[4] = r_ptr->flags5; n_ptr[4] = r_info_flags5;
4119                 f_ptr[5] = r_ptr->flags6; n_ptr[5] = r_info_flags6;
4120                 f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7;
4121                 f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8;
4122                 f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9;
4123
4124                 /* Write New/Number/Name */
4125                 fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name);
4126
4127                 /* Write Graphic */
4128                 fprintf(fff, "G:%c:%c\n", r_ptr->d_char, color_char[r_ptr->d_attr]);
4129
4130                 /* Write Information */
4131                 fprintf(fff, "I:%d:%dd%d:%d:%d:%d\n", r_ptr->speed, r_ptr->hdice, r_ptr->hside,
4132                                                                                                                   r_ptr->aaf, r_ptr->ac, r_ptr->sleep);
4133
4134                 /* Write more information */
4135                 fprintf(fff, "W:%d:%d:%d:%ld\n", r_ptr->level, r_ptr->rarity, r_ptr->extra, r_ptr->mexp);
4136
4137                 /* Write Blows */
4138                 for(j = 0; j < 4; j++)
4139                 {
4140                         b_ptr = &(r_ptr->blow[j]);
4141
4142                         /* Stop when done */
4143                         if (!b_ptr->method) break;
4144
4145                         /* Write the blows */
4146                         fprintf(fff, "B:%s:%s:%dd%d\n", r_info_blow_method[b_ptr->method],
4147                                                                                                           r_info_blow_effect[b_ptr->effect],
4148                                                                                                           b_ptr->d_dice, b_ptr->d_side);
4149                 }
4150
4151                 /* Extract the flags */
4152                 for (fc = 0, j = 0; j < 96; j++)
4153                 {
4154                         /* Check this flag */
4155                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4156                 }
4157
4158                 /* Extract the extra flags */
4159                 for (j = 192; j < 288; j++)
4160                 {
4161                         /* Check this flag */
4162                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4163                 }
4164
4165                 /* Write the flags */
4166                 for (j = 0; j < fc;)
4167                 {
4168                         char buf[160];
4169
4170                         /* Start the line */
4171                         sprintf(buf, "F:");
4172
4173                         for (bc = 0; (bc < 60) && (j < fc); j++)
4174                         {
4175                                 char t[80];
4176
4177                                 /* Format the flag */
4178                                 sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4179
4180                                 /* Add it to the buffer */
4181                                 strcat(buf, t);
4182
4183                                 /* Note the length */
4184                                 bc += strlen(t);
4185                         }
4186
4187                         /* Done with this line; write it */
4188                         fprintf(fff, "%s\n", buf);
4189                 }
4190
4191                 /* Write Spells if applicable */
4192                 if (r_ptr->freq_spell)
4193                 {
4194                         /* Write the frequency */
4195                         fprintf(fff, "S:1_IN_%d | \n", 100 / r_ptr->freq_spell);
4196
4197                         /* Extract the spell flags */
4198                         for (fc = 0, j = 96; j < 192; j++)
4199                         {
4200                                 /* Check this flag */
4201                                 if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4202                         }
4203
4204                         /* Write the flags */
4205                         for (j = 0; j < fc;)
4206                         {
4207                                 char buf[160], *t;
4208
4209                                 /* Start the line */
4210                                 sprintf(buf, "S:");
4211
4212                                 for (bc = 0, t = buf + 2; (bc < 60) && (j < fc); j++)
4213                                 {
4214                                         int tlen;
4215
4216                                         /* Format the flag */
4217                                         sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4218
4219                                         tlen = strlen(t);
4220
4221                                         /* Note the length */
4222                                         bc += tlen;
4223
4224                                         /* Advance */
4225                                         t += tlen;
4226                                 }
4227
4228                                 /* Done with this line; write it */
4229                                 fprintf(fff, "%s\n", buf);
4230                         }
4231                 }
4232
4233                 /* Acquire the description */
4234                 desc = r_text + r_ptr->text;
4235                 dlen = strlen(desc);
4236
4237                 /* Write Description */
4238                 for (j = 0; j < dlen;)
4239                 {
4240                         char buf[160], *t;
4241
4242                         /* Start the line */
4243                         sprintf(buf, "D:");
4244
4245                         for (bc = 0, t = buf + 2; ((bc < 60) || !isspace(desc[j])) && (j < dlen); j++, bc++, t++)
4246                         {
4247                                 *t = desc[j];
4248                         }
4249
4250                         /* Terminate it */
4251                         *t = '\0';
4252
4253                         /* Done with this line; write it */
4254                         fprintf(fff, "%s\n", buf);
4255                 }
4256
4257                 /* Space between entries */
4258                 fprintf(fff, "\n");
4259         }
4260
4261         /* Done */
4262         fclose(fff);
4263 }
4264
4265 #endif