OSDN Git Service

#37287 init1.cとmelee2.c、monster2.c内のC4457警告に対応 / Deal C4457 warning in init1.c, melee...
[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
2166                 /* XXX XXX XXX Simply read each number following a colon */
2167                 for (i = 0, s = buf+1; s && (s[0] == ':') && s[1]; ++i)
2168                 {
2169                                 /* Default chance */
2170                         k_ptr->chance[i] = 1;
2171
2172                                 /* Store the attack damage index */
2173                         k_ptr->locale[i] = atoi(s+1);
2174
2175                                 /* Find the slash */
2176                         t = my_strchr(s+1, '/');
2177
2178                                 /* Find the next colon */
2179                         s = my_strchr(s+1, ':');
2180
2181                                 /* If the slash is "nearby", use it */
2182                         if (t && (!s || t < s))
2183                         {
2184                                 int chance = atoi(t+1);
2185                                 if (chance > 0) k_ptr->chance[i] = chance;
2186                         }
2187                 }
2188         }
2189
2190         /* Hack -- Process 'P' for "power" and such */
2191         else if (buf[0] == 'P')
2192         {
2193                 int ac, hd1, hd2, th, td, ta;
2194
2195                 /* Scan for the values */
2196                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2197                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
2198
2199                 k_ptr->ac = ac;
2200                 k_ptr->dd = hd1;
2201                 k_ptr->ds = hd2;
2202                 k_ptr->to_h = th;
2203                 k_ptr->to_d = td;
2204                 k_ptr->to_a =  ta;
2205         }
2206
2207         /* Hack -- Process 'U' for activation index */
2208         else if (buf[0] == 'U')
2209         {
2210                 byte n;
2211                 n = grab_one_activation_flag(buf + 2);
2212                 if (n > 0)
2213                 {
2214                         k_ptr->act_idx = n;
2215                 }
2216                 else
2217                 {
2218                         return (5);
2219                 }
2220         }
2221
2222         /* Hack -- Process 'F' for flags */
2223         else if (buf[0] == 'F')
2224         {
2225                 /* Parse every entry textually */
2226                 for (s = buf + 2; *s; )
2227                 {
2228                                 /* Find the end of this entry */
2229                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2230
2231                                 /* Nuke and skip any dividers */
2232                         if (*t)
2233                         {
2234                                 *t++ = '\0';
2235                                 while (*t == ' ' || *t == '|') t++;
2236                         }
2237
2238                                 /* Parse this entry */
2239                         if (0 != grab_one_kind_flag(k_ptr, s)) return (5);
2240
2241                                 /* Start the next entry */
2242                         s = t;
2243                 }
2244         }
2245
2246
2247         /* Oops */
2248         else return (6);
2249
2250
2251         /* Success */
2252         return (0);
2253 }
2254
2255 /*!
2256  * @brief テキストトークンを走査してフラグを一つ得る(アーティファクト用) /
2257  * Grab one activation index flag
2258  * @param a_ptr 保管先のアーティファクト構造体参照ポインタ
2259  * @param what 参照元の文字列ポインタ
2260  * @return エラーがあった場合1、エラーがない場合0を返す
2261  */
2262 static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what)
2263 {
2264         int i;
2265
2266         /* Check flags */
2267         for (i = 0; i < TR_FLAG_MAX; i++)
2268         {
2269                 if (streq(what, k_info_flags[i]))
2270                 {
2271                         add_flag(a_ptr->flags, i);
2272                         return (0);
2273                 }
2274         }
2275
2276         if (grab_one_flag(&a_ptr->gen_flags, k_info_gen_flags, what) == 0)
2277                 return 0;
2278
2279         /* Oops */
2280         msg_format(_("未知の伝説のアイテム・フラグ '%s'。", "Unknown artifact flag '%s'."), what);
2281
2282         /* Error */
2283         return (1);
2284 }
2285
2286
2287 /*!
2288  * @brief 固定アーティファクト情報(a_info)のパース関数 /
2289  * Initialize the "a_info" array, by parsing an ascii "template" file
2290  * @param buf テキスト列
2291  * @param head ヘッダ構造体
2292  * @return エラーコード
2293  */
2294 errr parse_a_info(char *buf, header *head)
2295 {
2296         int i;
2297
2298         char *s, *t;
2299
2300         /* Current entry */
2301         static artifact_type *a_ptr = NULL;
2302
2303
2304         /* Process 'N' for "New/Number/Name" */
2305         if (buf[0] == 'N')
2306         {
2307                 /* Find the colon before the name */
2308                 s = my_strchr(buf+2, ':');
2309
2310                         /* Verify that colon */
2311                 if (!s) return (1);
2312
2313                 /* Nuke the colon, advance to the name */
2314                 *s++ = '\0';
2315 #ifdef JP
2316                 /* Paranoia -- require a name */
2317                 if (!*s) return (1);
2318 #endif
2319                 /* Get the index */
2320                 i = atoi(buf+2);
2321
2322                 /* Verify information */
2323                 if (i < error_idx) return (4);
2324
2325                 /* Verify information */
2326                 if (i >= head->info_num) return (2);
2327
2328                 /* Save the index */
2329                 error_idx = i;
2330
2331                 /* Point at the "info" */
2332                 a_ptr = &a_info[i];
2333
2334                 /* Ignore everything */
2335                 add_flag(a_ptr->flags, TR_IGNORE_ACID);
2336                 add_flag(a_ptr->flags, TR_IGNORE_ELEC);
2337                 add_flag(a_ptr->flags, TR_IGNORE_FIRE);
2338                 add_flag(a_ptr->flags, TR_IGNORE_COLD);
2339 #ifdef JP
2340                 /* Store the name */
2341                 if (!add_name(&a_ptr->name, head, s)) return (7);
2342 #endif
2343         }
2344
2345         /* There better be a current a_ptr */
2346         else if (!a_ptr) return (3);
2347
2348
2349 #ifdef JP
2350         /* 英語名を読むルーチンを追加 */
2351         /* 'E' から始まる行は英語名としている */
2352         else if (buf[0] == 'E')
2353         {
2354                 /* nothing to do */
2355         }
2356 #else
2357         else if (buf[0] == 'E')
2358         {
2359                 /* Acquire the Text */
2360                 s = buf+2;
2361
2362                 /* Store the name */
2363                 if (!add_name(&a_ptr->name, head, s)) return (7);
2364         }
2365 #endif
2366
2367         /* Process 'D' for "Description" */
2368         else if (buf[0] == 'D')
2369         {
2370 #ifdef JP
2371                 if (buf[2] == '$')
2372                         return (0);
2373                 /* Acquire the text */
2374                 s = buf+2;
2375 #else
2376                 if (buf[2] != '$')
2377                         return (0);
2378                 /* Acquire the text */
2379                 s = buf+3;
2380 #endif
2381
2382                 /* Store the text */
2383                 if (!add_text(&a_ptr->text, head, s, TRUE)) return (7);
2384         }
2385
2386
2387         /* Process 'I' for "Info" (one line only) */
2388         else if (buf[0] == 'I')
2389         {
2390                 int tval, sval, pval;
2391
2392                 /* Scan for the values */
2393                 if (3 != sscanf(buf+2, "%d:%d:%d",
2394                                 &tval, &sval, &pval)) return (1);
2395
2396                 /* Save the values */
2397                 a_ptr->tval = tval;
2398                 a_ptr->sval = sval;
2399                 a_ptr->pval = pval;
2400         }
2401
2402         /* Process 'W' for "More Info" (one line only) */
2403         else if (buf[0] == 'W')
2404         {
2405                 int level, rarity, wgt;
2406                 long cost;
2407
2408                 /* Scan for the values */
2409                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
2410                                 &level, &rarity, &wgt, &cost)) return (1);
2411
2412                 /* Save the values */
2413                 a_ptr->level = level;
2414                 a_ptr->rarity = rarity;
2415                 a_ptr->weight = wgt;
2416                 a_ptr->cost = cost;
2417         }
2418
2419         /* Hack -- Process 'P' for "power" and such */
2420         else if (buf[0] == 'P')
2421         {
2422                 int ac, hd1, hd2, th, td, ta;
2423
2424                 /* Scan for the values */
2425                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2426                                 &ac, &hd1, &hd2, &th, &td, &ta)) return (1);
2427
2428                 a_ptr->ac = ac;
2429                 a_ptr->dd = hd1;
2430                 a_ptr->ds = hd2;
2431                 a_ptr->to_h = th;
2432                 a_ptr->to_d = td;
2433                 a_ptr->to_a =  ta;
2434         }
2435
2436         /* Hack -- Process 'U' for activation index */
2437         else if (buf[0] == 'U')
2438         {
2439                 byte n;
2440                 n = grab_one_activation_flag(buf + 2);
2441                 if (n > 0)
2442                 {
2443                         a_ptr->act_idx = n;
2444                 }
2445                 else
2446                 {
2447                         return (5);
2448                 }
2449         }
2450
2451         /* Hack -- Process 'F' for flags */
2452         else if (buf[0] == 'F')
2453         {
2454                 /* Parse every entry textually */
2455                 for (s = buf + 2; *s; )
2456                 {
2457                                 /* Find the end of this entry */
2458                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2459
2460                                 /* Nuke and skip any dividers */
2461                         if (*t)
2462                         {
2463                                 *t++ = '\0';
2464                                 while ((*t == ' ') || (*t == '|')) t++;
2465                         }
2466
2467                                 /* Parse this entry */
2468                         if (0 != grab_one_artifact_flag(a_ptr, s)) return (5);
2469
2470                                 /* Start the next entry */
2471                         s = t;
2472                 }
2473         }
2474
2475
2476         /* Oops */
2477         else return (6);
2478
2479
2480         /* Success */
2481         return (0);
2482 }
2483
2484
2485 /*!
2486  * @brief テキストトークンを走査してフラグを一つ得る(アーティファクト用) /
2487  * Grab one flag in a ego-item_type from a textual string
2488  * @param e_ptr 保管先のエゴ構造体参照ポインタ
2489  * @param what 参照元の文字列ポインタ
2490  * @return エラーがあった場合1、エラーがない場合0を返す
2491  */
2492 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what)
2493 {
2494         int i;
2495
2496         /* Check flags */
2497         for (i = 0; i < TR_FLAG_MAX; i++)
2498         {
2499                 if (streq(what, k_info_flags[i]))
2500                 {
2501                         add_flag(e_ptr->flags, i);
2502                         return (0);
2503                 }
2504         }
2505
2506         if (grab_one_flag(&e_ptr->gen_flags, k_info_gen_flags, what) == 0)
2507                 return 0;
2508
2509         /* Oops */
2510         msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what);
2511
2512         /* Error */
2513         return (1);
2514 }
2515
2516
2517 /*!
2518  * @brief アイテムエゴ情報(e_info)のパース関数 /
2519  * Initialize the "e_info" array, by parsing an ascii "template" file
2520  * @param buf テキスト列
2521  * @param head ヘッダ構造体
2522  * @return エラーコード
2523  */
2524 errr parse_e_info(char *buf, header *head)
2525 {
2526         int i;
2527
2528         char *s, *t;
2529
2530         /* Current entry */
2531         static ego_item_type *e_ptr = NULL;
2532
2533
2534         /* Just before the first record */
2535         error_idx = -1;
2536
2537         /* Just before the first line */
2538         error_line = -1;
2539
2540
2541         /* Process 'N' for "New/Number/Name" */
2542         if (buf[0] == 'N')
2543         {
2544                 /* Find the colon before the name */
2545                 s = my_strchr(buf+2, ':');
2546
2547                         /* Verify that colon */
2548                 if (!s) return (1);
2549
2550                 /* Nuke the colon, advance to the name */
2551                 *s++ = '\0';
2552 #ifdef JP
2553                 /* Paranoia -- require a name */
2554                 if (!*s) return (1);
2555 #endif
2556                 /* Get the index */
2557                 i = atoi(buf+2);
2558
2559                 /* Verify information */
2560                 if (i < error_idx) return (4);
2561
2562                 /* Verify information */
2563                 if (i >= head->info_num) return (2);
2564
2565                 /* Save the index */
2566                 error_idx = i;
2567
2568                 /* Point at the "info" */
2569                 e_ptr = &e_info[i];
2570 #ifdef JP
2571                 /* Store the name */
2572                 if (!add_name(&e_ptr->name, head, s)) return (7);
2573 #endif
2574         }
2575
2576         /* There better be a current e_ptr */
2577         else if (!e_ptr) return (3);
2578
2579
2580 #ifdef JP
2581         /* 英語名を読むルーチンを追加 */
2582         /* 'E' から始まる行は英語名 */
2583         else if (buf[0] == 'E')
2584         {
2585                 /* nothing to do */
2586         }
2587 #else
2588         else if (buf[0] == 'E')
2589         {
2590                 /* Acquire the Text */
2591                 s = buf+2;
2592
2593                 /* Store the name */
2594                 if (!add_name(&e_ptr->name, head, s)) return (7);
2595         }
2596 #endif
2597 #if 0
2598
2599         /* Process 'D' for "Description" */
2600         else if (buf[0] == 'D')
2601         {
2602                 /* Acquire the text */
2603                 s = buf+2;
2604
2605                 /* Store the text */
2606                 if (!add_text(&e_ptr->text, head, s, TRUE)) return (7);
2607         }
2608
2609 #endif
2610
2611         /* Process 'X' for "Xtra" (one line only) */
2612         else if (buf[0] == 'X')
2613         {
2614                 int slot, rating;
2615
2616                 /* Scan for the values */
2617                 if (2 != sscanf(buf+2, "%d:%d",
2618                                 &slot, &rating)) return (1);
2619
2620                 /* Save the values */
2621                 e_ptr->slot = slot;
2622                 e_ptr->rating = rating;
2623         }
2624
2625         /* Process 'W' for "More Info" (one line only) */
2626         else if (buf[0] == 'W')
2627         {
2628                 int level, rarity, pad2;
2629                 long cost;
2630
2631                 /* Scan for the values */
2632                 if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
2633                                 &level, &rarity, &pad2, &cost)) return (1);
2634
2635                 /* Save the values */
2636                 e_ptr->level = level;
2637                 e_ptr->rarity = rarity;
2638                 /* e_ptr->weight = wgt; */
2639                 e_ptr->cost = cost;
2640         }
2641
2642         /* Hack -- Process 'C' for "creation" */
2643         else if (buf[0] == 'C')
2644         {
2645                 int th, td, ta, pv;
2646
2647                 /* Scan for the values */
2648                 if (4 != sscanf(buf+2, "%d:%d:%d:%d",
2649                                 &th, &td, &ta, &pv)) return (1);
2650
2651                 e_ptr->max_to_h = th;
2652                 e_ptr->max_to_d = td;
2653                 e_ptr->max_to_a = ta;
2654                 e_ptr->max_pval = pv;
2655         }
2656
2657         /* Hack -- Process 'U' for activation index */
2658         else if (buf[0] == 'U')
2659         {
2660                 byte n;
2661                 n = grab_one_activation_flag(buf + 2);
2662                 if (n > 0)
2663                 {
2664                         e_ptr->act_idx = n;
2665                 }
2666                 else
2667                 {
2668                         return (5);
2669                 }
2670         }
2671
2672         /* Hack -- Process 'F' for flags */
2673         else if (buf[0] == 'F')
2674         {
2675                 /* Parse every entry textually */
2676                 for (s = buf + 2; *s; )
2677                 {
2678                                 /* Find the end of this entry */
2679                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
2680
2681                                 /* Nuke and skip any dividers */
2682                         if (*t)
2683                         {
2684                                 *t++ = '\0';
2685                                 while ((*t == ' ') || (*t == '|')) t++;
2686                         }
2687
2688                                 /* Parse this entry */
2689                         if (0 != grab_one_ego_item_flag(e_ptr, s)) return (5);
2690
2691                                 /* Start the next entry */
2692                         s = t;
2693                 }
2694         }
2695
2696         /* Oops */
2697         else return (6);
2698
2699         /* Success */
2700         return (0);
2701 }
2702
2703
2704 /*!
2705  * @brief テキストトークンを走査してフラグを一つ得る(モンスター用1) /
2706  * Grab one (basic) flag in a monster_race from a textual string
2707  * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
2708  * @param what 参照元の文字列ポインタ
2709  * @return エラーコード
2710  */
2711 static errr grab_one_basic_flag(monster_race *r_ptr, cptr what)
2712 {
2713         if (grab_one_flag(&r_ptr->flags1, r_info_flags1, what) == 0)
2714                 return 0;
2715
2716         if (grab_one_flag(&r_ptr->flags2, r_info_flags2, what) == 0)
2717                 return 0;
2718
2719         if (grab_one_flag(&r_ptr->flags3, r_info_flags3, what) == 0)
2720                 return 0;
2721
2722         if (grab_one_flag(&r_ptr->flags7, r_info_flags7, what) == 0)
2723                 return 0;
2724
2725         if (grab_one_flag(&r_ptr->flags8, r_info_flags8, what) == 0)
2726                 return 0;
2727
2728         if (grab_one_flag(&r_ptr->flags9, r_info_flags9, what) == 0)
2729                 return 0;
2730
2731         if (grab_one_flag(&r_ptr->flagsr, r_info_flagsr, what) == 0)
2732                 return 0;
2733
2734         /* Oops */
2735         msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
2736
2737         /* Failure */
2738         return (1);
2739 }
2740
2741
2742 /*!
2743  * @brief テキストトークンを走査してフラグを一つ得る(モンスター用2) /
2744  * Grab one (spell) flag in a monster_race from a textual string
2745  * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
2746  * @param what 参照元の文字列ポインタ
2747  * @return エラーコード
2748  */
2749 static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
2750 {
2751         if (grab_one_flag(&r_ptr->flags4, r_info_flags4, what) == 0)
2752                 return 0;
2753
2754         if (grab_one_flag(&r_ptr->flags5, r_info_flags5, what) == 0)
2755                 return 0;
2756
2757         if (grab_one_flag(&r_ptr->flags6, r_info_flags6, what) == 0)
2758                 return 0;
2759
2760         /* Oops */
2761         msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
2762
2763         /* Failure */
2764         return (1);
2765 }
2766
2767
2768 /*!
2769  * @brief モンスター種族情報(r_info)のパース関数 /
2770  * Initialize the "r_info" array, by parsing an ascii "template" file
2771  * @param buf テキスト列
2772  * @param head ヘッダ構造体
2773  * @return エラーコード
2774  */
2775 errr parse_r_info(char *buf, header *head)
2776 {
2777         int i;
2778
2779         char *s, *t;
2780
2781         /* Current entry */
2782         static monster_race *r_ptr = NULL;
2783
2784
2785         /* Process 'N' for "New/Number/Name" */
2786         if (buf[0] == 'N')
2787         {
2788                 /* Find the colon before the name */
2789                 s = my_strchr(buf+2, ':');
2790
2791                         /* Verify that colon */
2792                 if (!s) return (1);
2793
2794                 /* Nuke the colon, advance to the name */
2795                 *s++ = '\0';
2796 #ifdef JP
2797                 /* Paranoia -- require a name */
2798                 if (!*s) return (1);
2799 #endif
2800                 /* Get the index */
2801                 i = atoi(buf+2);
2802
2803                 /* Verify information */
2804                 if (i < error_idx) return (4);
2805
2806                 /* Verify information */
2807                 if (i >= head->info_num) return (2);
2808
2809                 /* Save the index */
2810                 error_idx = i;
2811
2812                 /* Point at the "info" */
2813                 r_ptr = &r_info[i];
2814 #ifdef JP
2815                 /* Store the name */
2816                 if (!add_name(&r_ptr->name, head, s)) return (7);
2817 #endif
2818         }
2819
2820         /* There better be a current r_ptr */
2821         else if (!r_ptr) return (3);
2822
2823
2824 #ifdef JP
2825         /* 英語名を読むルーチンを追加 */
2826         /* 'E' から始まる行は英語名 */
2827         else if (buf[0] == 'E')
2828         {
2829                 /* Acquire the Text */
2830                 s = buf+2;
2831
2832                 /* Store the name */
2833                 if (!add_name(&r_ptr->E_name, head, s)) return (7);
2834         }
2835 #else
2836         else if (buf[0] == 'E')
2837         {
2838                 /* Acquire the Text */
2839                 s = buf+2;
2840
2841                 /* Store the name */
2842                 if (!add_name(&r_ptr->name, head, s)) return (7);
2843         }
2844 #endif
2845         /* Process 'D' for "Description" */
2846         else if (buf[0] == 'D')
2847         {
2848 #ifdef JP
2849                 if (buf[2] == '$')
2850                         return (0);
2851                 /* Acquire the text */
2852                 s = buf+2;
2853 #else
2854                 if (buf[2] != '$')
2855                         return (0);
2856                 /* Acquire the text */
2857                 s = buf+3;
2858 #endif
2859
2860                 /* Store the text */
2861                 if (!add_text(&r_ptr->text, head, s, TRUE)) return (7);
2862         }
2863
2864         /* Process 'G' for "Graphics" (one line only) */
2865         else if (buf[0] == 'G')
2866         {
2867                 char sym;
2868                 byte tmp;
2869
2870                 /* Paranoia */
2871                 if (buf[1] != ':') return (1);
2872                 if (!buf[2]) return (1);
2873                 if (buf[3] != ':') return (1);
2874                 if (!buf[4]) return (1);
2875
2876                 /* Extract the char */
2877                 sym = buf[2];
2878
2879                 /* Extract the attr */
2880                 tmp = color_char_to_attr(buf[4]);
2881
2882                 /* Paranoia */
2883                 if (tmp > 127) return (1);
2884
2885                 /* Save the values */
2886                 r_ptr->d_char = sym;
2887                 r_ptr->d_attr = tmp;
2888         }
2889
2890         /* Process 'I' for "Info" (one line only) */
2891         else if (buf[0] == 'I')
2892         {
2893                 int spd, hp1, hp2, aaf, ac, slp;
2894
2895                 /* Scan for the other values */
2896                 if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
2897                                 &spd, &hp1, &hp2, &aaf, &ac, &slp)) return (1);
2898
2899                 /* Save the values */
2900                 r_ptr->speed = spd;
2901                 r_ptr->hdice = MAX(hp1, 1);
2902                 r_ptr->hside = MAX(hp2, 1);
2903                 r_ptr->aaf = aaf;
2904                 r_ptr->ac = ac;
2905                 r_ptr->sleep = slp;
2906         }
2907
2908         /* Process 'W' for "More Info" (one line only) */
2909         else if (buf[0] == 'W')
2910         {
2911                 int lev, rar, pad;
2912                 long exp;
2913                 long nextexp;
2914                 int nextmon;
2915
2916                 /* Scan for the values */
2917                 if (6 != sscanf(buf+2, "%d:%d:%d:%ld:%ld:%d",
2918                                 &lev, &rar, &pad, &exp, &nextexp, &nextmon)) return (1);
2919
2920                 /* Save the values */
2921                 r_ptr->level = lev;
2922                 r_ptr->rarity = rar;
2923                 r_ptr->extra = pad;
2924                 r_ptr->mexp = exp;
2925                 r_ptr->next_exp = nextexp;
2926                 r_ptr->next_r_idx = nextmon;
2927         }
2928
2929         /* Process 'R' for "Reinforcement" (up to six lines) */
2930         else if (buf[0] == 'R')
2931         {
2932                 int id, ds, dd;
2933                 /* Find the next empty blow slot (if any) */
2934                 for (i = 0; i < 6; i++) if (r_ptr->reinforce_id[i] == 0) break;
2935
2936                 /* Oops, no more slots */
2937                 if (i == 6) return (1);
2938
2939                 /* Scan for the values */
2940                 if (3 != sscanf(buf+2, "%d:%dd%d", &id, &dd, &ds)) return (1);
2941                 r_ptr->reinforce_id[i] = id;
2942                 r_ptr->reinforce_dd[i] = dd;
2943                 r_ptr->reinforce_ds[i] = ds;
2944         }
2945
2946         /* Process 'B' for "Blows" (up to four lines) */
2947         else if (buf[0] == 'B')
2948         {
2949                 int n1, n2;
2950
2951                 /* Find the next empty blow slot (if any) */
2952                 for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break;
2953
2954                 /* Oops, no more slots */
2955                 if (i == 4) return (1);
2956
2957                 /* Analyze the first field */
2958                 for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
2959
2960                 /* Terminate the field (if necessary) */
2961                 if (*t == ':') *t++ = '\0';
2962
2963                 /* Analyze the method */
2964                 for (n1 = 0; r_info_blow_method[n1]; n1++)
2965                 {
2966                         if (streq(s, r_info_blow_method[n1])) break;
2967                 }
2968
2969                 /* Invalid method */
2970                 if (!r_info_blow_method[n1]) return (1);
2971
2972                 /* Analyze the second field */
2973                 for (s = t; *t && (*t != ':'); t++) /* loop */;
2974
2975                 /* Terminate the field (if necessary) */
2976                 if (*t == ':') *t++ = '\0';
2977
2978                 /* Analyze effect */
2979                 for (n2 = 0; r_info_blow_effect[n2]; n2++)
2980                 {
2981                         if (streq(s, r_info_blow_effect[n2])) break;
2982                 }
2983
2984                 /* Invalid effect */
2985                 if (!r_info_blow_effect[n2]) return (1);
2986
2987                 /* Analyze the third field */
2988                 for (s = t; *t && (*t != 'd'); t++) /* loop */;
2989
2990                 /* Terminate the field (if necessary) */
2991                 if (*t == 'd') *t++ = '\0';
2992
2993                 /* Save the method */
2994                 r_ptr->blow[i].method = n1;
2995
2996                 /* Save the effect */
2997                 r_ptr->blow[i].effect = n2;
2998
2999                 /* Extract the damage dice and sides */
3000                 r_ptr->blow[i].d_dice = atoi(s);
3001                 r_ptr->blow[i].d_side = atoi(t);
3002         }
3003
3004         /* Process 'F' for "Basic Flags" (multiple lines) */
3005         else if (buf[0] == 'F')
3006         {
3007                 /* Parse every entry */
3008                 for (s = buf + 2; *s; )
3009                 {
3010                                 /* Find the end of this entry */
3011                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3012
3013                                 /* Nuke and skip any dividers */
3014                         if (*t)
3015                         {
3016                                 *t++ = '\0';
3017                                 while (*t == ' ' || *t == '|') t++;
3018                         }
3019
3020                                 /* Parse this entry */
3021                         if (0 != grab_one_basic_flag(r_ptr, s)) return (5);
3022
3023                                 /* Start the next entry */
3024                         s = t;
3025                 }
3026         }
3027
3028         /* Process 'S' for "Spell Flags" (multiple lines) */
3029         else if (buf[0] == 'S')
3030         {
3031                 /* Parse every entry */
3032                 for (s = buf + 2; *s; )
3033                 {
3034                                 /* Find the end of this entry */
3035                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3036
3037                                 /* Nuke and skip any dividers */
3038                         if (*t)
3039                         {
3040                                 *t++ = '\0';
3041                                 while ((*t == ' ') || (*t == '|')) t++;
3042                         }
3043
3044                                 /* XXX XXX XXX Hack -- Read spell frequency */
3045                         if (1 == sscanf(s, "1_IN_%d", &i))
3046                         {
3047                                 /* Extract a "frequency" */
3048                                 r_ptr->freq_spell = 100 / i;
3049
3050                                         /* Start at next entry */
3051                                 s = t;
3052
3053                                 /* Continue */
3054                                 continue;
3055                         }
3056
3057                                 /* Parse this entry */
3058                         if (0 != grab_one_spell_flag(r_ptr, s)) return (5);
3059
3060                                 /* Start the next entry */
3061                         s = t;
3062                 }
3063         }
3064
3065         /* Process 'A' for "Artifact Flags" (multiple lines) */
3066         else if (buf[0] == 'A')
3067         {
3068                 int id, per, rarity;
3069
3070                 /* Find the next empty blow slot (if any) */
3071                 for (i = 0; i < 4; i++) if (!r_ptr->artifact_id[i]) break;
3072
3073                 /* Oops, no more slots */
3074                 if (i == 4) return (1);
3075
3076                 if (3 != sscanf(buf+2, "%d:%d:%d", &id, &rarity, &per)) return (1);
3077                 r_ptr->artifact_id[i] = id;
3078                 r_ptr->artifact_rarity[i] = rarity;
3079                 r_ptr->artifact_percent[i] = per;
3080         }
3081
3082         /* Process 'V' for "Arena power value ratio" */
3083         else if (buf[0] == 'V')
3084         {
3085                 int val;
3086                 if (3 != sscanf(buf+2, "%d", &val)) return (1);
3087                 r_ptr->arena_ratio = val;
3088         }
3089
3090         /* Oops */
3091         else return (6);
3092
3093
3094         /* Success */
3095         return (0);
3096 }
3097
3098
3099 /*!
3100  * @brief テキストトークンを走査してフラグを一つ得る(ダンジョン用) /
3101  * Grab one flag for a dungeon type from a textual string
3102  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
3103  * @param what 参照元の文字列ポインタ
3104  * @return エラーコード
3105  */
3106 static errr grab_one_dungeon_flag(dungeon_info_type *d_ptr, cptr what)
3107 {
3108         if (grab_one_flag(&d_ptr->flags1, d_info_flags1, what) == 0)
3109                 return 0;
3110
3111         /* Oops */
3112         msg_format(_("未知のダンジョン・フラグ '%s'。", "Unknown dungeon type flag '%s'."), what);
3113
3114         /* Failure */
3115         return (1);
3116 }
3117
3118 /*!
3119  * @brief テキストトークンを走査してフラグを一つ得る(モンスターのダンジョン出現条件用1) /
3120  * Grab one (basic) flag in a monster_race from a textual string
3121  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
3122  * @param what 参照元の文字列ポインタ
3123  * @return エラーコード
3124  */
3125 static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what)
3126 {
3127         if (grab_one_flag(&d_ptr->mflags1, r_info_flags1, what) == 0)
3128                 return 0;
3129
3130         if (grab_one_flag(&d_ptr->mflags2, r_info_flags2, what) == 0)
3131                 return 0;
3132
3133         if (grab_one_flag(&d_ptr->mflags3, r_info_flags3, what) == 0)
3134                 return 0;
3135
3136         if (grab_one_flag(&d_ptr->mflags7, r_info_flags7, what) == 0)
3137                 return 0;
3138
3139         if (grab_one_flag(&d_ptr->mflags8, r_info_flags8, what) == 0)
3140                 return 0;
3141
3142         if (grab_one_flag(&d_ptr->mflags9, r_info_flags9, what) == 0)
3143                 return 0;
3144
3145         if (grab_one_flag(&d_ptr->mflagsr, r_info_flagsr, what) == 0)
3146                 return 0;
3147
3148         /* Oops */
3149         msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
3150         /* Failure */
3151         return (1);
3152 }
3153
3154
3155 /*!
3156  * @brief テキストトークンを走査してフラグを一つ得る(モンスターのダンジョン出現条件用2) /
3157  * Grab one (spell) flag in a monster_race from a textual string
3158  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
3159  * @param what 参照元の文字列ポインタ
3160  * @return エラーコード
3161  */
3162 static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what)
3163 {
3164         if (grab_one_flag(&d_ptr->mflags4, r_info_flags4, what) == 0)
3165                 return 0;
3166
3167         if (grab_one_flag(&d_ptr->mflags5, r_info_flags5, what) == 0)
3168                 return 0;
3169
3170         if (grab_one_flag(&d_ptr->mflags6, r_info_flags6, what) == 0)
3171                 return 0;
3172
3173         /* Oops */
3174         msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
3175
3176         /* Failure */
3177         return (1);
3178 }
3179
3180 /*!
3181  * @brief ダンジョン情報(d_info)のパース関数 /
3182  * Initialize the "d_info" array, by parsing an ascii "template" file
3183  * @param buf テキスト列
3184  * @param head ヘッダ構造体
3185  * @return エラーコード
3186  */
3187 errr parse_d_info(char *buf, header *head)
3188 {
3189         int i;
3190
3191         char *s, *t;
3192
3193         /* Current entry */
3194         static dungeon_info_type *d_ptr = NULL;
3195
3196
3197         /* Process 'N' for "New/Number/Name" */
3198         if (buf[0] == 'N')
3199         {
3200                 /* Find the colon before the name */
3201                 s = my_strchr(buf+2, ':');
3202
3203                 /* Verify that colon */
3204                 if (!s) return (1);
3205
3206                 /* Nuke the colon, advance to the name */
3207                 *s++ = '\0';
3208 #ifdef JP
3209                 /* Paranoia -- require a name */
3210                 if (!*s) return (1);
3211 #endif
3212                 /* Get the index */
3213                 i = atoi(buf+2);
3214
3215                 /* Verify information */
3216                 if (i < error_idx) return (4);
3217
3218                 /* Verify information */
3219                 if (i >= head->info_num) return (2);
3220
3221                 /* Save the index */
3222                 error_idx = i;
3223
3224                 /* Point at the "info" */
3225                 d_ptr = &d_info[i];
3226 #ifdef JP
3227                 /* Store the name */
3228                 if (!add_name(&d_ptr->name, head, s)) return (7);
3229 #endif
3230         }
3231
3232 #ifdef JP
3233         else if (buf[0] == 'E') return (0);
3234 #else
3235         else if (buf[0] == 'E')
3236         {
3237                 /* Acquire the Text */
3238                 s = buf+2;
3239
3240                 /* Store the name */
3241                 if (!add_name(&d_ptr->name, head, s)) return (7);
3242         }
3243 #endif
3244
3245         /* Process 'D' for "Description */
3246         else if (buf[0] == 'D')
3247         {
3248 #ifdef JP
3249                 if (buf[2] == '$')
3250                         return (0);
3251                 /* Acquire the text */
3252                 s = buf+2;
3253 #else
3254                 if (buf[2] != '$')
3255                         return (0);
3256                 /* Acquire the text */
3257                 s = buf+3;
3258 #endif
3259
3260                 /* Store the text */
3261                 if (!add_text(&d_ptr->text, head, s, TRUE)) return (7);
3262         }
3263
3264         /* Process 'W' for "More Info" (one line only) */
3265         else if (buf[0] == 'W')
3266         {
3267                 int min_lev, max_lev;
3268                 int min_plev, mode;
3269                 int min_alloc, max_chance;
3270                 int obj_good, obj_great;
3271                 int pit, nest;
3272
3273                 /* Scan for the values */
3274                 if (10 != sscanf(buf+2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x",
3275                                  &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great, (unsigned int *)&pit, (unsigned int *)&nest)) return (1);
3276
3277                 /* Save the values */
3278                 d_ptr->mindepth = min_lev;
3279                 d_ptr->maxdepth = max_lev;
3280                 d_ptr->min_plev = min_plev;
3281                 d_ptr->mode = mode;
3282                 d_ptr->min_m_alloc_level = min_alloc;
3283                 d_ptr->max_m_alloc_chance = max_chance;
3284                 d_ptr->obj_good = obj_good;
3285                 d_ptr->obj_great = obj_great;
3286                 d_ptr->pit = pit;
3287                 d_ptr->nest = nest;
3288         }
3289
3290         /* Process 'P' for "Place Info" */
3291         else if (buf[0] == 'P')
3292         {
3293                 int dy, dx;
3294
3295                 /* Scan for the values */
3296                 if (2 != sscanf(buf+2, "%d:%d", &dy, &dx)) return (1);
3297
3298                 /* Save the values */
3299                 d_ptr->dy = dy;
3300                 d_ptr->dx = dx;
3301         }
3302
3303         /* Process 'L' for "fLoor type" (one line only) */
3304         else if (buf[0] == 'L')
3305         {
3306                 char *zz[16];
3307
3308                 /* Scan for the values */
3309                 if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 1, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 1)) return (1);
3310
3311                 /* Save the values */
3312                 for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++)
3313                 {
3314                         d_ptr->floor[i].feat = f_tag_to_index(zz[i * 2]);
3315                         if (d_ptr->floor[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3316
3317                         d_ptr->floor[i].percent = atoi(zz[i * 2 + 1]);
3318                 }
3319                 d_ptr->tunnel_percent = atoi(zz[DUNGEON_FEAT_PROB_NUM * 2]);
3320         }
3321
3322         /* Process 'A' for "wAll type" (one line only) */
3323         else if (buf[0] == 'A')
3324         {
3325                 char *zz[16];
3326
3327                 /* Scan for the values */
3328                 if (tokenize(buf+2, DUNGEON_FEAT_PROB_NUM * 2 + 4, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 4)) return (1);
3329
3330                 /* Save the values */
3331                 for (i = 0; i < DUNGEON_FEAT_PROB_NUM; i++)
3332                 {
3333                         d_ptr->fill[i].feat = f_tag_to_index(zz[i * 2]);
3334                         if (d_ptr->fill[i].feat < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3335
3336                         d_ptr->fill[i].percent = atoi(zz[i * 2 + 1]);
3337                 }
3338
3339                 d_ptr->outer_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2]);
3340                 if (d_ptr->outer_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3341
3342                 d_ptr->inner_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 1]);
3343                 if (d_ptr->inner_wall < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3344
3345                 d_ptr->stream1 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 2]);
3346                 if (d_ptr->stream1 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3347
3348                 d_ptr->stream2 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 3]);
3349                 if (d_ptr->stream2 < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3350         }
3351
3352         /* Process 'F' for "Dungeon Flags" (multiple lines) */
3353         else if (buf[0] == 'F')
3354         {
3355                 int artif = 0, monst = 0;
3356
3357                 /* Parse every entry */
3358                 for (s = buf + 2; *s; )
3359                 {
3360                         /* Find the end of this entry */
3361                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3362
3363                         /* Nuke and skip any dividers */
3364                         if (*t)
3365                         {
3366                                 *t++ = '\0';
3367                                 while (*t == ' ' || *t == '|') t++;
3368                         }
3369
3370                         /* XXX XXX XXX Hack -- Read Final Artifact */
3371                         if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif))
3372                         {
3373                                 /* Extract a "Final Artifact" */
3374                                 d_ptr->final_artifact = artif;
3375
3376                                 /* Start at next entry */
3377                                 s = t;
3378
3379                                 /* Continue */
3380                                 continue;
3381                         }
3382
3383                         /* XXX XXX XXX Hack -- Read Final Object */
3384                         if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif))
3385                         {
3386                                 /* Extract a "Final Artifact" */
3387                                 d_ptr->final_object = artif;
3388
3389                                 /* Start at next entry */
3390                                 s = t;
3391
3392                                 /* Continue */
3393                                 continue;
3394                         }
3395
3396                         /* XXX XXX XXX Hack -- Read Artifact Guardian */
3397                         if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst))
3398                         {
3399                                 /* Extract a "Artifact Guardian" */
3400                                 d_ptr->final_guardian = monst;
3401
3402                                 /* Start at next entry */
3403                                 s = t;
3404
3405                                 /* Continue */
3406                                 continue;
3407                         }
3408
3409                         /* XXX XXX XXX Hack -- Read Special Percentage */
3410                         if (1 == sscanf(s, "MONSTER_DIV_%d", &monst))
3411                         {
3412                                 /* Extract a "Special %" */
3413                                 d_ptr->special_div = monst;
3414
3415                                 /* Start at next entry */
3416                                 s = t;
3417
3418                                 /* Continue */
3419                                 continue;
3420                         }
3421
3422                         /* Parse this entry */
3423                         if (0 != grab_one_dungeon_flag(d_ptr, s)) return (5);
3424
3425                         /* Start the next entry */
3426                         s = t;
3427                 }
3428         }
3429
3430         /* Process 'M' for "Basic Flags" (multiple lines) */
3431         else if (buf[0] == 'M')
3432         {
3433                 /* Parse every entry */
3434                 for (s = buf + 2; *s; )
3435                 {
3436                         /* Find the end of this entry */
3437                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3438
3439                         /* Nuke and skip any dividers */
3440                         if (*t)
3441                         {
3442                                 *t++ = '\0';
3443                                 while (*t == ' ' || *t == '|') t++;
3444                         }
3445
3446                         /* Hack -- Read monster symbols */
3447                         if (!strncmp(s, "R_CHAR_", 7))
3448                         {
3449                                 /* Skip "R_CHAR_" */
3450                                 s += 7;
3451
3452                                 /* Read a string */
3453                                 strncpy(d_ptr->r_char, s, sizeof(d_ptr->r_char));
3454
3455                                 /* Start at next entry */
3456                                 s = t;
3457
3458                                 /* Continue */
3459                                 continue;
3460                         }
3461
3462                         /* Parse this entry */
3463                         if (0 != grab_one_basic_monster_flag(d_ptr, s)) return (5);
3464
3465                         /* Start the next entry */
3466                         s = t;
3467                 }
3468         }
3469
3470         /* Process 'S' for "Spell Flags" (multiple lines) */
3471         else if (buf[0] == 'S')
3472         {
3473                 /* Parse every entry */
3474                 for (s = buf + 2; *s; )
3475                 {
3476                                 /* Find the end of this entry */
3477                         for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
3478
3479                                 /* Nuke and skip any dividers */
3480                         if (*t)
3481                         {
3482                                 *t++ = '\0';
3483                                 while ((*t == ' ') || (*t == '|')) t++;
3484                         }
3485
3486                                 /* XXX XXX XXX Hack -- Read spell frequency */
3487                         if (1 == sscanf(s, "1_IN_%d", &i))
3488                         {
3489                                 /* Start at next entry */
3490                                 s = t;
3491
3492                                         /* Continue */
3493                                 continue;
3494                         }
3495
3496                                 /* Parse this entry */
3497                         if (0 != grab_one_spell_monster_flag(d_ptr, s)) return (5);
3498
3499                                 /* Start the next entry */
3500                         s = t;
3501                 }
3502         }
3503
3504         /* Oops */
3505         else return (6);
3506
3507         /* Success */
3508         return (0);
3509 }
3510
3511
3512 #else   /* ALLOW_TEMPLATES */
3513
3514 #ifdef MACINTOSH
3515 static int i = 0;
3516 #endif
3517
3518 #endif  /* ALLOW_TEMPLATES */
3519
3520
3521 /* Random dungeon grid effects */
3522 #define RANDOM_NONE         0x00000000
3523 #define RANDOM_FEATURE      0x00000001
3524 #define RANDOM_MONSTER      0x00000002
3525 #define RANDOM_OBJECT       0x00000004
3526 #define RANDOM_EGO          0x00000008
3527 #define RANDOM_ARTIFACT     0x00000010
3528 #define RANDOM_TRAP         0x00000020
3529
3530
3531 typedef struct dungeon_grid dungeon_grid;
3532
3533 struct dungeon_grid
3534 {
3535         int             feature;                /* Terrain feature */
3536         int             monster;                /* Monster */
3537         int             object;                 /* Object */
3538         int             ego;                    /* Ego-Item */
3539         int             artifact;               /* Artifact */
3540         int             trap;                   /* Trap */
3541         int             cave_info;              /* Flags for CAVE_MARK, CAVE_GLOW, CAVE_ICKY, CAVE_ROOM */
3542         int             special;                /* Reserved for special terrain info */
3543         int             random;                 /* Number of the random effect */
3544 };
3545
3546
3547 static dungeon_grid letter[255];
3548
3549
3550 /*!
3551  * @brief 地形情報の「F:」情報をパースする
3552  * Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid
3553  * @param buf 解析文字列
3554  * @return エラーコード
3555  */
3556 static errr parse_line_feature(char *buf)
3557 {
3558         int num;
3559         char *zz[9];
3560
3561
3562         if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3563
3564         /* Tokenize the line */
3565         if ((num = tokenize(buf+2, 9, zz, 0)) > 1)
3566         {
3567                 /* Letter to assign */
3568                 int index = zz[0][0];
3569
3570                 /* Reset the info for the letter */
3571                 letter[index].feature = feat_none;
3572                 letter[index].monster = 0;
3573                 letter[index].object = 0;
3574                 letter[index].ego = 0;
3575                 letter[index].artifact = 0;
3576                 letter[index].trap = feat_none;
3577                 letter[index].cave_info = 0;
3578                 letter[index].special = 0;
3579                 letter[index].random = RANDOM_NONE;
3580
3581                 switch (num)
3582                 {
3583                         /* Special */
3584                         case 9:
3585                                 letter[index].special = atoi(zz[8]);
3586                                 /* Fall through */
3587                         /* Trap */
3588                         case 8:
3589                                 if ((zz[7][0] == '*') && !zz[7][1])
3590                                 {
3591                                         letter[index].random |= RANDOM_TRAP;
3592                                 }
3593                                 else
3594                                 {
3595                                         letter[index].trap = f_tag_to_index(zz[7]);
3596                                         if (letter[index].trap < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3597                                 }
3598                                 /* Fall through */
3599                         /* Artifact */
3600                         case 7:
3601                                 if (zz[6][0] == '*')
3602                                 {
3603                                         letter[index].random |= RANDOM_ARTIFACT;
3604                                         if (zz[6][1]) letter[index].artifact = atoi(zz[6] + 1);
3605                                 }
3606                                 else if (zz[6][0] == '!')
3607                                 {
3608                                         if (p_ptr->inside_quest)
3609                                         {
3610                                                 letter[index].artifact = quest[p_ptr->inside_quest].k_idx;
3611                                         }
3612                                 }
3613                                 else
3614                                 {
3615                                         letter[index].artifact = atoi(zz[6]);
3616                                 }
3617                                 /* Fall through */
3618                         /* Ego-item */
3619                         case 6:
3620                                 if (zz[5][0] == '*')
3621                                 {
3622                                         letter[index].random |= RANDOM_EGO;
3623                                         if (zz[5][1]) letter[index].ego = atoi(zz[5] + 1);
3624                                 }
3625                                 else
3626                                 {
3627                                         letter[index].ego = atoi(zz[5]);
3628                                 }
3629                                 /* Fall through */
3630                         /* Object */
3631                         case 5:
3632                                 if (zz[4][0] == '*')
3633                                 {
3634                                         letter[index].random |= RANDOM_OBJECT;
3635                                         if (zz[4][1]) letter[index].object = atoi(zz[4] + 1);
3636                                 }
3637                                 else if (zz[4][0] == '!')
3638                                 {
3639                                         if (p_ptr->inside_quest)
3640                                         {
3641                                                 int a_idx = quest[p_ptr->inside_quest].k_idx;
3642                                                 if (a_idx)
3643                                                 {
3644                                                         artifact_type *a_ptr = &a_info[a_idx];
3645                                                         if (!(a_ptr->gen_flags & TRG_INSTA_ART))
3646                                                         {
3647                                                                 letter[index].object = lookup_kind(a_ptr->tval, a_ptr->sval);
3648                                                         }
3649                                                 }
3650                                         }
3651                                 }
3652                                 else
3653                                 {
3654                                         letter[index].object = atoi(zz[4]);
3655                                 }
3656                                 /* Fall through */
3657                         /* Monster */
3658                         case 4:
3659                                 if (zz[3][0] == '*')
3660                                 {
3661                                         letter[index].random |= RANDOM_MONSTER;
3662                                         if (zz[3][1]) letter[index].monster = atoi(zz[3] + 1);
3663                                 }
3664                                 else if (zz[3][0] == 'c')
3665                                 {
3666                                         if (!zz[3][1]) return PARSE_ERROR_GENERIC;
3667                                         letter[index].monster = - atoi(zz[3] + 1);
3668                                 }
3669                                 else
3670                                 {
3671                                         letter[index].monster = atoi(zz[3]);
3672                                 }
3673                                 /* Fall through */
3674                         /* Cave info */
3675                         case 3:
3676                                 letter[index].cave_info = atoi(zz[2]);
3677                                 /* Fall through */
3678                         /* Feature */
3679                         case 2:
3680                                 if ((zz[1][0] == '*') && !zz[1][1])
3681                                 {
3682                                         letter[index].random |= RANDOM_FEATURE;
3683                                 }
3684                                 else
3685                                 {
3686                                         letter[index].feature = f_tag_to_index(zz[1]);
3687                                         if (letter[index].feature < 0) return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
3688                                 }
3689                                 break;
3690                 }
3691
3692                 return (0);
3693         }
3694
3695         return (1);
3696 }
3697
3698
3699 /*!
3700  * @brief 地形情報の「B:」情報をパースする
3701  * Process "B:<Index>:<Command>:..." -- Building definition
3702  * @param buf 解析文字列
3703  * @return エラーコード
3704  */
3705 static errr parse_line_building(char *buf)
3706 {
3707         int i;
3708         char *zz[37];
3709         int index;
3710         char *s;
3711
3712 #ifdef JP
3713         if (buf[2] == '$')
3714                 return 0;
3715         s = buf + 2;
3716 #else
3717         if (buf[2] != '$')
3718                 return 0;
3719         s = buf + 3;
3720 #endif
3721         /* Get the building number */
3722         index = atoi(s);
3723
3724         /* Find the colon after the building number */
3725         s = my_strchr(s, ':');
3726
3727         /* Verify that colon */
3728         if (!s) return (1);
3729
3730         /* Nuke the colon, advance to the sub-index */
3731         *s++ = '\0';
3732
3733         /* Paranoia -- require a sub-index */
3734         if (!*s) return (1);
3735
3736         /* Building definition sub-index */
3737         switch (s[0])
3738         {
3739                 /* Building name, owner, race */
3740                 case 'N':
3741                 {
3742                         if (tokenize(s + 2, 3, zz, 0) == 3)
3743                         {
3744                                 /* Name of the building */
3745                                 strcpy(building[index].name, zz[0]);
3746
3747                                 /* Name of the owner */
3748                                 strcpy(building[index].owner_name, zz[1]);
3749
3750                                 /* Race of the owner */
3751                                 strcpy(building[index].owner_race, zz[2]);
3752
3753                                 break;
3754                         }
3755
3756                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3757                 }
3758
3759                 /* Building Action */
3760                 case 'A':
3761                 {
3762                         if (tokenize(s + 2, 8, zz, 0) >= 7)
3763                         {
3764                                 /* Index of the action */
3765                                 int action_index = atoi(zz[0]);
3766
3767                                 /* Name of the action */
3768                                 strcpy(building[index].act_names[action_index], zz[1]);
3769
3770                                 /* Cost of the action for members */
3771                                 building[index].member_costs[action_index] = atoi(zz[2]);
3772
3773                                 /* Cost of the action for non-members */
3774                                 building[index].other_costs[action_index] = atoi(zz[3]);
3775
3776                                 /* Letter assigned to the action */
3777                                 building[index].letters[action_index] = zz[4][0];
3778
3779                                 /* Action code */
3780                                 building[index].actions[action_index] = atoi(zz[5]);
3781
3782                                 /* Action restriction */
3783                                 building[index].action_restr[action_index] = atoi(zz[6]);
3784
3785                                 break;
3786                         }
3787
3788                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3789                 }
3790
3791                 /* Building Classes */
3792                 case 'C':
3793                 {
3794                         if (tokenize(s + 2, MAX_CLASS, zz, 0) == MAX_CLASS)
3795                         {
3796                                 for (i = 0; i < MAX_CLASS; i++)
3797                                 {
3798                                         building[index].member_class[i] = atoi(zz[i]);
3799                                 }
3800
3801                                 break;
3802                         }
3803
3804                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3805                 }
3806
3807                 /* Building Races */
3808                 case 'R':
3809                 {
3810                         if (tokenize(s+2, MAX_RACES, zz, 0) == MAX_RACES)
3811                         {
3812                                 for (i = 0; i < MAX_RACES; i++)
3813                                 {
3814                                         building[index].member_race[i] = atoi(zz[i]);
3815                                 }
3816
3817                                 break;
3818                         }
3819
3820                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3821                 }
3822
3823                 /* Building Realms */
3824                 case 'M':
3825                 {
3826                         if (tokenize(s+2, MAX_MAGIC, zz, 0) == MAX_MAGIC)
3827                         {
3828                                 for (i = 0; i < MAX_MAGIC; i++)
3829                                 {
3830                                         building[index].member_realm[i+1] = atoi(zz[i]);
3831                                 }
3832
3833                                 break;
3834                         }
3835
3836                         return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
3837                 }
3838
3839                 case 'Z':
3840                 {
3841                         /* Ignore scripts */
3842                         break;
3843                 }
3844
3845                 default:
3846                 {
3847                         return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
3848                 }
3849         }
3850
3851         return (0);
3852 }
3853
3854
3855 /*!
3856  * @brief フロアの所定のマスにオブジェクトを配置する
3857  * Place the object j_ptr to a grid
3858  * @param j_ptr オブジェクト構造体の参照ポインタ
3859  * @param y 配置先Y座標
3860  * @param x 配置先X座標
3861  * @return エラーコード
3862  */
3863 static void drop_here(object_type *j_ptr, int y, int x)
3864 {
3865         cave_type *c_ptr = &cave[y][x];
3866         object_type *o_ptr;
3867
3868         /* Get new object */
3869         s16b o_idx = o_pop();
3870
3871         /* Access new object */
3872         o_ptr = &o_list[o_idx];
3873
3874         /* Structure copy */
3875         object_copy(o_ptr, j_ptr);
3876
3877
3878         /* Locate */
3879         o_ptr->iy = y;
3880         o_ptr->ix = x;
3881
3882         /* No monster */
3883         o_ptr->held_m_idx = 0;
3884
3885         /* Build a stack */
3886         o_ptr->next_o_idx = c_ptr->o_idx;
3887
3888         /* Place the object */
3889         c_ptr->o_idx = o_idx;
3890 }
3891
3892
3893 /*!
3894  * @brief クエスト用固定ダンジョンをフロアに生成する
3895  * Parse a sub-file of the "extra info"
3896  * @param buf 文字列
3897  * @param ymin 詳細不明
3898  * @param xmin 詳細不明
3899  * @param ymax 詳細不明
3900  * @param xmax 詳細不明
3901  * @param y 詳細不明
3902  * @param x 詳細不明
3903  * @return エラーコード
3904  */
3905 static errr process_dungeon_file_aux(char *buf, int ymin, int xmin, int ymax, int xmax, int *y, int *x)
3906 {
3907         int i;
3908
3909         char *zz[33];
3910
3911
3912         /* Skip "empty" lines */
3913         if (!buf[0]) return (0);
3914
3915         /* Skip "blank" lines */
3916         if (iswspace(buf[0])) return (0);
3917
3918         /* Skip comments */
3919         if (buf[0] == '#') return (0);
3920
3921         /* Require "?:*" format */
3922         if (buf[1] != ':') return (1);
3923
3924
3925         /* Process "%:<fname>" */
3926         if (buf[0] == '%')
3927         {
3928                 /* Attempt to Process the given file */
3929                 return (process_dungeon_file(buf + 2, ymin, xmin, ymax, xmax));
3930         }
3931
3932         /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>" -- info for dungeon grid */
3933         if (buf[0] == 'F')
3934         {
3935                 return parse_line_feature(buf);
3936         }
3937
3938         /* Process "D:<dungeon>" -- info for the cave grids */
3939         else if (buf[0] == 'D')
3940         {
3941                 object_type object_type_body;
3942
3943                 /* Acquire the text */
3944                 char *s = buf + 2;
3945
3946                 /* Length of the text */
3947                 int len = strlen(s);
3948
3949                 if (init_flags & INIT_ONLY_BUILDINGS) return (0);
3950
3951                 for (*x = xmin, i = 0; ((*x < xmax) && (i < len)); (*x)++, s++, i++)
3952                 {
3953                         /* Access the grid */
3954                         cave_type *c_ptr = &cave[*y][*x];
3955
3956                         int idx = s[0];
3957
3958                         int object_index = letter[idx].object;
3959                         int monster_index = letter[idx].monster;
3960                         int random = letter[idx].random;
3961                         int artifact_index = letter[idx].artifact;
3962
3963                         /* Lay down a floor */
3964                         c_ptr->feat = conv_dungeon_feat(letter[idx].feature);
3965
3966                         /* Only the features */
3967                         if (init_flags & INIT_ONLY_FEATURES) continue;
3968
3969                         /* Cave info */
3970                         c_ptr->info = letter[idx].cave_info;
3971
3972                         /* Create a monster */
3973                         if (random & RANDOM_MONSTER)
3974                         {
3975                                 monster_level = base_level + monster_index;
3976
3977                                 place_monster(*y, *x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));
3978
3979                                 monster_level = base_level;
3980                         }
3981                         else if (monster_index)
3982                         {
3983                                 int old_cur_num, old_max_num;
3984                                 bool clone = FALSE;
3985
3986                                 if (monster_index < 0)
3987                                 {
3988                                         monster_index = -monster_index;
3989                                         clone = TRUE;
3990                                 }
3991                                 old_cur_num = r_info[monster_index].cur_num;
3992                                 old_max_num = r_info[monster_index].max_num;
3993
3994                                 /* Make alive again */
3995                                 if (r_info[monster_index].flags1 & RF1_UNIQUE)
3996                                 {
3997                                         r_info[monster_index].cur_num = 0;
3998                                         r_info[monster_index].max_num = 1;
3999                                 }
4000
4001                                 /* Make alive again */
4002                                 /* Hack -- Non-unique Nazguls are semi-unique */
4003                                 else if (r_info[monster_index].flags7 & RF7_NAZGUL)
4004                                 {
4005                                         if (r_info[monster_index].cur_num == r_info[monster_index].max_num)
4006                                         {
4007                                                 r_info[monster_index].max_num++;
4008                                         }
4009                                 }
4010
4011                                 /* Place it */
4012                                 place_monster_aux(0, *y, *x, monster_index, (PM_ALLOW_SLEEP | PM_NO_KAGE));
4013                                 if (clone)
4014                                 {
4015                                         /* clone */
4016                                         m_list[hack_m_idx_ii].smart |= SM_CLONED;
4017
4018                                         /* Make alive again for real unique monster */
4019                                         r_info[monster_index].cur_num = old_cur_num;
4020                                         r_info[monster_index].max_num = old_max_num;
4021                                 }
4022                         }
4023
4024                         /* Object (and possible trap) */
4025                         if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP))
4026                         {
4027                                 object_level = base_level + object_index;
4028
4029                                 /*
4030                                  * Random trap and random treasure defined
4031                                  * 25% chance for trap and 75% chance for object
4032                                  */
4033                                 if (randint0(100) < 75)
4034                                 {
4035                                         place_object(*y, *x, 0L);
4036                                 }
4037                                 else
4038                                 {
4039                                         place_trap(*y, *x);
4040                                 }
4041
4042                                 object_level = base_level;
4043                         }
4044                         else if (random & RANDOM_OBJECT)
4045                         {
4046                                 object_level = base_level + object_index;
4047
4048                                 /* Create an out of deep object */
4049                                 if (randint0(100) < 75)
4050                                         place_object(*y, *x, 0L);
4051                                 else if (randint0(100) < 80)
4052                                         place_object(*y, *x, AM_GOOD);
4053                                 else
4054                                         place_object(*y, *x, AM_GOOD | AM_GREAT);
4055
4056                                 object_level = base_level;
4057                         }
4058                         /* Random trap */
4059                         else if (random & RANDOM_TRAP)
4060                         {
4061                                 place_trap(*y, *x);
4062                         }
4063                         /* Hidden trap (or door) */
4064                         else if (letter[idx].trap)
4065                         {
4066                                 c_ptr->mimic = c_ptr->feat;
4067                                 c_ptr->feat = conv_dungeon_feat(letter[idx].trap);
4068                         }
4069                         else if (object_index)
4070                         {
4071                                 /* Get local object */
4072                                 object_type *o_ptr = &object_type_body;
4073
4074                                 /* Create the item */
4075                                 object_prep(o_ptr, object_index);
4076
4077                                 if (o_ptr->tval == TV_GOLD)
4078                                 {
4079                                         coin_type = object_index - OBJ_GOLD_LIST;
4080                                         make_gold(o_ptr);
4081                                         coin_type = 0;
4082                                 }
4083
4084                                 /* Apply magic (no messages, no artifacts) */
4085                                 apply_magic(o_ptr, base_level, AM_NO_FIXED_ART | AM_GOOD);
4086
4087                                 drop_here(o_ptr, *y, *x);
4088                         }
4089
4090                         /* Artifact */
4091                         if (artifact_index)
4092                         {
4093                                 if (a_info[artifact_index].cur_num)
4094                                 {
4095                                         int k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT);
4096                                         object_type forge;
4097                                         object_type *q_ptr = &forge;
4098
4099                                         object_prep(q_ptr, k_idx);
4100
4101                                         /* Drop it in the dungeon */
4102                                         drop_here(q_ptr, *y, *x);
4103                                 }
4104                                 else
4105                                 {
4106                                         /* Create the artifact */
4107                                         if (create_named_art(artifact_index, *y, *x))
4108                                                 a_info[artifact_index].cur_num = 1;
4109                                 }
4110                         }
4111
4112                         /* Terrain special */
4113                         c_ptr->special = letter[idx].special;
4114                 }
4115
4116                 (*y)++;
4117
4118                 return (0);
4119         }
4120
4121         /* Process "Q:<number>:<command>:... -- quest info */
4122         else if (buf[0] == 'Q')
4123         {
4124                 int num;
4125                 quest_type *q_ptr;
4126 #ifdef JP
4127                 if (buf[2] == '$')
4128                         return 0;
4129                 num = tokenize(buf + 2, 33, zz, 0);
4130 #else
4131                 if (buf[2] != '$')
4132                         return 0;
4133                 num = tokenize(buf + 3, 33, zz, 0);
4134 #endif
4135
4136                 /* Have we enough parameters? */
4137                 if (num < 3) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
4138
4139                 /* Get the quest */
4140                 q_ptr = &(quest[atoi(zz[0])]);
4141
4142                 /* Process "Q:<q_index>:Q:<type>:<num_mon>:<cur_num>:<max_num>:<level>:<r_idx>:<k_idx>:<flags>" -- quest info */
4143                 if (zz[1][0] == 'Q')
4144                 {
4145                         if (init_flags & INIT_ASSIGN)
4146                         {
4147                                 monster_race *r_ptr;
4148                                 artifact_type *a_ptr;
4149
4150                                 if (num < 9) return (PARSE_ERROR_TOO_FEW_ARGUMENTS);
4151
4152                                 q_ptr->type    = atoi(zz[2]);
4153                                 q_ptr->num_mon = atoi(zz[3]);
4154                                 q_ptr->cur_num = atoi(zz[4]);
4155                                 q_ptr->max_num = atoi(zz[5]);
4156                                 q_ptr->level   = atoi(zz[6]);
4157                                 q_ptr->r_idx   = atoi(zz[7]);
4158                                 q_ptr->k_idx   = atoi(zz[8]);
4159                                 q_ptr->dungeon = atoi(zz[9]);
4160
4161                                 if (num > 10)
4162                                         q_ptr->flags  = atoi(zz[10]);
4163
4164                                 r_ptr = &r_info[q_ptr->r_idx];
4165                                 if (r_ptr->flags1 & RF1_UNIQUE)
4166                                         r_ptr->flags1 |= RF1_QUESTOR;
4167
4168                                 a_ptr = &a_info[q_ptr->k_idx];
4169                                 a_ptr->gen_flags |= TRG_QUESTITEM;
4170                         }
4171                         return (0);
4172                 }
4173
4174                 else if (zz[1][0] == 'R')
4175                 {
4176                         if (init_flags & INIT_ASSIGN)
4177                         {
4178                                 int idx, count = 0;
4179                                 int reward_idx = 0;
4180
4181                                 for (idx = 2; idx < num; idx++)
4182                                 {
4183                                         int a_idx = atoi(zz[idx]);
4184                                         if (a_idx < 1) continue;
4185                                         if (a_info[a_idx].cur_num > 0) continue;
4186                                         count++;
4187                                         if (one_in_(count)) reward_idx = a_idx;
4188                                 }
4189
4190                                 if (reward_idx)
4191                                 {
4192                                         /* Set quest's rewarding artifact */
4193                                         q_ptr->k_idx = reward_idx;
4194                                         a_info[reward_idx].gen_flags |= TRG_QUESTITEM;
4195                                 }
4196                                 else
4197                                 {
4198                                         /* Change a quest type to KILL_ALL when all artifact of reward list are got */
4199                                         q_ptr->type = QUEST_TYPE_KILL_ALL;
4200                                 }
4201                         }
4202
4203                         return (0);
4204                 }
4205
4206                 /* Process "Q:<q_index>:N:<name>" -- quest name */
4207                 else if (zz[1][0] == 'N')
4208                 {
4209                         if (init_flags & (INIT_ASSIGN | INIT_SHOW_TEXT | INIT_NAME_ONLY))
4210                         {
4211                                 strcpy(q_ptr->name, zz[2]);
4212                         }
4213
4214                         return (0);
4215                 }
4216
4217                 /* Process "Q:<q_index>:T:<text>" -- quest description line */
4218                 else if (zz[1][0] == 'T')
4219                 {
4220                         if (init_flags & INIT_SHOW_TEXT)
4221                         {
4222                                 strcpy(quest_text[quest_text_line], zz[2]);
4223                                 quest_text_line++;
4224                         }
4225
4226                         return (0);
4227                 }
4228         }
4229
4230         /* Process "W:<command>: ..." -- info for the wilderness */
4231         else if (buf[0] == 'W')
4232         {
4233                 return parse_line_wilderness(buf, ymin, xmin, ymax, xmax, y, x);
4234         }
4235
4236         /* Process "P:<y>:<x>" -- player position */
4237         else if (buf[0] == 'P')
4238         {
4239                 if (init_flags & INIT_CREATE_DUNGEON)
4240                 {
4241                         if (tokenize(buf + 2, 2, zz, 0) == 2)
4242                         {
4243                                 int panels_x, panels_y;
4244
4245                                 /* Hack - Set the dungeon size */
4246                                 panels_y = (*y / SCREEN_HGT);
4247                                 if (*y % SCREEN_HGT) panels_y++;
4248                                 cur_hgt = panels_y * SCREEN_HGT;
4249
4250                                 panels_x = (*x / SCREEN_WID);
4251                                 if (*x % SCREEN_WID) panels_x++;
4252                                 cur_wid = panels_x * SCREEN_WID;
4253
4254                                 /* Assume illegal panel */
4255                                 panel_row_min = cur_hgt;
4256                                 panel_col_min = cur_wid;
4257
4258                                 /* Place player in a quest level */
4259                                 if (p_ptr->inside_quest)
4260                                 {
4261                                         int py, px;
4262
4263                                         /* Delete the monster (if any) */
4264                                         delete_monster(p_ptr->y, p_ptr->x);
4265
4266                                         py = atoi(zz[0]);
4267                                         px = atoi(zz[1]);
4268
4269                                         p_ptr->y = py;
4270                                         p_ptr->x = px;
4271                                 }
4272                                 /* Place player in the town */
4273                                 else if (!p_ptr->oldpx && !p_ptr->oldpy)
4274                                 {
4275                                         p_ptr->oldpy = atoi(zz[0]);
4276                                         p_ptr->oldpx = atoi(zz[1]);
4277                                 }
4278                         }
4279                 }
4280
4281                 return (0);
4282         }
4283
4284         /* Process "B:<Index>:<Command>:..." -- Building definition */
4285         else if (buf[0] == 'B')
4286         {
4287                 return parse_line_building(buf);
4288         }
4289
4290         /* Process "M:<type>:<maximum>" -- set maximum values */
4291         else if (buf[0] == 'M')
4292         {
4293                 if (tokenize(buf+2, 2, zz, 0) == 2)
4294                 {
4295                         /* Maximum towns */
4296                         if (zz[0][0] == 'T')
4297                         {
4298                                 max_towns = atoi(zz[1]);
4299                         }
4300
4301                         /* Maximum quests */
4302                         else if (zz[0][0] == 'Q')
4303                         {
4304                                 max_quests = atoi(zz[1]);
4305                         }
4306
4307                         /* Maximum r_idx */
4308                         else if (zz[0][0] == 'R')
4309                         {
4310                                 max_r_idx = atoi(zz[1]);
4311                         }
4312
4313                         /* Maximum k_idx */
4314                         else if (zz[0][0] == 'K')
4315                         {
4316                                 max_k_idx = atoi(zz[1]);
4317                         }
4318
4319                         /* Maximum v_idx */
4320                         else if (zz[0][0] == 'V')
4321                         {
4322                                 max_v_idx = atoi(zz[1]);
4323                         }
4324
4325                         /* Maximum f_idx */
4326                         else if (zz[0][0] == 'F')
4327                         {
4328                                 max_f_idx = atoi(zz[1]);
4329                         }
4330
4331                         /* Maximum a_idx */
4332                         else if (zz[0][0] == 'A')
4333                         {
4334                                 max_a_idx = atoi(zz[1]);
4335                         }
4336
4337                         /* Maximum e_idx */
4338                         else if (zz[0][0] == 'E')
4339                         {
4340                                 max_e_idx = atoi(zz[1]);
4341                         }
4342
4343                         /* Maximum d_idx */
4344                         else if (zz[0][0] == 'D')
4345                         {
4346                                 max_d_idx = atoi(zz[1]); 
4347                         }
4348
4349                         /* Maximum o_idx */
4350                         else if (zz[0][0] == 'O')
4351                         {
4352                                 max_o_idx = atoi(zz[1]);
4353                         }
4354
4355                         /* Maximum m_idx */
4356                         else if (zz[0][0] == 'M')
4357                         {
4358                                 max_m_idx = atoi(zz[1]);
4359                         }
4360
4361                         /* Wilderness size */
4362                         else if (zz[0][0] == 'W')
4363                         {
4364                                 /* Maximum wild_x_size */
4365                                 if (zz[0][1] == 'X')
4366                                         max_wild_x = atoi(zz[1]);
4367                                 /* Maximum wild_y_size */
4368                                 if (zz[0][1] == 'Y')
4369                                         max_wild_y = atoi(zz[1]);
4370                         }
4371
4372                         return (0);
4373                 }
4374         }
4375
4376
4377         /* Failure */
4378         return (1);
4379 }
4380
4381
4382 static char tmp[8];
4383 static cptr variant = "ZANGBAND";
4384
4385
4386 /*!
4387  * @brief クエスト用固定ダンジョン生成時の分岐処理
4388  * Helper function for "process_dungeon_file()"
4389  * @param sp
4390  * @param fp
4391  * @return エラーコード
4392  */
4393 static cptr process_dungeon_file_expr(char **sp, char *fp)
4394 {
4395         cptr v;
4396
4397         char *b;
4398         char *s;
4399
4400         char b1 = '[';
4401         char b2 = ']';
4402
4403         char f = ' ';
4404
4405         /* Initial */
4406         s = (*sp);
4407
4408         /* Skip spaces */
4409         while (iswspace(*s)) s++;
4410
4411         /* Save start */
4412         b = s;
4413
4414         /* Default */
4415         v = "?o?o?";
4416
4417         /* Analyze */
4418         if (*s == b1)
4419         {
4420                 const char *p;
4421                 const char *t;
4422
4423                 /* Skip b1 */
4424                 s++;
4425
4426                 /* First */
4427                 t = process_dungeon_file_expr(&s, &f);
4428
4429                 /* Oops */
4430                 if (!*t)
4431                 {
4432                         /* Nothing */
4433                 }
4434
4435                 /* Function: IOR */
4436                 else if (streq(t, "IOR"))
4437                 {
4438                         v = "0";
4439                         while (*s && (f != b2))
4440                         {
4441                                 t = process_dungeon_file_expr(&s, &f);
4442                                 if (*t && !streq(t, "0")) v = "1";
4443                         }
4444                 }
4445
4446                 /* Function: AND */
4447                 else if (streq(t, "AND"))
4448                 {
4449                         v = "1";
4450                         while (*s && (f != b2))
4451                         {
4452                                 t = process_dungeon_file_expr(&s, &f);
4453                                 if (*t && streq(t, "0")) v = "0";
4454                         }
4455                 }
4456
4457                 /* Function: NOT */
4458                 else if (streq(t, "NOT"))
4459                 {
4460                         v = "1";
4461                         while (*s && (f != b2))
4462                         {
4463                                 t = process_dungeon_file_expr(&s, &f);
4464                                 if (*t && streq(t, "1")) v = "0";
4465                         }
4466                 }
4467
4468                 /* Function: EQU */
4469                 else if (streq(t, "EQU"))
4470                 {
4471                         v = "0";
4472                         if (*s && (f != b2))
4473                         {
4474                                 t = process_dungeon_file_expr(&s, &f);
4475                         }
4476                         while (*s && (f != b2))
4477                         {
4478                                 p = process_dungeon_file_expr(&s, &f);
4479                                 if (streq(t, p)) v = "1";
4480                         }
4481                 }
4482
4483                 /* Function: LEQ */
4484                 else if (streq(t, "LEQ"))
4485                 {
4486                         v = "1";
4487                         if (*s && (f != b2))
4488                         {
4489                                 t = process_dungeon_file_expr(&s, &f);
4490                         }
4491                         while (*s && (f != b2))
4492                         {
4493                                 p = t;
4494                                 t = process_dungeon_file_expr(&s, &f);
4495                                 if (*t && atoi(p) > atoi(t)) v = "0";
4496                         }
4497                 }
4498
4499                 /* Function: GEQ */
4500                 else if (streq(t, "GEQ"))
4501                 {
4502                         v = "1";
4503                         if (*s && (f != b2))
4504                         {
4505                                 t = process_dungeon_file_expr(&s, &f);
4506                         }
4507                         while (*s && (f != b2))
4508                         {
4509                                 p = t;
4510                                 t = process_dungeon_file_expr(&s, &f);
4511
4512                                 /* Compare two numbers instead of string */
4513                                 if (*t && atoi(p) < atoi(t)) v = "0";
4514                         }
4515                 }
4516
4517                 /* Oops */
4518                 else
4519                 {
4520                         while (*s && (f != b2))
4521                         {
4522                                 t = process_dungeon_file_expr(&s, &f);
4523                         }
4524                 }
4525
4526                 /* Verify ending */
4527                 if (f != b2) v = "?x?x?";
4528
4529                 /* Extract final and Terminate */
4530                 if ((f = *s) != '\0') *s++ = '\0';
4531         }
4532
4533         /* Other */
4534         else
4535         {
4536                 /* Accept all printables except spaces and brackets */
4537 #ifdef JP
4538                 while (iskanji(*s) || (isprint(*s) && !my_strchr(" []", *s)))
4539                 {
4540                         if (iskanji(*s)) s++;
4541                         s++;
4542                 }
4543 #else
4544                 while (isprint(*s) && !my_strchr(" []", *s)) ++s;
4545 #endif
4546
4547                 /* Extract final and Terminate */
4548                 if ((f = *s) != '\0') *s++ = '\0';
4549
4550                 /* Variable */
4551                 if (*b == '$')
4552                 {
4553                         /* System */
4554                         if (streq(b+1, "SYS"))
4555                         {
4556                                 v = ANGBAND_SYS;
4557                         }
4558
4559                         /* Graphics */
4560                         else if (streq(b+1, "GRAF"))
4561                         {
4562                                 v = ANGBAND_GRAF;
4563                         }
4564
4565                         else if (streq(b+1, "MONOCHROME"))
4566                         {
4567                                 if (arg_monochrome)
4568                                         v = "ON";
4569                                 else
4570                                         v = "OFF";
4571                         }
4572
4573                         /* Race */
4574                         else if (streq(b+1, "RACE"))
4575                         {
4576                                 v = _(rp_ptr->E_title, rp_ptr->title);
4577                         }
4578
4579                         /* Class */
4580                         else if (streq(b+1, "CLASS"))
4581                         {
4582                                 v = _(cp_ptr->E_title, cp_ptr->title);
4583                         }
4584
4585                         /* First realm */
4586                         else if (streq(b+1, "REALM1"))
4587                         {
4588                                 v = _(E_realm_names[p_ptr->realm1], realm_names[p_ptr->realm1]);
4589                         }
4590
4591                         /* Second realm */
4592                         else if (streq(b+1, "REALM2"))
4593                         {
4594                                 v = _(E_realm_names[p_ptr->realm2], realm_names[p_ptr->realm2]);
4595                         }
4596
4597                         /* Player name */
4598                         else if (streq(b+1, "PLAYER"))
4599                         {
4600                                 static char tmp_player_name[32];
4601                                 char *pn, *tpn;
4602                                 for (pn = p_ptr->name, tpn = tmp_player_name; *pn; pn++, tpn++)
4603                                 {
4604 #ifdef JP
4605                                         if (iskanji(*pn))
4606                                         {
4607                                                 *(tpn++) = *(pn++);
4608                                                 *tpn = *pn;
4609                                                 continue;
4610                                         }
4611 #endif
4612                                         *tpn = my_strchr(" []", *pn) ? '_' : *pn;
4613                                 }
4614                                 *tpn = '\0';
4615                                 v = tmp_player_name;
4616                         }
4617
4618                         /* Town */
4619                         else if (streq(b+1, "TOWN"))
4620                         {
4621                                 sprintf(tmp, "%d", p_ptr->town_num);
4622                                 v = tmp;
4623                         }
4624
4625                         /* Level */
4626                         else if (streq(b+1, "LEVEL"))
4627                         {
4628                                 sprintf(tmp, "%d", p_ptr->lev);
4629                                 v = tmp;
4630                         }
4631
4632                         /* Current quest number */
4633                         else if (streq(b+1, "QUEST_NUMBER"))
4634                         {
4635                                 sprintf(tmp, "%d", p_ptr->inside_quest);
4636                                 v = tmp;
4637                         }
4638
4639                         /* Number of last quest */
4640                         else if (streq(b+1, "LEAVING_QUEST"))
4641                         {
4642                                 sprintf(tmp, "%d", leaving_quest);
4643                                 v = tmp;
4644                         }
4645
4646                         /* Quest type */
4647                         else if (prefix(b+1, "QUEST_TYPE"))
4648                         {
4649                                 /* "QUEST_TYPE" uses a special parameter to determine the type of the quest */
4650                                 sprintf(tmp, "%d", quest[atoi(b+11)].type);
4651                                 v = tmp;
4652                         }
4653
4654                         /* Quest status */
4655                         else if (prefix(b+1, "QUEST"))
4656                         {
4657                                 /* "QUEST" uses a special parameter to determine the number of the quest */
4658                                 sprintf(tmp, "%d", quest[atoi(b+6)].status);
4659                                 v = tmp;
4660                         }
4661
4662                         /* Random */
4663                         else if (prefix(b+1, "RANDOM"))
4664                         {
4665                                 /* "RANDOM" uses a special parameter to determine the number of the quest */
4666                                 sprintf(tmp, "%d", (int)(seed_town%atoi(b+7)));
4667                                 v = tmp;
4668                         }
4669
4670                         /* Variant name */
4671                         else if (streq(b+1, "VARIANT"))
4672                         {
4673                                 v = variant;
4674                         }
4675
4676                         /* Wilderness */
4677                         else if (streq(b+1, "WILDERNESS"))
4678                         {
4679                                 if (vanilla_town)
4680                                         sprintf(tmp, "NONE");
4681                                 else if (lite_town)
4682                                         sprintf(tmp, "LITE");
4683                                 else
4684                                         sprintf(tmp, "NORMAL");
4685                                 v = tmp;
4686                         }
4687                 }
4688
4689                 /* Constant */
4690                 else
4691                 {
4692                         v = b;
4693                 }
4694         }
4695
4696         /* Save */
4697         (*fp) = f;
4698
4699         /* Save */
4700         (*sp) = s;
4701
4702         /* Result */
4703         return (v);
4704 }
4705
4706
4707 /*!
4708  * @brief クエスト用固定ダンジョン生成時のメインルーチン
4709  * Helper function for "process_dungeon_file()"
4710  * @param name ファイル名
4711  * @param ymin 詳細不明
4712  * @param xmin 詳細不明
4713  * @param ymax 詳細不明
4714  * @param xmax 詳細不明
4715  * @return エラーコード
4716  */
4717 errr process_dungeon_file(cptr name, int ymin, int xmin, int ymax, int xmax)
4718 {
4719         FILE *fp;
4720
4721         char buf[1024];
4722
4723         int num = -1;
4724
4725         errr err = 0;
4726
4727         bool bypass = FALSE;
4728
4729         int x = xmin, y = ymin;
4730
4731
4732         /* Build the filename */
4733         path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, name);
4734
4735         /* Open the file */
4736         fp = my_fopen(buf, "r");
4737
4738         /* No such file */
4739         if (!fp) return (-1);
4740
4741
4742         /* Process the file */
4743         while (0 == my_fgets(fp, buf, sizeof(buf)))
4744         {
4745                 /* Count lines */
4746                 num++;
4747
4748
4749                 /* Skip "empty" lines */
4750                 if (!buf[0]) continue;
4751
4752                 /* Skip "blank" lines */
4753                 if (iswspace(buf[0])) continue;
4754
4755                 /* Skip comments */
4756                 if (buf[0] == '#') continue;
4757
4758
4759                 /* Process "?:<expr>" */
4760                 if ((buf[0] == '?') && (buf[1] == ':'))
4761                 {
4762                         char f;
4763                         cptr v;
4764                         char *s;
4765
4766                         /* Start */
4767                         s = buf + 2;
4768
4769                         /* Parse the expr */
4770                         v = process_dungeon_file_expr(&s, &f);
4771
4772                         /* Set flag */
4773                         bypass = (streq(v, "0") ? TRUE : FALSE);
4774
4775                         /* Continue */
4776                         continue;
4777                 }
4778
4779                 /* Apply conditionals */
4780                 if (bypass) continue;
4781
4782                 /* Process the line */
4783                 err = process_dungeon_file_aux(buf, ymin, xmin, ymax, xmax, &y, &x);
4784
4785                 /* Oops */
4786                 if (err) break;
4787         }
4788
4789         /* Errors */
4790         if (err)
4791         {
4792                 cptr oops;
4793
4794                 /* Error string */
4795                 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
4796
4797                 /* Oops */
4798                 msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
4799                 msg_format(_("'%s'を解析中。", "Parsing '%s'."), buf);
4800
4801                 msg_print(NULL);
4802         }
4803
4804
4805         /* Close the file */
4806         my_fclose(fp);
4807
4808         /* Result */
4809         return (err);
4810 }
4811
4812
4813
4814 #if 0
4815 void write_r_info_txt(void)
4816 {
4817         int i, j, z, fc, bc;
4818         int dlen;
4819
4820         cptr flags[32 * 10];
4821
4822         u32b f_ptr[10];
4823         cptr *n_ptr[10];
4824
4825         monster_race *r_ptr;
4826
4827         monster_blow *b_ptr;
4828
4829         FILE *fff = fopen("output.txt", "wt");
4830
4831         cptr desc;
4832
4833         int mode = -1;
4834
4835         if (!fff) return;
4836
4837         fprintf(fff, "# File: r_info.txt (autogenerated)\n\n");
4838
4839         fprintf(fff, "# Version stamp (required)\n\n");
4840
4841         /* Write Version */
4842         fprintf(fff, "V:%d.%d.%d\n\n\n", r_head->v_major, r_head->v_minor, r_head->v_patch);
4843
4844         /* Write a note */
4845         fprintf(fff, "##### The Player #####\n\n");
4846
4847         for (z = -1; z < alloc_race_size; z++)
4848         {
4849                 /* Output the monsters in order */
4850                 i = (z >= 0) ? alloc_race_table[z].index : 0;
4851
4852                 /* Acquire the monster */
4853                 r_ptr = &r_info[i];
4854
4855                 /* Ignore empty monsters */
4856                 if (!strlen(r_name + r_ptr->name)) continue;
4857
4858                 /* Ignore useless monsters */
4859                 if (i && !r_ptr->speed) continue;
4860
4861                 /* Write a note if necessary */
4862                 if (i && (!r_ptr->level != !mode))
4863                 {
4864                         /* Note the town */
4865                         if (!r_ptr->level)
4866                         {
4867                                 fprintf(fff, "\n##### Town monsters #####\n\n");
4868                         }
4869                         /* Note the dungeon */
4870                         else
4871                         {
4872                                 fprintf(fff, "\n##### Normal monsters #####\n\n");
4873                         }
4874
4875                         /* Record the change */
4876                         mode = r_ptr->level;
4877                 }
4878
4879                 /* Acquire the flags */
4880                 f_ptr[0] = r_ptr->flags1; n_ptr[0] = r_info_flags1;
4881                 f_ptr[1] = r_ptr->flags2; n_ptr[1] = r_info_flags2;
4882                 f_ptr[2] = r_ptr->flags3; n_ptr[2] = r_info_flags3;
4883                 f_ptr[3] = r_ptr->flags4; n_ptr[3] = r_info_flags4;
4884                 f_ptr[4] = r_ptr->flags5; n_ptr[4] = r_info_flags5;
4885                 f_ptr[5] = r_ptr->flags6; n_ptr[5] = r_info_flags6;
4886                 f_ptr[6] = r_ptr->flags7; n_ptr[6] = r_info_flags7;
4887                 f_ptr[7] = r_ptr->flags8; n_ptr[7] = r_info_flags8;
4888                 f_ptr[8] = r_ptr->flags9; n_ptr[8] = r_info_flags9;
4889                 f_ptr[9] = r_ptr->flagsr; n_ptr[9] = r_info_flagsr;
4890
4891                 /* Write New/Number/Name */
4892                 fprintf(fff, "N:%d:%s\n", z + 1, r_name + r_ptr->name);
4893
4894                 /* Write Graphic */
4895                 fprintf(fff, "G:%c:%c\n", r_ptr->d_char, color_char[r_ptr->d_attr]);
4896
4897                 /* Write Information */
4898                 fprintf(fff, "I:%d:%dd%d:%d:%d:%d\n", r_ptr->speed, r_ptr->hdice, r_ptr->hside,
4899                                                                                                                   r_ptr->aaf, r_ptr->ac, r_ptr->sleep);
4900
4901                 /* Write more information */
4902                 fprintf(fff, "W:%d:%d:%d:%ld\n", r_ptr->level, r_ptr->rarity, r_ptr->extra, r_ptr->mexp);
4903
4904                 /* Write Blows */
4905                 for(j = 0; j < 4; j++)
4906                 {
4907                         b_ptr = &(r_ptr->blow[j]);
4908
4909                         /* Stop when done */
4910                         if (!b_ptr->method) break;
4911
4912                         /* Write the blows */
4913                         fprintf(fff, "B:%s:%s:%dd%d\n", r_info_blow_method[b_ptr->method],
4914                                                                                                           r_info_blow_effect[b_ptr->effect],
4915                                                                                                           b_ptr->d_dice, b_ptr->d_side);
4916                 }
4917
4918                 /* Extract the flags */
4919                 for (fc = 0, j = 0; j < 32 * 3; j++)
4920                 {
4921                         /* Check this flag */
4922                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4923                 }
4924
4925                 /* Extract the extra flags */
4926                 for (j = 32 * 6; j < 32 * 10; j++)
4927                 {
4928                         /* Check this flag */
4929                         if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4930                 }
4931
4932                 /* Write the flags */
4933                 for (j = 0; j < fc;)
4934                 {
4935                         char buf[160];
4936
4937                         /* Start the line */
4938                         sprintf(buf, "F:");
4939
4940                         for (bc = 0; (bc < 60) && (j < fc); j++)
4941                         {
4942                                 char t[80];
4943
4944                                 /* Format the flag */
4945                                 sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4946
4947                                 /* Add it to the buffer */
4948                                 strcat(buf, t);
4949
4950                                 /* Note the length */
4951                                 bc += strlen(t);
4952                         }
4953
4954                         /* Done with this line; write it */
4955                         fprintf(fff, "%s\n", buf);
4956                 }
4957
4958                 /* Write Spells if applicable */
4959                 if (r_ptr->freq_spell)
4960                 {
4961                         /* Write the frequency */
4962                         fprintf(fff, "S:1_IN_%d | \n", 100 / r_ptr->freq_spell);
4963
4964                         /* Extract the spell flags */
4965                         for (fc = 0, j = 96; j < 192; j++)
4966                         {
4967                                 /* Check this flag */
4968                                 if (f_ptr[j / 32] & (1L << (j % 32))) flags[fc++] = n_ptr[j / 32][j % 32];
4969                         }
4970
4971                         /* Write the flags */
4972                         for (j = 0; j < fc;)
4973                         {
4974                                 char buf[160], *t;
4975
4976                                 /* Start the line */
4977                                 sprintf(buf, "S:");
4978
4979                                 for (bc = 0, t = buf + 2; (bc < 60) && (j < fc); j++)
4980                                 {
4981                                         int tlen;
4982
4983                                         /* Format the flag */
4984                                         sprintf(t, "%s%s", flags[j], (j < fc - 1) ? " | " : "");
4985
4986                                         tlen = strlen(t);
4987
4988                                         /* Note the length */
4989                                         bc += tlen;
4990
4991                                         /* Advance */
4992                                         t += tlen;
4993                                 }
4994
4995                                 /* Done with this line; write it */
4996                                 fprintf(fff, "%s\n", buf);
4997                         }
4998                 }
4999
5000                 /* Acquire the description */
5001                 desc = r_text + r_ptr->text;
5002                 dlen = strlen(desc);
5003
5004                 /* Write Description */
5005                 for (j = 0; j < dlen;)
5006                 {
5007                         char buf[160], *t;
5008
5009                         /* Start the line */
5010                         sprintf(buf, "D:");
5011
5012                         for (bc = 0, t = buf + 2; ((bc < 60) || !iswspace(desc[j])) && (j < dlen); j++, bc++, t++)
5013                         {
5014                                 *t = desc[j];
5015                         }
5016
5017                         /* Terminate it */
5018                         *t = '\0';
5019
5020                         /* Done with this line; write it */
5021                         fprintf(fff, "%s\n", buf);
5022                 }
5023
5024                 /* Space between entries */
5025                 fprintf(fff, "\n");
5026         }
5027
5028         /* Done */
5029         fclose(fff);
5030 }
5031
5032 #endif