OSDN Git Service

[Refactor] enum classの型名変更 TRG -> ItemGenerationTraitType
[hengbandforosx/hengbandosx.git] / src / info-reader / ego-reader.cpp
index 95a6559..5a34eb0 100644 (file)
@@ -1,53 +1,56 @@
 #include "info-reader/ego-reader.h"
+#include "artifact/random-art-effects.h"
+#include "info-reader/info-reader-util.h"
 #include "info-reader/kind-info-tokens-table.h"
+#include "info-reader/parse-error-types.h"
 #include "main/angband-headers.h"
 #include "object-enchant/object-ego.h"
 #include "object-enchant/tr-types.h"
-#include "parse-error-types.h"
 #include "util/bit-flags-calculator.h"
 #include "util/string-processor.h"
 #include "view/display-messages.h"
-#include <string>
-#include <utility>
 
 /*!
  * @brief テキストトークンを走査してフラグを一つ得る(エゴ用) /
  * Grab one flag in a ego-item_type from a textual string
  * @param e_ptr 保管先のエゴ構造体参照ポインタ
  * @param what 参照元の文字列ポインタ
- * @return エラーがあった場合1、エラーがない場合0を返す
+ * @return 見つけたらtrue
  */
 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, std::string_view what)
 {
-    if (k_info_flags.find(what) != k_info_flags.end()) {
-        add_flag(e_ptr->flags, k_info_flags[what]);
-        return 0;
-    }
+    if (TrFlags::grab_one_flag(e_ptr->flags, k_info_flags, what))
+        return true;
 
-    if (EnumClassFlagGroup<TRG>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
-        return 0;
+    if (EnumClassFlagGroup<ItemGenerationTraitType>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
+        return true;
 
-    msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what);
-    return 1;
+    msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what.data());
+    return false;
 }
 
