OSDN Git Service

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