OSDN Git Service

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