OSDN Git Service

[Refactor] #40413 Moved angband_str*() from util.c/h to string-processor.c/h
[hengband/hengband.git] / src / info-reader / race-reader.c
1 #include "info-reader/race-reader.h"
2 #include "info-reader/race-info-tokens-table.h"
3 #include "term/gameterm.h"
4 #include "util/string-processor.h"
5 #include "view/display-messages.h"
6
7 /*!
8  * @brief テキストトークンを走査してフラグを一つ得る(モンスター用1) /
9  * Grab one (basic) flag in a monster_race from a textual string
10  * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
11  * @param what 参照元の文字列ポインタ
12  * @return エラーコード
13  */
14 static errr grab_one_basic_flag(monster_race *r_ptr, concptr what)
15 {
16     if (grab_one_flag(&r_ptr->flags1, r_info_flags1, what) == 0)
17         return 0;
18
19     if (grab_one_flag(&r_ptr->flags2, r_info_flags2, what) == 0)
20         return 0;
21
22     if (grab_one_flag(&r_ptr->flags3, r_info_flags3, what) == 0)
23         return 0;
24
25     if (grab_one_flag(&r_ptr->flags7, r_info_flags7, what) == 0)
26         return 0;
27
28     if (grab_one_flag(&r_ptr->flags8, r_info_flags8, what) == 0)
29         return 0;
30
31     if (grab_one_flag(&r_ptr->flags9, r_info_flags9, what) == 0)
32         return 0;
33
34     if (grab_one_flag(&r_ptr->flagsr, r_info_flagsr, what) == 0)
35         return 0;
36
37     msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
38     return 1;
39 }
40
41 /*!
42  * @brief テキストトークンを走査してフラグを一つ得る(モンスター用2) /
43  * Grab one (spell) flag in a monster_race from a textual string
44  * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
45  * @param what 参照元の文字列ポインタ
46  * @return エラーコード
47  */
48 static errr grab_one_spell_flag(monster_race *r_ptr, concptr what)
49 {
50     if (grab_one_flag(&r_ptr->flags4, r_info_flags4, what) == 0)
51         return 0;
52
53     if (grab_one_flag(&r_ptr->a_ability_flags1, r_a_ability_flags1, what) == 0)
54         return 0;
55
56     if (grab_one_flag(&r_ptr->a_ability_flags2, r_a_ability_flags2, what) == 0)
57         return 0;
58
59     msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
60     return 1;
61 }
62
63 /*!
64  * @brief モンスター種族情報(r_info)のパース関数 /
65  * Initialize the "r_info" array, by parsing an ascii "template" file
66  * @param buf テキスト列
67  * @param head ヘッダ構造体
68  * @return エラーコード
69  */
70 errr parse_r_info(char *buf, angband_header *head)
71 {
72     static monster_race *r_ptr = NULL;
73     char *s, *t;
74     if (buf[0] == 'N') {
75         s = angband_strchr(buf + 2, ':');
76         if (!s)
77             return 1;
78
79         *s++ = '\0';
80 #ifdef JP
81         if (!*s)
82             return 1;
83 #endif
84
85         int i = atoi(buf + 2);
86         if (i < error_idx)
87             return 4;
88         if (i >= head->info_num)
89             return 2;
90
91         error_idx = i;
92         r_ptr = &r_info[i];
93 #ifdef JP
94         if (!add_name(&r_ptr->name, head, s))
95             return 7;
96 #endif
97     } else if (!r_ptr) {
98         return 3;
99     }
100 #ifdef JP
101     /* 英語名を読むルーチンを追加 */
102     /* 'E' から始まる行は英語名 */
103     else if (buf[0] == 'E') {
104         s = buf + 2;
105         if (!add_name(&r_ptr->E_name, head, s))
106             return 7;
107     }
108 #else
109     else if (buf[0] == 'E') {
110         s = buf + 2;
111         if (!add_name(&r_ptr->name, head, s))
112             return 7;
113     }
114 #endif
115     else if (buf[0] == 'D') {
116 #ifdef JP
117         if (buf[2] == '$')
118             return 0;
119         s = buf + 2;
120 #else
121         if (buf[2] != '$')
122             return 0;
123         s = buf + 3;
124 #endif
125         if (!add_text(&r_ptr->text, head, s, TRUE))
126             return 7;
127     } else if (buf[0] == 'G') {
128         if (buf[1] != ':')
129             return 1;
130         if (!buf[2])
131             return 1;
132         if (buf[3] != ':')
133             return 1;
134         if (!buf[4])
135             return 1;
136
137         char sym = buf[2];
138         byte tmp = color_char_to_attr(buf[4]);
139         if (tmp > 127)
140             return 1;
141
142         r_ptr->d_char = sym;
143         r_ptr->d_attr = tmp;
144     } else if (buf[0] == 'I') {
145         int spd, hp1, hp2, aaf, ac, slp;
146
147         if (6 != sscanf(buf + 2, "%d:%dd%d:%d:%d:%d", &spd, &hp1, &hp2, &aaf, &ac, &slp))
148             return 1;
149
150         r_ptr->speed = (SPEED)spd;
151         r_ptr->hdice = (DICE_NUMBER)MAX(hp1, 1);
152         r_ptr->hside = (DICE_SID)MAX(hp2, 1);
153         r_ptr->aaf = (POSITION)aaf;
154         r_ptr->ac = (ARMOUR_CLASS)ac;
155         r_ptr->sleep = (SLEEP_DEGREE)slp;
156     } else if (buf[0] == 'W') {
157         int lev, rar, pad;
158         long exp;
159         long nextexp;
160         int nextmon;
161         if (6 != sscanf(buf + 2, "%d:%d:%d:%ld:%ld:%d", &lev, &rar, &pad, &exp, &nextexp, &nextmon))
162             return 1;
163
164         r_ptr->level = (DEPTH)lev;
165         r_ptr->rarity = (RARITY)rar;
166         r_ptr->extra = (BIT_FLAGS16)pad;
167         r_ptr->mexp = (EXP)exp;
168         r_ptr->next_exp = (EXP)nextexp;
169         r_ptr->next_r_idx = (MONRACE_IDX)nextmon;
170     } else if (buf[0] == 'R') {
171         int id, ds, dd;
172         int i = 0;
173         for (; i < A_MAX; i++)
174             if (r_ptr->reinforce_id[i] == 0)
175                 break;
176
177         if (i == 6)
178             return 1;
179
180         if (3 != sscanf(buf + 2, "%d:%dd%d", &id, &dd, &ds))
181             return 1;
182         r_ptr->reinforce_id[i] = (MONRACE_IDX)id;
183         r_ptr->reinforce_dd[i] = (DICE_NUMBER)dd;
184         r_ptr->reinforce_ds[i] = (DICE_SID)ds;
185     } else if (buf[0] == 'B') {
186         int n1, n2;
187         int i = 0;
188         for (i = 0; i < 4; i++)
189             if (!r_ptr->blow[i].method)
190                 break;
191
192         if (i == 4)
193             return 1;
194
195         /* loop */
196         for (s = t = buf + 2; *t && (*t != ':'); t++)
197             ;
198
199         if (*t == ':')
200             *t++ = '\0';
201
202         for (n1 = 0; r_info_blow_method[n1]; n1++) {
203             if (streq(s, r_info_blow_method[n1]))
204                 break;
205         }
206
207         if (!r_info_blow_method[n1])
208             return 1;
209
210         /* loop */
211         for (s = t; *t && (*t != ':'); t++)
212             ;
213
214         if (*t == ':')
215             *t++ = '\0';
216
217         for (n2 = 0; r_info_blow_effect[n2]; n2++) {
218             if (streq(s, r_info_blow_effect[n2]))
219                 break;
220         }
221
222         if (!r_info_blow_effect[n2])
223             return 1;
224
225         /* loop */
226         for (s = t; *t && (*t != 'd'); t++)
227             ;
228
229         if (*t == 'd')
230             *t++ = '\0';
231
232         r_ptr->blow[i].method = (rbm_type)n1;
233         r_ptr->blow[i].effect = (rbe_type)n2;
234         r_ptr->blow[i].d_dice = atoi(s);
235         r_ptr->blow[i].d_side = atoi(t);
236     } else if (buf[0] == 'F') {
237         for (s = buf + 2; *s;) {
238             /* loop */
239             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
240                 ;
241
242             if (*t) {
243                 *t++ = '\0';
244                 while (*t == ' ' || *t == '|')
245                     t++;
246             }
247
248             if (0 != grab_one_basic_flag(r_ptr, s))
249                 return 5;
250
251             s = t;
252         }
253     } else if (buf[0] == 'S') {
254         for (s = buf + 2; *s;) {
255
256             /* loop */
257             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
258                 ;
259
260             if (*t) {
261                 *t++ = '\0';
262                 while ((*t == ' ') || (*t == '|'))
263                     t++;
264             }
265
266             int i;
267             if (1 == sscanf(s, "1_IN_%d", &i)) {
268                 r_ptr->freq_spell = 100 / i;
269                 s = t;
270                 continue;
271             }
272
273             if (0 != grab_one_spell_flag(r_ptr, s))
274                 return 5;
275
276             s = t;
277         }
278     } else if (buf[0] == 'A') {
279         int id, per, rarity;
280         int i = 0;
281         for (i = 0; i < 4; i++)
282             if (!r_ptr->artifact_id[i])
283                 break;
284
285         if (i == 4)
286             return 1;
287
288         if (3 != sscanf(buf + 2, "%d:%d:%d", &id, &rarity, &per))
289             return 1;
290         r_ptr->artifact_id[i] = (ARTIFACT_IDX)id;
291         r_ptr->artifact_rarity[i] = (RARITY)rarity;
292         r_ptr->artifact_percent[i] = (PERCENTAGE)per;
293     } else if (buf[0] == 'V') {
294         int val;
295         if (3 != sscanf(buf + 2, "%d", &val))
296             return 1;
297         r_ptr->arena_ratio = (PERCENTAGE)val;
298     } else {
299         return 6;
300     }
301
302     return 0;
303 }