1 #include "flavor/flavor-util.h"
2 #include "flavor/flag-inscriptions-table.h"
3 #include "object-enchant/object-ego.h"
4 #include "object-enchant/tr-types.h"
5 #include "object/object-flags.h"
6 #include "object/tval-types.h"
7 #include "perception/object-perception.h"
8 #include "sv-definition/sv-food-types.h"
9 #include "system/artifact-type-definition.h"
10 #include "system/baseitem-info.h"
11 #include "system/item-entity.h"
12 #include "util/bit-flags-calculator.h"
13 #include "util/enum-converter.h"
14 #include "util/quarks.h"
16 flavor_type *initialize_flavor_type(flavor_type *flavor_ptr, char *buf, ItemEntity *o_ptr, BIT_FLAGS mode)
18 flavor_ptr->buf = buf;
19 flavor_ptr->o_ptr = o_ptr;
20 flavor_ptr->mode = mode;
21 flavor_ptr->kindname = baseitems_info[o_ptr->bi_id].name.data();
22 flavor_ptr->basenm = flavor_ptr->kindname;
23 flavor_ptr->modstr = "";
24 flavor_ptr->aware = false;
25 flavor_ptr->known = false;
26 flavor_ptr->flavor = true;
33 flavor_ptr->k_ptr = &baseitems_info[o_ptr->bi_id];
34 flavor_ptr->flavor_k_ptr = &baseitems_info[flavor_ptr->k_ptr->flavor];
39 * @brief 対象文字配列に一文字だけをコピーする。
43 * Print a char "c" into a string "t", as if by sprintf(t, "%c", c),\n
44 * and return a pointer to the terminator (t + 1).\n
46 char *object_desc_chr(char *t, char c)
54 * @brief 対象文字配列に文字列をコピーする。
56 * @param s コピーしたい文字列ポインタ
59 * Print a string "s" into a string "t", as if by strcpy(t, s),
60 * and return a pointer to the terminator.
62 char *object_desc_str(char *t, concptr s)
73 * @brief 対象文字配列に符号なし整数値をコピーする。
77 * Print an unsigned number "n" into a string "t", actually by
78 * sprintf(t, "%u", n), and return a pointer to the terminator.
80 char *object_desc_num(char *t, uint n)
82 int ret = sprintf(t, "%u", n);
92 * @brief 対象文字配列に符号あり整数値をコピーする。
96 * Print an signed number "v" into a string "t", as if by
97 * sprintf(t, "%+d", n), and return a pointer to the terminator.
98 * Note that we always print a sign, either "+" or "-".
100 char *object_desc_int(char *t, int v)
112 for (p = 1; n >= p * 10; p = p * 10) {
127 * @brief オブジェクトフラグを追加する
128 * @param short_flavor フラグの短縮表現 (反魔法/アンチテレポの"["、耐性の"r"、耐混乱の"乱" 等)
129 * @param ptr 特性短縮表記を格納する文字列ポインタ
131 static void add_inscription(char **short_flavor, concptr str)
133 *short_flavor = object_desc_str(*short_flavor, str);
137 * @brief get_inscriptionのサブセットとしてオブジェクトの特性フラグを返す / Helper function for get_inscription()
138 * @param fi_vec 参照する特性表示記号テーブル
139 * @param flgs 対応するオブジェクトのフラグ文字列
140 * @param kanji TRUEならば漢字記述/FALSEならば英語記述
141 * @param ptr フラグ群を保管する文字列参照ポインタ
142 * @return フラグ群を保管する文字列参照ポインタ(ptrと同じ)
144 * Print an signed number "v" into a string "t", as if by
145 * sprintf(t, "%+d", n), and return a pointer to the terminator.
146 * Note that we always print a sign, either "+" or "-".
148 static char *inscribe_flags_aux(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs, bool kanji, char *ptr)
155 for (const auto &fi : fi_vec) {
156 if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
157 add_inscription(&ptr, _(kanji ? fi.japanese : fi.english, fi.english));
165 * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of has_flag for
167 * @param fi_vec 参照する特性表示記号テーブル
168 * @param flgs 対応するオブジェクトのフラグ文字列
169 * @return 1つでも該当の特性があったらTRUEを返す。
171 static bool has_flag_of(const std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs)
173 for (const auto &fi : fi_vec) {
174 if (flgs.has(fi.flag) && (!fi.except_flag.has_value() || flgs.has_not(fi.except_flag.value()))) {
183 * @brief オブジェクト名の特性短縮表記をまとめて提示する。
184 * @param short_flavor 特性短縮表記を格納する文字列ポインタ
185 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
186 * @param kanji TRUEならば漢字表記 / FALSEなら英語表記
187 * @param all TRUEならばベースアイテム上で明らかなフラグは省略する
190 char *get_ability_abbreviation(char *short_flavor, ItemEntity *o_ptr, bool kanji, bool all)
192 char *prev_ptr = short_flavor;
193 auto flgs = object_flags(o_ptr);
195 auto *k_ptr = &baseitems_info[o_ptr->bi_id];
196 flgs.reset(k_ptr->flags);
198 if (o_ptr->is_fixed_artifact()) {
199 const auto &a_ref = artifacts_info.at(o_ptr->fixed_artifact_idx);
200 flgs.reset(a_ref.flags);
203 if (o_ptr->is_ego()) {
204 auto *e_ptr = &egos_info[o_ptr->ego_idx];
205 flgs.reset(e_ptr->flags);
209 if (has_dark_flag(flgs)) {
210 if (flgs.has(TR_LITE_1)) {
211 flgs.reset(TR_LITE_1);
214 if (flgs.has(TR_LITE_2)) {
215 flgs.reset(TR_LITE_2);
218 if (flgs.has(TR_LITE_3)) {
219 flgs.reset(TR_LITE_3);
221 } else if (has_lite_flag(flgs)) {
223 if (flgs.has(TR_LITE_2)) {
224 flgs.reset(TR_LITE_2);
227 if (flgs.has(TR_LITE_3)) {
228 flgs.reset(TR_LITE_3);
232 if (has_flag_of(flag_insc_plus, flgs) && kanji) {
233 add_inscription(&short_flavor, "+");
236 short_flavor = inscribe_flags_aux(flag_insc_plus, flgs, kanji, short_flavor);
238 if (has_flag_of(flag_insc_immune, flgs)) {
239 if (!kanji && short_flavor != prev_ptr) {
240 add_inscription(&short_flavor, ";");
241 prev_ptr = short_flavor;
244 add_inscription(&short_flavor, "*");
247 short_flavor = inscribe_flags_aux(flag_insc_immune, flgs, kanji, short_flavor);
249 if (has_flag_of(flag_insc_vuln, flgs)) {
250 if (!kanji && short_flavor != prev_ptr) {
251 add_inscription(&short_flavor, ";");
252 prev_ptr = short_flavor;
255 add_inscription(&short_flavor, "v");
258 short_flavor = inscribe_flags_aux(flag_insc_vuln, flgs, kanji, short_flavor);
260 if (has_flag_of(flag_insc_resistance, flgs)) {
262 add_inscription(&short_flavor, "r");
263 } else if (short_flavor != prev_ptr) {
264 add_inscription(&short_flavor, ";");
265 prev_ptr = short_flavor;
269 short_flavor = inscribe_flags_aux(flag_insc_resistance, flgs, kanji, short_flavor);
271 if (has_flag_of(flag_insc_misc, flgs) && (short_flavor != prev_ptr)) {
272 add_inscription(&short_flavor, ";");
273 prev_ptr = short_flavor;
276 short_flavor = inscribe_flags_aux(flag_insc_misc, flgs, kanji, short_flavor);
278 if (has_flag_of(flag_insc_aura, flgs)) {
279 add_inscription(&short_flavor, "[");
282 short_flavor = inscribe_flags_aux(flag_insc_aura, flgs, kanji, short_flavor);
284 if (has_flag_of(flag_insc_brand, flgs)) {
285 add_inscription(&short_flavor, "|");
288 short_flavor = inscribe_flags_aux(flag_insc_brand, flgs, kanji, short_flavor);
290 if (has_flag_of(flag_insc_kill, flgs)) {
291 add_inscription(&short_flavor, "/X");
294 short_flavor = inscribe_flags_aux(flag_insc_kill, flgs, kanji, short_flavor);
296 if (has_flag_of(flag_insc_slay, flgs)) {
297 add_inscription(&short_flavor, "/");
300 short_flavor = inscribe_flags_aux(flag_insc_slay, flgs, kanji, short_flavor);
303 if (has_flag_of(flag_insc_esp1, flgs) || has_flag_of(flag_insc_esp2, flgs)) {
304 add_inscription(&short_flavor, "~");
307 short_flavor = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, short_flavor);
308 short_flavor = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, short_flavor);
310 if (has_flag_of(flag_insc_esp1, flgs)) {
311 add_inscription(&short_flavor, "~");
314 short_flavor = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, short_flavor);
316 if (has_flag_of(flag_insc_esp2, flgs)) {
317 add_inscription(&short_flavor, "~");
320 short_flavor = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, short_flavor);
323 if (has_flag_of(flag_insc_sust, flgs)) {
324 add_inscription(&short_flavor, "(");
327 short_flavor = inscribe_flags_aux(flag_insc_sust, flgs, kanji, short_flavor);
328 *short_flavor = '\0';
333 * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
334 * @param buff 特性短縮表記を格納する文字列ポインタ
335 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
337 void get_inscription(char *buff, ItemEntity *o_ptr)
339 concptr insc = quark_str(o_ptr->inscription);
341 if (!o_ptr->is_fully_known()) {
346 if (buff > ptr + MAX_INSCRIPTION - 1) {
350 if (iskanji(*insc)) {
362 for (; *insc; insc++) {
365 } else if ('%' == *insc) {
369 if (ptr >= buff + MAX_NLEN) {
374 if ('%' == insc[1]) {
382 if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3]) {
389 ptr = get_ability_abbreviation(ptr, o_ptr, kanji, all);
391 add_inscription(&ptr, " ");
403 * @brief 日本語の個数表示ルーチン
404 * @param t 保管先文字列ポインタ
405 * @param o_ptr 記述したいオブジェクトの構造体参照ポインタ
407 * cmd1.c で流用するために object_desc_japanese から移動した。
409 char *object_desc_count_japanese(char *t, ItemEntity *o_ptr)
411 t = object_desc_num(t, o_ptr->number);
412 switch (o_ptr->tval) {
413 case ItemKindType::BOLT:
414 case ItemKindType::ARROW:
415 case ItemKindType::POLEARM:
416 case ItemKindType::STAFF:
417 case ItemKindType::WAND:
418 case ItemKindType::ROD:
419 case ItemKindType::DIGGING: {
420 t = object_desc_str(t, "本");
423 case ItemKindType::SCROLL: {
424 t = object_desc_str(t, "巻");
427 case ItemKindType::POTION: {
428 t = object_desc_str(t, "服");
431 case ItemKindType::LIFE_BOOK:
432 case ItemKindType::SORCERY_BOOK:
433 case ItemKindType::NATURE_BOOK:
434 case ItemKindType::CHAOS_BOOK:
435 case ItemKindType::DEATH_BOOK:
436 case ItemKindType::TRUMP_BOOK:
437 case ItemKindType::ARCANE_BOOK:
438 case ItemKindType::CRAFT_BOOK:
439 case ItemKindType::DEMON_BOOK:
440 case ItemKindType::CRUSADE_BOOK:
441 case ItemKindType::MUSIC_BOOK:
442 case ItemKindType::HISSATSU_BOOK:
443 case ItemKindType::HEX_BOOK: {
444 t = object_desc_str(t, "冊");
447 case ItemKindType::SOFT_ARMOR:
448 case ItemKindType::HARD_ARMOR:
449 case ItemKindType::DRAG_ARMOR:
450 case ItemKindType::CLOAK: {
451 t = object_desc_str(t, "着");
454 case ItemKindType::SWORD:
455 case ItemKindType::HAFTED:
456 case ItemKindType::BOW: {
457 t = object_desc_str(t, "振");
460 case ItemKindType::BOOTS: {
461 t = object_desc_str(t, "足");
464 case ItemKindType::CARD: {
465 t = object_desc_str(t, "枚");
468 case ItemKindType::FOOD: {
469 if (o_ptr->sval == SV_FOOD_JERKY) {
470 t = object_desc_str(t, "切れ");
476 if (o_ptr->number < 10) {
477 t = object_desc_str(t, "つ");
479 t = object_desc_str(t, "個");
488 bool has_lite_flag(const TrFlags &flags)
490 return flags.has(TR_LITE_1) || flags.has(TR_LITE_2) || flags.has(TR_LITE_3);
493 bool has_dark_flag(const TrFlags &flags)
495 return flags.has(TR_LITE_M1) || flags.has(TR_LITE_M2) || flags.has(TR_LITE_M3);