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/object-kind.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/object-type-definition.h"
11 #include "util/bit-flags-calculator.h"
12 #include "util/enum-converter.h"
13 #include "util/quarks.h"
15 flavor_type *initialize_flavor_type(flavor_type *flavor_ptr, char *buf, ObjectType *o_ptr, BIT_FLAGS mode)
17 flavor_ptr->buf = buf;
18 flavor_ptr->o_ptr = o_ptr;
19 flavor_ptr->mode = mode;
20 flavor_ptr->kindname = k_info[o_ptr->k_idx].name.c_str();
21 flavor_ptr->basenm = flavor_ptr->kindname;
22 flavor_ptr->modstr = "";
23 flavor_ptr->aware = false;
24 flavor_ptr->known = false;
25 flavor_ptr->flavor = true;
26 flavor_ptr->show_weapon = false;
27 flavor_ptr->show_armour = false;
34 flavor_ptr->k_ptr = &k_info[o_ptr->k_idx];
35 flavor_ptr->flavor_k_ptr = &k_info[flavor_ptr->k_ptr->flavor];
40 * @brief 対象文字配列に一文字だけをコピーする。
44 * Print a char "c" into a string "t", as if by sprintf(t, "%c", c),\n
45 * and return a pointer to the terminator (t + 1).\n
47 char *object_desc_chr(char *t, char c)
55 * @brief 対象文字配列に文字列をコピーする。
57 * @param s コピーしたい文字列ポインタ
60 * Print a string "s" into a string "t", as if by strcpy(t, s),
61 * and return a pointer to the terminator.
63 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)
126 * @brief オブジェクトフラグを追加する
127 * @param short_flavor フラグの短縮表現 (反魔法/アンチテレポの"["、耐性の"r"、耐混乱の"乱" 等)
128 * @param ptr 特性短縮表記を格納する文字列ポインタ
130 static void add_inscription(char **short_flavor, concptr str) { *short_flavor = object_desc_str(*short_flavor, str); }
133 * @brief get_inscriptionのサブセットとしてオブジェクトの特性フラグを返す / Helper function for get_inscription()
134 * @param fi_vec 参照する特性表示記号テーブル
135 * @param flgs 対応するオブジェクトのフラグ文字列
136 * @param kanji TRUEならば漢字記述/FALSEならば英語記述
137 * @param ptr フラグ群を保管する文字列参照ポインタ
138 * @return フラグ群を保管する文字列参照ポインタ(ptrと同じ)
140 * Print an signed number "v" into a string "t", as if by
141 * sprintf(t, "%+d", n), and return a pointer to the terminator.
142 * Note that we always print a sign, either "+" or "-".
144 static char *inscribe_flags_aux(std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs, bool kanji, char *ptr)
151 for (flag_insc_table &fi : fi_vec)
152 if (flgs.has(fi.flag) && (fi.except_flag == -1 || flgs.has_not(i2enum<tr_type>(fi.except_flag))))
153 add_inscription(&ptr, _(kanji ? fi.japanese : fi.english, fi.english));
159 * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of has_flag for
161 * @param fi_vec 参照する特性表示記号テーブル
162 * @param flgs 対応するオブジェクトのフラグ文字列
163 * @return 1つでも該当の特性があったらTRUEを返す。
165 static bool has_flag_of(std::vector<flag_insc_table> &fi_vec, const TrFlags &flgs)
167 for (flag_insc_table &fi : fi_vec)
168 if (flgs.has(fi.flag) && (fi.except_flag == -1 || flgs.has_not(i2enum<tr_type>(fi.except_flag))))
175 * @brief オブジェクト名の特性短縮表記をまとめて提示する。
176 * @param short_flavor 特性短縮表記を格納する文字列ポインタ
177 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
178 * @param kanji TRUEならば漢字表記 / FALSEなら英語表記
179 * @param all TRUEならばベースアイテム上で明らかなフラグは省略する
182 char *get_ability_abbreviation(char *short_flavor, ObjectType *o_ptr, bool kanji, bool all)
184 char *prev_ptr = short_flavor;
185 auto flgs = object_flags(o_ptr);
187 auto *k_ptr = &k_info[o_ptr->k_idx];
188 flgs.reset(k_ptr->flags);
190 if (o_ptr->is_fixed_artifact()) {
191 auto *a_ptr = &a_info[o_ptr->fixed_artifact_idx];
192 flgs.reset(a_ptr->flags);
195 if (o_ptr->is_ego()) {
196 auto *e_ptr = &e_info[o_ptr->ego_idx];
197 flgs.reset(e_ptr->flags);
201 if (has_dark_flag(flgs)) {
202 if (flgs.has(TR_LITE_1))
203 flgs.reset(TR_LITE_1);
205 if (flgs.has(TR_LITE_2))
206 flgs.reset(TR_LITE_2);
208 if (flgs.has(TR_LITE_3))
209 flgs.reset(TR_LITE_3);
210 } else if (has_lite_flag(flgs)) {
212 if (flgs.has(TR_LITE_2))
213 flgs.reset(TR_LITE_2);
215 if (flgs.has(TR_LITE_3))
216 flgs.reset(TR_LITE_3);
219 if (has_flag_of(flag_insc_plus, flgs) && kanji)
220 add_inscription(&short_flavor, "+");
222 short_flavor = inscribe_flags_aux(flag_insc_plus, flgs, kanji, short_flavor);
224 if (has_flag_of(flag_insc_immune, flgs)) {
225 if (!kanji && short_flavor != prev_ptr) {
226 add_inscription(&short_flavor, ";");
227 prev_ptr = short_flavor;
230 add_inscription(&short_flavor, "*");
233 short_flavor = inscribe_flags_aux(flag_insc_immune, flgs, kanji, short_flavor);
235 if (has_flag_of(flag_insc_vuln, flgs)) {
236 if (!kanji && short_flavor != prev_ptr) {
237 add_inscription(&short_flavor, ";");
238 prev_ptr = short_flavor;
241 add_inscription(&short_flavor, "v");
244 short_flavor = inscribe_flags_aux(flag_insc_vuln, flgs, kanji, short_flavor);
246 if (has_flag_of(flag_insc_resistance, flgs)) {
248 add_inscription(&short_flavor, "r");
249 else if (short_flavor != prev_ptr) {
250 add_inscription(&short_flavor, ";");
251 prev_ptr = short_flavor;
255 short_flavor = inscribe_flags_aux(flag_insc_resistance, flgs, kanji, short_flavor);
257 if (has_flag_of(flag_insc_misc, flgs) && (short_flavor != prev_ptr)) {
258 add_inscription(&short_flavor, ";");
259 prev_ptr = short_flavor;
262 short_flavor = inscribe_flags_aux(flag_insc_misc, flgs, kanji, short_flavor);
264 if (has_flag_of(flag_insc_aura, flgs))
265 add_inscription(&short_flavor, "[");
267 short_flavor = inscribe_flags_aux(flag_insc_aura, flgs, kanji, short_flavor);
269 if (has_flag_of(flag_insc_brand, flgs))
270 add_inscription(&short_flavor, "|");
272 short_flavor = inscribe_flags_aux(flag_insc_brand, flgs, kanji, short_flavor);
274 if (has_flag_of(flag_insc_kill, flgs))
275 add_inscription(&short_flavor, "/X");
277 short_flavor = inscribe_flags_aux(flag_insc_kill, flgs, kanji, short_flavor);
279 if (has_flag_of(flag_insc_slay, flgs))
280 add_inscription(&short_flavor, "/");
282 short_flavor = inscribe_flags_aux(flag_insc_slay, flgs, kanji, short_flavor);
285 if (has_flag_of(flag_insc_esp1, flgs) || has_flag_of(flag_insc_esp2, flgs))
286 add_inscription(&short_flavor, "~");
288 short_flavor = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, short_flavor);
289 short_flavor = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, short_flavor);
291 if (has_flag_of(flag_insc_esp1, flgs))
292 add_inscription(&short_flavor, "~");
294 short_flavor = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, short_flavor);
296 if (has_flag_of(flag_insc_esp2, flgs))
297 add_inscription(&short_flavor, "~");
299 short_flavor = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, short_flavor);
302 if (has_flag_of(flag_insc_sust, flgs))
303 add_inscription(&short_flavor, "(");
305 short_flavor = inscribe_flags_aux(flag_insc_sust, flgs, kanji, short_flavor);
306 *short_flavor = '\0';
311 * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
312 * @param buff 特性短縮表記を格納する文字列ポインタ
313 * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
315 void get_inscription(char *buff, ObjectType *o_ptr)
317 concptr insc = quark_str(o_ptr->inscription);
319 if (!o_ptr->is_fully_known()) {
323 if (buff > ptr + MAX_INSCRIPTION - 1)
337 for (; *insc; insc++) {
340 else if ('%' == *insc) {
344 if (ptr >= buff + MAX_NLEN)
348 if ('%' == insc[1]) {
355 if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3]) {
361 ptr = get_ability_abbreviation(ptr, o_ptr, kanji, all);
363 add_inscription(&ptr, " ");
373 * @brief 日本語の個数表示ルーチン
374 * @param t 保管先文字列ポインタ
375 * @param o_ptr 記述したいオブジェクトの構造体参照ポインタ
377 * cmd1.c で流用するために object_desc_japanese から移動した。
379 char *object_desc_count_japanese(char *t, ObjectType *o_ptr)
381 t = object_desc_num(t, o_ptr->number);
382 switch (o_ptr->tval) {
383 case ItemKindType::BOLT:
384 case ItemKindType::ARROW:
385 case ItemKindType::POLEARM:
386 case ItemKindType::STAFF:
387 case ItemKindType::WAND:
388 case ItemKindType::ROD:
389 case ItemKindType::DIGGING: {
390 t = object_desc_str(t, "本");
393 case ItemKindType::SCROLL: {
394 t = object_desc_str(t, "巻");
397 case ItemKindType::POTION: {
398 t = object_desc_str(t, "服");
401 case ItemKindType::LIFE_BOOK:
402 case ItemKindType::SORCERY_BOOK:
403 case ItemKindType::NATURE_BOOK:
404 case ItemKindType::CHAOS_BOOK:
405 case ItemKindType::DEATH_BOOK:
406 case ItemKindType::TRUMP_BOOK:
407 case ItemKindType::ARCANE_BOOK:
408 case ItemKindType::CRAFT_BOOK:
409 case ItemKindType::DEMON_BOOK:
410 case ItemKindType::CRUSADE_BOOK:
411 case ItemKindType::MUSIC_BOOK:
412 case ItemKindType::HISSATSU_BOOK:
413 case ItemKindType::HEX_BOOK: {
414 t = object_desc_str(t, "冊");
417 case ItemKindType::SOFT_ARMOR:
418 case ItemKindType::HARD_ARMOR:
419 case ItemKindType::DRAG_ARMOR:
420 case ItemKindType::CLOAK: {
421 t = object_desc_str(t, "着");
424 case ItemKindType::SWORD:
425 case ItemKindType::HAFTED:
426 case ItemKindType::BOW: {
427 t = object_desc_str(t, "振");
430 case ItemKindType::BOOTS: {
431 t = object_desc_str(t, "足");
434 case ItemKindType::CARD: {
435 t = object_desc_str(t, "枚");
438 case ItemKindType::FOOD: {
439 if (o_ptr->sval == SV_FOOD_JERKY) {
440 t = object_desc_str(t, "切れ");
446 if (o_ptr->number < 10) {
447 t = object_desc_str(t, "つ");
449 t = object_desc_str(t, "個");
458 bool has_lite_flag(const TrFlags &flags)
460 return flags.has(TR_LITE_1) || flags.has(TR_LITE_2) || flags.has(TR_LITE_3);
463 bool has_dark_flag(const TrFlags &flags)
465 return flags.has(TR_LITE_M1) || flags.has(TR_LITE_M2) || flags.has(TR_LITE_M3);