2 * @brief オブジェクトの記述処理 / Mbject flavor code
5 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7 * This software may be copied and distributed for educational, research,\n
8 * and not for profit purposes provided that this copyright and statement\n
9 * are included in all such copies. Other copyrights may also apply.\n
12 #include "flavor/object-flavor.h"
13 #include "combat/shoot.h"
14 #include "flavor/flag-inscriptions-table.h"
15 #include "flavor/flavor-util.h"
16 #include "flavor/object-flavor-types.h"
17 #include "game-option/text-display-options.h"
18 #include "grid/trap.h"
19 #include "inventory/inventory-slot-types.h"
20 #include "io/files-util.h"
21 #include "locale/english.h"
22 #include "locale/japanese.h"
23 #include "mind/mind-sniper.h"
24 #include "mind/mind-weaponsmith.h"
25 #include "monster-race/monster-race.h"
26 #include "monster-race/race-flags1.h"
27 #include "object-enchant/object-ego.h"
28 #include "object-enchant/special-object-flags.h"
29 #include "object-enchant/tr-types.h"
30 #include "object-enchant/trg-types.h"
31 #include "object-hook/hook-quest.h"
32 #include "object/object-flags.h"
33 #include "object/object-info.h"
34 #include "perception/object-perception.h"
35 #include "player-info/class-info.h"
36 #include "player/player-status.h"
37 #include "sv-definition/sv-food-types.h"
38 #include "sv-definition/sv-lite-types.h"
39 #include "system/baseitem-info.h"
40 #include "util/bit-flags-calculator.h"
41 #include "util/quarks.h"
42 #include "util/string-processor.h"
43 #include "world/world.h"
49 * @brief 最初から簡易な名称が明らかになるベースアイテムの判定。 / Certain items, if aware, are known instantly
51 * @return 簡易名称を明らかにするならTRUEを返す。
53 * This function is used only by "flavor_init()"
55 static bool object_easy_know(int i)
57 const auto &baseitem = baseitems_info[i];
58 switch (baseitem.bi_key.tval()) {
59 case ItemKindType::LIFE_BOOK:
60 case ItemKindType::SORCERY_BOOK:
61 case ItemKindType::NATURE_BOOK:
62 case ItemKindType::CHAOS_BOOK:
63 case ItemKindType::DEATH_BOOK:
64 case ItemKindType::TRUMP_BOOK:
65 case ItemKindType::ARCANE_BOOK:
66 case ItemKindType::CRAFT_BOOK:
67 case ItemKindType::DEMON_BOOK:
68 case ItemKindType::CRUSADE_BOOK:
69 case ItemKindType::MUSIC_BOOK:
70 case ItemKindType::HISSATSU_BOOK:
71 case ItemKindType::HEX_BOOK:
73 case ItemKindType::FLASK:
74 case ItemKindType::JUNK:
75 case ItemKindType::BOTTLE:
76 case ItemKindType::SKELETON:
77 case ItemKindType::SPIKE:
78 case ItemKindType::WHISTLE:
80 case ItemKindType::FOOD:
81 case ItemKindType::POTION:
82 case ItemKindType::SCROLL:
83 case ItemKindType::ROD:
94 * @brief 各種語彙からランダムな名前を作成する
95 * @return std::string 作成した名前
96 * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
97 * syllables 配列と elvish.txt を組み合わせる
99 std::string get_table_name_aux()
101 std::stringstream ss;
103 ss << get_random_line("aname_j.txt", 1).value();
104 ss << get_random_line("aname_j.txt", 2).value();
107 static std::vector<std::string_view> syllables = {
108 "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
109 "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "der", "doe", "dok", "eep", "el", "eng",
110 "er", "ere", "erk", "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion",
111 "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
112 "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re",
113 "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri",
114 "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
115 "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu"
118 int testcounter = randint1(3) + 1;
119 if (randint1(3) == 2) {
120 while (testcounter--) {
121 ss << syllables[randint0(syllables.size())];
124 testcounter = randint1(2) + 1;
125 while (testcounter--) {
126 ss << get_random_line("elvish.txt", 0).value();
130 auto name = ss.str();
131 name[0] = toupper(name[0]);
137 * @brief ランダムな名前をアーティファクト銘として整形する。 / Create a name from random parts with quotes.
138 * @return std::string 作成した名前
139 * @details get_table_name_aux()ほぼ完全に実装を依存している。
141 std::string get_table_name()
143 return std::string(_("『", "'")).append(get_table_name_aux()).append(_("』", "'"));
147 * @brief ランダムなシンダリン銘を作成する / Make random Sindarin name
148 * @return std::string 作成した名前
149 * @details sname.txtが語幹の辞書となっている。
151 std::string get_table_sindarin_aux()
153 std::stringstream ss;
154 ss << get_random_line("sname.txt", 1).value();
155 ss << get_random_line("sname.txt", 2).value();
156 auto name = ss.str();
157 return _(sindarin_to_kana(name), name);
161 * @brief シンダリン銘をアーティファクト用に整形する。 / Make random Sindarin name with quotes
162 * @param out_string 作成した名を保管する参照ポインタ
163 * @return std::string 作成した名前
164 * @details get_table_sindarin_aux()ほぼ完全に実装を依存している。
166 std::string get_table_sindarin()
168 return std::string(_("『", "'")).append(get_table_sindarin_aux()).append(_("』", "'"));
172 * @brief ベースアイテムの未確定名を共通tval間でシャッフルする / Shuffle flavor indices of a group of objects with given tval
173 * @param tval シャッフルしたいtval
174 * @details 巻物、各種魔道具などに利用される。
176 static void shuffle_flavors(ItemKindType tval)
178 std::vector<std::reference_wrapper<IDX>> flavor_idx_ref_list;
179 for (const auto &baseitem : baseitems_info) {
180 if (baseitem.bi_key.tval() != tval) {
184 if (baseitem.flavor == 0) {
188 if (baseitem.flags.has(TR_FIXED_FLAVOR)) {
192 flavor_idx_ref_list.push_back(baseitems_info[baseitem.idx].flavor);
195 rand_shuffle(flavor_idx_ref_list.begin(), flavor_idx_ref_list.end());
199 * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン
202 void flavor_init(void)
204 const auto state_backup = w_ptr->rng.get_state();
205 w_ptr->rng.set_state(w_ptr->seed_flavor);
206 for (auto &baseitem : baseitems_info) {
207 if (baseitem.flavor_name.empty()) {
211 baseitem.flavor = baseitem.idx;
214 shuffle_flavors(ItemKindType::RING);
215 shuffle_flavors(ItemKindType::AMULET);
216 shuffle_flavors(ItemKindType::STAFF);
217 shuffle_flavors(ItemKindType::WAND);
218 shuffle_flavors(ItemKindType::ROD);
219 shuffle_flavors(ItemKindType::FOOD);
220 shuffle_flavors(ItemKindType::POTION);
221 shuffle_flavors(ItemKindType::SCROLL);
222 w_ptr->rng.set_state(state_backup);
223 for (auto &baseitem : baseitems_info) {
224 if (baseitem.idx == 0 || baseitem.name.empty()) {
228 if (!baseitem.flavor) {
229 baseitem.aware = true;
232 baseitem.easy_know = object_easy_know(baseitem.idx);
237 * @brief nameバッファ内からベースアイテム名を返す / Strip an "object name" into a buffer
238 * @param buf ベースアイテム格納先の参照ポインタ
239 * @param bi_id ベースアイテムID
241 std::string strip_name(short bi_id)
243 const auto &baseitem = baseitems_info[bi_id];
244 auto tok = str_split(baseitem.name, ' ');
245 std::stringstream name;
246 for (const auto &s : tok) {
247 if (s == "" || s == "~" || s == "&" || s == "#") {
252 auto endpos = s.size();
253 auto is_kanji = false;
255 if (s[0] == '~' || s[0] == '#') {
260 is_kanji = iskanji(s[endpos - 2]);
264 if (!is_kanji && (s[endpos - 1] == '~' || s[endpos - 1] == '#')) {
268 name << s.substr(offset, endpos);