OSDN Git Service

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