1 #include "info-reader/artifact-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/tr-types.h"
8 #include "system/artifact-type-definition.h"
9 #include "util/bit-flags-calculator.h"
10 #include "util/enum-converter.h"
11 #include "util/string-processor.h"
12 #include "view/display-messages.h"
15 * @brief テキストトークンを走査してフラグを一つ得る(アーティファクト用) /
16 * Grab one activation index flag
17 * @param a_ptr 保管先のアーティファクト構造体参照ポインタ
18 * @param what 参照元の文字列ポインタ
21 static bool grab_one_artifact_flag(artifact_type *a_ptr, std::string_view what)
23 if (TrFlags::grab_one_flag(a_ptr->flags, k_info_flags, what)) {
27 if (EnumClassFlagGroup<ItemGenerationTraitType>::grab_one_flag(a_ptr->gen_flags, k_info_gen_flags, what)) {
31 msg_format(_("未知の伝説のアイテム・フラグ '%s'。", "Unknown artifact flag '%s'."), what.data());
36 * @brief 固定アーティファクト情報(a_info)のパース関数 /
37 * Initialize the "a_info" array, by parsing an ascii "template" file
42 errr parse_a_info(std::string_view buf, angband_header *)
44 static artifact_type *a_ptr = nullptr;
45 const auto &tokens = str_split(buf, ':', false, 10);
47 if (tokens[0] == "N") {
49 if (tokens.size() < 3 || tokens[1].size() == 0) {
50 return PARSE_ERROR_GENERIC;
53 auto i = std::stoi(tokens[1]);
55 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
57 if (i >= static_cast<int>(a_info.size())) {
63 a_ptr->idx = static_cast<ARTIFACT_IDX>(i);
64 a_ptr->flags.set(TR_IGNORE_ACID);
65 a_ptr->flags.set(TR_IGNORE_ELEC);
66 a_ptr->flags.set(TR_IGNORE_FIRE);
67 a_ptr->flags.set(TR_IGNORE_COLD);
70 a_ptr->name = tokens[2];
73 return PARSE_ERROR_MISSING_RECORD_HEADER;
74 } else if (tokens[0] == "E") {
77 if (tokens[1].size() == 0) {
78 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
80 a_ptr->name = tokens[1];
82 } else if (tokens[0] == "D") {
85 if (tokens.size() < 2 || tokens[1].size() == 0) {
86 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
89 if (tokens[1][0] == '$') {
90 return PARSE_ERROR_NONE;
92 a_ptr->text.append(buf.substr(2));
94 if (tokens[1][0] != '$') {
95 return PARSE_ERROR_NONE;
97 append_english_text(a_ptr->text, buf.substr(3));
99 } else if (tokens[0] == "I") {
101 if (tokens.size() < 4) {
102 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
105 info_set_value(a_ptr->tval, tokens[1]);
106 info_set_value(a_ptr->sval, tokens[2]);
107 info_set_value(a_ptr->pval, tokens[3]);
108 } else if (tokens[0] == "W") {
109 // W:level:ratiry:weight:cost
110 if (tokens.size() < 5) {
111 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
114 info_set_value(a_ptr->level, tokens[1]);
115 info_set_value(a_ptr->rarity, tokens[2]);
116 info_set_value(a_ptr->weight, tokens[3]);
117 info_set_value(a_ptr->cost, tokens[4]);
118 } else if (tokens[0] == "P") {
119 // P:ac:dd:ds:to_h:to_d:to_a
120 if (tokens.size() < 6) {
121 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
124 const auto &dice = str_split(tokens[2], 'd', false, 2);
125 if (dice.size() != 2) {
126 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
129 info_set_value(a_ptr->ac, tokens[1]);
130 info_set_value(a_ptr->dd, dice[0]);
131 info_set_value(a_ptr->ds, dice[1]);
132 info_set_value(a_ptr->to_h, tokens[3]);
133 info_set_value(a_ptr->to_d, tokens[4]);
134 info_set_value(a_ptr->to_a, tokens[5]);
135 } else if (tokens[0] == "U") {
137 if (tokens.size() < 2 || tokens[1].size() == 0) {
138 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
140 auto n = grab_one_activation_flag(tokens[1].c_str());
141 if (n <= RandomArtActType::NONE) {
142 return PARSE_ERROR_INVALID_FLAG;
146 } else if (tokens[0] == "F") {
148 if (tokens.size() < 2 || tokens[1].size() == 0) {
149 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
152 const auto &flags = str_split(tokens[1], '|', true, 10);
153 for (const auto &f : flags) {
157 if (!grab_one_artifact_flag(a_ptr, f)) {
158 return PARSE_ERROR_INVALID_FLAG;
162 return PARSE_ERROR_UNDEFINED_DIRECTIVE;
165 return PARSE_ERROR_NONE;