1 #include "info-reader/race-reader.h"
2 #include "info-reader/parse-error-types.h"
3 #include "info-reader/race-info-tokens-table.h"
4 #include "main/angband-headers.h"
5 #include "monster-race/monster-race.h"
6 #include "term/gameterm.h"
7 #include "util/string-processor.h"
8 #include "view/display-messages.h"
11 * @brief テキストトークンを走査してフラグを一つ得る(モンスター用1) /
12 * Grab one (basic) flag in a monster_race from a textual string
13 * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
14 * @param what 参照元の文字列ポインタ
17 static errr grab_one_basic_flag(monster_race *r_ptr, concptr what)
19 if (grab_one_flag(&r_ptr->flags1, r_info_flags1, what) == 0)
20 return PARSE_ERROR_NONE;
22 if (grab_one_flag(&r_ptr->flags2, r_info_flags2, what) == 0)
23 return PARSE_ERROR_NONE;
25 if (grab_one_flag(&r_ptr->flags3, r_info_flags3, what) == 0)
26 return PARSE_ERROR_NONE;
28 if (grab_one_flag(&r_ptr->flags7, r_info_flags7, what) == 0)
29 return PARSE_ERROR_NONE;
31 if (grab_one_flag(&r_ptr->flags8, r_info_flags8, what) == 0)
32 return PARSE_ERROR_NONE;
34 if (grab_one_flag(&r_ptr->flags9, r_info_flags9, what) == 0)
35 return PARSE_ERROR_NONE;
37 if (grab_one_flag(&r_ptr->flagsr, r_info_flagsr, what) == 0)
38 return PARSE_ERROR_NONE;
40 msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
41 return PARSE_ERROR_GENERIC;
45 * @brief テキストトークンを走査してフラグを一つ得る(モンスター用2) /
46 * Grab one (spell) flag in a monster_race from a textual string
47 * @param r_ptr 保管先のモンスター種族構造体参照ポインタ
48 * @param what 参照元の文字列ポインタ
51 static errr grab_one_spell_flag(monster_race *r_ptr, concptr what)
53 if (FlagGroup<RF_ABILITY>::grab_one_flag(r_ptr->ability_flags, r_info_ability_flags, what))
54 return PARSE_ERROR_NONE;
56 msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what);
57 return PARSE_ERROR_GENERIC;
61 * @brief モンスター種族情報(r_info)のパース関数 /
62 * Initialize the "r_info" array, by parsing an ascii "template" file
67 errr parse_r_info(char *buf, angband_header *head)
69 static monster_race *r_ptr = NULL;
72 s = angband_strchr(buf + 2, ':');
74 return PARSE_ERROR_GENERIC;
79 return PARSE_ERROR_GENERIC;
82 int i = atoi(buf + 2);
84 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
86 if (i >= head->info_num)
87 return PARSE_ERROR_OBSOLETE_FILE;
92 r_ptr->name = std::string(s);
95 return PARSE_ERROR_MISSING_RECORD_HEADER;
100 else if (buf[0] == 'E') {
101 r_ptr->E_name = std::string(buf + 2);
104 else if (buf[0] == 'E') {
105 r_ptr->name = std::string(buf + 2);
108 else if (buf[0] == 'D') {
111 return PARSE_ERROR_NONE;
116 return PARSE_ERROR_NONE;
119 r_ptr->text.append(s);
120 } else if (buf[0] == 'G') {
121 if ((buf[1] != ':') || !buf[2] || (buf[3] != ':') || !buf[4])
122 return PARSE_ERROR_GENERIC;
125 byte tmp = color_char_to_attr(buf[4]);
127 return PARSE_ERROR_GENERIC;
131 } else if (buf[0] == 'I') {
132 int spd, hp1, hp2, aaf, ac, slp;
133 if (sscanf(buf + 2, "%d:%dd%d:%d:%d:%d", &spd, &hp1, &hp2, &aaf, &ac, &slp) != 6)
134 return PARSE_ERROR_GENERIC;
136 r_ptr->speed = (SPEED)spd;
137 r_ptr->hdice = (DICE_NUMBER)MAX(hp1, 1);
138 r_ptr->hside = (DICE_SID)MAX(hp2, 1);
139 r_ptr->aaf = (POSITION)aaf;
140 r_ptr->ac = (ARMOUR_CLASS)ac;
141 r_ptr->sleep = (SLEEP_DEGREE)slp;
142 } else if (buf[0] == 'W') {
147 if (sscanf(buf + 2, "%d:%d:%d:%ld:%ld:%d", &lev, &rar, &pad, &exp, &nextexp, &nextmon) != 6)
148 return PARSE_ERROR_GENERIC;
150 r_ptr->level = (DEPTH)lev;
151 r_ptr->rarity = (RARITY)rar;
152 r_ptr->extra = (BIT_FLAGS16)pad;
153 r_ptr->mexp = (EXP)exp;
154 r_ptr->next_exp = (EXP)nextexp;
155 r_ptr->next_r_idx = (MONRACE_IDX)nextmon;
156 } else if (buf[0] == 'R') {
159 for (; i < A_MAX; i++)
160 if (r_ptr->reinforce_id[i] == 0)
163 if ((i == 6) || (sscanf(buf + 2, "%d:%dd%d", &id, &dd, &ds) != 3))
164 return PARSE_ERROR_GENERIC;
166 r_ptr->reinforce_id[i] = (MONRACE_IDX)id;
167 r_ptr->reinforce_dd[i] = (DICE_NUMBER)dd;
168 r_ptr->reinforce_ds[i] = (DICE_SID)ds;
169 } else if (buf[0] == 'B') {
172 for (i = 0; i < 4; i++)
173 if (!r_ptr->blow[i].method)
177 return PARSE_ERROR_GENERIC;
180 for (s = t = buf + 2; *t && (*t != ':'); t++)
186 for (n1 = 0; r_info_blow_method[n1]; n1++) {
187 if (streq(s, r_info_blow_method[n1]))
191 if (!r_info_blow_method[n1])
192 return PARSE_ERROR_GENERIC;
195 for (s = t; *t && (*t != ':'); t++)
201 for (n2 = 0; r_info_blow_effect[n2]; n2++) {
202 if (streq(s, r_info_blow_effect[n2]))
206 if (!r_info_blow_effect[n2])
207 return PARSE_ERROR_GENERIC;
210 for (s = t; *t && (*t != 'd'); t++)
216 r_ptr->blow[i].method = (rbm_type)n1;
217 r_ptr->blow[i].effect = (rbe_type)n2;
218 r_ptr->blow[i].d_dice = atoi(s);
219 r_ptr->blow[i].d_side = atoi(t);
220 } else if (buf[0] == 'F') {
221 for (s = buf + 2; *s;) {
223 for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
228 while (*t == ' ' || *t == '|')
232 if (0 != grab_one_basic_flag(r_ptr, s))
233 return PARSE_ERROR_INVALID_FLAG;
237 } else if (buf[0] == 'S') {
238 for (s = buf + 2; *s;) {
241 for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
246 while ((*t == ' ') || (*t == '|'))
251 if (1 == sscanf(s, "1_IN_%d", &i)) {
252 r_ptr->freq_spell = 100 / i;
257 if (grab_one_spell_flag(r_ptr, s) != PARSE_ERROR_NONE)
258 return PARSE_ERROR_INVALID_FLAG;
262 } else if (buf[0] == 'A') {
265 for (i = 0; i < 4; i++)
266 if (!r_ptr->artifact_id[i])
269 if ((i == 4) || (sscanf(buf + 2, "%d:%d:%d", &id, &rarity, &per) != 3))
270 return PARSE_ERROR_GENERIC;
272 r_ptr->artifact_id[i] = (ARTIFACT_IDX)id;
273 r_ptr->artifact_rarity[i] = (RARITY)rarity;
274 r_ptr->artifact_percent[i] = (PERCENTAGE)per;
275 } else if (buf[0] == 'V') {
277 if (sscanf(buf + 2, "%d", &val) != 3)
280 r_ptr->arena_ratio = (PERCENTAGE)val;
282 return PARSE_ERROR_UNDEFINED_DIRECTIVE;
285 return PARSE_ERROR_NONE;