OSDN Git Service

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