OSDN Git Service

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