OSDN Git Service

c661c112f185625c02cbd250eda24afeef42403f
[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
871         { "CHARM_ANIMAL", ACT_CHARM_ANIMAL },
872         { "CHARM_UNDEAD", ACT_CHARM_UNDEAD },
873         { "CHARM_OTHER", ACT_CHARM_OTHER },
874         { "CHARM_ANIMALS", ACT_CHARM_ANIMALS },
875         { "CHARM_OTHERS", ACT_CHARM_OTHERS },
876         { "SUMMON_ANIMAL", ACT_SUMMON_ANIMAL },
877         { "SUMMON_PHANTOM", ACT_SUMMON_PHANTOM },
878         { "SUMMON_ELEMENTAL", ACT_SUMMON_ELEMENTAL },
879         { "SUMMON_DEMON", ACT_SUMMON_DEMON },
880         { "SUMMON_UNDEAD", ACT_SUMMON_UNDEAD },
881         { "SUMMON_HOUND", ACT_SUMMON_HOUND },
882         { "SUMMON_DAWN", ACT_SUMMON_DAWN },
883         { "SUMMON_OCTOPUS", ACT_SUMMON_OCTOPUS },
884
885         { "CHOIR_SINGS", ACT_CHOIR_SINGS },
886         { "CURE_LW", ACT_CURE_LW },
887         { "CURE_MW", ACT_CURE_MW },
888         { "CURE_POISON", ACT_CURE_POISON },
889         { "REST_LIFE", ACT_REST_LIFE },
890         { "REST_ALL", ACT_REST_ALL },
891         { "CURE_700", ACT_CURE_700 },
892         { "CURE_1000", ACT_CURE_1000 },
893         { "CURING", ACT_CURING },
894         { "CURE_MANA_FULL", ACT_CURE_MANA_FULL },
895
896         { "ESP", ACT_ESP },
897         { "BERSERK", ACT_BERSERK },
898         { "PROT_EVIL", ACT_PROT_EVIL },
899         { "RESIST_ALL", ACT_RESIST_ALL },
900         { "SPEED", ACT_SPEED },
901         { "XTRA_SPEED", ACT_XTRA_SPEED },
902         { "WRAITH", ACT_WRAITH },
903         { "INVULN", ACT_INVULN },
904         { "HELO", ACT_HELO },
905         { "HELO_SPEED", ACT_HELO_SPEED },
906         { "RESIST_ACID", ACT_RESIST_ACID },
907         { "RESIST_FIRE", ACT_RESIST_ACID },
908         { "RESIST_COLD", ACT_RESIST_ACID },
909         { "RESIST_ELEC", ACT_RESIST_ACID },
910         { "RESIST_POIS", ACT_RESIST_ACID },
911
912         { "LIGHT", ACT_LIGHT },
913         { "MAP_LIGHT", ACT_MAP_LIGHT },
914         { "DETECT_ALL", ACT_DETECT_ALL },
915         { "DETECT_XTRA", ACT_DETECT_XTRA },
916         { "ID_FULL", ACT_ID_FULL },
917         { "ID_PLAIN", ACT_ID_PLAIN },
918         { "RUNE_EXPLO", ACT_RUNE_EXPLO },
919         { "RUNE_PROT", ACT_RUNE_PROT },
920         { "SATIATE", ACT_SATIATE },
921         { "DEST_DOOR", ACT_DEST_DOOR },
922         { "STONE_MUD", ACT_STONE_MUD },
923         { "RECHARGE", ACT_RECHARGE },
924         { "ALCHEMY", ACT_ALCHEMY },
925         { "DIM_DOOR", ACT_DIM_DOOR },
926         { "TELEPORT", ACT_TELEPORT },
927         { "RECALL", ACT_RECALL },
928         { "JUDGE", ACT_JUDGE },
929         { "TELEKINESIS", ACT_TELEKINESIS },
930         { "DETECT_UNIQUE", ACT_DETECT_UNIQUE },
931         { "ESCAPE", ACT_ESCAPE },
932         { "DISP_CURSE_XTRA", ACT_DISP_CURSE_XTRA },
933         { "BRAND_FIRE_BOLTS", ACT_BRAND_FIRE_BOLTS },
934         { "RECHARGE_XTRA", ACT_RECHARGE_XTRA },
935         { "LORE", ACT_LORE },
936         { "SHIKOFUMI", ACT_SHIKOFUMI },
937
938         { "FISHING", ACT_FISHING },
939
940         { NULL, 0 }
941 };
942
943 /*
944  * Dungeon flags
945  */
946 static cptr d_info_flags1[] =
947 {
948         "WINNER",
949         "MAZE",
950         "SMALLEST",
951         "BEGINNER",
952         "BIG",
953         "NO_DOORS",
954         "WATER_RIVER",
955         "LAVA_RIVER",
956         "CURTAIN",
957         "GLASS_DOOR",
958         "CAVE",
959         "CAVERN",
960         "XXX",
961         "XXX",
962         "XXX",
963         "XXX",
964         "FORGET",
965         "LAKE_WATER",
966         "LAKE_LAVA",
967         "LAKE_RUBBLE",
968         "LAKE_TREE",
969         "NO_VAULT",
970         "ARENA",
971         "DESTROY",
972         "GLASS_ROOM",
973         "NO_CAVE",
974         "NO_MAGIC",
975         "NO_MELEE",
976         "CHAMELEON",
977         "DARKNESS",
978         "XXX",
979         "XXX"
980 };
981
982
983 /*
984  * Add a text to the text-storage and store offset to it.
985  *
986  * Returns FALSE when there isn't enough space available to store
987  * the text.
988  */
989 static bool add_text(u32b *offset, header *head, cptr buf, bool normal_text)
990 {
991         /* Hack -- Verify space */
992         if (head->text_size + strlen(buf) + 8 > FAKE_TEXT_SIZE)
993                 return (FALSE);
994
995         /* New text? */
996         if (*offset == 0)
997         {
998                 /* Advance and save the text index */
999                 *offset = ++head->text_size;
1000         }
1001
1002         /* Additional text */
1003         else if (normal_text)
1004         {
1005                 /*
1006                  * If neither the end of the last line nor
1007                  * the beginning of current line is not a space,
1008                  * fill up a space as a correct separator of two words.
1009                  */
1010                 if (head->text_size > 0 &&
1011 #ifdef JP
1012                     (*(head->text_ptr + head->text_size - 1) != ' ') &&
1013                     ((head->text_size == 1) || !iskanji(*(head->text_ptr + head->text_size - 2))) && 
1014                     (buf[0] != ' ') && !iskanji(buf[0])
1015 #else
1016                     (*(head->text_ptr + head->text_size - 1) != ' ') &&
1017                     (buf[0] != ' ')
1018 #endif
1019                     )
1020                 {
1021                         /* Append a space */
1022                         *(head->text_ptr + head->text_size) = ' ';
1023
1024                         /* Advance the index */
1025                         head->text_size++;
1026                 }
1027         }
1028
1029         /* Append chars to the text */
1030         strcpy(head->text_ptr + head->text_size, buf);
1031
1032         /* Advance the index */
1033         head->text_size += strlen(buf);
1034
1035         /* Success */
1036         return (TRUE);
1037 }
1038
1039
1040 /*
1041  * Add a name to the name-storage and return an offset to it.
1042  *
1043  * Returns FALSE when there isn't enough space available to store
1044  * the name.
1045  */
1046 static bool add_name(u32b *offset, header *head, cptr buf)
1047 {
1048         /* Hack -- Verify space */
1049         if (head->name_size + strlen(buf) + 8 > FAKE_NAME_SIZE)
1050                 return (FALSE);
1051
1052         /* New name? */
1053         if (*offset == 0)
1054         {
1055                 /* Advance and save the name index */
1056                 *offset = ++head->name_size;
1057         }
1058
1059         /* Append chars to the names */
1060         strcpy(head->name_ptr + head->name_size, buf);
1061
1062         /* Advance the index */
1063         head->name_size += strlen(buf);
1064
1065         /* Success */
1066         return (TRUE);
1067 }
1068
1069
1070 /*
1071  * Add a tag to the tag-storage and return an offset to it.
1072  *
1073  * Returns FALSE when there isn't enough space available to store
1074  * the name.
1075  */
1076 static bool add_tag(s16b *offset, header *head, cptr buf)
1077 {
1078         u32b i;
1079
1080         /* Search for an existing (fake) tag */
1081         for (i = 1; i < head->tag_size; i += strlen(&head->tag_ptr[i]) + 1)
1082         {
1083                 /* Found it */
1084                 if (streq(&head->tag_ptr[i], buf)) break;
1085         }
1086
1087         /* There was no existing tag */
1088         if (i >= head->tag_size)
1089         {
1090                 /* Hack -- Verify space */
1091                 if (head->tag_size + strlen(buf) + 8 > FAKE_TAG_SIZE)
1092                         return FALSE;
1093
1094                 /* Append chars to the tags */
1095                 strcpy(head->tag_ptr + head->tag_size, buf);
1096
1097                 /* Point the new tag */
1098                 i = head->tag_size;
1099
1100                 /* Advance the index */
1101                 head->tag_size += strlen(buf) + 1;
1102         }
1103
1104         /* Return offset of the tag */
1105         *offset = (s16b)i;
1106
1107         /* Success */
1108         return TRUE;
1109 }
1110
1111
1112 /*
1113  * Convert a "color letter" into an "actual" color
1114  * The colors are: dwsorgbuDWvyRGBU, as shown below
1115  */
1116 byte color_char_to_attr(char c)
1117 {
1118         switch (c)
1119         {
1120                 case 'd': return (TERM_DARK);
1121                 case 'w': return (TERM_WHITE);
1122                 case 's': return (TERM_SLATE);
1123                 case 'o': return (TERM_ORANGE);
1124                 case 'r': return (TERM_RED);
1125                 case 'g': return (TERM_GREEN);
1126                 case 'b': return (TERM_BLUE);
1127                 case 'u': return (TERM_UMBER);
1128
1129                 case 'D': return (TERM_L_DARK);
1130                 case 'W': return (TERM_L_WHITE);
1131                 case 'v': return (TERM_VIOLET);
1132                 case 'y': return (TERM_YELLOW);
1133                 case 'R': return (TERM_L_RED);
1134                 case 'G': return (TERM_L_GREEN);
1135                 case 'B': return (TERM_L_BLUE);
1136                 case 'U': return (TERM_L_UMBER);
1137         }
1138
1139         return (255);
1140 }
1141
1142
1143
1144 /*** Initialize from ascii template files ***/
1145
1146
1147 /*
1148  * Initialize an "*_info" array, by parsing an ascii "template" file
1149  */
1150 errr init_info_txt(FILE *fp, char *buf, header *head,
1151                    parse_info_txt_func parse_info_txt_line)
1152 {
1153         errr err;
1154
1155         /* Just before the first record */
1156         error_idx = -1;
1157
1158         /* Just before the first line */
1159         error_line = 0;
1160
1161
1162         /* Prepare the "fake" stuff */
1163         head->name_size = 0;
1164         head->text_size = 0;
1165         head->tag_size = 0;
1166
1167         /* Parse */
1168         while (0 == my_fgets(fp, buf, 1024))
1169         {
1170                 /* Advance the line number */
1171                 error_line++;
1172
1173                 /* Skip comments and blank lines */
1174                 if (!buf[0] || (buf[0] == '#')) continue;
1175
1176                 /* Verify correct "colon" format */
1177                 if (buf[1] != ':') return (PARSE_ERROR_GENERIC);
1178
1179
1180                 /* Hack -- Process 'V' for "Version" */
1181                 if (buf[0] == 'V')
1182                 {
1183                         /* ignore */
1184                         continue;
1185                 }
1186
1187                 /* Mega Hack -- Calculate Check Sum */
1188                 if (buf[0] != 'N' && buf[0] != 'D')
1189                 {
1190                         int i;
1191                         for (i = 0; buf[i]; i++)
1192                         {
1193                                 head->v_extra += (byte)buf[i];
1194                                 head->v_extra ^= (1 << (i % 8));
1195                         }
1196                 }
1197
1198                 /* Parse the line */
1199                 if ((err = (*parse_info_txt_line)(buf, head)) != 0)
1200                         return (err);
1201         }
1202
1203
1204         /* Complete the "name" and "text" sizes */
1205         if (head->name_size) head->name_size++;
1206         if (head->text_size) head->text_size++;
1207
1208         /* Success */
1209         return (0);
1210 }
1211
1212
1213 /*
1214  * Initialize the "v_info" array, by parsing an ascii "template" file
1215  */
1216 errr parse_v_info(char *buf, header *head)
1217 {
1218         int i;
1219         char *s;
1220
1221         /* Current entry */
1222         static vault_type *v_ptr = NULL;
1223
1224         /* Process 'N' for "New/Number/Name" */
1225         if (buf[0] == 'N')
1226         {
1227                 /* Find the colon before the name */
1228                 s = my_strchr(buf+2, ':');
1229
1230                 /* Verify that colon */
1231                 if (!s) return (1);
1232
1233                 /* Nuke the colon, advance to the name */
1234                 *s++ = '\0';
1235
1236                 /* Paranoia -- require a name */
1237                 if (!*s) return (1);
1238
1239                 /* Get the index */
1240                 i = atoi(buf+2);
1241
1242                 /* Verify information */
1243                 if (i <= error_idx) return (4);
1244
1245                 /* Verify information */
1246                 if (i >= head->info_num) return (2);
1247
1248                 /* Save the index */
1249                 error_idx = i;
1250
1251                 /* Point at the "info" */
1252                 v_ptr = &v_info[i];
1253
1254                 /* Store the name */
1255                 if (!add_name(&v_ptr->name, head, s)) return (7);
1256         }
1257
1258         /* There better be a current v_ptr */
1259         else if (!v_ptr) return (3);
1260
1261         /* Process 'D' for "Description" */
1262         else if (buf[0] == 'D')
1263         {
1264                 /* Acquire the text */
1265                 s = buf+2;
1266
1267                 /* Store the text */
1268                 if (!add_text(&v_ptr->text, head, s, FALSE)) return (7);
1269         }
1270
1271         /* Process 'X' for "Extra info" (one line only) */
1272         else if (buf[0] == 'X')
1273         {
1274                 int typ, rat, hgt, wid;
1275
1276                 /* Scan for the values */
1277                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1278                         &typ, &rat, &hgt, &wid)) return (1);
1279
1280                 /* Save the values */
1281                 v_ptr->typ = typ;
1282                 v_ptr->rat = rat;
1283                 v_ptr->hgt = hgt;
1284                 v_ptr->wid = wid;
1285         }
1286
1287         /* Oops */
1288         else    return (6);
1289
1290         /* Success */
1291         return (0);
1292 }
1293
1294
1295
1296 /*
1297  * Initialize the "s_info" array, by parsing an ascii "template" file
1298  */
1299 errr parse_s_info(char *buf, header *head)
1300 {
1301         int i;
1302
1303         /* Current entry */
1304         static skill_table *s_ptr = NULL;
1305
1306
1307         /* Process 'N' for "New/Number/Name" */
1308         if (buf[0] == 'N')
1309         {
1310                 /* Get the index */
1311                 i = atoi(buf+2);
1312
1313                         /* Verify information */
1314                 if (i <= error_idx) return (4);
1315
1316                 /* Verify information */
1317                 if (i >= head->info_num) return (2);
1318
1319                 /* Save the index */
1320                 error_idx = i;
1321
1322                 /* Point at the "info" */
1323                 s_ptr = &s_info[i];
1324         }
1325
1326         /* There better be a current s_ptr */
1327         else if (!s_ptr) return (3);
1328
1329         /* Process 'W' for "Weapon exp" */
1330         else if (buf[0] == 'W')
1331         {
1332                 int tval, sval, start, max;
1333                 const s16b exp_conv_table[] =
1334                 {
1335                         WEAPON_EXP_UNSKILLED, WEAPON_EXP_BEGINNER, WEAPON_EXP_SKILLED,
1336                         WEAPON_EXP_EXPERT, WEAPON_EXP_MASTER
1337                 };
1338
1339                 /* Scan for the values */
1340                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1341                                 &tval, &sval, &start, &max)) return (1);
1342
1343                 if (start < EXP_LEVEL_UNSKILLED || start > EXP_LEVEL_MASTER
1344                         || max < EXP_LEVEL_UNSKILLED || max > EXP_LEVEL_MASTER) return (8);
1345
1346                 /* Save the values */
1347                 s_ptr->w_start[tval][sval] = exp_conv_table[start];
1348                 s_ptr->w_max[tval][sval] = exp_conv_table[max];
1349         }
1350
1351         /* Process 'S' for "Skill exp" */
1352         else if (buf[0] == 'S')
1353         {
1354                 int num, start, max;
1355
1356                 /* Scan for the values */
1357                 if (3 != sscanf(buf+2, "%d:%d:%d",
1358                                 &num, &start, &max)) return (1);
1359
1360                 if (start < WEAPON_EXP_UNSKILLED || start > WEAPON_EXP_MASTER
1361                         || max < WEAPON_EXP_UNSKILLED || max > WEAPON_EXP_MASTER) return (8);
1362
1363                 /* Save the values */
1364                 s_ptr->s_start[num] = start;
1365                 s_ptr->s_max[num] = max;
1366         }
1367
1368
1369         /* Oops */
1370         else return (6);
1371
1372         /* Success */
1373         return (0);
1374 }
1375
1376
1377 /*
1378  * Initialize the "m_info" array, by parsing an ascii "template" file
1379  */
1380 errr parse_m_info(char *buf, header *head)
1381 {
1382         int i;
1383
1384         char *s;
1385
1386         /* Current entry */
1387         static player_magic *m_ptr = NULL;
1388
1389         /* ---Hack--- */
1390         static int realm, magic_idx = 0, readable = 0;
1391
1392
1393         /* Process 'N' for "New/Number/Name" */
1394         if (buf[0] == 'N')
1395         {
1396                 /* Get the index */
1397                 i = atoi(buf+2);
1398
1399                         /* Verify information */
1400                 if (i <= error_idx) return (4);
1401
1402                 /* Verify information */
1403                 if (i >= head->info_num) return (2);
1404
1405                 /* Save the index */
1406                 error_idx = i;
1407
1408                 /* Point at the "info" */
1409                 m_ptr = &m_info[i];
1410         }
1411
1412         /* There better be a current m_ptr */
1413         else if (!m_ptr) return (3);
1414
1415         /* Process 'I' for "Info" (one line only) */
1416         else if (buf[0] == 'I')
1417         {
1418                 char *book, *stat;
1419                 int xtra, type, first, weight;
1420
1421                 /* Find the colon before the name */
1422                 s = my_strchr(buf+2, ':');
1423
1424                 /* Verify that colon */
1425                 if (!s) return (1);
1426
1427                 /* Nuke the colon, advance to the name */
1428                 *s++ = '\0';
1429
1430                 book = buf+2;
1431
1432                 if (streq(book, "SORCERY")) m_ptr->spell_book = TV_SORCERY_BOOK;
1433                 else if (streq(book, "LIFE")) m_ptr->spell_book = TV_LIFE_BOOK;
1434                 else if (streq(book, "MUSIC")) m_ptr->spell_book = TV_MUSIC_BOOK;
1435                 else if (streq(book, "HISSATSU")) m_ptr->spell_book = TV_HISSATSU_BOOK;
1436                 else if (streq(book, "NONE")) m_ptr->spell_book = 0;
1437                 else return (5);
1438
1439                 stat = s;
1440
1441                 /* Find the colon before the name */
1442                 s = my_strchr(s, ':');
1443
1444                 /* Verify that colon */
1445                 if (!s) return (1);
1446
1447                 /* Nuke the colon, advance to the name */
1448                 *s++ = '\0';
1449
1450                 if (streq(stat, "STR")) m_ptr->spell_stat = A_STR;
1451                 else if (streq(stat, "INT")) m_ptr->spell_stat = A_INT;
1452                 else if (streq(stat, "WIS")) m_ptr->spell_stat = A_WIS;
1453                 else if (streq(stat, "DEX")) m_ptr->spell_stat = A_DEX;
1454                 else if (streq(stat, "CON")) m_ptr->spell_stat = A_CON;
1455                 else if (streq(stat, "CHR")) m_ptr->spell_stat = A_CHR;
1456                 else return (5);
1457
1458
1459                 /* Scan for the values */
1460                 if (4 != sscanf(s, "%x:%d:%d:%d",
1461                                 (uint *)&xtra, &type, &first, &weight)) return (1);
1462
1463                 m_ptr->spell_xtra = xtra;
1464                 m_ptr->spell_type = type;
1465                 m_ptr->spell_first = first;
1466                 m_ptr->spell_weight = weight;
1467         }
1468
1469
1470         /* Process 'R' for "Realm" (one line only) */
1471         else if (buf[0] == 'R')
1472         {
1473                 /* Scan for the values */
1474                 if (2 != sscanf(buf+2, "%d:%d",
1475                                 &realm, &readable)) return (1);
1476
1477                 magic_idx = 0;
1478         }
1479
1480         else if (buf[0] == 'T')
1481         {
1482                 int level, mana, fail, exp;
1483
1484                 if (!readable) return (1);
1485                 /* Scan for the values */
1486                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
1487                                 &level, &mana, &fail, &exp)) return (1);
1488
1489                 m_ptr->info[realm][magic_idx].slevel = level;
1490                 m_ptr->info[realm][magic_idx].smana = mana;
1491                 m_ptr->info[realm][magic_idx].sfail = fail;
1492                 m_ptr->info[realm][magic_idx].sexp = exp;
1493                 magic_idx ++;
1494         }
1495
1496
1497         /* Oops */
1498         else return (6);
1499
1500         /* Success */
1501         return (0);
1502 }
1503
1504
1505 /*
1506  * Grab one flag from a textual string
1507  */
1508 static errr grab_one_flag(u32b *flags, cptr names[], cptr what)
1509 {
1510         int i;
1511
1512         /* Check flags */
1513         for (i = 0; i < 32; i++)
1514         {
1515                 if (streq(what, names[i]))
1516                 {
1517                         *flags |= (1L << i);
1518                         return 0;
1519                 }
1520         }
1521
1522         return -1;
1523 }
1524
1525
1526 /*
1527  * Grab one flag in an feature_type from a textual string
1528  */
1529 static errr grab_one_feat_flag(feature_type *f_ptr, cptr what)
1530 {
1531         int i;
1532
1533         /* Check flags */
1534         for (i = 0; i < FF_FLAG_MAX; i++)
1535         {
1536                 if (streq(what, f_info_flags[i]))
1537                 {
1538                         add_flag(f_ptr->flags, i);
1539                         return 0;
1540                 }
1541         }
1542
1543         /* Oops */
1544 #ifdef JP
1545         msg_format("̤ÃΤÎÃÏ·Á¥Õ¥é¥° '%s'¡£", what);
1546 #else
1547         msg_format("Unknown feature flag '%s'.", what);
1548 #endif
1549
1550         /* Error */
1551         return PARSE_ERROR_GENERIC;
1552 }
1553
1554
1555 /*
1556  * Grab an action in an feature_type from a textual string
1557  */
1558 static errr grab_one_feat_action(feature_type *f_ptr, cptr what, int count)
1559 {
1560         int i;
1561
1562         /* Check flags */
1563         for (i = 0; i < FF_FLAG_MAX; i++)
1564         {
1565                 if (streq(what, f_info_flags[i]))
1566                 {
1567                         f_ptr->state[count].action = i;
1568                         return 0;
1569                 }
1570         }
1571
1572         /* Oops */
1573 #ifdef JP
1574         msg_format("̤ÃΤÎÃÏ·Á¥¢¥¯¥·¥ç¥ó '%s'¡£", what);
1575 #else
1576         msg_format("Unknown feature action '%s'.", what);
1577 #endif
1578
1579         /* Error */
1580         return PARSE_ERROR_GENERIC;
1581 }
1582
1583
1584 /*
1585  * Initialize the "f_info" array, by parsing an ascii "template" file
1586  */
1587 errr parse_f_info(char *buf, header *head)
1588 {
1589         int i;
1590
1591         char *s, *t;
1592
1593         /* Current entry */
1594         static feature_type *f_ptr = NULL;
1595
1596
1597         /* Process 'N' for "New/Number/Name" */
1598         if (buf[0] == 'N')
1599         {
1600                 /* Find the colon before the name */
1601                 s = my_strchr(buf+2, ':');
1602
1603                 if (s)
1604                 {
1605                         /* Nuke the colon, advance to the name */
1606                         *s++ = '\0';
1607                 }
1608
1609                 /* Get the index */
1610                 i = atoi(buf+2);
1611
1612                 /* Verify information */
1613                 if (i <= error_idx) return (4);
1614
1615                 /* Verify information */
1616                 if (i >= head->info_num) return (2);
1617
1618                 /* Save the index */
1619                 error_idx = i;
1620
1621                 /* Point at the "info" */
1622                 f_ptr = &f_info[i];
1623
1624                 /* Tag name is given */
1625                 if (s)
1626                 {
1627                         /* Store the tag */
1628                         if (!add_tag(&f_ptr->tag, head, s)) return (7);
1629                 }
1630
1631                 /* Default "mimic" */
1632                 f_ptr->mimic = i;
1633
1634                 /* Default "destroyed state" -- if not specified */
1635                 f_ptr->destroyed = i;
1636
1637                 /* Default "states" */
1638                 for (i = 0; i < MAX_FEAT_STATES; i++) f_ptr->state[i].action = FF_FLAG_MAX;
1639         }
1640
1641         /* There better be a current f_ptr */
1642         else if (!f_ptr) return (3);
1643
1644 #ifdef JP
1645         else if (buf[0] == 'J')
1646         {
1647                 /* Store the name */
1648                 if (!add_name(&f_ptr->name, head, buf+2)) return (7);
1649         }
1650
1651         else if (buf[0] == 'E')
1652         {
1653                 /* Ignore english name */
1654         }
1655 #else
1656         else if (buf[0] == 'J')
1657         {
1658                 /* Ignore Japanese name */
1659         }
1660
1661         else if (buf[0] == 'E')
1662         {
1663                 /* Acquire the Text */
1664                 s = buf+2;
1665
1666                 /* Store the name */
1667                 if (!add_name(&f_ptr->name, head, s)) return (7);
1668         }
1669 #endif
1670
1671
1672         /* Process 'M' for "Mimic" (one line only) */
1673         else if (buf[0] == 'M')
1674         {
1675                 s16b offset;
1676
1677                 if (!add_tag(&offset, head, buf + 2)) return PARSE_ERROR_OUT_OF_MEMORY;
1678
1679                 /* Record a fake tag index */
1680                 f_ptr->mimic = -offset;
1681         }
1682
1683
1684         /* Process 'G' for "Graphics" (one line only) */
1685         else if (buf[0] == 'G')
1686         {
1687                 int j;
1688                 byte s_attr;
1689                 char char_tmp[F_LIT_MAX];
1690
1691                 /* Paranoia */
1692                 if (buf[1] != ':') return (1);
1693                 if (!buf[2]) return (1);
1694                 if (buf[3] != ':') return (1);
1695                 if (!buf[4]) return (1);
1696
1697                 /* Extract the char */
1698                 char_tmp[F_LIT_STANDARD] = buf[2];
1699
1700                 /* Extract the color */
1701                 s_attr = color_char_to_attr(buf[4]);
1702
1703                 /* Paranoia */
1704                 if (s_attr > 127) return (1);
1705
1706                 /* Save the standard values */
1707                 f_ptr->d_attr[F_LIT_STANDARD] = s_attr;
1708                 f_ptr->d_char[F_LIT_STANDARD] = char_tmp[F_LIT_STANDARD];
1709
1710                 /* Is this feature supports lighting? */
1711                 if (buf[5] == ':')
1712                 {
1713                         /* G:c:a:LIT (default) */
1714                         apply_default_feat_lighting(f_ptr->d_attr, f_ptr->d_char);
1715
1716                         /* G:c:a:lc:la:dc:da */
1717                         if (!streq(buf + 6, "LIT"))
1718                         {
1719                                 char attr_lite_tmp[F_LIT_MAX - F_LIT_NS_BEGIN];
1720
1721                                 if ((F_LIT_MAX - F_LIT_NS_BEGIN) * 2 != sscanf(buf + 6, "%c:%c:%c:%c",
1722                                         &char_tmp[F_LIT_LITE], &attr_lite_tmp[F_LIT_LITE - F_LIT_NS_BEGIN],
1723                                         &char_tmp[F_LIT_DARK], &attr_lite_tmp[F_LIT_DARK - F_LIT_NS_BEGIN])) return 1;
1724                                 if (buf[F_LIT_MAX * 4 + 1]) return 1;
1725
1726                                 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
1727                                 {
1728                                         switch (attr_lite_tmp[j - F_LIT_NS_BEGIN])
1729                                         {
1730                                         case '*':
1731                                                 /* Use default lighting */
1732                                                 break;
1733                                         case '-':
1734                                                 /* No lighting support */
1735                                                 f_ptr->d_attr[j] = f_ptr->d_attr[F_LIT_STANDARD];
1736                                                 break;
1737                                         default:
1738                                                 /* Extract the color */
1739                                                 f_ptr->d_attr[j] = color_char_to_attr(attr_lite_tmp[j - F_LIT_NS_BEGIN]);
1740                                                 if (f_ptr->d_attr[j] > 127) return 1;
1741                                                 break;
1742                                         }
1743                                         f_ptr->d_char[j] = char_tmp[j];
1744                                 }
1745                         }
1746                 }
1747                 else if (!buf[5])
1748                 {
1749                         for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
1750                         {
1751                                 f_ptr->d_attr[j] = s_attr;
1752                                 f_ptr->d_char[j] = char_tmp[F_LIT_STANDARD];
1753                         }
1754                 }
1755                 else return 1;
1756         }
1757
1758         /* Hack -- Process 'F' for flags */
1759         else if (buf[0] == 'F')
1760         {
1761                 /* Parse every entry textually */
1762                 for (s = buf + 2; *s; )
1763                 {
1764                         /* Find the end of this entry */
1765                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
1766
1767                         /* Nuke and skip any dividers */
1768                         if (*t)
1769                         {
1770                                 *t++ = '\0';
1771                                 while (*t == ' ' || *t == '|') t++;
1772                         }
1773
1774                         /* XXX XXX XXX Hack -- Read feature subtype */
1775                         if (1 == sscanf(s, "SUBTYPE_%d", &i))
1776                         {
1777                                 /* Extract a "subtype" */
1778                                 f_ptr->subtype =  i;
1779
1780                                 /* Start at next entry */
1781                                 s = t;
1782
1783                                 /* Continue */
1784                                 continue;
1785                         }
1786
1787                         /* XXX XXX XXX Hack -- Read feature power */
1788                         if (1 == sscanf(s, "POWER_%d", &i))
1789                         {
1790                                 /* Extract a "power" */
1791                                 f_ptr->power =  i;
1792
1793                                 /* Start at next entry */
1794                                 s = t;
1795
1796                                 /* Continue */
1797                                 continue;
1798                         }
1799
1800                         /* Parse this entry */
1801                         if (0 != grab_one_feat_flag(f_ptr, s)) return (PARSE_ERROR_INVALID_FLAG);
1802
1803                         /* Start the next entry */
1804                         s = t;
1805                 }
1806         }
1807
1808         /* Process 'W' for "More Info" (one line only) */
1809         else if (buf[0] == 'W')
1810         {
1811                 int priority;
1812
1813                 /* Scan for the value */
1814                 if (1 != sscanf(buf+2, "%d", &priority)) return (PARSE_ERROR_GENERIC);
1815
1816                 /* Save the value */
1817                 f_ptr->priority = priority;
1818         }
1819
1820         /* Process 'K' for "States" (up to four lines + default (which cannot be last)) */
1821         else if (buf[0] == 'K')
1822         {
1823                 s16b offset;
1824
1825                 /* Find the next empty state slot (if any) */
1826                 for (i = 0; i < MAX_FEAT_STATES; i++) if (f_ptr->state[i].action == FF_FLAG_MAX) break;
1827
1828                 /* Oops, no more slots */
1829                 if (i == MAX_FEAT_STATES) return PARSE_ERROR_GENERIC;
1830
1831                 /* Analyze the first field */
1832                 for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
1833
1834                 /* Terminate the field (if necessary) */
1835                 if (*t == ':') *t++ = '\0';
1836
1837                 /* Is this default entry? */
1838                 if (streq(s, "DESTROYED"))
1839                 {
1840                         if (!add_tag(&offset, head, t)) return PARSE_ERROR_OUT_OF_MEMORY;
1841
1842                         /* Record a fake tag index */
1843                         f_ptr->destroyed = -offset;
1844                 }
1845                 else
1846                 {
1847                         /* Reset */
1848                         f_ptr->state[i].action = 0;
1849
1850                         /* Parse this entry */
1851                         if (0 != grab_one_feat_action(f_ptr, s, i)) return PARSE_ERROR_INVALID_FLAG;
1852
1853                         if (!add_tag(&offset, head, t)) return PARSE_ERROR_OUT_OF_MEMORY;
1854
1855                         /* Record a fake tag index */
1856                         f_ptr->state[i].result = -offset;
1857                 }
1858         }
1859
1860         /* Oops */
1861         else    return (6);
1862
1863         /* Success */
1864         return (0);
1865 }
1866
1867
1868 /*
1869  * Convert a fake tag to a real feat index
1870  */
1871 s16b f_tag_to_index(cptr str)
1872 {
1873         u16b i;
1874
1875         /* Search for real index corresponding to this fake tag */
1876         for (i = 0; i < f_head.info_num; i++)
1877         {
1878                 if (streq(f_tag + f_info[i].tag, str))
1879                 {
1880                         /* Return the index */
1881                         return (s16b)i;
1882                 }
1883         }
1884
1885         /* Not found */
1886         return -1;
1887 }
1888
1889
1890 /*
1891  * Search for real index corresponding to this fake tag
1892  */
1893 static void search_real_feat(s16b *feat)
1894 {
1895         int i;
1896
1897         /* Don't convert non-fake tag */
1898         if (*feat >= 0) return;
1899
1900         /* Search for real index corresponding to this fake tag */
1901         for (i = 0; i < f_head.info_num; i++)
1902         {
1903                 if ((-(*feat)) == f_info[i].tag)
1904                 {
1905                         /* Record real index */
1906                         *feat = (s16b)i;
1907                         return;
1908                 }
1909         }
1910
1911         /* Undefined tag */
1912 #ifdef JP
1913         msg_format("̤ÄêµÁ¤Î¥¿¥° '%s'¡£", f_tag + (-(*feat)));
1914 #else
1915         msg_format("%s is undefined.", f_tag + (-(*feat)));
1916 #endif
1917 }
1918
1919
1920 /*
1921  * Retouch fake tags of f_info
1922  */
1923 void retouch_f_info(header *head)
1924 {
1925         int i;
1926
1927         /* Convert fake tags to real feat indices */
1928         for (i = 0; i < head->info_num; i++)
1929         {
1930                 feature_type *f_ptr = &f_info[i];
1931                 int j;
1932
1933                 search_real_feat(&f_ptr->mimic);
1934
1935                 search_real_feat(&f_ptr->destroyed);
1936
1937                 for (j = 0; j < MAX_FEAT_STATES; j++) search_real_feat(&f_ptr->state[j].result);
1938         }
1939 }
1940
1941
1942 /*
1943  * Grab one flag in an object_kind from a textual string
1944  */
1945 static errr grab_one_kind_flag(object_kind *k_ptr, cptr what)
1946 {
1947         int i;
1948
1949         /* Check flags */
1950         for (i = 0; i < TR_FLAG_MAX; i++)
1951         {
1952                 if (streq(what, k_info_flags[i]))
1953                 {
1954                         add_flag(k_ptr->flags, i);
1955                         return (0);
1956                 }
1957         }
1958
1959         if (grab_one_flag(&k_ptr->gen_flags, k_info_gen_flags, what) == 0)
1960                 return 0;
1961
1962         /* Oops */
1963 #ifdef JP
1964         msg_format("̤ÃΤΥ¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
1965 #else
1966         msg_format("Unknown object flag '%s'.", what);
1967 #endif
1968
1969
1970         /* Error */
1971         return (1);
1972 }
1973
1974
1975 /*
1976  * Initialize the "k_info" array, by parsing an ascii "template" file
1977  */
1978 errr parse_k_info(char *buf, header *head)
1979 {
1980         int i;
1981
1982         char *s, *t;
1983
1984         /* Current entry */
1985         static object_kind *k_ptr = NULL;
1986
1987
1988         /* Process 'N' for "New/Number/Name" */
1989         if (buf[0] == 'N')
1990         {
1991 #ifdef JP
1992                 char *flavor;
1993 #endif
1994
1995                 /* Find the colon before the name */
1996                 s = my_strchr(buf+2, ':');
1997
1998                 /* Verify that colon */
1999                 if (!s) return (1);
2000
2001                 /* Nuke the colon, advance to the name */
2002                 *s++ = '\0';
2003
2004                 /* Get the index */
2005                 i = atoi(buf+2);
2006
2007                 /* Verify information */
2008                 if (i <= error_idx) return (4);
2009
2010                 /* Verify information */
2011                 if (i >= head->info_num) return (2);
2012
2013                 /* Save the index */
2014                 error_idx = i;
2015
2016                 /* Point at the "info" */
2017                 k_ptr = &k_info[i];
2018
2019 #ifdef JP
2020                 /* Paranoia -- require a name */
2021                 if (!*s) return (1);
2022
2023                 /* Find the colon before the flavor */
2024                 flavor = my_strchr(s, ':');
2025
2026                 /* Verify that colon */
2027                 if (flavor)
2028                 {
2029                         /* Nuke the colon, advance to the flavor */
2030                         *flavor++ = '\0';
2031
2032                         /* Store the flavor */
2033                         if (!add_name(&k_ptr->flavor_name, head, flavor)) return (7);
2034                 }
2035
2036                 /* Store the name */
2037                 if (!add_name(&k_ptr->name, head, s)) return (7);
2038 #endif
2039         }
2040
2041         /* There better be a current k_ptr */
2042         else if (!k_ptr) return (3);
2043
2044
2045 #ifdef JP
2046         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2047         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
2048         else if (buf[0] == 'E')
2049         {
2050                 /* nothing to do */
2051         }
2052 #else
2053         else if (buf[0] == 'E')
2054         {
2055                 char *flavor;
2056
2057                 /* Acquire the name */
2058                 s = buf+2;
2059
2060                 /* Find the colon before the flavor */
2061                 flavor = my_strchr(s, ':');
2062
2063                 /* Verify that colon */
2064                 if (flavor)
2065                 {
2066                         /* Nuke the colon, advance to the flavor */
2067                         *flavor++ = '\0';
2068
2069                         /* Store the flavor */
2070                         if (!add_name(&k_ptr->flavor_name, head, flavor)) return (7);
2071                 }
2072
2073                 /* Store the name */
2074                 if (!add_name(&k_ptr->name, head, s)) return (7);
2075         }
2076 #endif
2077
2078         /* Process 'D' for "Description" */
2079         else if (buf[0] == 'D')
2080         {
2081 #ifdef JP
2082                 if (buf[2] == '$')
2083                         return (0);
2084                 /* Acquire the text */
2085                 s = buf+2;
2086 #else
2087                 if (buf[2] != '$')
2088                         return (0);
2089                 /* Acquire the text */
2090                 s = buf+3;
2091 #endif
2092
2093                 /* Store the text */
2094                 if (!add_text(&k_ptr->text, head, s, TRUE)) return (7);
2095         }
2096
2097         /* Process 'G' for "Graphics" (one line only) */
2098         else if (buf[0] == 'G')
2099         {
2100                 char sym;
2101                 byte tmp;
2102
2103                 /* Paranoia */
2104                 if (buf[1] != ':') return (1);
2105                 if (!buf[2]) return (1);
2106                 if (buf[3] != ':') return (1);
2107                 if (!buf[4]) return (1);
2108
2109                 /* Extract the char */
2110                 sym = buf[2];
2111
2112                 /* Extract the attr */
2113                 tmp = color_char_to_attr(buf[4]);
2114
2115                 /* Paranoia */
2116                 if (tmp > 127) return (1);
2117
2118                 /* Save the values */
2119                 k_ptr->d_attr = tmp;
2120                 k_ptr->d_char = sym;
2121         }
2122
2123         /* Process 'I' for "Info" (one line only) */
2124         else if (buf[0] == 'I')
2125         {
2126                 int tval, sval, pval;
2127
2128                 /* Scan for the values */
2129                 if (3 != sscanf(buf+2, "%d:%d:%d",
2130                                 &tval, &sval, &pval)) return (1);
2131
2132                 /* Save the values */
2133                 k_ptr->tval = tval;
2134                 k_ptr->sval = sval;
2135                 k_ptr->pval = pval;
2136         }
2137
2138         /* Process 'W' for "More Info" (one line only) */
2139         else if (buf[0] == 'W')
2140         {
2141                 int level, extra, wgt;
2142                 long cost;
2143
2144                 /* Scan for the values */
2145                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
2146                                 &level, &extra, &wgt, &cost)) return (1);
2147
2148                 /* Save the values */
2149                 k_ptr->level = level;
2150                 k_ptr->extra = extra;
2151                 k_ptr->weight = wgt;
2152                 k_ptr->cost = cost;
2153         }
2154
2155         /* Process 'A' for "Allocation" (one line only) */
2156         else if (buf[0] == 'A')
2157         {
2158                 int i;
2159
2160                 /* XXX XXX XXX Simply read each number following a colon */
2161                 for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i)
2162                 {
2163                                 /* Default chance */
2164                         k_ptr->chance[i] = 1;
2165
2166                                 /* Store the attack damage index */
2167                         k_ptr->locale[i] = atoi(s+1);
2168
2169                                 /* Find the slash */
2170                         t = my_strchr(s+1, '/');
2171
2172                                 /* Find the next colon */
2173                         s = my_strchr(s+1, ':');
2174
2175                                 /* If the slash is "nearby", use it */
2176                         if (t && (!s || t < s))
2177                         {
2178                                 int chance = atoi(t+1);
2179                                 if (chance > 0) k_ptr->chance[i] = chance;
2180                         }
2181                 }
2182         }
2183
2184         /* Hack -- Process 'P' for "power" and such */
2185         else if (buf[0] == 'P')
2186         {
2187                 int ac, hd1, hd2, th, td, ta;
2188
2189                 /* Scan for the values */
2190                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2191                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
2192
2193                 k_ptr->ac = ac;
2194                 k_ptr->dd = hd1;
2195                 k_ptr->ds = hd2;
2196                 k_ptr->to_h = th;
2197                 k_ptr->to_d = td;
2198                 k_ptr->to_a =  ta;
2199         }
2200
2201         /* Hack -- Process 'F' for flags */
2202         else if (buf[0] == 'F')
2203         {
2204                 /* Parse every entry textually */
2205                 for (s = buf + 2; *s; )
2206                 {
2207                                 /* Find the end of this entry */
2208                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2209
2210                                 /* Nuke and skip any dividers */
2211                         if (*t)
2212                         {
2213                                 *t++ = '\0';
2214                                 while (*t == ' ' || *t == '|') t++;
2215                         }
2216
2217                                 /* Parse this entry */
2218                         if (0 != grab_one_kind_flag(k_ptr, s)) return (5);
2219
2220                                 /* Start the next entry */
2221                         s = t;
2222                 }
2223         }
2224
2225
2226         /* Oops */
2227         else return (6);
2228
2229
2230         /* Success */
2231         return (0);
2232 }
2233
2234
2235 /*
2236  * Grab one flag in an artifact_type from a textual string
2237  */
2238 static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what)
2239 {
2240         int i;
2241
2242         /* Check flags */
2243         for (i = 0; i < TR_FLAG_MAX; i++)
2244         {
2245                 if (streq(what, k_info_flags[i]))
2246                 {
2247                         add_flag(a_ptr->flags, i);
2248                         return (0);
2249                 }
2250         }
2251
2252         if (grab_one_flag(&a_ptr->gen_flags, k_info_gen_flags, what) == 0)
2253                 return 0;
2254
2255         /* Oops */
2256 #ifdef JP
2257         msg_format("̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
2258 #else
2259         msg_format("Unknown artifact flag '%s'.", what);
2260 #endif
2261
2262
2263         /* Error */
2264         return (1);
2265 }
2266
2267 /*
2268  * Grab one activation index flag
2269  */
2270 static byte grab_one_activation_flag(cptr what)
2271 {
2272         int i;
2273
2274         for (i = 0; ; i++)
2275         {
2276                 if (k_info_activation_flags[i].flag == NULL) break;
2277
2278                 if (streq(what, k_info_activation_flags[i].flag))
2279                 {
2280                         return k_info_activation_flags[i].index;
2281                 }
2282         }
2283
2284         i = atoi(what);
2285          if (i > 0)
2286          {
2287                  return ((byte) i);
2288          }
2289
2290         /* Oops */
2291 #ifdef JP
2292         msg_format("̤ÃΤÎȯư¡¦¥Õ¥é¥° '%s'¡£", what);
2293 #else
2294         msg_format("Unknown activation flag '%s'.", what);
2295 #endif
2296
2297         /* Error */
2298         return (0);
2299 }
2300
2301
2302 /*
2303  * Initialize the "a_info" array, by parsing an ascii "template" file
2304  */
2305 errr parse_a_info(char *buf, header *head)
2306 {
2307         int i;
2308
2309         char *s, *t;
2310
2311         /* Current entry */
2312         static artifact_type *a_ptr = NULL;
2313
2314
2315         /* Process 'N' for "New/Number/Name" */
2316         if (buf[0] == 'N')
2317         {
2318                 /* Find the colon before the name */
2319                 s = my_strchr(buf+2, ':');
2320
2321                         /* Verify that colon */
2322                 if (!s) return (1);
2323
2324                 /* Nuke the colon, advance to the name */
2325                 *s++ = '\0';
2326 #ifdef JP
2327                 /* Paranoia -- require a name */
2328                 if (!*s) return (1);
2329 #endif
2330                 /* Get the index */
2331                 i = atoi(buf+2);
2332
2333                 /* Verify information */
2334                 if (i < error_idx) return (4);
2335
2336                 /* Verify information */
2337                 if (i >= head->info_num) return (2);
2338
2339                 /* Save the index */
2340                 error_idx = i;
2341
2342                 /* Point at the "info" */
2343                 a_ptr = &a_info[i];
2344
2345                 /* Ignore everything */
2346                 add_flag(a_ptr->flags, TR_IGNORE_ACID);
2347                 add_flag(a_ptr->flags, TR_IGNORE_ELEC);
2348                 add_flag(a_ptr->flags, TR_IGNORE_FIRE);
2349                 add_flag(a_ptr->flags, TR_IGNORE_COLD);
2350 #ifdef JP
2351                 /* Store the name */
2352                 if (!add_name(&a_ptr->name, head, s)) return (7);
2353 #endif
2354         }
2355
2356         /* There better be a current a_ptr */
2357         else if (!a_ptr) return (3);
2358
2359
2360 #ifdef JP
2361         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2362         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾¤È¤·¤Æ¤¤¤ë */
2363         else if (buf[0] == 'E')
2364         {
2365                 /* nothing to do */
2366         }
2367 #else
2368         else if (buf[0] == 'E')
2369         {
2370                 /* Acquire the Text */
2371                 s = buf+2;
2372
2373                 /* Store the name */
2374                 if (!add_name(&a_ptr->name, head, s)) return (7);
2375         }
2376 #endif
2377
2378         /* Process 'D' for "Description" */
2379         else if (buf[0] == 'D')
2380         {
2381 #ifdef JP
2382                 if (buf[2] == '$')
2383                         return (0);
2384                 /* Acquire the text */
2385                 s = buf+2;
2386 #else
2387                 if (buf[2] != '$')
2388                         return (0);
2389                 /* Acquire the text */
2390                 s = buf+3;
2391 #endif
2392
2393                 /* Store the text */
2394                 if (!add_text(&a_ptr->text, head, s, TRUE)) return (7);
2395         }
2396
2397
2398         /* Process 'I' for "Info" (one line only) */
2399         else if (buf[0] == 'I')
2400         {
2401                 int tval, sval, pval;
2402
2403                 /* Scan for the values */
2404                 if (3 != sscanf(buf+2, "%d:%d:%d",
2405                                 &tval, &sval, &pval)) return (1);
2406
2407                 /* Save the values */
2408                 a_ptr->tval = tval;
2409                 a_ptr->sval = sval;
2410                 a_ptr->pval = pval;
2411         }
2412
2413         /* Process 'W' for "More Info" (one line only) */
2414         else if (buf[0] == 'W')
2415         {
2416                 int level, rarity, wgt;
2417                 long cost;
2418
2419                 /* Scan for the values */
2420                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
2421                                 &level, &rarity, &wgt, &cost)) return (1);
2422
2423                 /* Save the values */
2424                 a_ptr->level = level;
2425                 a_ptr->rarity = rarity;
2426                 a_ptr->weight = wgt;
2427                 a_ptr->cost = cost;
2428         }
2429
2430         /* Hack -- Process 'P' for "power" and such */
2431         else if (buf[0] == 'P')
2432         {
2433                 int ac, hd1, hd2, th, td, ta;
2434
2435                 /* Scan for the values */
2436                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2437                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
2438
2439                 a_ptr->ac = ac;
2440                 a_ptr->dd = hd1;
2441                 a_ptr->ds = hd2;
2442                 a_ptr->to_h = th;
2443                 a_ptr->to_d = td;
2444                 a_ptr->to_a =  ta;
2445         }
2446
2447         /* Hack -- Process 'U' for activation index */
2448         else if (buf[0] == 'U')
2449         {
2450                 byte n;
2451                 n = grab_one_activation_flag(buf + 2);
2452                 if (n > 0)
2453                 {
2454                         a_ptr->act_idx = n;
2455                 }
2456                 else
2457                 {
2458                         return (5);
2459                 }
2460         }
2461
2462         /* Hack -- Process 'F' for flags */
2463         else if (buf[0] == 'F')
2464         {
2465                 /* Parse every entry textually */
2466                 for (s = buf + 2; *s; )
2467                 {
2468                                 /* Find the end of this entry */
2469                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2470
2471                                 /* Nuke and skip any dividers */
2472                         if (*t)
2473                         {
2474                                 *t++ = '\0';
2475                                 while ((*t == ' ') || (*t == '|')) t++;
2476                         }
2477
2478                                 /* Parse this entry */
2479                         if (0 != grab_one_artifact_flag(a_ptr, s)) return (5);
2480
2481                                 /* Start the next entry */
2482                         s = t;
2483                 }
2484         }
2485
2486
2487         /* Oops */
2488         else return (6);
2489
2490
2491         /* Success */
2492         return (0);
2493 }
2494
2495
2496 /*
2497  * Grab one flag in a ego-item_type from a textual string
2498  */
2499 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what)
2500 {
2501         int i;
2502
2503         /* Check flags */
2504         for (i = 0; i < TR_FLAG_MAX; i++)
2505         {
2506                 if (streq(what, k_info_flags[i]))
2507                 {
2508                         add_flag(e_ptr->flags, i);
2509                         return (0);
2510                 }
2511         }
2512
2513         if (grab_one_flag(&e_ptr->gen_flags, k_info_gen_flags, what) == 0)
2514                 return 0;
2515
2516         /* Oops */
2517 #ifdef JP
2518         msg_format("̤ÃΤÎ̾¤Î¤¢¤ë¥¢¥¤¥Æ¥à¡¦¥Õ¥é¥° '%s'¡£", what);
2519 #else
2520         msg_format("Unknown ego-item flag '%s'.", what);
2521 #endif
2522
2523
2524         /* Error */
2525         return (1);
2526 }
2527
2528
2529
2530
2531 /*
2532  * Initialize the "e_info" array, by parsing an ascii "template" file
2533  */
2534 errr parse_e_info(char *buf, header *head)
2535 {
2536         int i;
2537
2538         char *s, *t;
2539
2540         /* Current entry */
2541         static ego_item_type *e_ptr = NULL;
2542
2543
2544         /* Just before the first record */
2545         error_idx = -1;
2546
2547         /* Just before the first line */
2548         error_line = -1;
2549
2550
2551         /* Process 'N' for "New/Number/Name" */
2552         if (buf[0] == 'N')
2553         {
2554                 /* Find the colon before the name */
2555                 s = my_strchr(buf+2, ':');
2556
2557                         /* Verify that colon */
2558                 if (!s) return (1);
2559
2560                 /* Nuke the colon, advance to the name */
2561                 *s++ = '\0';
2562 #ifdef JP
2563                 /* Paranoia -- require a name */
2564                 if (!*s) return (1);
2565 #endif
2566                 /* Get the index */
2567                 i = atoi(buf+2);
2568
2569                 /* Verify information */
2570                 if (i < error_idx) return (4);
2571
2572                 /* Verify information */
2573                 if (i >= head->info_num) return (2);
2574
2575                 /* Save the index */
2576                 error_idx = i;
2577
2578                 /* Point at the "info" */
2579                 e_ptr = &e_info[i];
2580 #ifdef JP
2581                 /* Store the name */
2582                 if (!add_name(&e_ptr->name, head, s)) return (7);
2583 #endif
2584         }
2585
2586         /* There better be a current e_ptr */
2587         else if (!e_ptr) return (3);
2588
2589
2590 #ifdef JP
2591         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2592         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
2593         else if (buf[0] == 'E')
2594         {
2595                 /* nothing to do */
2596         }
2597 #else
2598         else if (buf[0] == 'E')
2599         {
2600                 /* Acquire the Text */
2601                 s = buf+2;
2602
2603                 /* Store the name */
2604                 if (!add_name(&e_ptr->name, head, s)) return (7);
2605         }
2606 #endif
2607 #if 0
2608
2609         /* Process 'D' for "Description" */
2610         else if (buf[0] == 'D')
2611         {
2612                 /* Acquire the text */
2613                 s = buf+2;
2614
2615                 /* Store the text */
2616                 if (!add_text(&e_ptr->text, head, s, TRUE)) return (7);
2617         }
2618
2619 #endif
2620
2621         /* Process 'X' for "Xtra" (one line only) */
2622         else if (buf[0] == 'X')
2623         {
2624                 int slot, rating;
2625
2626                 /* Scan for the values */
2627                 if (2 != sscanf(buf+2, "%d:%d",
2628                                 &slot, &rating)) return (1);
2629
2630                 /* Save the values */
2631                 e_ptr->slot = slot;
2632                 e_ptr->rating = rating;
2633         }
2634
2635         /* Process 'W' for "More Info" (one line only) */
2636         else if (buf[0] == 'W')
2637         {
2638                 int level, rarity, pad2;
2639                 long cost;
2640
2641                 /* Scan for the values */
2642                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
2643                                 &level, &rarity, &pad2, &cost)) return (1);
2644
2645                 /* Save the values */
2646                 e_ptr->level = level;
2647                 e_ptr->rarity = rarity;
2648                 /* e_ptr->weight = wgt; */
2649                 e_ptr->cost = cost;
2650         }
2651
2652         /* Hack -- Process 'C' for "creation" */
2653         else if (buf[0] == 'C')
2654         {
2655                 int th, td, ta, pv;
2656
2657                 /* Scan for the values */
2658                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
2659                                 &th, &td, &ta, &pv)) return (1);
2660
2661                 e_ptr->max_to_h = th;
2662                 e_ptr->max_to_d = td;
2663                 e_ptr->max_to_a = ta;
2664                 e_ptr->max_pval = pv;
2665         }
2666
2667         /* Hack -- Process 'F' for flags */
2668         else if (buf[0] == 'F')
2669         {
2670                 /* Parse every entry textually */
2671                 for (s = buf + 2; *s; )
2672                 {
2673                                 /* Find the end of this entry */
2674                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2675
2676                                 /* Nuke and skip any dividers */
2677                         if (*t)
2678                         {
2679                                 *t++ = '\0';
2680                                 while ((*t == ' ') || (*t == '|')) t++;
2681                         }
2682
2683                                 /* Parse this entry */
2684                         if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5);
2685
2686                                 /* Start the next entry */
2687                         s = t;
2688                 }
2689         }
2690
2691         /* Oops */
2692         else return (6);
2693
2694         /* Success */
2695         return (0);
2696 }
2697
2698
2699 /*
2700  * Grab one (basic) flag in a monster_race from a textual string
2701  */
2702 static errr grab_one_basic_flag(monster_race *r_ptr, cptr what)
2703 {
2704         if (grab_one_flag(&r_ptr->flags1, r_info_flags1, what) == 0)
2705                 return 0;
2706
2707         if (grab_one_flag(&r_ptr->flags2, r_info_flags2, what) == 0)
2708                 return 0;
2709
2710         if (grab_one_flag(&r_ptr->flags3, r_info_flags3, what) == 0)
2711                 return 0;
2712
2713         if (grab_one_flag(&r_ptr->flags7, r_info_flags7, what) == 0)
2714                 return 0;
2715
2716         if (grab_one_flag(&r_ptr->flags8, r_info_flags8, what) == 0)
2717                 return 0;
2718
2719         if (grab_one_flag(&r_ptr->flags9, r_info_flags9, what) == 0)
2720                 return 0;
2721
2722         if (grab_one_flag(&r_ptr->flagsr, r_info_flagsr, what) == 0)
2723                 return 0;
2724
2725         /* Oops */
2726 #ifdef JP
2727         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2728 #else
2729         msg_format("Unknown monster flag '%s'.", what);
2730 #endif
2731
2732
2733         /* Failure */
2734         return (1);
2735 }
2736
2737
2738 /*
2739  * Grab one (spell) flag in a monster_race from a textual string
2740  */
2741 static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
2742 {
2743         if (grab_one_flag(&r_ptr->flags4, r_info_flags4, what) == 0)
2744                 return 0;
2745
2746         if (grab_one_flag(&r_ptr->flags5, r_info_flags5, what) == 0)
2747                 return 0;
2748
2749         if (grab_one_flag(&r_ptr->flags6, r_info_flags6, what) == 0)
2750                 return 0;
2751
2752         /* Oops */
2753 #ifdef JP
2754         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
2755 #else
2756         msg_format("Unknown monster flag '%s'.", what);
2757 #endif
2758
2759
2760         /* Failure */
2761         return (1);
2762 }
2763
2764
2765
2766
2767 /*
2768  * Initialize the "r_info" array, by parsing an ascii "template" file
2769  */
2770 errr parse_r_info(char *buf, header *head)
2771 {
2772         int i;
2773
2774         char *s, *t;
2775
2776         /* Current entry */
2777         static monster_race *r_ptr = NULL;
2778
2779
2780         /* Process 'N' for "New/Number/Name" */
2781         if (buf[0] == 'N')
2782         {
2783                 /* Find the colon before the name */
2784                 s = my_strchr(buf+2, ':');
2785
2786                         /* Verify that colon */
2787                 if (!s) return (1);
2788
2789                 /* Nuke the colon, advance to the name */
2790                 *s++ = '\0';
2791 #ifdef JP
2792                 /* Paranoia -- require a name */
2793                 if (!*s) return (1);
2794 #endif
2795                 /* Get the index */
2796                 i = atoi(buf+2);
2797
2798                 /* Verify information */
2799                 if (i < error_idx) return (4);
2800
2801                 /* Verify information */
2802                 if (i >= head->info_num) return (2);
2803
2804                 /* Save the index */
2805                 error_idx = i;
2806
2807                 /* Point at the "info" */
2808                 r_ptr = &r_info[i];
2809 #ifdef JP
2810                 /* Store the name */
2811                 if (!add_name(&r_ptr->name, head, s)) return (7);
2812 #endif
2813         }
2814
2815         /* There better be a current r_ptr */
2816         else if (!r_ptr) return (3);
2817
2818
2819 #ifdef JP
2820         /* ±Ñ¸ì̾¤òÆɤà¥ë¡¼¥Á¥ó¤òÄɲà*/
2821         /* 'E' ¤«¤é»Ï¤Þ¤ë¹Ô¤Ï±Ñ¸ì̾ */
2822         else if (buf[0] == 'E')
2823         {
2824                 /* Acquire the Text */
2825                 s = buf+2;
2826
2827                 /* Store the name */
2828                 if (!add_name(&r_ptr->E_name, head, s)) return (7);
2829         }
2830 #else
2831         else if (buf[0] == 'E')
2832         {
2833                 /* Acquire the Text */
2834                 s = buf+2;
2835
2836                 /* Store the name */
2837                 if (!add_name(&r_ptr->name, head, s)) return (7);
2838         }
2839 #endif
2840         /* Process 'D' for "Description" */
2841         else if (buf[0] == 'D')
2842         {
2843 #ifdef JP
2844                 if (buf[2] == '$')
2845                         return (0);
2846                 /* Acquire the text */
2847                 s = buf+2;
2848 #else
2849                 if (buf[2] != '$')
2850                         return (0);
2851                 /* Acquire the text */
2852                 s = buf+3;
2853 #endif
2854
2855                 /* Store the text */
2856                 if (!add_text(&r_ptr->text, head, s, TRUE)) return (7);
2857         }
2858
2859         /* Process 'G' for "Graphics" (one line only) */
2860         else if (buf[0] == 'G')
2861         {
2862                 char sym;
2863                 byte tmp;
2864
2865                 /* Paranoia */
2866                 if (buf[1] != ':') return (1);
2867                 if (!buf[2]) return (1);
2868                 if (buf[3] != ':') return (1);
2869                 if (!buf[4]) return (1);
2870
2871                 /* Extract the char */
2872                 sym = buf[2];
2873
2874                 /* Extract the attr */
2875                 tmp = color_char_to_attr(buf[4]);
2876
2877                 /* Paranoia */
2878                 if (tmp > 127) return (1);
2879
2880                 /* Save the values */
2881                 r_ptr->d_char = sym;
2882                 r_ptr->d_attr = tmp;
2883         }
2884
2885         /* Process 'I' for "Info" (one line only) */
2886         else if (buf[0] == 'I')
2887         {
2888                 int spd, hp1, hp2, aaf, ac, slp;
2889
2890                 /* Scan for the other values */
2891                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2892                                 &spd, &hp1, &hp2, &aaf, &ac, &slp)) return (1);
2893
2894                 /* Save the values */
2895                 r_ptr->speed = spd;
2896                 r_ptr->hdice = MAX(hp1, 1);
2897                 r_ptr->hside = MAX(hp2, 1);
2898                 r_ptr->aaf = aaf;
2899                 r_ptr->ac = ac;
2900                 r_ptr->sleep = slp;
2901         }
2902
2903         /* Process 'W' for "More Info" (one line only) */
2904         else if (buf[0] == 'W')
2905         {
2906                 int lev, rar, pad;
2907                 long exp;
2908                 long nextexp;
2909                 int nextmon;
2910
2911                 /* Scan for the values */
2912                 if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d",
2913                                 &lev, &rar, &pad, &exp, &nextexp, &nextmon)) return (1);
2914
2915                 /* Save the values */
2916                 r_ptr->level = lev;
2917                 r_ptr->rarity = rar;
2918                 r_ptr->extra = pad;
2919                 r_ptr->mexp = exp;
2920                 r_ptr->next_exp = nextexp;
2921                 r_ptr->next_r_idx = nextmon;
2922         }
2923
2924         /* Process 'B' for "Blows" (up to four lines) */
2925         else if (buf[0] == 'B')
2926         {
2927                 int n1, n2;
2928
2929                 /* Find the next empty blow slot (if any) */
2930                 for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break;
2931
2932                 /* Oops, no more slots */
2933                 if (i == 4) return (1);
2934
2935                 /* Analyze the first field */
2936                 for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
2937
2938                 /* Terminate the field (if necessary) */
2939                 if (*t == ':') *t++ = '\0';
2940
2941                 /* Analyze the method */
2942                 for (n1 = 0; r_info_blow_method[n1]; n1++)
2943                 {
2944                         if (streq(s, r_info_blow_method[n1])) break;
2945                 }
2946
2947                 /* Invalid method */
2948                 if (!r_info_blow_method[n1]) return (1);
2949
2950                 /* Analyze the second field */
2951                 for (s = t; *t && (*t != ':'); t++) /* loop */;
2952
2953                 /* Terminate the field (if necessary) */
2954                 if (*t == ':') *t++ = '\0';
2955
2956                 /* Analyze effect */
2957                 for (n2 = 0; r_info_blow_effect[n2]; n2++)
2958                 {
2959                         if (streq(s, r_info_blow_effect[n2])) break;
2960                 }
2961
2962                 /* Invalid effect */
2963                 if (!r_info_blow_effect[n2]) return (1);
2964
2965                 /* Analyze the third field */
2966                 for (s = t; *t && (*t != 'd'); t++) /* loop */;
2967
2968                 /* Terminate the field (if necessary) */
2969                 if (*t == 'd') *t++ = '\0';
2970
2971                 /* Save the method */
2972                 r_ptr->blow[i].method = n1;
2973
2974                 /* Save the effect */
2975                 r_ptr->blow[i].effect = n2;
2976
2977                 /* Extract the damage dice and sides */
2978                 r_ptr->blow[i].d_dice = atoi(s);
2979                 r_ptr->blow[i].d_side = atoi(t);
2980         }
2981
2982         /* Process 'F' for "Basic Flags" (multiple lines) */
2983         else if (buf[0] == 'F')
2984         {
2985                 /* Parse every entry */
2986                 for (s = buf + 2; *s; )
2987                 {
2988                                 /* Find the end of this entry */
2989                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2990
2991                                 /* Nuke and skip any dividers */
2992                         if (*t)
2993                         {
2994                                 *t++ = '\0';
2995                                 while (*t == ' ' || *t == '|') t++;
2996                         }
2997
2998                                 /* Parse this entry */
2999                         if (0 != grab_one_basic_flag(r_ptr, s)) return (5);
3000
3001                                 /* Start the next entry */
3002                         s = t;
3003                 }
3004         }
3005
3006         /* Process 'S' for "Spell Flags" (multiple lines) */
3007         else if (buf[0] == 'S')
3008         {
3009                 /* Parse every entry */
3010                 for (s = buf + 2; *s; )
3011                 {
3012                                 /* Find the end of this entry */
3013                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3014
3015                                 /* Nuke and skip any dividers */
3016                         if (*t)
3017                         {
3018                                 *t++ = '\0';
3019                                 while ((*t == ' ') || (*t == '|')) t++;
3020                         }
3021
3022                                 /* XXX XXX XXX Hack -- Read spell frequency */
3023                         if (1 == sscanf(s, "1_IN_%d", &i))
3024                         {
3025                                 /* Extract a "frequency" */
3026                                 r_ptr->freq_spell = 100 / i;
3027
3028                                         /* Start at next entry */
3029                                 s = t;
3030
3031                                 /* Continue */
3032                                 continue;
3033                         }
3034
3035                                 /* Parse this entry */
3036                         if (0 != grab_one_spell_flag(r_ptr, s)) return (5);
3037
3038                                 /* Start the next entry */
3039                         s = t;
3040                 }
3041         }
3042
3043         /* Oops */
3044         else return (6);
3045
3046
3047         /* Success */
3048         return (0);
3049 }
3050
3051
3052 /*
3053  * Grab one flag for a dungeon type from a textual string
3054  */
3055 static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what)
3056 {
3057         if (grab_one_flag(&d_ptr->flags1, d_info_flags1, what) == 0)
3058                 return 0;
3059
3060         /* Oops */
3061 #ifdef JP
3062         msg_format("̤ÃΤΥÀ¥ó¥¸¥ç¥ó¡¦¥Õ¥é¥° '%s'¡£", what);
3063 #else
3064         msg_format("Unknown dungeon type flag '%s'.", what);
3065 #endif
3066
3067         /* Failure */
3068         return (1);
3069 }
3070
3071 /*
3072  * Grab one (basic) flag in a monster_race from a textual string
3073  */
3074 static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what)
3075 {
3076         if (grab_one_flag(&d_ptr->mflags1, r_info_flags1, what) == 0)
3077                 return 0;
3078
3079         if (grab_one_flag(&d_ptr->mflags2, r_info_flags2, what) == 0)
3080                 return 0;
3081
3082         if (grab_one_flag(&d_ptr->mflags3, r_info_flags3, what) == 0)
3083                 return 0;
3084
3085         if (grab_one_flag(&d_ptr->mflags7, r_info_flags7, what) == 0)
3086                 return 0;
3087
3088         if (grab_one_flag(&d_ptr->mflags8, r_info_flags8, what) == 0)
3089                 return 0;
3090
3091         if (grab_one_flag(&d_ptr->mflags9, r_info_flags9, what) == 0)
3092                 return 0;
3093
3094         if (grab_one_flag(&d_ptr->mflagsr, r_info_flagsr, what) == 0)
3095                 return 0;
3096
3097         /* Oops */
3098 #ifdef JP
3099         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
3100 #else
3101         msg_format("Unknown monster flag '%s'.", what);
3102 #endif
3103         /* Failure */
3104         return (1);
3105 }
3106
3107
3108 /*
3109  * Grab one (spell) flag in a monster_race from a textual string
3110  */
3111 static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what)
3112 {
3113         if (grab_one_flag(&d_ptr->mflags4, r_info_flags4, what) == 0)
3114                 return 0;
3115
3116         if (grab_one_flag(&d_ptr->mflags5, r_info_flags5, what) == 0)
3117                 return 0;
3118
3119         if (grab_one_flag(&d_ptr->mflags6, r_info_flags6, what) == 0)
3120                 return 0;
3121
3122         /* Oops */
3123 #ifdef JP
3124         msg_format("̤ÃΤΥâ¥ó¥¹¥¿¡¼¡¦¥Õ¥é¥° '%s'¡£", what);
3125 #else
3126         msg_format("Unknown monster flag '%s'.", what);
3127 #endif
3128
3129         /* Failure */
3130         return (1);
3131 }
3132
3133 /*
3134  * Initialize the "d_info" array, by parsing an ascii "template" file
3135  */
3136 errr parse_d_info(char *buf, header *head)
3137 {
3138         int i;
3139
3140         char *s, *t;
3141
3142         /* Current entry */
3143         static dungeon_info_type *d_ptr = NULL;
3144
3145
3146         /* Process 'N' for "New/Number/Name" */
3147         if (buf[0] == 'N')
3148         {
3149                 /* Find the colon before the name */
3150                 s = my_strchr(buf+2, ':');
3151
3152                 /* Verify that colon */
3153                 if (!s) return (1);
3154
3155                 /* Nuke the colon, advance to the name */
3156                 *s++ = '\0';
3157 #ifdef JP
3158                 /* Paranoia -- require a name */
3159                 if (!*s) return (1);
3160 #endif
3161                 /* Get the index */
3162                 i = atoi(buf+2);
3163
3164                 /* Verify information */
3165                 if (i < error_idx) return (4);
3166
3167                 /* Verify information */
3168                 if (i >= head->info_num) return (2);
3169
3170                 /* Save the index */
3171                 error_idx = i;
3172
3173                 /* Point at the "info" */
3174                 d_ptr = &d_info[i];
3175 #ifdef JP
3176                 /* Store the name */
3177                 if (!add_name(&d_ptr->name, head, s)) return (7);
3178 #endif
3179         }
3180
3181 #ifdef JP
3182         else if (buf[0] == 'E') return (0);
3183 #else
3184         else if (buf[0] == 'E')
3185         {
3186                 /* Acquire the Text */
3187                 s = buf+2;
3188
3189                 /* Store the name */
3190                 if (!add_name(&d_ptr->name, head, s)) return (7);
3191         }
3192 #endif
3193
3194         /* Process 'D' for "Description */
3195         else if (buf[0] == 'D')
3196         {
3197 #ifdef JP
3198                 if (buf[2] == '$')
3199                         return (0);
3200                 /* Acquire the text */
3201                 s = buf+2;
3202 #else
3203                 if (buf[2] != '$')
3204                         return (0);
3205                 /* Acquire the text */
3206                 s = buf+3;
3207 #endif
3208
3209                 /* Store the text */
3210                 if (!add_text(&d_ptr->text, head, s, TRUE)) return (7);
3211         }
3212
3213         /* Process 'W' for "More Info" (one line only) */
3214         else if (buf[0] == 'W')
3215         {
3216                 int min_lev, max_lev;
3217                 int min_plev, mode;
3218                 int min_alloc, max_chance;
3219                 int obj_good, obj_great;
3220                 int pit, nest;
3221
3222                 /* Scan for the values */
3223                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x",
3224                                  &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1);
3225
3226                 /* Save the values */
3227                 d_ptr->mindepth = min_lev;
3228                 d_ptr->maxdepth = max_lev;
3229                 d_ptr->min_plev = min_plev;
3230                 d_ptr->mode = mode;
3231                 d_ptr->min_m_alloc_level = min_alloc;
3232                 d_ptr->max_m_alloc_chance = max_chance;
3233                 d_ptr->obj_good = obj_good;
3234                 d_ptr->obj_great = obj_great;
3235                 d_ptr->pit = pit;
3236                 d_ptr->nest = nest;
3237         }
3238
3239         /* Process 'P' for "Place Info" */
3240         else if (buf[0] == 'P')
3241         {
3242                 int dy, dx;
3243
3244                 /* Scan for the values */
3245                 if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1);
3246
3247                 /* Save the values */
3248                 d_ptr->dy = dy;
3249                 d_ptr->dx = dx;
3250         }
3251
3252         /* Process 'L' for "fLoor type" (one line only) */
3253         else if (buf[0] == 'L')
3254         {
3255                 char *zz[16];
3256
3257                 /* Scan for the values */
3258                 if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 1, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 1)) return (1);
3259
3260                 /* Save the values */
3261                 for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++)
3262                 {
3263                         d_ptr->floor[i].feat = f_tag_to_index(zz[i * 2]);
3264                         if (d_ptr->floor[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3265
3266                         d_ptr->floor[i].percent = atoi(zz[i * 2 + 1]);
3267                 }
3268                 d_ptr->tunnel_percent = atoi(zz[DUNGEON_FEAT_PROB_NUM * 2]);
3269         }
3270
3271         /* Process 'A' for "wAll type" (one line only) */
3272         else if (buf[0] == 'A')
3273         {
3274                 char *zz[16];
3275
3276                 /* Scan for the values */
3277                 if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 4, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 4)) return (1);
3278
3279                 /* Save the values */
3280                 for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++)
3281                 {
3282                         d_ptr->fill[i].feat = f_tag_to_index(zz[i * 2]);
3283                         if (d_ptr->fill[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3284
3285                         d_ptr->fill[i].percent = atoi(zz[i * 2 + 1]);
3286                 }
3287
3288                 d_ptr->outer_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2]);
3289                 if (d_ptr->outer_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3290
3291                 d_ptr->inner_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 1]);
3292                 if (d_ptr->inner_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3293
3294                 d_ptr->stream1 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 2]);
3295                 if (d_ptr->stream1 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3296
3297                 d_ptr->stream2 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 3]);
3298                 if (d_ptr->stream2 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3299         }
3300
3301         /* Process 'F' for "Dungeon Flags" (multiple lines) */
3302         else if (buf[0] == 'F')
3303         {
3304                 int artif = 0, monst = 0;
3305
3306                 /* Parse every entry */
3307                 for (s = buf + 2; *s; )
3308                 {
3309                         /* Find the end of this entry */
3310                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3311
3312                         /* Nuke and skip any dividers */
3313                         if (*t)
3314                         {
3315                                 *t++ = '\0';
3316                                 while (*t == ' ' || *t == '|') t++;
3317                         }
3318
3319                         /* XXX XXX XXX Hack -- Read Final Artifact */
3320                         if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif))
3321                         {
3322                                 /* Extract a "Final Artifact" */
3323                                 d_ptr->final_artifact = artif;
3324
3325                                 /* Start at next entry */
3326                                 s = t;
3327
3328                                 /* Continue */
3329                                 continue;
3330                         }
3331
3332                         /* XXX XXX XXX Hack -- Read Final Object */
3333                         if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif))
3334                         {
3335                                 /* Extract a "Final Artifact" */
3336                                 d_ptr->final_object = artif;
3337
3338                                 /* Start at next entry */
3339                                 s = t;
3340
3341                                 /* Continue */
3342                                 continue;
3343                         }
3344
3345                         /* XXX XXX XXX Hack -- Read Artifact Guardian */
3346                         if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst))
3347                         {
3348                                 /* Extract a "Artifact Guardian" */
3349                                 d_ptr->final_guardian = monst;
3350
3351                                 /* Start at next entry */
3352                                 s = t;
3353
3354                                 /* Continue */
3355                                 continue;
3356                         }
3357
3358                         /* XXX XXX XXX Hack -- Read Special Percentage */
3359                         if (1 == sscanf(s, "MONSTER_DIV_%d", &monst))
3360                         {
3361                                 /* Extract a "Special %" */
3362                                 d_ptr->special_div = monst;
3363
3364                                 /* Start at next entry */
3365                                 s = t;
3366
3367                                 /* Continue */
3368                                 continue;
3369                         }
3370
3371                         /* Parse this entry */
3372                         if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5);
3373
3374                         /* Start the next entry */
3375                         s = t;
3376                 }
3377         }
3378
3379         /* Process 'M' for "Basic Flags" (multiple lines) */
3380         else if (buf[0] == 'M')
3381         {
3382                 /* Parse every entry */
3383                 for (s = buf + 2; *s; )
3384                 {
3385                         /* Find the end of this entry */
3386                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3387
3388                         /* Nuke and skip any dividers */
3389                         if (*t)
3390                         {
3391                                 *t++ = '\0';
3392                                 while (*t == ' ' || *t == '|') t++;
3393                         }
3394
3395                         /* Hack -- Read monster symbols */
3396                         if (!strncmp(s, "R_CHAR_", 7))
3397                         {
3398                                 /* Skip "R_CHAR_" */
3399                                 s += 7;
3400
3401                                 /* Read a string */
3402                                 strncpy(d_ptr->r_char, s, sizeof(d_ptr->r_char));
3403
3404                                 /* Start at next entry */
3405                                 s = t;
3406
3407                                 /* Continue */
3408                                 continue;
3409                         }
3410
3411                         /* Parse this entry */
3412                         if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5);
3413
3414                         /* Start the next entry */
3415                         s = t;
3416                 }
3417         }
3418
3419         /* Process 'S' for "Spell Flags" (multiple lines) */
3420         else if (buf[0] == 'S')
3421         {
3422                 /* Parse every entry */
3423                 for (s = buf + 2; *s; )
3424                 {
3425                                 /* Find the end of this entry */
3426                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3427
3428                                 /* Nuke and skip any dividers */
3429                         if (*t)
3430                         {
3431                                 *t++ = '\0';
3432                                 while ((*t == ' ') || (*t == '|')) t++;
3433                         }
3434
3435                                 /* XXX XXX XXX Hack -- Read spell frequency */
3436                         if (1 == sscanf(s, "1_IN_%d", &i))
3437                         {
3438                                 /* Start at next entry */
3439                                 s = t;
3440
3441                                         /* Continue */
3442                                 continue;
3443                         }
3444
3445                                 /* Parse this entry */
3446                         if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5);
3447
3448                                 /* Start the next entry */
3449                         s = t;
3450                 }
3451         }
3452
3453         /* Oops */
3454         else return (6);
3455
3456         /* Success */
3457         return (0);
3458 }
3459
3460
3461 #else   /* ALLOW_TEMPLATES */
3462
3463 #ifdef MACINTOSH
3464 static int i = 0;
3465 #endif
3466
3467 #endif  /* ALLOW_TEMPLATES */
3468
3469
3470 /* Random dungeon grid effects */
3471 #define RANDOM_NONE         0x00000000
3472 #define RANDOM_FEATURE      0x00000001
3473 #define RANDOM_MONSTER      0x00000002
3474 #define RANDOM_OBJECT       0x00000004
3475 #define RANDOM_EGO          0x00000008
3476 #define RANDOM_ARTIFACT     0x00000010
3477 #define RANDOM_TRAP         0x00000020
3478
3479
3480 typedef struct dungeon_grid dungeon_grid;
3481
3482 struct dungeon_grid
3483 {
3484         int             feature;                /* Terrain feature */
3485         int             monster;                /* Monster */
3486         int             object;                 /* Object */
3487         int             ego;                    /* Ego-Item */
3488         int             artifact;               /* Artifact */
3489         int             trap;                   /* Trap */
3490         int             cave_info;              /* Flags for CAVE_MARK, CAVE_GLOW, CAVE_ICKY, CAVE_ROOM */
3491         int             special;                /* Reserved for special terrain info */
3492         int             random;                 /* Number of the random effect */
3493 };
3494
3495
3496 static dungeon_grid letter[255];
3497
3498
3499 /*
3500  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3501  */
3502 static errr parse_line_feature(char *buf)
3503 {
3504         int num;
3505         char *zz[9];
3506
3507
3508         if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3509
3510         /* Tokenize the line */
3511         if ((num = tokenize(buf+2, 9, zz, 0)) > 1)
3512         {
3513                 /* Letter to assign */
3514                 int index = zz[0][0];
3515
3516                 /* Reset the info for the letter */
3517                 letter[index].feature = feat_none;
3518                 letter[index].monster = 0;
3519                 letter[index].object = 0;
3520                 letter[index].ego = 0;
3521                 letter[index].artifact = 0;
3522                 letter[index].trap = feat_none;
3523                 letter[index].cave_info = 0;
3524                 letter[index].special = 0;
3525                 letter[index].random = RANDOM_NONE;
3526
3527                 switch (num)
3528                 {
3529                         /* Special */
3530                         case 9:
3531                                 letter[index].special = atoi(zz[8]);
3532                                 /* Fall through */
3533                         /* Trap */
3534                         case 8:
3535                                 if ((zz[7][0] == '*') && !zz[7][1])
3536                                 {
3537                                         letter[index].random |= RANDOM_TRAP;
3538                                 }
3539                                 else
3540                                 {
3541                                         letter[index].trap = f_tag_to_index(zz[7]);
3542                                         if (letter[index].trap < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3543                                 }
3544                                 /* Fall through */
3545                         /* Artifact */
3546                         case 7:
3547                                 if (zz[6][0] == '*')
3548                                 {
3549                                         letter[index].random |= RANDOM_ARTIFACT;
3550                                         if (zz[6][1]) letter[index].artifact = atoi(zz[6] + 1);
3551                                 }
3552                                 else if (zz[6][0] == '!')
3553                                 {
3554                                         if (p_ptr->inside_quest)
3555                                         {
3556                                                 letter[index].artifact = quest[p_ptr->inside_quest].k_idx;
3557                                         }
3558                                 }
3559                                 else
3560                                 {
3561                                         letter[index].artifact = atoi(zz[6]);
3562                                 }
3563                                 /* Fall through */
3564                         /* Ego-item */
3565                         case 6:
3566                                 if (zz[5][0] == '*')
3567                                 {
3568                                         letter[index].random |= RANDOM_EGO;
3569                                         if (zz[5][1]) letter[index].ego = atoi(zz[5] + 1);
3570                                 }
3571                                 else
3572                                 {
3573                                         letter[index].ego = atoi(zz[5]);
3574                                 }
3575                                 /* Fall through */
3576                         /* Object */
3577                         case 5:
3578                                 if (zz[4][0] == '*')
3579                                 {
3580                                         letter[index].random |= RANDOM_OBJECT;
3581                                         if (zz[4][1]) letter[index].object = atoi(zz[4] + 1);
3582                                 }
3583                                 else if (zz[4][0] == '!')
3584                                 {
3585                                         if (p_ptr->inside_quest)
3586                                         {
3587                                                 int a_idx = quest[p_ptr->inside_quest].k_idx;
3588                                                 if (a_idx)
3589                                                 {
3590                                                         artifact_type *a_ptr = &a_info[a_idx];
3591                                                         if (!(a_ptr->gen_flags & TRG_INSTA_ART))
3592                                                         {
3593                                                                 letter[index].object = lookup_kind(a_ptr->tval, a_ptr->sval);
3594                                                         }
3595                                                 }
3596                                         }
3597                                 }
3598                                 else
3599                                 {
3600                                         letter[index].object = atoi(zz[4]);
3601                                 }
3602                                 /* Fall through */
3603                         /* Monster */
3604                         case 4:
3605                                 if (zz[3][0] == '*')
3606                                 {
3607                                         letter[index].random |= RANDOM_MONSTER;
3608                                         if (zz[3][1]) letter[index].monster = atoi(zz[3] + 1);
3609                                 }
3610                                 else if (zz[3][0] == 'c')
3611                                 {
3612                                         if (!zz[3][1]) return PARSE_ERROR_GENERIC;
3613                                         letter[index].monster = - atoi(zz[3] + 1);
3614                                 }
3615                                 else
3616                                 {
3617                                         letter[index].monster = atoi(zz[3]);
3618                                 }
3619                                 /* Fall through */
3620                         /* Cave info */
3621                         case 3:
3622                                 letter[index].cave_info = atoi(zz[2]);
3623                                 /* Fall through */
3624                         /* Feature */
3625                         case 2:
3626                                 if ((zz[1][0] == '*') && !zz[1][1])
3627                                 {
3628                                         letter[index].random |= RANDOM_FEATURE;
3629                                 }
3630                                 else
3631                                 {
3632                                         letter[index].feature = f_tag_to_index(zz[1]);
3633                                         if (letter[index].feature < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3634                                 }
3635                                 break;
3636                 }
3637
3638                 return (0);
3639         }
3640
3641         return (1);
3642 }
3643
3644
3645 /*
3646  * Process "B:<Index>:<Command>:..." -- Building definition
3647  */
3648 static errr parse_line_building(char *buf)
3649 {
3650         int i;
3651         char *zz[37];
3652         int index;
3653         char *s;
3654
3655 #ifdef JP
3656         if (buf[2] == '$')
3657                 return 0;
3658         s = buf + 2;
3659 #else
3660         if (buf[2] != '$')
3661                 return 0;
3662         s = buf + 3;
3663 #endif
3664         /* Get the building number */
3665         index = atoi(s);
3666
3667         /* Find the colon after the building number */
3668         s = my_strchr(s, ':');
3669
3670         /* Verify that colon */
3671         if (!s) return (1);
3672
3673         /* Nuke the colon, advance to the sub-index */
3674         *s++ = '\0';
3675
3676         /* Paranoia -- require a sub-index */
3677         if (!*s) return (1);
3678
3679         /* Building definition sub-index */
3680         switch (s[0])
3681         {
3682                 /* Building name, owner, race */
3683                 case 'N':
3684                 {
3685                         if (tokenize(s + 2, 3, zz, 0) == 3)
3686                         {
3687                                 /* Name of the building */
3688                                 strcpy(building[index].name, zz[0]);
3689
3690                                 /* Name of the owner */
3691                                 strcpy(building[index].owner_name, zz[1]);
3692
3693                                 /* Race of the owner */
3694                                 strcpy(building[index].owner_race, zz[2]);
3695
3696                                 break;
3697                         }
3698
3699                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3700                 }
3701
3702                 /* Building Action */
3703                 case 'A':
3704                 {
3705                         if (tokenize(s + 2, 8, zz, 0) >= 7)
3706                         {
3707                                 /* Index of the action */
3708                                 int action_index = atoi(zz[0]);
3709
3710                                 /* Name of the action */
3711                                 strcpy(building[index].act_names[action_index], zz[1]);
3712
3713                                 /* Cost of the action for members */
3714                                 building[index].member_costs[action_index] = atoi(zz[2]);
3715
3716                                 /* Cost of the action for non-members */
3717                                 building[index].other_costs[action_index] = atoi(zz[3]);
3718
3719                                 /* Letter assigned to the action */
3720                                 building[index].letters[action_index] = zz[4][0];
3721
3722                                 /* Action code */
3723                                 building[index].actions[action_index] = atoi(zz[5]);
3724
3725                                 /* Action restriction */
3726                                 building[index].action_restr[action_index] = atoi(zz[6]);
3727
3728                                 break;
3729                         }
3730
3731                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3732                 }
3733
3734                 /* Building Classes */
3735                 case 'C':
3736                 {
3737                         if (tokenize(s + 2, MAX_CLASS, zz, 0) == MAX_CLASS)
3738                         {
3739                                 for (i = 0; i < MAX_CLASS; i++)
3740                                 {
3741                                         building[index].member_class[i] = atoi(zz[i]);
3742                                 }
3743
3744                                 break;
3745                         }
3746
3747                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3748                 }
3749
3750                 /* Building Races */
3751                 case 'R':
3752                 {
3753                         if (tokenize(s+2, MAX_RACES, zz, 0) == MAX_RACES)
3754                         {
3755                                 for (i = 0; i < MAX_RACES; i++)
3756                                 {
3757                                         building[index].member_race[i] = atoi(zz[i]);
3758                                 }
3759
3760                                 break;
3761                         }
3762
3763                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3764                 }
3765
3766                 /* Building Realms */
3767                 case 'M':
3768                 {
3769                         if (tokenize(s+2, MAX_MAGIC, zz, 0) == MAX_MAGIC)
3770                         {
3771                                 for (i = 0; i < MAX_MAGIC; i++)
3772                                 {
3773                                         building[index].member_realm[i+1] = atoi(zz[i]);
3774                                 }
3775
3776                                 break;
3777                         }
3778
3779                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3780                 }
3781
3782                 case 'Z':
3783                 {
3784                         /* Ignore scripts */
3785                         break;
3786                 }
3787
3788                 default:
3789                 {
3790                         return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
3791                 }
3792         }
3793
3794         return (0);
3795 }
3796
3797
3798 /*
3799  * Place the object j_ptr to a grid
3800  */
3801 static void drop_here(object_type *j_ptr, int y, int x)
3802 {
3803         cave_type *c_ptr = &cave[y][x];
3804         object_type *o_ptr;
3805
3806         /* Get new object */
3807         s16b o_idx = o_pop();
3808
3809         /* Access new object */
3810         o_ptr = &o_list[o_idx];
3811
3812         /* Structure copy */
3813         object_copy(o_ptr, j_ptr);
3814
3815
3816         /* Locate */
3817         o_ptr->iy = y;
3818         o_ptr->ix = x;
3819
3820         /* No monster */
3821         o_ptr->held_m_idx = 0;
3822
3823         /* Build a stack */
3824         o_ptr->next_o_idx = c_ptr->o_idx;
3825
3826         /* Place the object */
3827         c_ptr->o_idx = o_idx;
3828 }
3829
3830
3831 /*
3832  * Parse a sub-file of the "extra info"
3833  */
3834 static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
3835 {
3836         int i;
3837
3838         char *zz[33];
3839
3840
3841         /* Skip "empty" lines */
3842         if (!buf[0]) return (0);
3843
3844         /* Skip "blank" lines */
3845         if (isspace(buf[0])) return (0);
3846
3847         /* Skip comments */
3848         if (buf[0] == '#') return (0);
3849
3850         /* Require "?:*" format */
3851         if (buf[1] != ':') return (1);
3852
3853
3854         /* Process "%:<fname>" */
3855         if (buf[0] == '%')
3856         {
3857                 /* Attempt to Process the given file */
3858                 return (process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax));
3859         }
3860
3861         /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
3862         if (buf[0] == 'F')
3863         {
3864                 return parse_line_feature(buf);
3865         }
3866
3867         /* Process "D:<dungeon>" -- info for the cave grids */
3868         else if (buf[0] == 'D')
3869         {
3870                 object_type object_type_body;
3871
3872                 /* Acquire the text */
3873                 char *s = buf + 2;
3874
3875                 /* Length of the text */
3876                 int len = strlen(s);
3877
3878                 if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3879
3880                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
3881                 {
3882                         /* Access the grid */
3883                         cave_type *c_ptr = &cave[*y][*x];
3884
3885                         int idx = s[0];
3886
3887                         int object_index = letter[idx].object;
3888                         int monster_index = letter[idx].monster;
3889                         int random = letter[idx].random;
3890                         int artifact_index = letter[idx].artifact;
3891
3892                         /* Lay down a floor */
3893                         c_ptr->feat = conv_dungeon_feat(letter[idx].feature);
3894
3895                         /* Only the features */
3896                         if (init_flags & INIT_ONLY_FEATURES) continue;
3897
3898                         /* Cave info */
3899                         c_ptr->info = letter[idx].cave_info;
3900
3901                         /* Create a monster */
3902                         if (random & RANDOM_MONSTER)
3903                         {
3904                                 monster_level = base_level + monster_index;
3905
3906                                 place_monster(*y, *x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));
3907
3908                                 monster_level = base_level;
3909                         }
3910                         else if (monster_index)
3911                         {
3912                                 int old_cur_num, old_max_num;
3913                                 bool clone = FALSE;
3914
3915                                 if (monster_index < 0)
3916                                 {
3917                                         monster_index = -monster_index;
3918                                         clone = TRUE;
3919                                 }
3920                                 old_cur_num = r_info[monster_index].cur_num;
3921                                 old_max_num = r_info[monster_index].max_num;
3922
3923                                 /* Make alive again */
3924                                 if (r_info[monster_index].flags1 & RF1_UNIQUE)
3925                                 {
3926                                         r_info[monster_index].cur_num = 0;
3927                                         r_info[monster_index].max_num = 1;
3928                                 }
3929
3930                                 /* Make alive again */
3931                                 /* Hack -- Non-unique Nazguls are semi-unique */
3932                                 else if (r_info[monster_index].flags7 & RF7_NAZGUL)
3933                                 {
3934                                         if (r_info[monster_index].cur_num == r_info[monster_index].max_num)
3935                                         {
3936                                                 r_info[monster_index].max_num++;
3937                                         }
3938                                 }
3939
3940                                 /* Place it */
3941                                 place_monster_aux(0, *y, *x, monster_index, (PM_ALLOW_SLEEP | PM_NO_KAGE));
3942                                 if (clone)
3943                                 {
3944                                         /* clone */
3945                                         m_list[hack_m_idx_ii].smart |= SM_CLONED;
3946
3947                                         /* Make alive again for real unique monster */
3948                                         r_info[monster_index].cur_num = old_cur_num;
3949                                         r_info[monster_index].max_num = old_max_num;
3950                                 }
3951                         }
3952
3953                         /* Object (and possible trap) */
3954                         if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP))
3955                         {
3956                                 object_level = base_level + object_index;
3957
3958                                 /*
3959                                  * Random trap and random treasure defined
3960                                  * 25% chance for trap and 75% chance for object
3961                                  */
3962                                 if (randint0(100) < 75)
3963                                 {
3964                                         place_object(*y, *x, 0L);
3965                                 }
3966                                 else
3967                                 {
3968                                         place_trap(*y, *x);
3969                                 }
3970
3971                                 object_level = base_level;
3972                         }
3973                         else if (random & RANDOM_OBJECT)
3974                         {
3975                                 object_level = base_level + object_index;
3976
3977                                 /* Create an out of deep object */
3978                                 if (randint0(100) < 75)
3979                                         place_object(*y, *x, 0L);
3980                                 else if (randint0(100) < 80)
3981                                         place_object(*y, *x, AM_GOOD);
3982                                 else
3983                                         place_object(*y, *x, AM_GOOD | AM_GREAT);
3984
3985                                 object_level = base_level;
3986                         }
3987                         /* Random trap */
3988                         else if (random & RANDOM_TRAP)
3989                         {
3990                                 place_trap(*y, *x);
3991                         }
3992                         /* Hidden trap (or door) */
3993                         else if (letter[idx].trap)
3994                         {
3995                                 c_ptr->mimic = c_ptr->feat;
3996                                 c_ptr->feat = conv_dungeon_feat(letter[idx].trap);
3997                         }
3998                         else if (object_index)
3999                         {
4000                                 /* Get local object */
4001                                 object_type *o_ptr = &object_type_body;
4002
4003                                 /* Create the item */
4004                                 object_prep(o_ptr, object_index);
4005
4006                                 if (o_ptr->tval == TV_GOLD)
4007                                 {
4008                                         coin_type = object_index - OBJ_GOLD_LIST;
4009                                         make_gold(o_ptr);
4010                                         coin_type = 0;
4011                                 }
4012
4013                                 /* Apply magic (no messages, no artifacts) */
4014                                 apply_magic(o_ptr, base_level, AM_NO_FIXED_ART | AM_GOOD);
4015
4016                                 drop_here(o_ptr, *y, *x);
4017                         }
4018
4019                         /* Artifact */
4020                         if (artifact_index)
4021                         {
4022                                 if (a_info[artifact_index].cur_num)
4023                                 {
4024                                         int k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT);
4025                                         object_type forge;
4026                                         object_type *q_ptr = &forge;
4027
4028                                         object_prep(q_ptr, k_idx);
4029
4030                                         /* Drop it in the dungeon */
4031                                         drop_here(q_ptr, *y, *x);
4032                                 }
4033                                 else
4034                                 {
4035                                         /* Create the artifact */
4036                                         if (create_named_art(artifact_index, *y, *x))
4037                                                 a_info[artifact_index].cur_num = 1;
4038                                 }
4039                         }
4040
4041                         /* Terrain special */
4042                         c_ptr->special = letter[idx].special;
4043                 }
4044
4045                 (*y)++;
4046
4047                 return (0);
4048         }
4049
4050         /* Process "Q:<number>:<command>:... -- quest info */
4051         else if (buf[0] == 'Q')
4052         {
4053                 int num;
4054                 quest_type *q_ptr;
4055 #ifdef JP
4056                 if (buf[2] == '$')
4057                         return 0;
4058                 num = tokenize(buf + 2, 33, zz, 0);
4059 #else
4060                 if (buf[2] != '$')
4061                         return 0;
4062                 num = tokenize(buf + 3, 33, zz, 0);
4063 #endif
4064
4065                 /* Have we enough parameters? */
4066                 if (num < 3) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
4067
4068                 /* Get the quest */
4069                 q_ptr = &(quest[atoi(zz[0])]);
4070
4071                 /* Process "Q:<q_index>:Q:<type>:<num_mon>:<cur_num>:<max_num>:<level>:<r_idx>:<k_idx>:<flags>" -- quest info */
4072                 if (zz[1][0] == 'Q')
4073                 {
4074                         if (init_flags & INIT_ASSIGN)
4075                         {
4076                                 monster_race *r_ptr;
4077                                 artifact_type *a_ptr;
4078
4079                                 if (num < 9) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
4080
4081                                 q_ptr->type    = atoi(zz[2]);
4082                                 q_ptr->num_mon = atoi(zz[3]);
4083                                 q_ptr->cur_num = atoi(zz[4]);
4084                                 q_ptr->max_num = atoi(zz[5]);
4085                                 q_ptr->level   = atoi(zz[6]);
4086                                 q_ptr->r_idx   = atoi(zz[7]);
4087                                 q_ptr->k_idx   = atoi(zz[8]);
4088                                 q_ptr->dungeon = atoi(zz[9]);
4089
4090                                 if (num > 10)
4091                                         q_ptr->flags  = atoi(zz[10]);
4092
4093                                 r_ptr = &r_info[q_ptr->r_idx];
4094                                 if (r_ptr->flags1 & RF1_UNIQUE)
4095                                         r_ptr->flags1 |= RF1_QUESTOR;
4096
4097                                 a_ptr = &a_info[q_ptr->k_idx];
4098                                 a_ptr->gen_flags |= TRG_QUESTITEM;
4099                         }
4100                         return (0);
4101                 }
4102
4103                 else if (zz[1][0] == 'R')
4104                 {
4105                         if (init_flags & INIT_ASSIGN)
4106                         {
4107                                 int idx, count = 0;
4108                                 int reward_idx = 0;
4109
4110                                 for (idx = 2; idx < num; idx++)
4111                                 {
4112                                         int a_idx = atoi(zz[idx]);
4113                                         if (a_idx < 1) continue;
4114                                         if (a_info[a_idx].cur_num > 0) continue;
4115                                         count++;
4116                                         if (one_in_(count)) reward_idx = a_idx;
4117                                 }
4118
4119                                 if (reward_idx)
4120                                 {
4121                                         /* Set quest's rewarding artifact */
4122                                         q_ptr->k_idx = reward_idx;
4123                                         a_info[reward_idx].gen_flags |= TRG_QUESTITEM;
4124                                 }
4125                                 else
4126                                 {
4127                                         /* Change a quest type to KILL_ALL when all artifact of reward list are got */
4128                                         q_ptr->type = QUEST_TYPE_KILL_ALL;
4129                                 }
4130                         }
4131
4132                         return (0);
4133                 }
4134
4135                 /* Process "Q:<q_index>:N:<name>" -- quest name */
4136                 else if (zz[1][0] == 'N')
4137                 {
4138                         if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT | INIT_NAME_ONLY))
4139                         {
4140                                 strcpy(q_ptr->name, zz[2]);
4141                         }
4142
4143                         return (0);
4144                 }
4145
4146                 /* Process "Q:<q_index>:T:<text>" -- quest description line */
4147                 else if (zz[1][0] == 'T')
4148                 {
4149                         if (init_flags & INIT_SHOW_TEXT)
4150                         {
4151                                 strcpy(quest_text[quest_text_line], zz[2]);
4152                                 quest_text_line++;
4153                         }
4154
4155                         return (0);
4156                 }
4157         }
4158
4159         /* Process "W:<command>: ..." -- info for the wilderness */
4160         else if (buf[0] == 'W')
4161         {
4162                 return parse_line_wilderness(buf, ymin, xmin, ymax, xmax, y, x);
4163         }
4164
4165         /* Process "P:<y>:<x>" -- player position */
4166         else if (buf[0] == 'P')
4167         {
4168                 if (init_flags & INIT_CREATE_DUNGEON)
4169                 {
4170                         if (tokenize(buf + 2, 2, zz, 0) == 2)
4171                         {
4172                                 int panels_x, panels_y;
4173
4174                                 /* Hack - Set the dungeon size */
4175                                 panels_y = (*y / SCREEN_HGT);
4176                                 if (*y % SCREEN_HGT) panels_y++;
4177                                 cur_hgt = panels_y * SCREEN_HGT;
4178
4179                                 panels_x = (*x / SCREEN_WID);
4180                                 if (*x % SCREEN_WID) panels_x++;
4181                                 cur_wid = panels_x * SCREEN_WID;
4182
4183                                 /* Assume illegal panel */
4184                                 panel_row_min = cur_hgt;
4185                                 panel_col_min = cur_wid;
4186
4187                                 /* Place player in a quest level */
4188                                 if (p_ptr->inside_quest)
4189                                 {
4190                                         int y, x;
4191
4192                                         /* Delete the monster (if any) */
4193                                         delete_monster(py, px);
4194
4195                                         y = atoi(zz[0]);
4196                                         x = atoi(zz[1]);
4197
4198                                         py = y;
4199                                         px = x;
4200                                 }
4201                                 /* Place player in the town */
4202                                 else if (!p_ptr->oldpx && !p_ptr->oldpy)
4203                                 {
4204                                         p_ptr->oldpy = atoi(zz[0]);
4205                                         p_ptr->oldpx = atoi(zz[1]);
4206                                 }
4207                         }
4208                 }
4209
4210                 return (0);
4211         }
4212
4213         /* Process "B:<Index>:<Command>:..." -- Building definition */
4214         else if (buf[0] == 'B')
4215         {
4216                 return parse_line_building(buf);
4217         }
4218
4219         /* Process "M:<type>:<maximum>" -- set maximum values */
4220         else if (buf[0] == 'M')
4221         {
4222                 if (tokenize(buf+2, 2, zz, 0) == 2)
4223                 {
4224                         /* Maximum towns */
4225                         if (zz[0][0] == 'T')
4226                         {
4227                                 max_towns = atoi(zz[1]);
4228                         }
4229
4230                         /* Maximum quests */
4231                         else if (zz[0][0] == 'Q')
4232                         {
4233                                 max_quests = atoi(zz[1]);
4234                         }
4235
4236                         /* Maximum r_idx */
4237                         else if (zz[0][0] == 'R')
4238                         {
4239                                 max_r_idx = atoi(zz[1]);
4240                         }
4241
4242                         /* Maximum k_idx */
4243                         else if (zz[0][0] == 'K')
4244                         {
4245                                 max_k_idx = atoi(zz[1]);
4246                         }
4247
4248                         /* Maximum v_idx */
4249                         else if (zz[0][0] == 'V')
4250                         {
4251                                 max_v_idx = atoi(zz[1]);
4252                         }
4253
4254                         /* Maximum f_idx */
4255                         else if (zz[0][0] == 'F')
4256                         {
4257                                 max_f_idx = atoi(zz[1]);
4258                         }
4259
4260                         /* Maximum a_idx */
4261                         else if (zz[0][0] == 'A')
4262                         {
4263                                 max_a_idx = atoi(zz[1]);
4264                         }
4265
4266                         /* Maximum e_idx */
4267                         else if (zz[0][0] == 'E')
4268                         {
4269                                 max_e_idx = atoi(zz[1]);
4270                         }
4271
4272                         /* Maximum d_idx */
4273                         else if (zz[0][0] == 'D')
4274                         {
4275                                 max_d_idx = atoi(zz[1]); 
4276                         }
4277
4278                         /* Maximum o_idx */
4279                         else if (zz[0][0] == 'O')
4280                         {
4281                                 max_o_idx = atoi(zz[1]);
4282                         }
4283
4284                         /* Maximum m_idx */
4285                         else if (zz[0][0] == 'M')
4286                         {
4287                                 max_m_idx = atoi(zz[1]);
4288                         }
4289
4290                         /* Wilderness size */
4291                         else if (zz[0][0] == 'W')
4292                         {
4293                                 /* Maximum wild_x_size */
4294                                 if (zz[0][1] == 'X')
4295                                         max_wild_x = atoi(zz[1]);
4296                                 /* Maximum wild_y_size */
4297                                 if (zz[0][1] == 'Y')
4298                                         max_wild_y = atoi(zz[1]);
4299                         }
4300
4301                         return (0);
4302                 }
4303         }
4304
4305
4306         /* Failure */
4307         return (1);
4308 }
4309
4310
4311 static char tmp[8];
4312 static cptr variant = "ZANGBAND";
4313
4314
4315 /*
4316  * Helper function for "process_dungeon_file()"
4317  */
4318 static cptr process_dungeon_file_expr(char **sp, char *fp)
4319 {
4320         cptr v;
4321
4322         char *b;
4323         char *s;
4324
4325         char b1 = '[';
4326         char b2 = ']';
4327
4328         char f = ' ';
4329
4330         /* Initial */
4331         s = (*sp);
4332
4333         /* Skip spaces */
4334         while (isspace(*s)) s++;
4335
4336         /* Save start */
4337         b = s;
4338
4339         /* Default */
4340         v = "?o?o?";
4341
4342         /* Analyze */
4343         if (*s == b1)
4344         {
4345                 const char *p;
4346                 const char *t;
4347
4348                 /* Skip b1 */
4349                 s++;
4350
4351                 /* First */
4352                 t = process_dungeon_file_expr(&s, &f);
4353
4354                 /* Oops */
4355                 if (!*t)
4356                 {
4357                         /* Nothing */
4358                 }
4359
4360                 /* Function: IOR */
4361                 else if (streq(t, "IOR"))
4362                 {
4363                         v = "0";
4364                         while (*s && (f != b2))
4365                         {
4366                                 t = process_dungeon_file_expr(&s, &f);
4367                                 if (*t && !streq(t, "0")) v = "1";
4368                         }
4369                 }
4370
4371                 /* Function: AND */
4372                 else if (streq(t, "AND"))
4373                 {
4374                         v = "1";
4375                         while (*s && (f != b2))
4376                         {
4377                                 t = process_dungeon_file_expr(&s, &f);
4378                                 if (*t && streq(t, "0")) v = "0";
4379                         }
4380                 }
4381
4382                 /* Function: NOT */
4383                 else if (streq(t, "NOT"))
4384                 {
4385                         v = "1";
4386                         while (*s && (f != b2))
4387                         {
4388                                 t = process_dungeon_file_expr(&s, &f);
4389                                 if (*t && streq(t, "1")) v = "0";
4390                         }
4391                 }
4392
4393                 /* Function: EQU */
4394                 else if (streq(t, "EQU"))
4395                 {
4396                         v = "0";
4397                         if (*s && (f != b2))
4398                         {
4399                                 t = process_dungeon_file_expr(&s, &f);
4400                         }
4401                         while (*s && (f != b2))
4402                         {
4403                                 p = process_dungeon_file_expr(&s, &f);
4404                                 if (streq(t, p)) v = "1";
4405                         }
4406                 }
4407
4408                 /* Function: LEQ */
4409                 else if (streq(t, "LEQ"))
4410                 {
4411                         v = "1";
4412                         if (*s && (f != b2))
4413                         {
4414                                 t = process_dungeon_file_expr(&s, &f);
4415                         }
4416                         while (*s && (f != b2))
4417                         {
4418                                 p = t;
4419                                 t = process_dungeon_file_expr(&s, &f);
4420                                 if (*t && atoi(p) > atoi(t)) v = "0";
4421                         }
4422                 }
4423
4424                 /* Function: GEQ */
4425                 else if (streq(t, "GEQ"))
4426                 {
4427                         v = "1";
4428                         if (*s && (f != b2))
4429                         {
4430                                 t = process_dungeon_file_expr(&s, &f);
4431                         }
4432                         while (*s && (f != b2))
4433                         {
4434                                 p = t;
4435                                 t = process_dungeon_file_expr(&s, &f);
4436
4437                                 /* Compare two numbers instead of string */
4438                                 if (*t && atoi(p) < atoi(t)) v = "0";
4439                         }
4440                 }
4441
4442                 /* Oops */
4443                 else
4444                 {
4445                         while (*s && (f != b2))
4446                         {
4447                                 t = process_dungeon_file_expr(&s, &f);
4448                         }
4449                 }
4450
4451                 /* Verify ending */
4452                 if (f != b2) v = "?x?x?";
4453
4454                 /* Extract final and Terminate */
4455                 if ((f = *s) != '\0') *s++ = '\0';
4456         }
4457
4458         /* Other */
4459         else
4460         {
4461                 /* Accept all printables except spaces and brackets */
4462 #ifdef JP
4463                 while (iskanji(*s) || (isprint(*s) && !my_strchr(" []", *s)))
4464                 {
4465                         if (iskanji(*s)) s++;
4466                         s++;
4467                 }
4468 #else
4469                 while (isprint(*s) && !my_strchr(" []", *s)) ++s;
4470 #endif
4471
4472                 /* Extract final and Terminate */
4473                 if ((f = *s) != '\0') *s++ = '\0';
4474
4475                 /* Variable */
4476                 if (*b == '$')
4477                 {
4478                         /* System */
4479                         if (streq(b+1, "SYS"))
4480                         {
4481                                 v = ANGBAND_SYS;
4482                         }
4483
4484                         /* Graphics */
4485                         else if (streq(b+1, "GRAF"))
4486                         {
4487                                 v = ANGBAND_GRAF;
4488                         }
4489
4490                         else if (streq(b+1, "MONOCHROME"))
4491                         {
4492                                 if (arg_monochrome)
4493                                         v = "ON";
4494                                 else
4495                                         v = "OFF";
4496                         }
4497
4498                         /* Race */
4499                         else if (streq(b+1, "RACE"))
4500                         {
4501 #ifdef JP
4502                                 v = rp_ptr->E_title;
4503 #else
4504                                 v = rp_ptr->title;
4505 #endif
4506                         }
4507
4508                         /* Class */
4509                         else if (streq(b+1, "CLASS"))
4510                         {
4511 #ifdef JP
4512                                 v = cp_ptr->E_title;
4513 #else
4514                                 v = cp_ptr->title;
4515 #endif
4516                         }
4517
4518                         /* First realm */
4519                         else if (streq(b+1, "REALM1"))
4520                         {
4521 #ifdef JP
4522                                 v = E_realm_names[p_ptr->realm1];
4523 #else
4524                                 v = realm_names[p_ptr->realm1];
4525 #endif
4526                         }
4527
4528                         /* Second realm */
4529                         else if (streq(b+1, "REALM2"))
4530                         {
4531 #ifdef JP
4532                                 v = E_realm_names[p_ptr->realm2];
4533 #else
4534                                 v = realm_names[p_ptr->realm2];
4535 #endif
4536                         }
4537
4538                         /* Player name */
4539                         else if (streq(b+1, "PLAYER"))
4540                         {
4541                                 static char tmp_player_name[32];
4542                                 char *pn, *tpn;
4543                                 for (pn = player_name, tpn = tmp_player_name; *pn; pn++, tpn++)
4544                                 {
4545 #ifdef JP
4546                                         if (iskanji(*pn))
4547                                         {
4548                                                 *(tpn++) = *(pn++);
4549                                                 *tpn = *pn;
4550                                                 continue;
4551                                         }
4552 #endif
4553                                         *tpn = my_strchr(" []", *pn) ? '_' : *pn;
4554                                 }
4555                                 *tpn = '\0';
4556                                 v = tmp_player_name;
4557                         }
4558
4559                         /* Town */
4560                         else if (streq(b+1, "TOWN"))
4561                         {
4562                                 sprintf(tmp, "%d", p_ptr->town_num);
4563                                 v = tmp;
4564                         }
4565
4566                         /* Level */
4567                         else if (streq(b+1, "LEVEL"))
4568                         {
4569                                 sprintf(tmp, "%d", p_ptr->lev);
4570                                 v = tmp;
4571                         }
4572
4573                         /* Current quest number */
4574                         else if (streq(b+1, "QUEST_NUMBER"))
4575                         {
4576                                 sprintf(tmp, "%d", p_ptr->inside_quest);
4577                                 v = tmp;
4578                         }
4579
4580                         /* Number of last quest */
4581                         else if (streq(b+1, "LEAVING_QUEST"))
4582                         {
4583                                 sprintf(tmp, "%d", leaving_quest);
4584                                 v = tmp;
4585                         }
4586
4587                         /* Quest type */
4588                         else if (prefix(b+1, "QUEST_TYPE"))
4589                         {
4590                                 /* "QUEST_TYPE" uses a special parameter to determine the type of the quest */
4591                                 sprintf(tmp, "%d", quest[atoi(b+11)].type);
4592                                 v = tmp;
4593                         }
4594
4595                         /* Quest status */
4596                         else if (prefix(b+1, "QUEST"))
4597                         {
4598                                 /* "QUEST" uses a special parameter to determine the number of the quest */
4599                                 sprintf(tmp, "%d", quest[atoi(b+6)].status);
4600                                 v = tmp;
4601                         }
4602
4603                         /* Random */
4604                         else if (prefix(b+1, "RANDOM"))
4605                         {
4606                                 /* "RANDOM" uses a special parameter to determine the number of the quest */
4607                                 sprintf(tmp, "%d", (int)(seed_town%atoi(b+7)));
4608                                 v = tmp;
4609                         }
4610
4611                         /* Variant name */
4612                         else if (streq(b+1, "VARIANT"))
4613                         {
4614                                 v = variant;
4615                         }
4616
4617                         /* Wilderness */
4618                         else if (streq(b+1, "WILDERNESS"))
4619                         {
4620                                 if (vanilla_town)
4621                                         sprintf(tmp, "NONE");
4622                                 else if (lite_town)
4623                                         sprintf(tmp, "LITE");
4624                                 else
4625                                         sprintf(tmp, "NORMAL");
4626                                 v = tmp;
4627                         }
4628                 }
4629
4630                 /* Constant */
4631                 else
4632                 {
4633                         v = b;
4634                 }
4635         }
4636
4637         /* Save */
4638         (*fp) = f;
4639
4640         /* Save */
4641         (*sp) = s;
4642
4643         /* Result */
4644         return (v);
4645 }
4646
4647
4648 errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax)
4649 {
4650         FILE *fp;
4651
4652         char buf[1024];
4653
4654         int num = -1;
4655
4656         errr err = 0;
4657
4658         bool bypass = FALSE;
4659
4660         int x = xmin, y = ymin;
4661
4662
4663         /* Build the filename */
4664         path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, name);
4665
4666         /* Open the file */
4667         fp = my_fopen(buf, "r");
4668
4669         /* No such file */
4670         if (!fp) return (-1);
4671
4672
4673         /* Process the file */
4674         while (0 == my_fgets(fp, buf, sizeof(buf)))
4675         {
4676                 /* Count lines */
4677                 num++;
4678
4679
4680                 /* Skip "empty" lines */
4681                 if (!buf[0]) continue;
4682
4683                 /* Skip "blank" lines */
4684                 if (isspace(buf[0])) continue;
4685
4686                 /* Skip comments */
4687                 if (buf[0] == '#') continue;
4688
4689
4690                 /* Process "?:<expr>" */
4691                 if ((buf[0] == '?') && (buf[1] == ':'))
4692                 {
4693                         char f;
4694                         cptr v;
4695                         char *s;
4696
4697                         /* Start */
4698                         s = buf + 2;
4699
4700                         /* Parse the expr */
4701                         v = process_dungeon_file_expr(&s, &f);
4702
4703                         /* Set flag */
4704                         bypass = (streq(v, "0") ? TRUE : FALSE);
4705
4706                         /* Continue */
4707                         continue;
4708                 }
4709
4710                 /* Apply conditionals */
4711                 if (bypass) continue;
4712
4713                 /* Process the line */
4714                 err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x);
4715
4716                 /* Oops */
4717                 if (err) break;
4718         }
4719
4720         /* Errors */
4721         if (err)
4722         {
4723                 cptr oops;
4724
4725                 /* Error string */
4726                 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
4727
4728                 /* Oops */
4729                 msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
4730 #ifdef JP
4731 msg_format("'%s'¤ò²òÀÏÃæ¡£", buf);
4732 #else
4733                 msg_format("Parsing '%s'.", buf);
4734 #endif
4735
4736                 msg_print(NULL);
4737         }
4738
4739
4740         /* Close the file */
4741         my_fclose(fp);
4742
4743         /* Result */
4744         return (err);
4745 }
4746
4747
4748
4749 #if 0
4750 void write_r_info_txt(void)
4751 {
4752         int i, j, z, fc, bc;
4753         int dlen;
4754
4755         cptr flags[32 * 10];
4756
4757         u32b f_ptr[10];
4758         cptr *n_ptr[10];
4759
4760         monster_race *r_ptr;
4761
4762         monster_blow *b_ptr;
4763
4764         FILE *fff = fopen("output.txt", "wt");
4765
4766         cptr desc;
4767
4768         int mode = -1;
4769
4770         if (!fff) return;
4771
4772         fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");
4773
4774         fprintf(fff, "# Version stamp (required)\n\n");
4775
4776         /* Write Version */
4777         fprintf(fff, "V:%d.%d.%d\n\n\n", r_head->v_major, r_head->v_minor, r_head->v_patch);
4778
4779         /* Write a note */
4780         fprintf(fff, "##### The Player #####\n\n");
4781
4782         for (z = -1; z < alloc_race_size; z++)
4783         {
4784                 /* Output the monsters in order */
4785                 i = (z >= 0) ? alloc_race_table[z].index : 0;
4786
4787                 /* Acquire the monster */
4788                 r_ptr = &r_info[i];
4789
4790                 /* Ignore empty monsters */
4791                 if (!strlen(r_name + r_ptr->name)) continue;
4792
4793                 /* Ignore useless monsters */
4794                 if (i && !r_ptr->speed) continue;
4795
4796                 /* Write a note if necessary */
4797                 if (i && (!r_ptr->level != !mode))
4798                 {
4799                         /* Note the town */
4800                         if (!r_ptr->level)
4801                         {
4802                                 fprintf(fff, "\n##### Town monsters #####\n\n");
4803                         }
4804                         /* Note the dungeon */
4805                         else
4806                         {
4807                                 fprintf(fff, "\n##### Normal monsters #####\n\n");
4808                         }
4809
4810                         /* Record the change */
4811                         mode = r_ptr->level;
4812                 }
4813
4814                 /* Acquire the flags */
4815                 f_ptr[0] = r_ptr->flags1; n_ptr[0] = r_info_flags1;
4816                 f_ptr[1] = r_ptr->flags2; n_ptr[1] = r_info_flags2;
4817                 f_ptr[2] = r_ptr->flags3; n_ptr[2] = r_info_flags3;
4818                 f_ptr[3] = r_ptr->flags4; n_ptr[3] = r_info_flags4;
4819                 f_ptr[4] = r_ptr->flags5; n_ptr[4] = r_info_flags5;
4820                 f_ptr[5] = r_ptr->flags6; n_ptr[5] = r_info_flags6;
4821                 f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7;
4822                 f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8;
4823                 f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9;
4824                 f_ptr[9] = r_ptr->flagsr; n_ptr[9] = r_info_flagsr;
4825
4826                 /* Write New/Number/Name */
4827                 fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name);
4828
4829                 /* Write Graphic */
4830                 fprintf(fff, "G:%c:%c\n", r_ptr->d_char, color_char[r_ptr->d_attr]);
4831
4832                 /* Write Information */
4833                 fprintf(fff, "I:%d:%dd%d:%d:%d:%d\n", r_ptr->speed, r_ptr->hdice, r_ptr->hside,
4834                                                                                                                   r_ptr->aaf, r_ptr->ac, r_ptr->sleep);
4835
4836                 /* Write more information */
4837                 fprintf(fff, "W:%d:%d:%d:%ld\n", r_ptr->level, r_ptr->rarity, r_ptr->extra, r_ptr->mexp);
4838
4839                 /* Write Blows */
4840                 for(j = 0; j < 4; j++)
4841                 {
4842                         b_ptr = &(r_ptr->blow[j]);
4843
4844                         /* Stop when done */
4845                         if (!b_ptr->method) break;
4846
4847                         /* Write the blows */
4848                         fprintf(fff, "B:%s:%s:%dd%d\n", r_info_blow_method[b_ptr->method],
4849                                                                                                           r_info_blow_effect[b_ptr->effect],
4850                                                                                                           b_ptr->d_dice, b_ptr->d_side);
4851                 }
4852
4853                 /* Extract the flags */
4854                 for (fc = 0, j = 0; j < 32 * 3; j++)
4855                 {
4856                         /* Check this flag */
4857                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4858                 }
4859
4860                 /* Extract the extra flags */
4861                 for (j = 32 * 6; j < 32 * 10; j++)
4862                 {
4863                         /* Check this flag */
4864                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4865                 }
4866
4867                 /* Write the flags */
4868                 for (j = 0; j < fc;)
4869                 {
4870                         char buf[160];
4871
4872                         /* Start the line */
4873                         sprintf(buf, "F:");
4874
4875                         for (bc = 0; (bc < 60) && (j < fc); j++)
4876                         {
4877                                 char t[80];
4878
4879                                 /* Format the flag */
4880                                 sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4881
4882                                 /* Add it to the buffer */
4883                                 strcat(buf, t);
4884
4885                                 /* Note the length */
4886                                 bc += strlen(t);
4887                         }
4888
4889                         /* Done with this line; write it */
4890                         fprintf(fff, "%s\n", buf);
4891                 }
4892
4893                 /* Write Spells if applicable */
4894                 if (r_ptr->freq_spell)
4895                 {
4896                         /* Write the frequency */
4897                         fprintf(fff, "S:1_IN_%d | \n", 100 / r_ptr->freq_spell);
4898
4899                         /* Extract the spell flags */
4900                         for (fc = 0, j = 96; j < 192; j++)
4901                         {
4902                                 /* Check this flag */
4903                                 if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4904                         }
4905
4906                         /* Write the flags */
4907                         for (j = 0; j < fc;)
4908                         {
4909                                 char buf[160], *t;
4910
4911                                 /* Start the line */
4912                                 sprintf(buf, "S:");
4913
4914                                 for (bc = 0, t = buf + 2; (bc < 60) && (j < fc); j++)
4915                                 {
4916                                         int tlen;
4917
4918                                         /* Format the flag */
4919                                         sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4920
4921                                         tlen = strlen(t);
4922
4923                                         /* Note the length */
4924                                         bc += tlen;
4925
4926                                         /* Advance */
4927                                         t += tlen;
4928                                 }
4929
4930                                 /* Done with this line; write it */
4931                                 fprintf(fff, "%s\n", buf);
4932                         }
4933                 }
4934
4935                 /* Acquire the description */
4936                 desc = r_text + r_ptr->text;
4937                 dlen = strlen(desc);
4938
4939                 /* Write Description */
4940                 for (j = 0; j < dlen;)
4941                 {
4942                         char buf[160], *t;
4943
4944                         /* Start the line */
4945                         sprintf(buf, "D:");
4946
4947                         for (bc = 0, t = buf + 2; ((bc < 60) || !isspace(desc[j])) && (j < dlen); j++, bc++, t++)
4948                         {
4949                                 *t = desc[j];
4950                         }
4951
4952                         /* Terminate it */
4953                         *t = '\0';
4954
4955                         /* Done with this line; write it */
4956                         fprintf(fff, "%s\n", buf);
4957                 }
4958
4959                 /* Space between entries */
4960                 fprintf(fff, "\n");
4961         }
4962
4963         /* Done */
4964         fclose(fff);
4965 }
4966
4967 #endif