OSDN Git Service

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