OSDN Git Service

[Refactor] #40460 Separated parse_qtw_D() from generate_fixed_map_floor()
[hengband/hengband.git] / src / info-reader / fixed-map-parser.c
1 /*!
2  * @brief ゲームデータ初期化1 / Initialization (part 1) -BEN-
3  * @date 2014/01/28
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  * 2014 Deskull rearranged comment for Doxygen
7  */
8
9 #include "info-reader/fixed-map-parser.h"
10 #include "dungeon/quest.h"
11 #include "floor/floor.h"
12 #include "floor/fixed-map-generator.h"
13 #include "io/files-util.h"
14 #include "system/system-variables.h"
15 #include "world/world.h"
16
17 static char tmp[8];
18 static concptr variant = "ZANGBAND";
19
20 /*!
21  * @brief 固定マップ (クエスト&街&広域マップ)生成時の分岐処理
22  * Helper function for "parse_fixed_map()"
23  * @param player_ptr プレーヤーへの参照ポインタ
24  * @param sp
25  * @param fp
26  * @return エラーコード
27  */
28 static concptr parse_fixed_map_expression(player_type *player_ptr, char **sp, char *fp)
29 {
30     char b1 = '[';
31     char b2 = ']';
32
33     char f = ' ';
34
35     char *s;
36     s = (*sp);
37
38     while (iswspace(*s))
39         s++;
40
41     char *b;
42     b = s;
43     concptr v = "?o?o?";
44     if (*s == b1) {
45         concptr p;
46         concptr t;
47         s++;
48         t = parse_fixed_map_expression(player_ptr, &s, &f);
49         if (!*t) {
50             /* Nothing */
51         } else if (streq(t, "IOR")) {
52             v = "0";
53             while (*s && (f != b2)) {
54                 t = parse_fixed_map_expression(player_ptr, &s, &f);
55                 if (*t && !streq(t, "0"))
56                     v = "1";
57             }
58         } else if (streq(t, "AND")) {
59             v = "1";
60             while (*s && (f != b2)) {
61                 t = parse_fixed_map_expression(player_ptr, &s, &f);
62                 if (*t && streq(t, "0"))
63                     v = "0";
64             }
65         } else if (streq(t, "NOT")) {
66             v = "1";
67             while (*s && (f != b2)) {
68                 t = parse_fixed_map_expression(player_ptr, &s, &f);
69                 if (*t && streq(t, "1"))
70                     v = "0";
71             }
72         } else if (streq(t, "EQU")) {
73             v = "0";
74             if (*s && (f != b2)) {
75                 t = parse_fixed_map_expression(player_ptr, &s, &f);
76             }
77
78             while (*s && (f != b2)) {
79                 p = parse_fixed_map_expression(player_ptr, &s, &f);
80                 if (streq(t, p))
81                     v = "1";
82             }
83         } else if (streq(t, "LEQ")) {
84             v = "1";
85             if (*s && (f != b2)) {
86                 t = parse_fixed_map_expression(player_ptr, &s, &f);
87             }
88
89             while (*s && (f != b2)) {
90                 p = t;
91                 t = parse_fixed_map_expression(player_ptr, &s, &f);
92                 if (*t && atoi(p) > atoi(t))
93                     v = "0";
94             }
95         } else if (streq(t, "GEQ")) {
96             v = "1";
97             if (*s && (f != b2)) {
98                 t = parse_fixed_map_expression(player_ptr, &s, &f);
99             }
100
101             while (*s && (f != b2)) {
102                 p = t;
103                 t = parse_fixed_map_expression(player_ptr, &s, &f);
104                 if (*t && atoi(p) < atoi(t))
105                     v = "0";
106             }
107         } else {
108             while (*s && (f != b2)) {
109                 t = parse_fixed_map_expression(player_ptr, &s, &f);
110             }
111         }
112
113         if (f != b2)
114             v = "?x?x?";
115         if ((f = *s) != '\0')
116             *s++ = '\0';
117
118         (*fp) = f;
119         (*sp) = s;
120         return v;
121     }
122
123 #ifdef JP
124     while (iskanji(*s) || (isprint(*s) && !my_strchr(" []", *s))) {
125         if (iskanji(*s))
126             s++;
127         s++;
128     }
129 #else
130     while (isprint(*s) && !my_strchr(" []", *s))
131         ++s;
132 #endif
133     if ((f = *s) != '\0')
134         *s++ = '\0';
135
136     if (*b != '$') {
137         v = b;
138         (*fp) = f;
139         (*sp) = s;
140         return v;
141     }
142
143     if (streq(b + 1, "SYS")) {
144         v = ANGBAND_SYS;
145     } else if (streq(b + 1, "GRAF")) {
146         v = ANGBAND_GRAF;
147     } else if (streq(b + 1, "MONOCHROME")) {
148         if (arg_monochrome)
149             v = "ON";
150         else
151             v = "OFF";
152     } else if (streq(b + 1, "RACE")) {
153         v = _(rp_ptr->E_title, rp_ptr->title);
154     } else if (streq(b + 1, "CLASS")) {
155         v = _(cp_ptr->E_title, cp_ptr->title);
156     } else if (streq(b + 1, "REALM1")) {
157         v = _(E_realm_names[player_ptr->realm1], realm_names[player_ptr->realm1]);
158     } else if (streq(b + 1, "REALM2")) {
159         v = _(E_realm_names[player_ptr->realm2], realm_names[player_ptr->realm2]);
160     } else if (streq(b + 1, "PLAYER")) {
161         static char tmp_player_name[32];
162         char *pn, *tpn;
163         for (pn = player_ptr->name, tpn = tmp_player_name; *pn; pn++, tpn++) {
164 #ifdef JP
165             if (iskanji(*pn)) {
166                 *(tpn++) = *(pn++);
167                 *tpn = *pn;
168                 continue;
169             }
170 #endif
171             *tpn = my_strchr(" []", *pn) ? '_' : *pn;
172         }
173
174         *tpn = '\0';
175         v = tmp_player_name;
176     } else if (streq(b + 1, "TOWN")) {
177         sprintf(tmp, "%d", player_ptr->town_num);
178         v = tmp;
179     } else if (streq(b + 1, "LEVEL")) {
180         sprintf(tmp, "%d", player_ptr->lev);
181         v = tmp;
182     } else if (streq(b + 1, "QUEST_NUMBER")) {
183         sprintf(tmp, "%d", player_ptr->current_floor_ptr->inside_quest);
184         v = tmp;
185     } else if (streq(b + 1, "LEAVING_QUEST")) {
186         sprintf(tmp, "%d", leaving_quest);
187         v = tmp;
188     } else if (prefix(b + 1, "QUEST_TYPE")) {
189         sprintf(tmp, "%d", quest[atoi(b + 11)].type);
190         v = tmp;
191     } else if (prefix(b + 1, "QUEST")) {
192         sprintf(tmp, "%d", quest[atoi(b + 6)].status);
193         v = tmp;
194     } else if (prefix(b + 1, "RANDOM")) {
195         sprintf(tmp, "%d", (int)(current_world_ptr->seed_town % atoi(b + 7)));
196         v = tmp;
197     } else if (streq(b + 1, "VARIANT")) {
198         v = variant;
199     } else if (streq(b + 1, "WILDERNESS")) {
200         if (vanilla_town)
201             sprintf(tmp, "NONE");
202         else if (lite_town)
203             sprintf(tmp, "LITE");
204         else
205             sprintf(tmp, "NORMAL");
206         v = tmp;
207     }
208
209     (*fp) = f;
210     (*sp) = s;
211     return v;
212 }
213
214 /*!
215  * @brief 固定マップ (クエスト&街&広域マップ)をq_info、t_info、w_infoから読み込んでパースする
216  * @param player_ptr プレーヤーへの参照ポインタ
217  * @param name ファイル名
218  * @param ymin 詳細不明
219  * @param xmin 詳細不明
220  * @param ymax 詳細不明
221  * @param xmax 詳細不明
222  * @return エラーコード
223  */
224 errr parse_fixed_map(player_type *player_ptr, concptr name, int ymin, int xmin, int ymax, int xmax)
225 {
226     char buf[1024];
227     path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, name);
228     FILE *fp;
229     fp = my_fopen(buf, "r");
230     if (fp == NULL)
231         return -1;
232
233     int num = -1;
234     errr err = 0;
235     bool bypass = FALSE;
236     int x = xmin, y = ymin;
237     qtwg_type tmp_qg;
238     qtwg_type *qg_ptr = initialize_quest_generator_type(&tmp_qg, buf, ymin, xmin, ymax, xmax, &y, &x);
239     while (my_fgets(fp, buf, sizeof(buf)) == 0) {
240         num++;
241         if (!buf[0])
242             continue;
243         if (iswspace(buf[0]))
244             continue;
245         if (buf[0] == '#')
246             continue;
247         if ((buf[0] == '?') && (buf[1] == ':')) {
248             char f;
249             char *s;
250             s = buf + 2;
251             concptr v = parse_fixed_map_expression(player_ptr, &s, &f);
252             bypass = (streq(v, "0") ? TRUE : FALSE);
253             continue;
254         }
255
256         if (bypass)
257             continue;
258
259         err = generate_fixed_map_floor(player_ptr, qg_ptr, parse_fixed_map);
260         if (err)
261             break;
262     }
263
264     if (err != 0) {
265         concptr oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : "unknown");
266         msg_format("Error %d (%s) at line %d of '%s'.", err, oops, num, name);
267         msg_format(_("'%s'を解析中。", "Parsing '%s'."), buf);
268         msg_print(NULL);
269     }
270
271     my_fclose(fp);
272     return err;
273 }