1 #include "info-reader/artifact-reader.h"
2 #include "artifact/fixed-art-types.h"
3 #include "artifact/random-art-effects.h"
4 #include "info-reader/baseitem-tokens-table.h"
5 #include "info-reader/info-reader-util.h"
6 #include "info-reader/parse-error-types.h"
7 #include "main/angband-headers.h"
8 #include "object-enchant/tr-types.h"
9 #include "system/artifact-type-definition.h"
10 #include "util/bit-flags-calculator.h"
11 #include "util/enum-converter.h"
12 #include "util/string-processor.h"
13 #include "view/display-messages.h"
16 * @brief テキストトークンを走査してフラグを一つ得る(アーティファクト用) /
17 * Grab one activation index flag
18 * @param a_ptr 保管先のアーティファクト構造体参照ポインタ
19 * @param what 参照元の文字列ポインタ
22 static bool grab_one_artifact_flag(ArtifactType *a_ptr, std::string_view what)
24 if (TrFlags::grab_one_flag(a_ptr->flags, baseitem_flags, what)) {
28 if (EnumClassFlagGroup<ItemGenerationTraitType>::grab_one_flag(a_ptr->gen_flags, baseitem_geneneration_flags, what)) {
32 msg_format(_("未知の伝説のアイテム・フラグ '%s'。", "Unknown artifact flag '%s'."), what.data());
37 * @brief 固定アーティファクト定義(ArtifactDefinitions)のパース関数
42 errr parse_artifacts_info(std::string_view buf, angband_header *)
44 const auto &tokens = str_split(buf, ':', false, 10);
45 if (tokens[0] == "N") {
47 if (tokens.size() < 3 || tokens[1].size() == 0) {
48 return PARSE_ERROR_GENERIC;
51 const auto int_idx = std::stoi(tokens[1]);
52 const auto a_idx = i2enum<FixedArtifactId>(int_idx);
53 if (int_idx < error_idx) {
54 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
58 ArtifactType artifact;
59 artifact.flags.set(TR_IGNORE_ACID);
60 artifact.flags.set(TR_IGNORE_ELEC);
61 artifact.flags.set(TR_IGNORE_FIRE);
62 artifact.flags.set(TR_IGNORE_COLD);
64 artifact.name = tokens[2];
66 artifacts_info.emplace(a_idx, artifact);
67 return PARSE_ERROR_NONE;
70 if (tokens[0] == "E") {
73 return PARSE_ERROR_NONE;
75 if (tokens[1].size() == 0) {
76 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
79 const auto it = artifacts_info.rbegin();
80 auto &artifact = it->second;
81 artifact.name = tokens[1];
82 return PARSE_ERROR_NONE;
86 if (tokens[0] == "D") {
89 if (tokens.size() < 2 || tokens[1].size() == 0) {
90 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
93 if (tokens[1][0] == '$') {
94 return PARSE_ERROR_NONE;
97 const auto it = artifacts_info.rbegin();
98 auto &artifact = it->second;
99 artifact.text.append(tokens[1]);
101 if (tokens[1][0] != '$') {
102 return PARSE_ERROR_NONE;
105 const auto it = artifacts_info.rbegin();
106 auto &artifact = it->second;
107 append_english_text(artifact.text, tokens[1].substr(1));
109 return PARSE_ERROR_NONE;
112 if (tokens[0] == "I") {
114 if (tokens.size() < 4) {
115 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
118 const auto it = artifacts_info.rbegin();
119 auto &artifact = it->second;
120 constexpr auto base = 10;
121 const auto tval = i2enum<ItemKindType>(std::stoi(tokens[1], nullptr, base));
122 const auto sval = std::stoi(tokens[2], nullptr, base);
123 artifact.bi_key = { tval, sval };
124 info_set_value(artifact.pval, tokens[3]);
125 return PARSE_ERROR_NONE;
128 if (tokens[0] == "W") {
129 // W:level:ratiry:weight:cost
130 if (tokens.size() < 5) {
131 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
134 const auto it = artifacts_info.rbegin();
135 auto &artifact = it->second;
136 info_set_value(artifact.level, tokens[1]);
137 info_set_value(artifact.rarity, tokens[2]);
138 info_set_value(artifact.weight, tokens[3]);
139 info_set_value(artifact.cost, tokens[4]);
140 return PARSE_ERROR_NONE;
143 if (tokens[0] == "P") {
144 // P:ac:dd:ds:to_h:to_d:to_a
145 if (tokens.size() < 6) {
146 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
149 const auto &dice = str_split(tokens[2], 'd', false, 2);
150 if (dice.size() != 2) {
151 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
154 const auto it = artifacts_info.rbegin();
155 auto &artifact = it->second;
156 info_set_value(artifact.ac, tokens[1]);
157 info_set_value(artifact.dd, dice[0]);
158 info_set_value(artifact.ds, dice[1]);
159 info_set_value(artifact.to_h, tokens[3]);
160 info_set_value(artifact.to_d, tokens[4]);
161 info_set_value(artifact.to_a, tokens[5]);
162 return PARSE_ERROR_NONE;
165 if (tokens[0] == "U") {
167 if (tokens.size() < 2 || tokens[1].size() == 0) {
168 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
171 auto n = grab_one_activation_flag(tokens[1].data());
172 if (n <= RandomArtActType::NONE) {
173 return PARSE_ERROR_INVALID_FLAG;
176 const auto it = artifacts_info.rbegin();
177 auto &artifact = it->second;
178 artifact.act_idx = n;
179 return PARSE_ERROR_NONE;
182 if (tokens[0] == "F") {
184 if (tokens.size() < 2 || tokens[1].size() == 0) {
185 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
188 const auto &flags = str_split(tokens[1], '|', true, 10);
189 for (const auto &f : flags) {
194 const auto it = artifacts_info.rbegin();
195 auto *a_ptr = &it->second;
196 if (!grab_one_artifact_flag(a_ptr, f)) {
197 return PARSE_ERROR_INVALID_FLAG;
201 return PARSE_ERROR_NONE;
204 return PARSE_ERROR_UNDEFINED_DIRECTIVE;