OSDN Git Service

Merge branch 'develop' into macos-develop
[hengbandforosx/hengbandosx.git] / src / flavor / flavor-util.cpp
index e37dda0..076f762 100644 (file)
@@ -1,13 +1,11 @@
-#include "flavor/flavor-util.h"
+#include "flavor/flavor-util.h"
 #include "flavor/flag-inscriptions-table.h"
 #include "object-enchant/tr-flags.h"
 #include "object-enchant/tr-types.h"
-#include "object/object-flags.h"
 #include "object/tval-types.h"
 #include "sv-definition/sv-food-types.h"
 #include "system/artifact-type-definition.h"
 #include "system/item-entity.h"
-#include "util/quarks.h"
 #include "util/string-processor.h"
 #include <sstream>
 
@@ -22,31 +20,18 @@ static bool has_dark_flag(const TrFlags &flags)
 }
 
 /*!
- * @brief オブジェクトフラグを追加する
- * @param short_flavor フラグの短縮表現 (反魔法/アンチテレポの"["、耐性の"r"、耐混乱の"乱" 等)
- * @param ptr 特性短縮表記を格納する文字列ポインタ
- *
- * @todo バッファサイズが不明なのでとりあえず16バイト決め打ちで angband_strcpy を呼び出している。
- * get_ability_abbrev のインターフェースを std::string を返すように変更するときに合わせて修正すること。
- */
-static void add_inscription(char **short_flavor, concptr str)
-{
-    *short_flavor += angband_strcpy(*short_flavor, str, 16);
-}
-
-/*!
  * @brief get_inscriptionのサブセットとしてアイテムの特性フラグを表す文字列を返す
  * @param fi_vec 参照する特性表示記号テーブル
- * @param flgs 対応するアイテムの特性フラグ
+ * @param flags 対応するアイテムの特性フラグ
  * @param is_kanji trueならば漢字記述/falseならば英語記述
  * @return アイテムの特性フラグを表す文字列
  */
