OSDN Git Service

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