OSDN Git Service

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