1 #include "info-reader/ego-reader.h"
2 #include "artifact/random-art-effects.h"
3 #include "info-reader/info-reader-util.h"
4 #include "info-reader/kind-info-tokens-table.h"
5 #include "info-reader/parse-error-types.h"
6 #include "main/angband-headers.h"
7 #include "object-enchant/object-ego.h"
8 #include "object-enchant/tr-types.h"
9 #include "util/bit-flags-calculator.h"
10 #include "util/string-processor.h"
11 #include "view/display-messages.h"
14 * @brief テキストトークンを走査してフラグを一つ得る(エゴ用) /
15 * Grab one flag in a ego-item_type from a textual string
16 * @param e_ptr 保管先のエゴ構造体参照ポインタ
17 * @param what 参照元の文字列ポインタ
20 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, std::string_view what)
22 if (TrFlags::grab_one_flag(e_ptr->flags, k_info_flags, what))
25 if (EnumClassFlagGroup<TRG>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
28 msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what.data());
33 * @brief テキストトークンを走査して生成フラグを一つ得る(エゴ用) /
34 * Grab one genetation flag in a ego-item_type from a textual string
35 * @param e_ptr 保管先のエゴ構造体参照ポインタ
36 * @param what 参照元の文字列ポインタ
39 static bool grab_ego_generate_flags(ego_generate_type &xtra, std::string_view what)
41 if (auto it = k_info_flags.find(what); it != k_info_flags.end()) {
42 xtra.tr_flags.push_back(it->second);
46 if (auto it = k_info_gen_flags.find(what); it != k_info_gen_flags.end()) {
47 xtra.trg_flags.push_back(it->second);
55 * @brief アイテムエゴ情報(e_info)のパース関数 /
56 * Initialize the "e_info" array, by parsing an ascii "template" file
61 errr parse_e_info(std::string_view buf, angband_header *)
63 static ego_item_type *e_ptr = nullptr;
64 const auto &tokens = str_split(buf, ':', false, 10);
66 error_idx = 0; //!< @note 順不同で登録しているため
68 if (tokens[0] == "N") {
70 if (tokens.size() < 3 || tokens[1].size() == 0)
71 return PARSE_ERROR_GENERIC;
73 auto i = std::stoi(tokens[1]);
75 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
76 if (i >= static_cast<int>(e_info.size())) {
82 e_ptr->idx = static_cast<EGO_IDX>(i);
84 e_ptr->name = tokens[2];
87 return PARSE_ERROR_MISSING_RECORD_HEADER;
88 else if (tokens[0] == "E") {
91 if (tokens[1].size() == 0)
92 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
93 e_ptr->name = tokens[1];
95 } else if (tokens[0] == "X") {
97 if (tokens.size() < 3)
98 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
100 info_set_value(e_ptr->slot, tokens[1]);
101 info_set_value(e_ptr->rating, tokens[2]);
102 } else if (tokens[0] == "W") {
103 // W:level:ratiry:xtra:cost
105 if (tokens.size() < 5)
106 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
108 info_set_value(e_ptr->level, tokens[1]);
109 info_set_value(e_ptr->rarity, tokens[2]);
110 info_set_value(e_ptr->cost, tokens[4]);
111 } else if (tokens[0] == "B") {
113 // B:to_hit:to_dam:to_ac
114 if (tokens.size() < 4)
115 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
117 info_set_value(e_ptr->base_to_h, tokens[1]);
118 info_set_value(e_ptr->base_to_d, tokens[2]);
119 info_set_value(e_ptr->base_to_a, tokens[3]);
120 } else if (tokens[0] == "C") {
121 // Creation bonuses (random plus)
122 // C:to_hit:to_dam:to_ac:pval
123 if (tokens.size() < 5)
124 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
126 info_set_value(e_ptr->max_to_h, tokens[1]);
127 info_set_value(e_ptr->max_to_d, tokens[2]);
128 info_set_value(e_ptr->max_to_a, tokens[3]);
129 info_set_value(e_ptr->max_pval, tokens[4]);
130 } else if (tokens[0] == "U") {
132 if (tokens.size() < 2 || tokens[1].size() == 0)
133 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
135 auto n = grab_one_activation_flag(tokens[1].c_str());
136 if (n <=RandomArtActType::NONE)
137 return PARSE_ERROR_INVALID_FLAG;
140 } else if (tokens[0] == "F") {
142 if (tokens.size() < 2 || tokens[1].size() == 0)
143 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
145 const auto& flags = str_split(tokens[1], '|', true, 10);
146 for (const auto& f : flags) {
149 if (!grab_one_ego_item_flag(e_ptr, f))
150 return PARSE_ERROR_INVALID_FLAG;
152 } else if (tokens[0] == "G") {
154 if (tokens.size() < 3)
155 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
157 const auto &prob = str_split(tokens[1], '/', false, 2);
158 if (prob.size() != 2 || tokens[1].size() == 0 || tokens[2].size() == 0)
159 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
161 ego_generate_type xtra;
162 xtra.mul = std::stoi(prob[0]);
163 xtra.dev = std::stoi(prob[1]);
165 const auto& flags = str_split(tokens[2], '|', true, 10);
166 for (const auto& f : flags) {
169 if (!grab_ego_generate_flags(xtra, f))
170 return PARSE_ERROR_INVALID_FLAG;
173 e_ptr->xtra_flags.push_back(std::move(xtra));
175 return PARSE_ERROR_UNDEFINED_DIRECTIVE;
177 return PARSE_ERROR_NONE;