OSDN Git Service

Merge pull request #765 from sikabane-works/release/3.0.0Alpha17
[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 (FlagGroup<RF_ABILITY>::grab_one_flag(d_ptr->m_ability_flags, r_info_ability_flags, what))
73         return 0;
74
75     msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
76     return 1;
77 }
78
79 /*!
80  * @brief ダンジョン情報(d_info)のパース関数 /
81  * Initialize the "d_info" array, by parsing an ascii "template" file
82  * @param buf テキスト列
83  * @param head ヘッダ構造体
84  * @return エラーコード
85  */
86 errr parse_d_info(char *buf, angband_header *head)
87 {
88     static dungeon_type *d_ptr = NULL;
89     char *s, *t;
90     if (buf[0] == 'N') {
91         s = angband_strchr(buf + 2, ':');
92         if (!s)
93             return 1;
94
95         *s++ = '\0';
96 #ifdef JP
97         if (!*s)
98             return 1;
99 #endif
100
101         int i = atoi(buf + 2);
102         if (i < error_idx)
103             return 4;
104         if (i >= head->info_num)
105             return 2;
106
107         error_idx = i;
108         d_ptr = &d_info[i];
109 #ifdef JP
110         d_ptr->name = std::string(s);
111 #endif
112     }
113 #ifdef JP
114     else if (buf[0] == 'E')
115         return 0;
116 #else
117     else if (buf[0] == 'E') {
118         /* Acquire the Text */
119         s = buf + 2;
120
121         /* Store the name */
122         d_ptr->name = std::string(s);
123     }
124 #endif
125     else if (buf[0] == 'D') {
126 #ifdef JP
127         if (buf[2] == '$')
128             return 0;
129         s = buf + 2;
130 #else
131         if (buf[2] != '$')
132             return 0;
133         s = buf + 3;
134 #endif
135         d_ptr->text.append(s);
136     } else if (buf[0] == 'W') {
137         int min_lev, max_lev;
138         int min_plev, mode;
139         int min_alloc, max_chance;
140         int obj_good, obj_great;
141         int pit, nest;
142
143         if (10
144             != 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,
145                 (unsigned int *)&pit, (unsigned int *)&nest))
146             return 1;
147
148         d_ptr->mindepth = (DEPTH)min_lev;
149         d_ptr->maxdepth = (DEPTH)max_lev;
150         d_ptr->min_plev = (PLAYER_LEVEL)min_plev;
151         d_ptr->mode = (BIT_FLAGS8)mode;
152         d_ptr->min_m_alloc_level = min_alloc;
153         d_ptr->max_m_alloc_chance = max_chance;
154         d_ptr->obj_good = obj_good;
155         d_ptr->obj_great = obj_great;
156         d_ptr->pit = (BIT_FLAGS16)pit;
157         d_ptr->nest = (BIT_FLAGS16)nest;
158     } else if (buf[0] == 'P') {
159         int dy, dx;
160         if (2 != sscanf(buf + 2, "%d:%d", &dy, &dx))
161             return 1;
162
163         d_ptr->dy = dy;
164         d_ptr->dx = dx;
165     } else if (buf[0] == 'L') {
166         char *zz[16];
167         if (tokenize(buf + 2, DUNGEON_FEAT_PROB_NUM * 2 + 1, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 1))
168             return 1;
169
170         for (int i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) {
171             d_ptr->floor[i].feat = f_tag_to_index(zz[i * 2]);
172             if (d_ptr->floor[i].feat < 0)
173                 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
174
175             d_ptr->floor[i].percent = (PERCENTAGE)atoi(zz[i * 2 + 1]);
176         }
177
178         d_ptr->tunnel_percent = atoi(zz[DUNGEON_FEAT_PROB_NUM * 2]);
179     } else if (buf[0] == 'A') {
180         char *zz[16];
181         if (tokenize(buf + 2, DUNGEON_FEAT_PROB_NUM * 2 + 4, zz, 0) != (DUNGEON_FEAT_PROB_NUM * 2 + 4))
182             return 1;
183
184         for (int i = 0; i < DUNGEON_FEAT_PROB_NUM; i++) {
185             d_ptr->fill[i].feat = f_tag_to_index(zz[i * 2]);
186             if (d_ptr->fill[i].feat < 0)
187                 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
188
189             d_ptr->fill[i].percent = (PERCENTAGE)atoi(zz[i * 2 + 1]);
190         }
191
192         d_ptr->outer_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2]);
193         if (d_ptr->outer_wall < 0)
194             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
195
196         d_ptr->inner_wall = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 1]);
197         if (d_ptr->inner_wall < 0)
198             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
199
200         d_ptr->stream1 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 2]);
201         if (d_ptr->stream1 < 0)
202             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
203
204         d_ptr->stream2 = f_tag_to_index(zz[DUNGEON_FEAT_PROB_NUM * 2 + 3]);
205         if (d_ptr->stream2 < 0)
206             return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
207     } else if (buf[0] == 'F') {
208         int artif = 0, monst = 0;
209
210         for (s = buf + 2; *s;) {
211             /* loop */
212             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
213                 ;
214
215             if (*t) {
216                 *t++ = '\0';
217                 while (*t == ' ' || *t == '|')
218                     t++;
219             }
220
221             if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif)) {
222                 d_ptr->final_artifact = (ARTIFACT_IDX)artif;
223                 s = t;
224                 continue;
225             }
226
227             if (1 == sscanf(s, "FINAL_OBJECT_%d", &artif)) {
228                 d_ptr->final_object = (KIND_OBJECT_IDX)artif;
229                 s = t;
230                 continue;
231             }
232
233             if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) {
234                 d_ptr->final_guardian = (MONRACE_IDX)monst;
235                 s = t;
236                 continue;
237             }
238
239             if (1 == sscanf(s, "MONSTER_DIV_%d", &monst)) {
240                 d_ptr->special_div = (PROB)monst;
241                 s = t;
242                 continue;
243             }
244
245             if (0 != grab_one_dungeon_flag(d_ptr, s))
246                 return 5;
247
248             s = t;
249         }
250     } else if (buf[0] == 'M') {
251         for (s = buf + 2; *s;) {
252             /* loop */
253             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
254                 ;
255
256             if (*t) {
257                 *t++ = '\0';
258                 while (*t == ' ' || *t == '|')
259                     t++;
260             }
261
262             if (!strncmp(s, "R_CHAR_", 7)) {
263                 s += 7;
264                 angband_strcpy(d_ptr->r_char, s, sizeof(d_ptr->r_char));
265                 s = t;
266                 continue;
267             }
268
269             if (0 != grab_one_basic_monster_flag(d_ptr, s))
270                 return 5;
271
272             s = t;
273         }
274     } else if (buf[0] == 'S') {
275         for (s = buf + 2; *s;) {
276             /* loop */
277             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
278                 ;
279
280             if (*t) {
281                 *t++ = '\0';
282                 while ((*t == ' ') || (*t == '|'))
283                     t++;
284             }
285
286             int i;
287             if (1 == sscanf(s, "1_IN_%d", &i)) {
288                 s = t;
289                 continue;
290             }
291
292             if (0 != grab_one_spell_monster_flag(d_ptr, s))
293                 return 5;
294
295             s = t;
296         }
297     } else {
298         return 6;
299     }
300
301     return 0;
302 }