OSDN Git Service

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