OSDN Git Service

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