OSDN Git Service

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