OSDN Git Service

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