OSDN Git Service

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