OSDN Git Service

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