1 #include "info-reader/ego-reader.h"
2 #include "info-reader/kind-info-tokens-table.h"
3 #include "main/angband-headers.h"
4 #include "object-enchant/object-ego.h"
5 #include "object-enchant/tr-types.h"
6 #include "parse-error-types.h"
7 #include "util/bit-flags-calculator.h"
8 #include "util/string-processor.h"
9 #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 参照元の文字列ポインタ
18 * @return エラーがあった場合1、エラーがない場合0を返す
20 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, std::string_view what)
22 if (k_info_flags.find(what) != k_info_flags.end()) {
23 add_flag(e_ptr->flags, k_info_flags[what]);
27 if (EnumClassFlagGroup<TRG>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
30 msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what);
34 static bool grab_ego_generate_flags(ego_generate_type &xtra, std::string_view what)
36 if (k_info_flags.find(what) != k_info_flags.end()) {
37 xtra.tr_flags.push_back(k_info_flags[what]);
41 auto it = k_info_gen_flags.find(what);
42 if (it != k_info_gen_flags.end()) {
43 xtra.trg_flags.push_back(it->second);
52 * @brief アイテムエゴ情報(e_info)のパース関数 /
53 * Initialize the "e_info" array, by parsing an ascii "template" file
58 errr parse_e_info(char *buf, angband_header *head)
60 static ego_item_type *e_ptr = NULL;
61 auto line = std::string(buf);
62 auto tok = str_split(line, ':', false);
68 if (tok[1].size() == 0)
69 return PARSE_ERROR_GENERIC;
71 auto i = std::stoi(tok[1]);
73 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
74 if (i >= head->info_num)
75 return PARSE_ERROR_OUT_OF_BOUNDS;
83 return PARSE_ERROR_MISSING_RECORD_HEADER;
84 else if (tok[0] == "E") {
87 if (tok[1].size() == 0)
92 else if (tok[0] == "X") {
95 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
96 e_ptr->slot = (INVENTORY_IDX)std::stoi(tok[1]);
97 e_ptr->rating = (PRICE)std::stoi(tok[2]);
98 } else if (tok[0] == "W") {
99 // W:level:ratiry:xtra:cost
102 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
103 e_ptr->level = (DEPTH)std::stoi(tok[1]);
104 e_ptr->rarity = (RARITY)std::stoi(tok[2]);
105 e_ptr->cost = (PRICE)std::stoi(tok[4]);
106 } else if (tok[0] == "C") {
107 // Creation bonuses (random plus)
108 // C:to_hit:to_dam:to_ac:pval
110 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
111 e_ptr->max_to_h = (HIT_PROB)std::stoi(tok[1]);
112 e_ptr->max_to_d = (HIT_POINT)std::stoi(tok[2]);
113 e_ptr->max_to_a = (ARMOUR_CLASS)std::stoi(tok[3]);
114 e_ptr->max_pval = (PARAMETER_VALUE)std::stoi(tok[4]);
115 } else if (tok[0] == "U") {
117 if (tok.size() < 2 || tok[1].size() == 0)
118 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
119 auto n = grab_one_activation_flag(tok[1].c_str());
121 return PARSE_ERROR_INVALID_FLAG;
122 e_ptr->act_idx = (IDX)n;
123 } else if (tok[0] == "F") {
125 if (tok.size() < 2 || tok[1].size() == 0)
126 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
128 const auto& flags = str_split(tok[1], '|', true);
129 for (const auto& f : flags) {
132 if (0 != grab_one_ego_item_flag(e_ptr, f))
133 return PARSE_ERROR_INVALID_FLAG;
135 } else if (tok[0] == "G") {
138 return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
140 auto prob = str_split(tok[1], '/');
141 if (prob.size() != 2 || tok[1].size() == 0 || tok[2].size() == 0)
142 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
144 ego_generate_type xtra;
145 xtra.mul = std::stoi(prob[0]);
146 xtra.dev = std::stoi(prob[1]);
148 const auto& flags = str_split(tok[2], '|', true);
149 for (const auto& f : flags) {
152 if (grab_ego_generate_flags(xtra, f))
153 return PARSE_ERROR_INVALID_FLAG;
156 e_ptr->xtra_flags.push_back(std::move(xtra));
158 return PARSE_ERROR_UNDEFINED_DIRECTIVE;
160 return PARSE_ERROR_NONE;