1 #include "info-reader/race-reader.h"
2 #include "artifact/fixed-art-types.h"
3 #include "info-reader/info-reader-util.h"
4 #include "info-reader/parse-error-types.h"
5 #include "info-reader/race-info-tokens-table.h"
6 #include "locale/japanese.h"
7 #include "main/angband-headers.h"
8 #include "monster-race/monster-race.h"
9 #include "player-ability/player-ability-types.h"
10 #include "system/monster-race-info.h"
11 #include "term/gameterm.h"
12 #include "util/enum-converter.h"
13 #include "util/string-processor.h"
14 #include "view/display-messages.h"
18 * @brief テキストトークンを走査してフラグを一つ得る(モンスター用1) /
19 * Grab one (basic) flag in a MonsterRaceInfo from a textual string
20 * @param monrace 保管先のモンスター種族構造体
21 * @param what 参照元の文字列ポインタ
24 static bool grab_one_basic_flag(MonsterRaceInfo &monrace, std::string_view what)
26 if (EnumClassFlagGroup<MonsterResistanceType>::grab_one_flag(monrace.resistance_flags, r_info_flagsr, what)) {
30 if (EnumClassFlagGroup<MonsterAuraType>::grab_one_flag(monrace.aura_flags, r_info_aura_flags, what)) {
34 if (EnumClassFlagGroup<MonsterBehaviorType>::grab_one_flag(monrace.behavior_flags, r_info_behavior_flags, what)) {
38 if (EnumClassFlagGroup<MonsterVisualType>::grab_one_flag(monrace.visual_flags, r_info_visual_flags, what)) {
42 if (EnumClassFlagGroup<MonsterKindType>::grab_one_flag(monrace.kind_flags, r_info_kind_flags, what)) {
46 if (EnumClassFlagGroup<MonsterDropType>::grab_one_flag(monrace.drop_flags, r_info_drop_flags, what)) {
50 if (EnumClassFlagGroup<MonsterWildernessType>::grab_one_flag(monrace.wilderness_flags, r_info_wilderness_flags, what)) {
54 if (EnumClassFlagGroup<MonsterFeatureType>::grab_one_flag(monrace.feature_flags, r_info_feature_flags, what)) {
58 if (EnumClassFlagGroup<MonsterPopulationType>::grab_one_flag(monrace.population_flags, r_info_population_flags, what)) {
62 if (EnumClassFlagGroup<MonsterSpeakType>::grab_one_flag(monrace.speak_flags, r_info_speak_flags, what)) {
66 if (EnumClassFlagGroup<MonsterBrightnessType>::grab_one_flag(monrace.brightness_flags, r_info_brightness_flags, what)) {
70 if (EnumClassFlagGroup<MonsterSpecialType>::grab_one_flag(monrace.special_flags, r_info_special_flags, what)) {
73 if (EnumClassFlagGroup<MonsterMiscType>::grab_one_flag(monrace.misc_flags, r_info_misc_flags, what)) {
77 msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what.data());
82 * @brief テキストトークンを走査してフラグを一つ得る(モンスター用2) /
83 * Grab one (spell) flag in a MonsterRaceInfo from a textual string
84 * @param monrace 保管先のモンスター種族構造体
85 * @param what 参照元の文字列ポインタ
88 static bool grab_one_spell_flag(MonsterRaceInfo &monrace, std::string_view what)
90 if (EnumClassFlagGroup<MonsterAbilityType>::grab_one_flag(monrace.ability_flags, r_info_ability_flags, what)) {
94 msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what.data());
99 * @brief JSON Objectからモンスター名をセットする
100 * @param name_data 名前情報の格納されたJSON Object
101 * @param monrace 保管先のモンスター種族構造体
104 static errr set_mon_name(const nlohmann::json &name_data, MonsterRaceInfo &monrace)
106 if (name_data.is_null()) {
107 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
109 if (!name_data["ja"].is_string() || !name_data["en"].is_string()) {
110 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
113 const auto ja_name = name_data["ja"].get<std::string>();
114 const auto en_name = name_data["en"].get<std::string>();
117 auto ja_name_sys = utf8_to_sys(ja_name);
119 return PARSE_ERROR_INVALID_FLAG;
121 monrace.name = std::move(*ja_name_sys);
122 monrace.E_name = en_name;
124 monrace.name = en_name;
126 return PARSE_ERROR_NONE;
130 * @brief JSON Objectからモンスターシンボルをセットする
131 * @param symbol_data シンボル情報の格納されたJSON Object
132 * @param monrace 保管先のモンスター種族構造体
135 static errr set_mon_symbol(const nlohmann::json &symbol_data, MonsterRaceInfo &monrace)
137 if (symbol_data.is_null()) {
138 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
141 const auto &character_obj = symbol_data["character"];
142 if (!character_obj.is_string()) {
143 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
146 const auto &color_obj = symbol_data["color"];
147 if (!color_obj.is_string()) {
148 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
151 const auto color = color_list.find(color_obj.get<std::string>());
152 if (color == color_list.end()) {
153 return PARSE_ERROR_INVALID_FLAG;
155 if (color->second > 127) {
156 return PARSE_ERROR_GENERIC;
159 monrace.cc_def = { color->second, character_obj.get<std::string>().front() };
160 return PARSE_ERROR_NONE;
164 * @brief JSON Objectからモンスター速度をセットする
165 * @param speed_data 速度情報の格納されたJSON Object
166 * @param monrace 保管先のモンスター種族構造体
169 static errr set_mon_speed(const nlohmann::json &speed_data, MonsterRaceInfo &monrace)
171 if (!speed_data.is_number_integer()) {
172 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
175 const auto speed = speed_data.get<int8_t>();
176 if (speed < -50 || speed > 99) {
177 return PARSE_ERROR_INVALID_FLAG;
179 monrace.speed = speed + STANDARD_SPEED;
180 return PARSE_ERROR_NONE;
184 * @brief JSON Objectからモンスター体力をセットする
185 * @param hp_data 体力情報の格納されたJSON Object
186 * @param monrace 保管先のモンスター種族構造体
189 static errr set_mon_hp(const nlohmann::json &hp_data, MonsterRaceInfo &monrace)
191 if (!hp_data.is_string()) {
192 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
195 const auto hit_point = hp_data.get<std::string>();
196 const auto &dice = str_split(hit_point, 'd', false, 2);
197 if (dice.size() < 2) {
198 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
200 monrace.hdice = std::stoi(dice[0]);
201 monrace.hside = std::stoi(dice[1]);
202 return PARSE_ERROR_NONE;
206 * @brief JSON Objectからモンスターの感知範囲をセットする
207 * @param vision_data 感知範囲情報の格納されたJSON Object
208 * @param monrace 保管先のモンスター種族構造体
211 static errr set_mon_vision(const nlohmann::json &vision_data, MonsterRaceInfo &monrace)
213 if (!vision_data.is_number_integer()) {
214 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
217 const auto vision = vision_data.get<int>();
218 if (vision < 0 || vision > 999) {
219 return PARSE_ERROR_INVALID_FLAG;
221 monrace.aaf = vision;
222 return PARSE_ERROR_NONE;
226 * @brief JSON Objectからモンスターの物理防御力をセットする
227 * @param ac_data 物理防御力情報の格納されたJSON Object
228 * @param monrace 保管先のモンスター種族構造体
231 static errr set_mon_ac(const nlohmann::json &ac_data, MonsterRaceInfo &monrace)
233 if (!ac_data.is_number_integer()) {
234 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
237 const auto armour_class = ac_data.get<short>();
238 if (armour_class < 0 || armour_class > 10000) {
239 return PARSE_ERROR_INVALID_FLAG;
241 monrace.ac = armour_class;
242 return PARSE_ERROR_NONE;
246 * @brief JSON Objectからモンスターの警戒度をセットする
247 * @param alertness_data 物理防御力情報の格納されたJSON Object
248 * @param monrace 保管先のモンスター種族構造体
251 static errr set_mon_alertness(const nlohmann::json &alertness_data, MonsterRaceInfo &monrace)
253 if (!alertness_data.is_number_integer()) {
254 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
257 const auto alertness = alertness_data.get<short>();
258 if (alertness < 0 || alertness > 255) {
259 return PARSE_ERROR_INVALID_FLAG;
261 monrace.sleep = alertness;
262 return PARSE_ERROR_NONE;
266 * @brief JSON Objectからモンスターの出現階層をセットする
267 * @param level_data 出現階層情報の格納されたJSON Object
268 * @param monrace 保管先のモンスター種族構造体
271 static errr set_mon_level(const nlohmann::json &level_data, MonsterRaceInfo &monrace)
273 if (!level_data.is_number_integer()) {
274 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
277 const auto level = level_data.get<int>();
278 if (level < 0 || level > 255) {
279 return PARSE_ERROR_INVALID_FLAG;
281 monrace.level = level;
282 return PARSE_ERROR_NONE;
286 * @brief JSON Objectからモンスターの出現階層をセットする
287 * @param rarity_data 出現階層情報の格納されたJSON Object
288 * @param monrace 保管先のモンスター種族構造体
291 static errr set_mon_rarity(const nlohmann::json &rarity_data, MonsterRaceInfo &monrace)
293 if (!rarity_data.is_number_integer()) {
294 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
297 const auto rarity = rarity_data.get<int>();
298 if (rarity < 0 || rarity > 255) {
299 return PARSE_ERROR_INVALID_FLAG;
301 monrace.rarity = (RARITY)rarity;
302 return PARSE_ERROR_NONE;
306 * @brief JSON Objectからモンスターの経験値をセットする
307 * @param exp_data 経験値情報の格納されたJSON Object
308 * @param monrace 保管先のモンスター種族構造体
311 static errr set_mon_exp(const nlohmann::json &exp_data, MonsterRaceInfo &monrace)
313 if (!exp_data.is_number_integer()) {
314 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
317 const auto exp = exp_data.get<int>();
318 if (exp < 0 || exp > 9999999) {
319 return PARSE_ERROR_INVALID_FLAG;
322 return PARSE_ERROR_NONE;
326 * @brief JSON Objectからモンスターの進化をセットする
327 * @param evolve_data 進化情報の格納されたJSON Object
328 * @param monrace 保管先のモンスター種族構造体
331 static errr set_mon_evolve(const nlohmann::json &evolve_data, MonsterRaceInfo &monrace)
333 if (evolve_data.is_null()) {
334 return PARSE_ERROR_NONE;
337 const auto &need_exp_obj = evolve_data["need_exp"];
338 const auto &evlove_to_obj = evolve_data["to"];
339 if (!need_exp_obj.is_number_integer()) {
340 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
342 if (!evlove_to_obj.is_number_integer()) {
343 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
345 const auto need_exp = need_exp_obj.get<int>();
346 const auto evlove_to = evlove_to_obj.get<int>();
347 if (need_exp <= 0 || need_exp > 9999999) {
348 return PARSE_ERROR_INVALID_FLAG;
350 if (evlove_to <= 0 || evlove_to > 9999) {
351 return PARSE_ERROR_INVALID_FLAG;
353 monrace.next_exp = need_exp;
354 monrace.next_r_idx = static_cast<MonsterRaceId>(evlove_to);
355 return PARSE_ERROR_NONE;
359 * @brief JSON Objectからモンスターの性別をセットする
360 * @param sex_data 性別情報の格納されたJSON Object
361 * @param monrace 保管先のモンスター種族構造体
364 static errr set_mon_sex(const nlohmann::json &sex_data, MonsterRaceInfo &monrace)
366 if (sex_data.is_null()) {
367 return PARSE_ERROR_NONE;
369 if (!sex_data.is_string()) {
370 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
374 if (!info_grab_one_const(sex, r_info_sex, sex_data.get<std::string>())) {
375 return PARSE_ERROR_INVALID_FLAG;
377 monrace.sex = static_cast<MonsterSex>(sex);
378 return PARSE_ERROR_NONE;
382 * @brief JSON Objectからモンスターの闘技場オッズをセットする
383 * @param odds_data オッズ情報の格納されたJSON Object
384 * @param monrace 保管先のモンスター種族構造体
387 static errr set_mon_odds_rate(const nlohmann::json &odds_data, MonsterRaceInfo &monrace)
389 if (odds_data.is_null()) {
390 return PARSE_ERROR_NONE;
392 if (!odds_data.is_number_integer()) {
393 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
396 const auto odds = odds_data.get<int>();
397 if (odds <= 0 || odds > 9999) {
398 return PARSE_ERROR_INVALID_FLAG;
400 monrace.arena_ratio = odds;
401 return PARSE_ERROR_NONE;
405 * @brief JSON Objectからモンスターの初期体力をセットする
406 * @param start_hp_data 初期体力情報の格納されたJSON Object
407 * @param monrace 保管先のモンスター種族構造体
410 static errr set_mon_start_hp_percentage(const nlohmann::json &start_hp_data, MonsterRaceInfo &monrace)
412 if (start_hp_data.is_null()) {
413 return PARSE_ERROR_NONE;
415 if (!start_hp_data.is_number_integer()) {
416 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
419 const auto start_hp = start_hp_data.get<int>();
420 if (start_hp < 0 || start_hp > 99) {
421 return PARSE_ERROR_INVALID_FLAG;
423 monrace.cur_hp_per = start_hp;
424 return PARSE_ERROR_NONE;
428 * @brief JSON Objectからモンスターの固定アーティファクトドロップ情報をセットする
429 * @param artifact_data 固定アーティファクトドロップ情報の格納されたJSON Object
430 * @param monrace 保管先のモンスター種族構造体
433 static errr set_mon_artifacts(const nlohmann::json &artifact_data, MonsterRaceInfo &monrace)
435 if (artifact_data.is_null()) {
436 return PARSE_ERROR_NONE;
438 if (!artifact_data.is_array()) {
439 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
442 for (auto &artifact : artifact_data.items()) {
443 const auto &artifact_id_obj = artifact.value()["drop_artifact_id"];
444 const auto &artifact_chance_obj = artifact.value()["drop_probability"];
446 if (!artifact_id_obj.is_number_integer()) {
447 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
449 if (!artifact_chance_obj.is_number_integer()) {
450 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
452 const auto artifact_id = artifact_id_obj.get<int>();
453 if (artifact_id < 0 || artifact_id > 1024) {
454 return PARSE_ERROR_INVALID_FLAG;
456 const auto a_idx = static_cast<FixedArtifactId>(artifact_id);
457 const auto artifact_chance = artifact_chance_obj.get<int>();
458 if (artifact_chance <= 0 || artifact_chance > 100) {
459 return PARSE_ERROR_INVALID_FLAG;
461 monrace.drop_artifacts.emplace_back(a_idx, artifact_chance);
463 return PARSE_ERROR_NONE;
467 * @brief JSON Objectからモンスターの護衛情報をセットする
468 * @param escort_data 護衛情報の格納されたJSON Object
469 * @param monrace 保管先のモンスター種族構造体
472 static errr set_mon_escorts(const nlohmann::json &escort_data, MonsterRaceInfo &monrace)
474 if (escort_data.is_null()) {
475 return PARSE_ERROR_NONE;
477 if (!escort_data.is_array()) {
478 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
481 for (auto &escort : escort_data.items()) {
482 const auto &escorts_id_obj = escort.value()["escorts_id"];
483 const auto &escort_num_obj = escort.value()["escort_num"];
484 if (!escorts_id_obj.is_number_integer()) {
485 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
487 if (!escort_num_obj.is_string()) {
488 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
491 const auto escorts_id = escorts_id_obj.get<int>();
492 if (escorts_id < 0 || escorts_id > 8192) {
493 return PARSE_ERROR_INVALID_FLAG;
496 const auto monrace_id = static_cast<MonsterRaceId>(escorts_id);
497 const auto escort_num = escort_num_obj.get<std::string>();
498 const auto &dice = str_split(escort_num, 'd', false, 2);
501 info_set_value(dd, dice[0]);
502 info_set_value(ds, dice[1]);
503 monrace.reinforces.emplace_back(monrace_id, dd, ds);
505 return PARSE_ERROR_NONE;
509 * @brief JSON Objectからモンスターの打撃攻撃をセットする
510 * @param blow_data 打撃攻撃情報の格納されたJSON Object
511 * @param monrace 保管先のモンスター種族構造体
514 static errr set_mon_blows(const nlohmann::json &blow_data, MonsterRaceInfo &monrace)
516 if (blow_data.is_null()) {
517 return PARSE_ERROR_NONE;
519 if (!blow_data.is_array()) {
520 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
524 for (auto &blow : blow_data.items()) {
526 return PARSE_ERROR_GENERIC;
529 const auto &blow_method = blow.value()["method"];
530 const auto &blow_effect = blow.value()["effect"];
531 if (blow_method.is_null() || blow_effect.is_null()) {
532 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
535 const auto rbm = r_info_blow_method.find(blow_method.get<std::string>());
536 if (rbm == r_info_blow_method.end()) {
537 return PARSE_ERROR_INVALID_FLAG;
540 const auto rbe = r_info_blow_effect.find(blow_effect.get<std::string>());
541 if (rbe == r_info_blow_effect.end()) {
542 return PARSE_ERROR_INVALID_FLAG;
544 monrace.blows[blow_num].method = rbm->second;
545 monrace.blows[blow_num].effect = rbe->second;
547 const auto &blow_dice = blow.value().find("damage_dice");
548 if (blow_dice != blow.value().end()) {
549 const auto &dice = str_split(blow_dice->get<std::string>(), 'd', false, 2);
550 info_set_value(monrace.blows[blow_num].d_dice, dice[0]);
551 info_set_value(monrace.blows[blow_num].d_side, dice[1]);
556 return PARSE_ERROR_NONE;
560 * @brief JSON Objectからモンスターフラグをセットする
561 * @param flag_data モンスターフラグ情報の格納されたJSON Object
562 * @param monrace 保管先のモンスター種族構造体
565 static errr set_mon_flags(const nlohmann::json &flag_data, MonsterRaceInfo &monrace)
567 if (flag_data.is_null()) {
568 return PARSE_ERROR_NONE;
570 if (!flag_data.is_array()) {
571 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
574 for (auto &flag : flag_data.items()) {
575 if (!grab_one_basic_flag(monrace, flag.value().get<std::string>())) {
576 return PARSE_ERROR_INVALID_FLAG;
579 return PARSE_ERROR_NONE;
583 * @brief JSON Objectからモンスターの発動能力をセットする
584 * @param skill_data 発動能力情報の格納されたJSON Object
585 * @param monrace 保管先のモンスター種族構造体
588 static errr set_mon_skills(const nlohmann::json &skill_data, MonsterRaceInfo &monrace)
590 if (skill_data.is_null()) {
591 return PARSE_ERROR_NONE;
593 if (!skill_data.is_object()) {
594 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
597 const auto &prob = skill_data["probability"];
598 if (!prob.is_string()) {
599 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
602 const auto &prob_token = str_split(prob.get<std::string>(), '_', false, 2);
603 if (prob_token.size() == 3 && prob_token[1] == "IN") {
604 if (prob_token[0] != "1") {
605 return PARSE_ERROR_GENERIC;
608 info_set_value(denominator, prob_token[2]);
609 monrace.freq_spell = 100 / denominator;
612 const auto &shoot_dice = skill_data.find("shoot");
613 const auto shoot = (shoot_dice != skill_data.end());
615 const auto &dice = str_split(shoot_dice->get<std::string>(), 'd', false, 2);
616 info_set_value(monrace.shoot_dam_dice, dice[0]);
617 info_set_value(monrace.shoot_dam_side, dice[1]);
618 monrace.ability_flags.set(MonsterAbilityType::SHOOT);
621 const auto &skill_list = skill_data.find("list");
622 if (skill_list == skill_data.end()) {
624 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
626 return PARSE_ERROR_NONE;
629 for (auto &skill : skill_list->items()) {
630 if (!grab_one_spell_flag(monrace, skill.value().get<std::string>())) {
631 return PARSE_ERROR_INVALID_FLAG;
634 return PARSE_ERROR_NONE;
638 * @brief JSON Objectからモンスターの説明文をセットする
639 * @param flag_data 説明文の情報の格納されたJSON Object
640 * @param monrace 保管先のモンスター種族構造体
643 static errr set_mon_flavor(const nlohmann::json &flavor_data, MonsterRaceInfo &monrace)
645 if (flavor_data.is_null()) {
646 return PARSE_ERROR_NONE;
648 if (!flavor_data.is_object()) {
649 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
653 const auto &flavor_ja = flavor_data.find("ja");
654 if (flavor_ja == flavor_data.end()) {
655 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
657 auto flavor_ja_sys = utf8_to_sys(flavor_ja->get<std::string>());
658 if (!flavor_ja_sys) {
659 return PARSE_ERROR_INVALID_FLAG;
661 monrace.text = std::move(*flavor_ja_sys);
663 const auto &flavor_en = flavor_data.find("en");
664 if (flavor_en == flavor_data.end()) {
665 return PARSE_ERROR_NONE;
667 monrace.text = flavor_en->get<std::string>();
669 return PARSE_ERROR_NONE;
673 * @brief モンスター種族情報(JSON Object)のパース関数
674 * @param mon_data モンスターデータの格納されたJSON Object
678 errr parse_monraces_info(nlohmann::json &mon_data, angband_header *)
680 if (!mon_data["id"].is_number_integer()) {
681 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
684 const auto monster_idx = mon_data["id"].get<int>();
685 if (monster_idx < error_idx) {
686 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
688 error_idx = monster_idx;
689 auto &monrace = monraces_info.emplace_hint(monraces_info.end(), i2enum<MonsterRaceId>(monster_idx), MonsterRaceInfo{})->second;
690 monrace.idx = i2enum<MonsterRaceId>(monster_idx);
693 err = set_mon_name(mon_data["name"], monrace);
695 msg_format(_("モンスター名読込失敗。ID: '%d'。", "Failed to load monster name. ID: '%d'."), error_idx);
698 err = set_mon_symbol(mon_data["symbol"], monrace);
700 msg_format(_("モンスターシンボル読込失敗。ID: '%d'。", "Failed to load monster symbol. ID: '%d'."), error_idx);
703 err = set_mon_speed(mon_data["speed"], monrace);
705 msg_format(_("モンスター速度読込失敗。ID: '%d'。", "Failed to load monster speed. ID: '%d'."), error_idx);
708 err = set_mon_hp(mon_data["hit_point"], monrace);
710 msg_format(_("モンスターHP読込失敗。ID: '%d'。", "Failed to load monster HP. ID: '%d'."), error_idx);
713 err = set_mon_vision(mon_data["vision"], monrace);
715 msg_format(_("モンスター感知範囲読込失敗。ID: '%d'。", "Failed to load monster vision. ID: '%d'."), error_idx);
718 err = set_mon_ac(mon_data["armor_class"], monrace);
720 msg_format(_("モンスターAC読込失敗。ID: '%d'。", "Failed to load monster AC. ID: '%d'."), error_idx);
723 err = set_mon_alertness(mon_data["alertness"], monrace);
725 msg_format(_("モンスター警戒度読込失敗。ID: '%d'。", "Failed to load monster alertness. ID: '%d'."), error_idx);
728 err = set_mon_level(mon_data["level"], monrace);
730 msg_format(_("モンスターレベル読込失敗。ID: '%d'。", "Failed to load monster level. ID: '%d'."), error_idx);
733 err = set_mon_rarity(mon_data["rarity"], monrace);
735 msg_format(_("モンスター希少度読込失敗。ID: '%d'。", "Failed to load monster rarity. ID: '%d'."), error_idx);
738 err = set_mon_exp(mon_data["exp"], monrace);
740 msg_format(_("モンスター経験値読込失敗。ID: '%d'。", "Failed to load monster exp. ID: '%d'."), error_idx);
743 err = set_mon_evolve(mon_data["evolve"], monrace);
745 msg_format(_("モンスター進化情報読込失敗。ID: '%d'。", "Failed to load monster evolve data. ID: '%d'."), error_idx);
748 err = set_mon_sex(mon_data["sex"], monrace);
750 msg_format(_("モンスター性別読込失敗。ID: '%d'。", "Failed to load monster sex. ID: '%d'."), error_idx);
753 err = set_mon_odds_rate(mon_data["odds_correction_ratio"], monrace);
755 msg_format(_("モンスター賭け倍率読込失敗。ID: '%d'。", "Failed to load monster odds for arena. ID: '%d'."), error_idx);
758 err = set_mon_start_hp_percentage(mon_data["start_hp_percentage"], monrace);
760 msg_format(_("モンスター初期体力読込失敗。ID: '%d'。", "Failed to load monster starting HP. ID: '%d'."), error_idx);
763 err = set_mon_artifacts(mon_data["artifacts"], monrace);
765 msg_format(_("モンスター固定アーティファクトドロップ情報読込失敗。ID: '%d'。", "Failed to load monster artifact drop data. ID: '%d'."), error_idx);
768 err = set_mon_escorts(mon_data["escorts"], monrace);
770 msg_format(_("モンスター護衛情報読込失敗。ID: '%d'。", "Failed to load monster escorts. ID: '%d'."), error_idx);
773 err = set_mon_blows(mon_data["blows"], monrace);
775 msg_format(_("モンスター打撃情報読込失敗。ID: '%d'。", "Failed to load monster blow data. ID: '%d'."), error_idx);
778 err = set_mon_flags(mon_data["flags"], monrace);
780 msg_format(_("モンスターフラグ読込失敗。ID: '%d'。", "Failed to load monster flag data. ID: '%d'."), error_idx);
783 err = set_mon_skills(mon_data["skill"], monrace);
785 msg_format(_("モンスター発動能力情報読込失敗。ID: '%d'。", "Failed to load monster skill data. ID: '%d'."), error_idx);
788 err = set_mon_flavor(mon_data["flavor"], monrace);
790 msg_format(_("モンスター説明文読込失敗。ID: '%d'。", "Failed to load monster flavor text. ID: '%d'."), error_idx);
794 return PARSE_ERROR_NONE;