OSDN Git Service

Refactor get_table_{name,name_aux,sindarin,sindarin_aux}() and sindarin_to_kana(...
[hengbandforosx/hengbandosx.git] / src / flavor / object-flavor.cpp
index e7b9ba7..e618cce 100644 (file)
@@ -18,6 +18,8 @@
 #include "grid/trap.h"
 #include "inventory/inventory-slot-types.h"
 #include "io/files-util.h"
+#include "locale/english.h"
+#include "locale/japanese.h"
 #include "mind/mind-sniper.h"
 #include "mind/mind-weaponsmith.h"
 #include "monster-race/monster-race.h"
 #include "object-hook/hook-quest.h"
 #include "object/object-flags.h"
 #include "object/object-info.h"
-#include "object/object-kind.h"
 #include "perception/object-perception.h"
 #include "player-info/class-info.h"
 #include "player/player-status.h"
 #include "sv-definition/sv-food-types.h"
 #include "sv-definition/sv-lite-types.h"
+#include "system/baseitem-info.h"
 #include "util/bit-flags-calculator.h"
 #include "util/quarks.h"
 #include "util/string-processor.h"
 #include "world/world.h"
-#ifdef JP
-#include "locale/japanese.h"
-#else
-#include "locale/english.h"
-#endif
+#include <functional>
+#include <sstream>
+#include <utility>
 
 /*!
  * @brief 最初から簡易な名称が明らかになるベースアイテムの判定。 /  Certain items, if aware, are known instantly
  */
 static bool object_easy_know(int i)
 {
-    object_kind *k_ptr = &k_info[i];
-    switch (k_ptr->tval) {
-    case TV_LIFE_BOOK:
-    case TV_SORCERY_BOOK:
-    case TV_NATURE_BOOK:
-    case TV_CHAOS_BOOK:
-    case TV_DEATH_BOOK:
-    case TV_TRUMP_BOOK:
-    case TV_ARCANE_BOOK:
-    case TV_CRAFT_BOOK:
-    case TV_DEMON_BOOK:
-    case TV_CRUSADE_BOOK:
-    case TV_MUSIC_BOOK:
-    case TV_HISSATSU_BOOK:
-    case TV_HEX_BOOK:
+    const auto &baseitem = baseitems_info[i];
+    switch (baseitem.bi_key.tval()) {
+    case ItemKindType::LIFE_BOOK:
+    case ItemKindType::SORCERY_BOOK:
+    case ItemKindType::NATURE_BOOK:
+    case ItemKindType::CHAOS_BOOK:
+    case ItemKindType::DEATH_BOOK:
+    case ItemKindType::TRUMP_BOOK:
+    case ItemKindType::ARCANE_BOOK:
+    case ItemKindType::CRAFT_BOOK:
+    case ItemKindType::DEMON_BOOK:
+    case ItemKindType::CRUSADE_BOOK:
+    case ItemKindType::MUSIC_BOOK:
+    case ItemKindType::HISSATSU_BOOK:
+    case ItemKindType::HEX_BOOK:
         return true;
-    case TV_FLASK:
-    case TV_JUNK:
-    case TV_BOTTLE:
-    case TV_SKELETON:
-    case TV_SPIKE:
-    case TV_WHISTLE:
+    case ItemKindType::FLASK:
+    case ItemKindType::JUNK:
+    case ItemKindType::BOTTLE:
+    case ItemKindType::SKELETON:
+    case ItemKindType::SPIKE:
+    case ItemKindType::WHISTLE:
         return true;
-    case TV_FOOD:
-    case TV_POTION:
-    case TV_SCROLL:
-    case TV_ROD:
+    case ItemKindType::FOOD:
+    case ItemKindType::POTION:
+    case ItemKindType::SCROLL:
+    case ItemKindType::ROD:
         return true;
 
     default:
@@ -92,18 +92,20 @@ static bool object_easy_know(int i)
 
 /*!
  * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts.
- * @param out_string 作成した名を保管する参照ポインタ
+ * @return std::string 作成した名前
  * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
  * syllables 配列と elvish.txt を組み合わせる。\n
  */
-void get_table_name_aux(char *out_string)
+std::string get_table_name_aux()
 {
+    std::string name;
 #ifdef JP
     char syllable[80];
     get_rnd_line("aname_j.txt", 1, syllable);
-    strcpy(out_string, syllable);
+    name = syllable;
     get_rnd_line("aname_j.txt", 2, syllable);
-    strcat(out_string, syllable);
+    name.append(syllable);
+    return name;
 #else
 #define MAX_SYLLABLES 164 /* Used with scrolls (see below) */
 
@@ -117,69 +119,59 @@ void get_table_name_aux(char *out_string)
         "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" };
 
     int testcounter = randint1(3) + 1;
-    strcpy(out_string, "");
     if (randint1(3) == 2) {
-        while (testcounter--)
-            strcat(out_string, syllables[randint0(MAX_SYLLABLES)]);
+        while (testcounter--) {
+            name.append(syllables[randint0(MAX_SYLLABLES)]);
+        }
     } else {
         char syllable[80];
         testcounter = randint1(2) + 1;
         while (testcounter--) {
             (void)get_rnd_line("elvish.txt", 0, syllable);
-            strcat(out_string, syllable);
+            name.append(syllable);
         }
     }
 
-    out_string[0] = toupper(out_string[1]);
-    out_string[16] = '\0';
+    name[0] = toupper(name[0]);
+    return name;
 #endif
 }
 
 /*!
  * @brief ランダムな名前をアーティファクト銘として整形する。 / Create a name from random parts with quotes.
- * @param out_string 作成した名を保管する参照ポインタ
+ * @return std::string 作成した名前
  * @details get_table_name_aux()ほぼ完全に実装を依存している。
  */
-void get_table_name(char *out_string)
+std::string get_table_name()
 {
-    char buff[80];
-    get_table_name_aux(buff);
-    sprintf(out_string, _("『%s』", "'%s'"), buff);
+    return std::string(_("『", "'")).append(get_table_name_aux()).append(_("』", "'"));
 }
 
 /*!
  * @brief ランダムなシンダリン銘を作成する / Make random Sindarin name
- * @param out_string 作成した名を保管する参照ポインタ
+ * @return std::string 作成した名前
  * @details sname.txtが語幹の辞書となっている。
  */
-void get_table_sindarin_aux(char *out_string)
+std::string get_table_sindarin_aux()
 {
     char syllable[80];
-#ifdef JP
-    char tmp[80];
-#endif
 
     get_rnd_line("sname.txt", 1, syllable);
-    strcpy(_(tmp, out_string), syllable);
+    std::string name = syllable;
     get_rnd_line("sname.txt", 2, syllable);
-#ifdef JP
-    strcat(tmp, syllable);
-    sindarin_to_kana(out_string, tmp);
-#else
-    strcat(out_string, syllable);
-#endif
+    name.append(syllable);
+    return _(sindarin_to_kana(name), name);
 }
 
 /*!
  * @brief シンダリン銘をアーティファクト用に整形する。 / Make random Sindarin name with quotes
  * @param out_string 作成した名を保管する参照ポインタ
+ * @return std::string 作成した名前
  * @details get_table_sindarin_aux()ほぼ完全に実装を依存している。
  */
-void get_table_sindarin(char *out_string)
+std::string get_table_sindarin()
 {
-    char buff[80];
-    get_table_sindarin_aux(buff);
-    sprintf(out_string, _("『%s』", "'%s'"), buff);
+    return std::string(_("『", "'")).append(get_table_sindarin_aux()).append(_("』", "'"));
 }
 
 /*!
@@ -187,106 +179,101 @@ void get_table_sindarin(char *out_string)
  * @param tval シャッフルしたいtval
  * @details 巻物、各種魔道具などに利用される。
  */
-static void shuffle_flavors(tval_type tval)
+static void shuffle_flavors(ItemKindType tval)
 {
-    KIND_OBJECT_IDX *k_idx_list;
-    KIND_OBJECT_IDX k_idx_list_num = 0;
-    C_MAKE(k_idx_list, max_k_idx, KIND_OBJECT_IDX);
-    for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
-        object_kind *k_ptr = &k_info[i];
-        if (k_ptr->tval != tval)
+    std::vector<std::reference_wrapper<IDX>> flavor_idx_ref_list;
+    for (const auto &baseitem : baseitems_info) {
+        if (baseitem.bi_key.tval() != tval) {
             continue;
+        }
 
-        if (!k_ptr->flavor)
+        if (baseitem.flavor == 0) {
             continue;
+        }
 
-        if (k_ptr->flags.has(TR_FIXED_FLAVOR))
+        if (baseitem.flags.has(TR_FIXED_FLAVOR)) {
             continue;
+        }
 
-        k_idx_list[k_idx_list_num] = i;
-        k_idx_list_num++;
-    }
-
-    for (KIND_OBJECT_IDX i = 0; i < k_idx_list_num; i++) {
-        object_kind *k1_ptr = &k_info[k_idx_list[i]];
-        object_kind *k2_ptr = &k_info[k_idx_list[randint0(k_idx_list_num)]];
-        int16_t tmp = k1_ptr->flavor;
-        k1_ptr->flavor = k2_ptr->flavor;
-        k2_ptr->flavor = tmp;
+        flavor_idx_ref_list.push_back(baseitems_info[baseitem.idx].flavor);
     }
 
-    C_KILL(k_idx_list, max_k_idx, int16_t);
+    rand_shuffle(flavor_idx_ref_list.begin(), flavor_idx_ref_list.end());
 }
 
 /*!
- * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン / Prepare the "variable" part of the "k_info" array.
+ * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン
  * @param なし
  */
 void flavor_init(void)
 {
-    uint32_t state_backup[4];
-    Rand_state_backup(state_backup);
-    Rand_state_set(current_world_ptr->seed_flavor);
-    for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
-        object_kind *k_ptr = &k_info[i];
-        if (k_ptr->flavor_name.empty())
+    const auto state_backup = w_ptr->rng.get_state();
+    w_ptr->rng.set_state(w_ptr->seed_flavor);
+    for (auto &baseitem : baseitems_info) {
+        if (baseitem.flavor_name.empty()) {
             continue;
+        }
 
-        k_ptr->flavor = i;
+        baseitem.flavor = baseitem.idx;
     }
 
-    shuffle_flavors(TV_RING);
-    shuffle_flavors(TV_AMULET);
-    shuffle_flavors(TV_STAFF);
-    shuffle_flavors(TV_WAND);
-    shuffle_flavors(TV_ROD);
-    shuffle_flavors(TV_FOOD);
-    shuffle_flavors(TV_POTION);
-    shuffle_flavors(TV_SCROLL);
-    Rand_state_restore(state_backup);
-    for (KIND_OBJECT_IDX i = 1; i < max_k_idx; i++) {
-        object_kind *k_ptr = &k_info[i];
-        if (k_ptr->name.empty())
+    shuffle_flavors(ItemKindType::RING);
+    shuffle_flavors(ItemKindType::AMULET);
+    shuffle_flavors(ItemKindType::STAFF);
+    shuffle_flavors(ItemKindType::WAND);
+    shuffle_flavors(ItemKindType::ROD);
+    shuffle_flavors(ItemKindType::FOOD);
+    shuffle_flavors(ItemKindType::POTION);
+    shuffle_flavors(ItemKindType::SCROLL);
+    w_ptr->rng.set_state(state_backup);
+    for (auto &baseitem : baseitems_info) {
+        if (baseitem.idx == 0 || baseitem.name.empty()) {
             continue;
+        }
 
-        if (!k_ptr->flavor)
-            k_ptr->aware = true;
+        if (!baseitem.flavor) {
+            baseitem.aware = true;
+        }
 
-        k_ptr->easy_know = object_easy_know(i);
+        baseitem.easy_know = object_easy_know(baseitem.idx);
     }
 }
 
 /*!
  * @brief nameバッファ内からベースアイテム名を返す / Strip an "object name" into a buffer
  * @param buf ベースアイテム格納先の参照ポインタ
- * @param k_idx ベースアイテムID
+ * @param bi_id ベースアイテムID
  */
-void strip_name(char *buf, KIND_OBJECT_IDX k_idx)
+std::string strip_name(short bi_id)
 {
-    auto k_ptr = &k_info[k_idx];
-    auto tok = str_split(k_ptr->name, ' ');
-    std::string name = "";
-    for (auto s : tok) {
-        if (s == "" || s == "~" || s == "&" || s == "#")
+    const auto &baseitem = baseitems_info[bi_id];
+    auto tok = str_split(baseitem.name, ' ');
+    std::stringstream name;
+    for (const auto &s : tok) {
+        if (s == "" || s == "~" || s == "&" || s == "#") {
             continue;
+        }
 
         auto offset = 0;
         auto endpos = s.size();
         auto is_kanji = false;
 
-        if (s[0] == '~' || s[0] == '#')
+        if (s[0] == '~' || s[0] == '#') {
             offset++;
+        }
 #ifdef JP
-        if (s.size() > 2)
+        if (s.size() > 2) {
             is_kanji = iskanji(s[endpos - 2]);
+        }
 
 #endif
-        if (!is_kanji && (s[endpos - 1] == '~' || s[endpos - 1] == '#'))
+        if (!is_kanji && (s[endpos - 1] == '~' || s[endpos - 1] == '#')) {
             endpos--;
+        }
 
-        name += s.substr(offset, endpos);
+        name << s.substr(offset, endpos);
     }
 
-    name += " ";
-    strcpy(buf, name.c_str());
+    name << " ";
+    return name.str();
 }