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/string-processor.h"
13 static bool has_lite_flag(const TrFlags &flags)
15 return flags.has(TR_LITE_1) || flags.has(TR_LITE_2) || flags.has(TR_LITE_3);
18 static bool has_dark_flag(const TrFlags &flags)
20 return flags.has(TR_LITE_M1) || flags.has(TR_LITE_M2) || flags.has(TR_LITE_M3);
24 * @brief get_inscriptionのサブセットとしてアイテムの特性フラグを表す文字列を返す
25 * @param fi_vec 参照する特性表示記号テーブル
26 * @param flags 対応するアイテムの特性フラグ
27 * @param is_kanji trueならば漢字記述/falseならば英語記述
28 * @return アイテムの特性フラグを表す文字列
30 static std::string inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flags, [[maybe_unused]] bool is_kanji)
34 for (const auto &fi : fi_vec) {
35 if (flags.has(fi.flag) && (!fi.except_flag.has_value() || flags.has_not(fi.except_flag.value()))) {
36 const auto flag_str = _(is_kanji ? fi.japanese : fi.english, fi.english);
45 * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of has_flag for
47 * @param fi_vec 参照する特性表示記号テーブル
48 * @param flags 対応するオブジェクトのフラグ文字列
49 * @return 1つでも該当の特性があったらTRUEを返す。
51 static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flags)
53 for (const auto &fi : fi_vec) {
54 if (flags.has(fi.flag) && (!fi.except_flag.has_value() || flags.has_not(fi.except_flag.value()))) {
63 * @brief アイテムの特性短縮表記をまとめて提示する。
64 * @param item 特性短縮表記を得たいアイテムの参照
65 * @param is_kanji trueならば漢字表記 / falseなら英語表記
66 * @param all falseならばベースアイテム上で明らかなフラグは省略する
69 std::string get_ability_abbreviation(const ItemEntity &item, bool is_kanji, bool all)
71 auto flags = object_flags(&item);
73 const auto &baseitem = item.get_baseitem();
74 flags.reset(baseitem.flags);
76 if (item.is_fixed_artifact()) {
77 const auto &artifact = item.get_fixed_artifact();
78 flags.reset(artifact.flags);
82 const auto &ego = item.get_ego();
83 flags.reset(ego.flags);
87 if (has_dark_flag(flags)) {
88 if (flags.has(TR_LITE_1)) {
89 flags.reset(TR_LITE_1);
92 if (flags.has(TR_LITE_2)) {
93 flags.reset(TR_LITE_2);
96 if (flags.has(TR_LITE_3)) {
97 flags.reset(TR_LITE_3);
99 } else if (has_lite_flag(flags)) {
100 flags.set(TR_LITE_1);
101 if (flags.has(TR_LITE_2)) {
102 flags.reset(TR_LITE_2);
105 if (flags.has(TR_LITE_3)) {
106 flags.reset(TR_LITE_3);
110 std::stringstream ss;
111 auto prev_tellp = ss.tellp();
113 if (has_flag_of(flag_insc_plus, flags) && is_kanji) {
117 ss << inscribe_flags_aux(flag_insc_plus, flags, is_kanji);
119 if (has_flag_of(flag_insc_immune, flags)) {
120 if (!is_kanji && (ss.tellp() != prev_tellp)) {
122 prev_tellp = ss.tellp();
128 ss << inscribe_flags_aux(flag_insc_immune, flags, is_kanji);
130 if (has_flag_of(flag_insc_vuln, flags)) {
131 if (!is_kanji && (ss.tellp() != prev_tellp)) {
133 prev_tellp = ss.tellp();
139 ss << inscribe_flags_aux(flag_insc_vuln, flags, is_kanji);
141 if (has_flag_of(flag_insc_resistance, flags)) {
144 } else if (ss.tellp() != prev_tellp) {
146 prev_tellp = ss.tellp();
150 ss << inscribe_flags_aux(flag_insc_resistance, flags, is_kanji);
152 if (has_flag_of(flag_insc_misc, flags) && (ss.tellp() != prev_tellp)) {
154 prev_tellp = ss.tellp();
157 ss << inscribe_flags_aux(flag_insc_misc, flags, is_kanji);
159 if (has_flag_of(flag_insc_aura, flags)) {
163 ss << inscribe_flags_aux(flag_insc_aura, flags, is_kanji);
165 if (has_flag_of(flag_insc_brand, flags)) {
169 ss << inscribe_flags_aux(flag_insc_brand, flags, is_kanji);
171 if (has_flag_of(flag_insc_kill, flags)) {
175 ss << inscribe_flags_aux(flag_insc_kill, flags, is_kanji);
177 if (has_flag_of(flag_insc_slay, flags)) {
181 ss << inscribe_flags_aux(flag_insc_slay, flags, is_kanji);
184 if (has_flag_of(flag_insc_esp1, flags) || has_flag_of(flag_insc_esp2, flags)) {
188 ss << inscribe_flags_aux(flag_insc_esp1, flags, is_kanji)
189 << inscribe_flags_aux(flag_insc_esp2, flags, is_kanji);
191 if (has_flag_of(flag_insc_esp1, flags)) {
195 ss << inscribe_flags_aux(flag_insc_esp1, flags, is_kanji);
197 if (has_flag_of(flag_insc_esp2, flags)) {
201 ss << inscribe_flags_aux(flag_insc_esp2, flags, is_kanji);
204 if (has_flag_of(flag_insc_sust, flags)) {
208 ss << inscribe_flags_aux(flag_insc_sust, flags, is_kanji);
214 * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
215 * @param buff 特性短縮表記を格納する文字列ポインタ
216 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
218 std::string get_inscription(const ItemEntity &item)
220 if (!item.is_inscribed()) {
224 std::stringstream ss;
226 if (!item.is_fully_known()) {
227 for (std::string_view sv = item.inscription.value(); !sv.empty(); sv.remove_prefix(1)) {
228 if (sv.front() == '#') {
231 if (ss.tellp() > MAX_INSCRIPTION - 1) {
235 if (iskanji(sv.front())) {
246 for (std::string_view sv = item.inscription.value(); !sv.empty(); sv.remove_prefix(1)) {
247 switch (sv.front()) {
251 const auto start_pos = ss.tellp();
252 if (start_pos >= MAX_NLEN) {
256 auto is_kanji = false;
258 if ((sv.size() > 1) && ('%' == sv[1])) {
266 if (sv.substr(1, 3) == "all") {
271 ss << get_ability_abbreviation(item, is_kanji, all);
272 if (ss.tellp() == start_pos) {
288 * @brief アイテムにふさわしい助数詞をつけて数を記述する
289 * @param item 数を記述したいアイテムの参照
292 std::string describe_count_with_counter_suffix(const ItemEntity &item)
294 std::stringstream ss;
297 switch (item.bi_key.tval()) {
298 case ItemKindType::BOLT:
299 case ItemKindType::ARROW:
300 case ItemKindType::POLEARM:
301 case ItemKindType::STAFF:
302 case ItemKindType::WAND:
303 case ItemKindType::ROD:
304 case ItemKindType::DIGGING:
307 case ItemKindType::SCROLL:
310 case ItemKindType::POTION:
313 case ItemKindType::LIFE_BOOK:
314 case ItemKindType::SORCERY_BOOK:
315 case ItemKindType::NATURE_BOOK:
316 case ItemKindType::CHAOS_BOOK:
317 case ItemKindType::DEATH_BOOK:
318 case ItemKindType::TRUMP_BOOK:
319 case ItemKindType::ARCANE_BOOK:
320 case ItemKindType::CRAFT_BOOK:
321 case ItemKindType::DEMON_BOOK:
322 case ItemKindType::CRUSADE_BOOK:
323 case ItemKindType::MUSIC_BOOK:
324 case ItemKindType::HISSATSU_BOOK:
325 case ItemKindType::HEX_BOOK:
328 case ItemKindType::SOFT_ARMOR:
329 case ItemKindType::HARD_ARMOR:
330 case ItemKindType::DRAG_ARMOR:
331 case ItemKindType::CLOAK:
334 case ItemKindType::SWORD:
335 case ItemKindType::HAFTED:
336 case ItemKindType::BOW:
339 case ItemKindType::BOOTS:
343 case ItemKindType::CARD:
347 case ItemKindType::FOOD:
348 if (item.bi_key.sval().value() == SV_FOOD_JERKY) {
354 if (item.number < 10) {