OSDN Git Service

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