OSDN Git Service

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