1 #include "flavor/flavor-util.h"
2 #include "flavor/flag-inscriptions-table.h"
3 #include "object-enchant/tr-flags.h"
4 #include "object-enchant/tr-types.h"
5 #include "object/object-flags.h"
6 #include "object/tval-types.h"
7 #include "sv-definition/sv-food-types.h"
8 #include "system/artifact-type-definition.h"
9 #include "system/item-entity.h"
10 #include "util/quarks.h"
11 #include "util/string-processor.h"
14 static bool has_lite_flag(const TrFlags &flags)
16 return flags.has(TR_LITE_1) || flags.has(TR_LITE_2) || flags.has(TR_LITE_3);
19 static bool has_dark_flag(const TrFlags &flags)
21 return flags.has(TR_LITE_M1) || flags.has(TR_LITE_M2) || flags.has(TR_LITE_M3);
25 * @brief オブジェクトフラグを追加する
26 * @param short_flavor フラグの短縮表現 (反魔法/アンチテレポの"["、耐性の"r"、耐混乱の"乱" 等)
27 * @param ptr 特性短縮表記を格納する文字列ポインタ
29 * @todo バッファサイズが不明なのでとりあえず16バイト決め打ちで angband_strcpy を呼び出している。
30 * get_ability_abbrev のインターフェースを std::string を返すように変更するときに合わせて修正すること。
32 static void add_inscription(char **short_flavor, concptr str)
34 *short_flavor += angband_strcpy(*short_flavor, str, 16);
38 * @brief get_inscriptionのサブセットとしてアイテムの特性フラグを表す文字列を返す
39 * @param fi_vec 参照する特性表示記号テーブル
40 * @param flgs 対応するアイテムの特性フラグ
41 * @param is_kanji trueならば漢字記述/falseならば英語記述
42 * @return アイテムの特性フラグを表す文字列
44 static std::string inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs, [[maybe_unused]] bool is_kanji)
48 for (const auto &fi : fi_vec) {
49 if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
50 const auto flag_str = _(is_kanji ? fi.japanese : fi.english, fi.english);
59 * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of has_flag for
61 * @param fi_vec 参照する特性表示記号テーブル
62 * @param flgs 対応するオブジェクトのフラグ文字列
63 * @return 1つでも該当の特性があったらTRUEを返す。
65 static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs)
67 for (const auto &fi : fi_vec) {
68 if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
77 * @brief アイテムの特性短縮表記をまとめて提示する。
78 * @param item 特性短縮表記を得たいアイテムの参照
79 * @param is_kanji trueならば漢字表記 / falseなら英語表記
80 * @param all falseならばベースアイテム上で明らかなフラグは省略する
83 std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool all)
85 auto flgs = object_flags(&item);
87 const auto &baseitem = baseitems_info[item.bi_id];
88 flgs.reset(baseitem.flags);
90 if (item.is_fixed_artifact()) {
91 const auto &a_ref = artifacts_info.at(item.fixed_artifact_idx);
92 flgs.reset(a_ref.flags);
96 auto *e_ptr = &egos_info[item.ego_idx];
97 flgs.reset(e_ptr->flags);
101 if (has_dark_flag(flgs)) {
102 if (flgs.has(TR_LITE_1)) {
103 flgs.reset(TR_LITE_1);
106 if (flgs.has(TR_LITE_2)) {
107 flgs.reset(TR_LITE_2);
110 if (flgs.has(TR_LITE_3)) {
111 flgs.reset(TR_LITE_3);
113 } else if (has_lite_flag(flgs)) {
115 if (flgs.has(TR_LITE_2)) {
116 flgs.reset(TR_LITE_2);
119 if (flgs.has(TR_LITE_3)) {
120 flgs.reset(TR_LITE_3);
124 std::stringstream ss;
125 auto prev_tellp = ss.tellp();
127 if (has_flag_of(flag_insc_plus, flgs) && is_kanji) {
131 ss << inscribe_flags_aux(flag_insc_plus, flgs, is_kanji);
133 if (has_flag_of(flag_insc_immune, flgs)) {
134 if (!is_kanji && (ss.tellp() != prev_tellp)) {
136 prev_tellp = ss.tellp();
142 ss << inscribe_flags_aux(flag_insc_immune, flgs, is_kanji);
144 if (has_flag_of(flag_insc_vuln, flgs)) {
145 if (!is_kanji && (ss.tellp() != prev_tellp)) {
147 prev_tellp = ss.tellp();
153 ss << inscribe_flags_aux(flag_insc_vuln, flgs, is_kanji);
155 if (has_flag_of(flag_insc_resistance, flgs)) {
158 } else if (ss.tellp() != prev_tellp) {
160 prev_tellp = ss.tellp();
164 ss << inscribe_flags_aux(flag_insc_resistance, flgs, is_kanji);
166 if (has_flag_of(flag_insc_misc, flgs) && (ss.tellp() != prev_tellp)) {
168 prev_tellp = ss.tellp();
171 ss << inscribe_flags_aux(flag_insc_misc, flgs, is_kanji);
173 if (has_flag_of(flag_insc_aura, flgs)) {
177 ss << inscribe_flags_aux(flag_insc_aura, flgs, is_kanji);
179 if (has_flag_of(flag_insc_brand, flgs)) {
183 ss << inscribe_flags_aux(flag_insc_brand, flgs, is_kanji);
185 if (has_flag_of(flag_insc_kill, flgs)) {
189 ss << inscribe_flags_aux(flag_insc_kill, flgs, is_kanji);
191 if (has_flag_of(flag_insc_slay, flgs)) {
195 ss << inscribe_flags_aux(flag_insc_slay, flgs, is_kanji);
198 if (has_flag_of(flag_insc_esp1, flgs) || has_flag_of(flag_insc_esp2, flgs)) {
202 ss << inscribe_flags_aux(flag_insc_esp1, flgs, is_kanji)
203 << inscribe_flags_aux(flag_insc_esp2, flgs, is_kanji);
205 if (has_flag_of(flag_insc_esp1, flgs)) {
209 ss << inscribe_flags_aux(flag_insc_esp1, flgs, is_kanji);
211 if (has_flag_of(flag_insc_esp2, flgs)) {
215 ss << inscribe_flags_aux(flag_insc_esp2, flgs, is_kanji);
218 if (has_flag_of(flag_insc_sust, flgs)) {
222 ss << inscribe_flags_aux(flag_insc_sust, flgs, is_kanji);
228 * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
229 * @param buff 特性短縮表記を格納する文字列ポインタ
230 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
232 void get_inscription(char *buff, const ItemEntity *o_ptr)
234 concptr insc = quark_str(o_ptr->inscription);
236 if (!o_ptr->is_fully_known()) {
241 if (buff > ptr + MAX_INSCRIPTION - 1) {
245 if (iskanji(*insc)) {
257 for (; *insc; insc++) {
260 } else if ('%' == *insc) {
264 if (ptr >= buff + MAX_NLEN) {
269 if ('%' == insc[1]) {
277 if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3]) {
284 const auto ability_abbrev = get_ability_abbreviation(*o_ptr, kanji, all);
285 ptr += angband_strcpy(ptr, ability_abbrev.data(), ability_abbrev.size());
287 add_inscription(&ptr, " ");
299 * @brief アイテムにふさわしい助数詞をつけて数を記述する
300 * @param item 数を記述したいアイテムの参照
303 std::string describe_count_with_counter_suffix(const ItemEntity &item)
305 std::stringstream ss;
308 switch (item.bi_key.tval()) {
309 case ItemKindType::BOLT:
310 case ItemKindType::ARROW:
311 case ItemKindType::POLEARM:
312 case ItemKindType::STAFF:
313 case ItemKindType::WAND:
314 case ItemKindType::ROD:
315 case ItemKindType::DIGGING:
318 case ItemKindType::SCROLL:
321 case ItemKindType::POTION:
324 case ItemKindType::LIFE_BOOK:
325 case ItemKindType::SORCERY_BOOK:
326 case ItemKindType::NATURE_BOOK:
327 case ItemKindType::CHAOS_BOOK:
328 case ItemKindType::DEATH_BOOK:
329 case ItemKindType::TRUMP_BOOK:
330 case ItemKindType::ARCANE_BOOK:
331 case ItemKindType::CRAFT_BOOK:
332 case ItemKindType::DEMON_BOOK:
333 case ItemKindType::CRUSADE_BOOK:
334 case ItemKindType::MUSIC_BOOK:
335 case ItemKindType::HISSATSU_BOOK:
336 case ItemKindType::HEX_BOOK:
339 case ItemKindType::SOFT_ARMOR:
340 case ItemKindType::HARD_ARMOR:
341 case ItemKindType::DRAG_ARMOR:
342 case ItemKindType::CLOAK:
345 case ItemKindType::SWORD:
346 case ItemKindType::HAFTED:
347 case ItemKindType::BOW:
350 case ItemKindType::BOOTS:
354 case ItemKindType::CARD:
358 case ItemKindType::FOOD:
359 if (item.bi_key.sval().value() == SV_FOOD_JERKY) {
365 if (item.number < 10) {