-static std::string inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs, [[maybe_unused]] bool is_kanji)
+static std::string inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flags, [[maybe_unused]] bool is_kanji)
 {
     std::stringstream ss;
 
     for (const auto &fi : fi_vec) {
-        if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
+        if (flags.has(fi.flag) && (!fi.except_flag || flags.has_not(*fi.except_flag))) {
             const auto flag_str = _(is_kanji ? fi.japanese : fi.english, fi.english);
             ss << flag_str;
         }
@@ -59,13 +44,13 @@ static std::string inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec
  * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of has_flag for
  * auto-inscription
  * @param fi_vec 参照する特性表示記号テーブル
- * @param flgs 対応するオブジェクトのフラグ文字列
+ * @param flags 対応するオブジェクトのフラグ文字列
  * @return 1つでも該当の特性があったらTRUEを返す。
  */
-static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs)
+static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flags)
 {
     for (const auto &fi : fi_vec) {
-        if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
+        if (flags.has(fi.flag) && (!fi.except_flag || flags.has_not(*fi.except_flag))) {
             return true;
         }
     }
@@ -82,55 +67,55 @@ static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlag
  */
 std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool all)
 {
-    auto flgs = object_flags(&item);
+    auto flags = item.get_flags();
     if (!all) {
-        const auto &baseitem = baseitems_info[item.bi_id];
-        flgs.reset(baseitem.flags);
+        const auto &baseitem = item.get_baseitem();
+        flags.reset(baseitem.flags);
 
         if (item.is_fixed_artifact()) {
-            const auto &a_ref = artifacts_info.at(item.fixed_artifact_idx);
-            flgs.reset(a_ref.flags);
+            const auto &artifact = item.get_fixed_artifact();
+            flags.reset(artifact.flags);
         }
 
         if (item.is_ego()) {
-            auto *e_ptr = &egos_info[item.ego_idx];
-            flgs.reset(e_ptr->flags);
+            const auto &ego = item.get_ego();
+            flags.reset(ego.flags);
         }
     }
 
-    if (has_dark_flag(flgs)) {
-        if (flgs.has(TR_LITE_1)) {
-            flgs.reset(TR_LITE_1);
+    if (has_dark_flag(flags)) {
+        if (flags.has(TR_LITE_1)) {
+            flags.reset(TR_LITE_1);
         }
 
-        if (flgs.has(TR_LITE_2)) {
-            flgs.reset(TR_LITE_2);
+        if (flags.has(TR_LITE_2)) {
+            flags.reset(TR_LITE_2);
         }
 
-        if (flgs.has(TR_LITE_3)) {
-            flgs.reset(TR_LITE_3);
+        if (flags.has(TR_LITE_3)) {
+            flags.reset(TR_LITE_3);
         }
-    } else if (has_lite_flag(flgs)) {
-        flgs.set(TR_LITE_1);
-        if (flgs.has(TR_LITE_2)) {
-            flgs.reset(TR_LITE_2);
+    } else if (has_lite_flag(flags)) {
+        flags.set(TR_LITE_1);
+        if (flags.has(TR_LITE_2)) {
+            flags.reset(TR_LITE_2);
         }
 
-        if (flgs.has(TR_LITE_3)) {
-            flgs.reset(TR_LITE_3);
+        if (flags.has(TR_LITE_3)) {
+            flags.reset(TR_LITE_3);
         }
     }
 
     std::stringstream ss;
     auto prev_tellp = ss.tellp();
 
-    if (has_flag_of(flag_insc_plus, flgs) && is_kanji) {
+    if (has_flag_of(flag_insc_plus, flags) && is_kanji) {
         ss << '+';
     }
 
-    ss << inscribe_flags_aux(flag_insc_plus, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_plus, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_immune, flgs)) {
+    if (has_flag_of(flag_insc_immune, flags)) {
         if (!is_kanji && (ss.tellp() != prev_tellp)) {
             ss << ';';
             prev_tellp = ss.tellp();
@@ -139,9 +124,9 @@ std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool
         ss << '*';
     }
 
-    ss << inscribe_flags_aux(flag_insc_immune, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_immune, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_vuln, flgs)) {
+    if (has_flag_of(flag_insc_vuln, flags)) {
         if (!is_kanji && (ss.tellp() != prev_tellp)) {
             ss << ';';
             prev_tellp = ss.tellp();
@@ -150,9 +135,9 @@ std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool
         ss << 'v';
     }
 
-    ss << inscribe_flags_aux(flag_insc_vuln, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_vuln, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_resistance, flgs)) {
+    if (has_flag_of(flag_insc_resistance, flags)) {
         if (is_kanji) {
             ss << 'r';
         } else if (ss.tellp() != prev_tellp) {
@@ -161,65 +146,65 @@ std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool
         }
     }
 
-    ss << inscribe_flags_aux(flag_insc_resistance, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_resistance, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_misc, flgs) && (ss.tellp() != prev_tellp)) {
+    if (has_flag_of(flag_insc_misc, flags) && (ss.tellp() != prev_tellp)) {
         ss << ';';
         prev_tellp = ss.tellp();
     }
 
-    ss << inscribe_flags_aux(flag_insc_misc, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_misc, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_aura, flgs)) {
+    if (has_flag_of(flag_insc_aura, flags)) {
         ss << '[';
     }
 
-    ss << inscribe_flags_aux(flag_insc_aura, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_aura, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_brand, flgs)) {
+    if (has_flag_of(flag_insc_brand, flags)) {
         ss << '|';
     }
 
-    ss << inscribe_flags_aux(flag_insc_brand, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_brand, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_kill, flgs)) {
+    if (has_flag_of(flag_insc_kill, flags)) {
         ss << "/X";
     }
 
-    ss << inscribe_flags_aux(flag_insc_kill, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_kill, flags, is_kanji);
 
-    if (has_flag_of(flag_insc_slay, flgs)) {
+    if (has_flag_of(flag_insc_slay, flags)) {
         ss << '/';
     }
 
-    ss << inscribe_flags_aux(flag_insc_slay, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_slay, flags, is_kanji);
 
     if (is_kanji) {
-        if (has_flag_of(flag_insc_esp1, flgs) || has_flag_of(flag_insc_esp2, flgs)) {
+        if (has_flag_of(flag_insc_esp1, flags) || has_flag_of(flag_insc_esp2, flags)) {
             ss << '~';
         }
 
-        ss << inscribe_flags_aux(flag_insc_esp1, flgs, is_kanji)
-           << inscribe_flags_aux(flag_insc_esp2, flgs, is_kanji);
+        ss << inscribe_flags_aux(flag_insc_esp1, flags, is_kanji)
+           << inscribe_flags_aux(flag_insc_esp2, flags, is_kanji);
     } else {
-        if (has_flag_of(flag_insc_esp1, flgs)) {
+        if (has_flag_of(flag_insc_esp1, flags)) {
             ss << '~';
         }
 
-        ss << inscribe_flags_aux(flag_insc_esp1, flgs, is_kanji);
+        ss << inscribe_flags_aux(flag_insc_esp1, flags, is_kanji);
 
-        if (has_flag_of(flag_insc_esp2, flgs)) {
+        if (has_flag_of(flag_insc_esp2, flags)) {
             ss << '~';
         }
 
-        ss << inscribe_flags_aux(flag_insc_esp2, flgs, is_kanji);
+        ss << inscribe_flags_aux(flag_insc_esp2, flags, is_kanji);
     }
 
-    if (has_flag_of(flag_insc_sust, flgs)) {
+    if (has_flag_of(flag_insc_sust, flags)) {
         ss << '(';
     }
 
-    ss << inscribe_flags_aux(flag_insc_sust, flgs, is_kanji);
+    ss << inscribe_flags_aux(flag_insc_sust, flags, is_kanji);
 
     return ss.str();
 }
@@ -229,69 +214,72 @@ std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool
  * @param buff 特性短縮表記を格納する文字列ポインタ
  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
  */
-void get_inscription(char *buff, const ItemEntity *o_ptr)
+std::string get_inscription(const ItemEntity &item)
 {
-    concptr insc = quark_str(o_ptr->inscription);
-    char *ptr = buff;
-    if (!o_ptr->is_fully_known()) {
-        while (*insc) {
-            if (*insc == '#') {
+    if (!item.is_inscribed()) {
+        return {};
+    }
+
+    std::stringstream ss;
+
+    if (!item.is_fully_known()) {
+        for (std::string_view sv = *item.inscription; !sv.empty(); sv.remove_prefix(1)) {
+            if (sv.front() == '#') {
                 break;
             }
-            if (buff > ptr + MAX_INSCRIPTION - 1) {
+            if (ss.tellp() > MAX_INSCRIPTION - 1) {
                 break;
             }
 #ifdef JP
-            if (iskanji(*insc)) {
-                *buff++ = *insc++;
+            if (iskanji(sv.front())) {
+                ss << sv.front();
+                sv.remove_prefix(1);
             }
 #endif
-            *buff++ = *insc++;
+            ss << sv.front();
         }
 
-        *buff = '\0';
-        return;
+        return ss.str();
     }
 
-    *buff = '\0';
-    for (; *insc; insc++) {
-        if (*insc == '#') {
-            break;
-        } else if ('%' == *insc) {
-            bool kanji = false;
-            bool all;
-            concptr start = ptr;
-            if (ptr >= buff + MAX_NLEN) {
-                continue;
+    for (std::string_view sv = *item.inscription; !sv.empty(); sv.remove_prefix(1)) {
+        switch (sv.front()) {
+        case '#':
+            return ss.str();
+        case '%': {
+            const auto start_pos = ss.tellp();
+            if (start_pos >= MAX_NLEN) {
+                break;
             }
 
+            auto is_kanji = false;
 #ifdef JP
-            if ('%' == insc[1]) {
-                insc++;
-                kanji = false;
+            if ((sv.size() > 1) && ('%' == sv[1])) {
+                sv.remove_prefix(1);
             } else {
-                kanji = true;
+                is_kanji = true;
             }
 #endif
 
-            if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3]) {
+            auto all = false;
+            if (sv.substr(1, 3) == "all") {
                 all = true;
-                insc += 3;
-            } else {
-                all = false;
+                sv.remove_prefix(3);
             }
 
-            const auto ability_abbrev = get_ability_abbreviation(*o_ptr, kanji, all);
-            ptr += angband_strcpy(ptr, ability_abbrev.data(), ability_abbrev.size());
-            if (ptr == start) {
-                add_inscription(&ptr, " ");
+            ss << get_ability_abbreviation(item, is_kanji, all);
+            if (ss.tellp() == start_pos) {
+                ss << ' ';
             }
-        } else {
-            *ptr++ = *insc;
+            break;
+        }
+        default:
+            ss << sv.front();
+            break;
         }
     }
 
-    *ptr = '\0';
+    return ss.str();
 }
 
 #ifdef JP
@@ -356,7 +344,7 @@ std::string describe_count_with_counter_suffix(const ItemEntity &item)
         break;
 
     case ItemKindType::FOOD:
-        if (item.bi_key.sval().value() == SV_FOOD_JERKY) {
+        if (item.bi_key.sval() == SV_FOOD_JERKY) {
             ss << "切れ";
             break;
         }