OSDN Git Service

Reword English message for giant eagle teleport self effect: original had subject...
[hengband/hengband.git] / src / info-reader / dungeon-reader.c
1 #include "info-reader/dungeon-reader.h"
2 #include "dungeon/dungeon.h"
3 #include "info-reader/dungeon-info-tokens-table.h"
4 #include "info-reader/feature-reader.h"
5 #include "info-reader/parse-error-types.h"
6 #include "info-reader/race-info-tokens-table.h"
7 #include "io/tokenizer.h"
8 #include "main/angband-headers.h"
9 #include "util/string-processor.h"
10 #include "view/display-messages.h"
11
12 /*!
13  * @brief テキストトークンを走査してフラグを一つ得る(ダンジョン用) /
14  * Grab one flag for a dungeon type from a textual string
15  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
16  * @param what 参照元の文字列ポインタ
17  * @return エラーコード
18  */
19 static errr grab_one_dungeon_flag(dungeon_type *d_ptr, concptr what)
20 {
21     if (grab_one_flag(&d_ptr->flags1, d_info_flags1, what) == 0)
22         return 0;
23
24     msg_format(_("未知のダンジョン・フラグ '%s'。", "Unknown dungeon type flag '%s'."), what);
25     return 1;
26 }
27
28 /*!
29  * @brief テキストトークンを走査してフラグを一つ得る(モンスターのダンジョン出現条件用1) /
30  * Grab one (basic) flag in a monster_race from a textual string
31  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
32  * @param what 参照元の文字列ポインタ
33  * @return エラーコード
34  */
35 static errr grab_one_basic_monster_flag(dungeon_type *d_ptr, concptr what)
36 {
37     if (grab_one_flag(&d_ptr->mflags1, r_info_flags1, what) == 0)
38         return 0;
39
40     if (grab_one_flag(&d_ptr->mflags2, r_info_flags2, what) == 0)
41         return 0;
42
43     if (grab_one_flag(&d_ptr->mflags3, r_info_flags3, what) == 0)
44         return 0;
45
46     if (grab_one_flag(&d_ptr->mflags7, r_info_flags7, what) == 0)
47         return 0;
48
49     if (grab_one_flag(&d_ptr->mflags8, r_info_flags8, what) == 0)
50         return 0;
51
52     if (grab_one_flag(&d_ptr->mflags9, r_info_flags9, what) == 0)
53         return 0;
54
55     if (grab_one_flag(&d_ptr->mflagsr, r_info_flagsr, what) == 0)
56         return 0;
57
58     msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
59     return 1;
60 }
61
62 /*!
63  * @brief テキストトークンを走査してフラグを一つ得る(モンスターのダンジョン出現条件用2) /
64  * Grab one (spell) flag in a monster_race from a textual string
65  * @param d_ptr 保管先のダンジョン構造体参照ポインタ
66  * @param what 参照元の文字列ポインタ
67  * @return エラーコード
68  */
69 static errr grab_one_spell_monster_flag(dungeon_type *d_ptr, concptr what)
70 {
71     if (grab_one_flag(&d_ptr->mflags4, r_info_flags4, what) == 0)
72         return 0;
73
74     if (grab_one_flag(&d_ptr->m_a_ability_flags1, r_a_ability_flags1, what) == 0)
75         return 0;
76
77     if (grab_one_flag(&d_ptr->m_a_ability_flags2, r_a_ability_flags2, what) == 0)
78         return 0;
79
80     msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
81     return 1;
82 }
83
84 /*!
85  * @brief ダンジョン情報(d_info)のパース関数 /
86  * Initialize the "d_info" array, by parsing an ascii "template" file
87  * @param buf テキスト列
88  * @param head ヘッダ構造体
89  * @return エラーコード
90  */
91 errr parse_d_info(char *buf, angband_header *head)
92 {
93     static dungeon_type *d_ptr = NULL;
94     char *s, *t;
95     if (buf[0] == 'N') {
96         s = angband_strchr(buf + 2, ':');
97         if (!s)
98             return 1;
99
100         *s++ = '\0';
101 #ifdef JP
102         if (!*s)
103             return 1;
104 #endif
105
106         int i = atoi(buf + 2);
107         if (i < error_idx)
108             return 4;
109         if (i >= head->info_num)
110             return 2;
111
112         error_idx = i;
113         d_ptr = &d_info[i];
114 #ifdef JP
115         if (!add_name(&d_ptr->name, head, s))
116             return 7;
117 #endif
118     }
119 #ifdef JP
120     else if (buf[0] == 'E')
121         return 0;
122 #else
123     else if (buf[0] == 'E') {
124         /* Acquire the Text */
125         s = buf + 2;
126
127         /* Store the name */
128         if (!add_name(&d_ptr->name, head, s))
129             return 7;
130     }
131 #endif
132     else if (buf[0] == 'D') {
133 #ifdef JP
134         if (buf[2] == '$')
135             return 0;
136         s = buf + 2;
137 #else
138         if (buf[2] != '$')
139             return 0;
140         s = buf + 3;
141 #endif
142         if (!add_text(&d_ptr->text, head, s, TRUE))
143             return 7;
144     } else if (buf[0] == 'W') {
145         int min_lev, max_lev;
146         int min_plev, mode;
147         int min_alloc, max_chance;
148         int obj_good, obj_great;
149         int pit, nest;
150
151         if (10
152             != sscanf(buf + 2, "%d:%d:%d:%d:%d:%d:%d:%d:%x:%x", &min_lev, &max_lev, &min_plev, &mode, &min_alloc, &max_chance, &obj_good, &obj_great,
153                 (unsigned int *)&pit, (unsigned int *)&nest))
154             return 1;
155
156         d_ptr->mindepth = (DEPTH)min_lev;
157         d_ptr->maxdepth = (DEPTH)max_lev;
158         d_ptr->min_plev = (PLAYER_LEVEL)min_plev;
159         d_ptr->mode = (BIT_FLAGS8)mode;
160         d_ptr->min_m_alloc_level = min_alloc;
161         d_ptr->max_m_alloc_chance = max_chance;
162         d_ptr->obj_good = obj_good;
163         d_ptr->obj_great = obj_great;
164         d_ptr->pit = (BIT_FLAGS16)pit;
165         d_ptr->nest = (BIT_FLAGS16)nest;
166     } else if (buf[0] == 'P') {
167         int dy, dx;
168         if (2 != sscanf(buf + 2, "%d:%d", &dy, &dx))
169             return 1;
170
171         d_ptr->dy = dy;
172         d_ptr->dx = dx;
173     } else if (buf[0] == 'L') {
174         char *zz[16];
175         if (tokenize(buf + 2, DUNGEON_FEAT_PROB_NUM * 2 + 1, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 1))
176             return 1;
177
178         for (int i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) {
179             d_ptr->floor[i].feat = f_tag_to_index(zz[i * 2]);
180             if (d_ptr->floor[i].feat < 0)
181                 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
182
183             d_ptr->floor[i].percent = (PERCENTAGE)atoi(zz[i * 2 + 1]);
184         }
185
186         d_ptr->tunnel_percent = atoi(zz[DUNGEON_FEAT_PROB_NUM * 2]);
187     } else if (buf[0] == 'A') {
188         char *zz[16];
189         if (tokenize(buf + 2, DUNGEON_FEAT_PROB_NUM * 2 + 4, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 4))
190             return 1;
191
192         for (int i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) {
193             d_ptr->fill[i].feat = f_tag_to_index(zz[i * 2]);
194             if (d_ptr->fill[i].feat < 0)
195                 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
196
197             d_ptr->fill[i].percent = (PERCENTAGE)atoi(zz[i * 2 + 1]);
198         }
199
200         d_ptr->outer_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2]);
201         if (d_ptr->outer_wall < 0)
202             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
203
204         d_ptr->inner_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 1]);
205         if (d_ptr->inner_wall < 0)
206             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
207
208         d_ptr->stream1 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 2]);
209         if (d_ptr->stream1 < 0)
210             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
211
212         d_ptr->stream2 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 3]);
213         if (d_ptr->stream2 < 0)
214             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
215     } else if (buf[0] == 'F') {
216         int artif = 0, monst = 0;
217
218         for (s = buf + 2; *s;) {
219             /* loop */
220             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
221                 ;
222
223             if (*t) {
224                 *t++ = '\0';
225                 while (*t == ' ' || *t == '|')
226                     t++;
227             }
228
229             if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif)) {
230                 d_ptr->final_artifact = (ARTIFACT_IDX)artif;
231                 s = t;
232                 continue;
233             }
234
235             if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif)) {
236                 d_ptr->final_object = (KIND_OBJECT_IDX)artif;
237                 s = t;
238                 continue;
239             }
240
241             if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) {
242                 d_ptr->final_guardian = (MONRACE_IDX)monst;
243                 s = t;
244                 continue;
245             }
246
247             if (1 == sscanf(s, "MONSTER_DIV_%d", &monst)) {
248                 d_ptr->special_div = (PROB)monst;
249                 s = t;
250                 continue;
251             }
252
253             if (0 != grab_one_dungeon_flag(d_ptr, s))
254                 return 5;
255
256             s = t;
257         }
258     } else if (buf[0] == 'M') {
259         for (s = buf + 2; *s;) {
260             /* loop */
261             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
262                 ;
263
264             if (*t) {
265                 *t++ = '\0';
266                 while (*t == ' ' || *t == '|')
267                     t++;
268             }
269
270             if (!strncmp(s, "R_CHAR_", 7)) {
271                 s += 7;
272                 strncpy(d_ptr->r_char, s, sizeof(d_ptr->r_char));
273                 s = t;
274                 continue;
275             }
276
277             if (0 != grab_one_basic_monster_flag(d_ptr, s))
278                 return 5;
279
280             s = t;
281         }
282     } else if (buf[0] == 'S') {
283         for (s = buf + 2; *s;) {
284             /* loop */
285             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
286                 ;
287
288             if (*t) {
289                 *t++ = '\0';
290                 while ((*t == ' ') || (*t == '|'))
291                     t++;
292             }
293
294             int i;
295             if (1 == sscanf(s, "1_IN_%d", &i)) {
296                 s = t;
297                 continue;
298             }
299
300             if (0 != grab_one_spell_monster_flag(d_ptr, s))
301                 return 5;
302
303             s = t;
304         }
305     } else {
306         return 6;
307     }
308
309     return 0;
310 }