OSDN Git Service

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