OSDN Git Service

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