+/*!
+ * @brief テキストトークンを走査して生成フラグを一つ得る(エゴ用) /
+ * Grab one genetation flag in a ego-item_type from a textual string
+ * @param e_ptr 保管先のエゴ構造体参照ポインタ
+ * @param what 参照元の文字列ポインタ
+ * @return 見つけたらtrue
+ */
 static bool grab_ego_generate_flags(ego_generate_type &xtra, std::string_view what)
 {
-    if (k_info_flags.find(what) != k_info_flags.end()) {
-        xtra.tr_flags.push_back(k_info_flags[what]);
-        return 0;
+    if (auto it = k_info_flags.find(what); it != k_info_flags.end()) {
+        xtra.tr_flags.push_back(it->second);
+        return true;
     }
 
-    auto it = k_info_gen_flags.find(what);
-    if (it != k_info_gen_flags.end()) {
+    if (auto it = k_info_gen_flags.find(what); it != k_info_gen_flags.end()) {
         xtra.trg_flags.push_back(it->second);
-        return false;
+        return true;
     }
 
-    return true;
+    return false;
 }
 
-
 /*!
  * @brief アイテムエゴ情報(e_info)のパース関数 /
  * Initialize the "e_info" array, by parsing an ascii "template" file
@@ -55,109 +58,115 @@ static bool grab_ego_generate_flags(ego_generate_type &xtra, std::string_view wh
  * @param head ヘッダ構造体
  * @return エラーコード
  */
-errr parse_e_info(char *buf, angband_header *head)
+errr parse_e_info(std::string_view buf, angband_header *)
 {
-    static ego_item_type *e_ptr = NULL;
-    auto line = std::string(buf);
-    auto tok = str_split(line, ':', false);
+    static ego_item_type *e_ptr = nullptr;
+    const auto &tokens = str_split(buf, ':', false, 10);
 
-    error_idx = 0;
+    error_idx = 0; //!< @note 順不同で登録しているため
 
-    if (tok[0] == "N") {
+    if (tokens[0] == "N") {
         // N:index:name_ja
-        if (tok[1].size() == 0)
+        if (tokens.size() < 3 || tokens[1].size() == 0)
             return PARSE_ERROR_GENERIC;
 
-        auto i = std::stoi(tok[1]);
+        auto i = std::stoi(tokens[1]);
         if (i < error_idx)
             return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
-        if (i >= head->info_num)
-            return PARSE_ERROR_OUT_OF_BOUNDS;
+        if (i >= static_cast<int>(e_info.size())) {
+            e_info.resize(i + 1);
+        }
 
         error_idx = i;
         e_ptr = &e_info[i];
+        e_ptr->idx = static_cast<EGO_IDX>(i);
 #ifdef JP
-        e_ptr->name = tok[2];
+        e_ptr->name = tokens[2];
 #endif
     } else if (!e_ptr)
         return PARSE_ERROR_MISSING_RECORD_HEADER;
-    else if (tok[0] == "E") {
+    else if (tokens[0] == "E") {
         // E:name_en
 #ifndef JP
-        if (tok[1].size() == 0)
-            return 1;
-        e_ptr->name = tok[1];
+        if (tokens[1].size() == 0)
+            return PARSE_ERROR_TOO_FEW_ARGUMENTS;
+        e_ptr->name = tokens[1];
 #endif
-    }
-    else if (tok[0] == "X") {
+    } else if (tokens[0] == "X") {
         // X:slot:rating
-        if (tok.size() < 3)
+        if (tokens.size() < 3)
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
-        e_ptr->slot = (INVENTORY_IDX)std::stoi(tok[1]);
-        e_ptr->rating = (PRICE)std::stoi(tok[2]);
-    } else if (tok[0] == "W") {
+
+        info_set_value(e_ptr->slot, tokens[1]);
+        info_set_value(e_ptr->rating, tokens[2]);
+    } else if (tokens[0] == "W") {
         // W:level:ratiry:xtra:cost
         // xtra is not used
-        if (tok.size() < 5)
+        if (tokens.size() < 5)
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
-        e_ptr->level = (DEPTH)std::stoi(tok[1]);
-        e_ptr->rarity = (RARITY)std::stoi(tok[2]);
-        e_ptr->cost = (PRICE)std::stoi(tok[4]);
-    } else if (tok[0] == "B") {
+
+        info_set_value(e_ptr->level, tokens[1]);
+        info_set_value(e_ptr->rarity, tokens[2]);
+        info_set_value(e_ptr->cost, tokens[4]);
+    } else if (tokens[0] == "B") {
         // Base bonuses
         // B:to_hit:to_dam:to_ac
-        if (tok.size() < 4)
-            return 1;
-        e_ptr->base_to_h = (HIT_PROB)std::stoi(tok[1]);
-        e_ptr->base_to_d = (HIT_POINT)std::stoi(tok[2]);
-        e_ptr->base_to_a = (ARMOUR_CLASS)std::stoi(tok[3]);
-    } else if (tok[0] == "C") {
+        if (tokens.size() < 4)
+            return PARSE_ERROR_TOO_FEW_ARGUMENTS;
+
+        info_set_value(e_ptr->base_to_h, tokens[1]);
+        info_set_value(e_ptr->base_to_d, tokens[2]);
+        info_set_value(e_ptr->base_to_a, tokens[3]);
+    } else if (tokens[0] == "C") {
         // Creation bonuses (random plus)
         // C:to_hit:to_dam:to_ac:pval
-        if (tok.size() < 5)
+        if (tokens.size() < 5)
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
-        e_ptr->max_to_h = (HIT_PROB)std::stoi(tok[1]);
-        e_ptr->max_to_d = (HIT_POINT)std::stoi(tok[2]);
-        e_ptr->max_to_a = (ARMOUR_CLASS)std::stoi(tok[3]);
-        e_ptr->max_pval = (PARAMETER_VALUE)std::stoi(tok[4]);
-    } else if (tok[0] == "U") {
+
+        info_set_value(e_ptr->max_to_h, tokens[1]);
+        info_set_value(e_ptr->max_to_d, tokens[2]);
+        info_set_value(e_ptr->max_to_a, tokens[3]);
+        info_set_value(e_ptr->max_pval, tokens[4]);
+    } else if (tokens[0] == "U") {
         // U:activation_flag
-        if (tok.size() < 2 || tok[1].size() == 0)
+        if (tokens.size() < 2 || tokens[1].size() == 0)
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
-        auto n = grab_one_activation_flag(tok[1].c_str());
-        if (n <= 0)
+
+        auto n = grab_one_activation_flag(tokens[1].c_str());
+        if (n <=RandomArtActType::NONE)
             return PARSE_ERROR_INVALID_FLAG;
-        e_ptr->act_idx = (IDX)n;
-    } else if (tok[0] == "F") {
+
+        e_ptr->act_idx = n;
+    } else if (tokens[0] == "F") {
         // F:flags
-        if (tok.size() < 2 || tok[1].size() == 0)
-            return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
+        if (tokens.size() < 2 || tokens[1].size() == 0)
+            return PARSE_ERROR_TOO_FEW_ARGUMENTS;
 
-        const auto& flags = str_split(tok[1], '|', true);
+        const auto& flags = str_split(tokens[1], '|', true, 10);
         for (const auto& f : flags) {
             if (f.size() == 0)
                 continue;
-            if (0 != grab_one_ego_item_flag(e_ptr, f))
+            if (!grab_one_ego_item_flag(e_ptr, f))
                 return PARSE_ERROR_INVALID_FLAG;
         }
-    } else if (tok[0] == "G") {
+    } else if (tokens[0] == "G") {
         // G:mul/dev:flags
-        if (tok.size() < 3)
-            return PARSE_ERROR_UNDEFINED_TERRAIN_TAG;
+        if (tokens.size() < 3)
+            return PARSE_ERROR_TOO_FEW_ARGUMENTS;
 
-        auto prob = str_split(tok[1], '/');
-        if (prob.size() != 2 || tok[1].size() == 0 || tok[2].size() == 0)
+        const auto &prob = str_split(tokens[1], '/', false, 2);
+        if (prob.size() != 2 || tokens[1].size() == 0 || tokens[2].size() == 0)
             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
 
         ego_generate_type xtra;
         xtra.mul = std::stoi(prob[0]);
         xtra.dev = std::stoi(prob[1]);
 
-        const auto& flags = str_split(tok[2], '|', true);
+        const auto& flags = str_split(tokens[2], '|', true, 10);
         for (const auto& f : flags) {
             if (f.size() == 0)
                 continue;
-            if (grab_ego_generate_flags(xtra, f))
+            if (!grab_ego_generate_flags(xtra, f))
                 return PARSE_ERROR_INVALID_FLAG;
         }