OSDN Git Service

[Refactor] #37353 コメント整理。 / Refactor comments.
[hengband/hengband.git] / src / flavor.c
1 /*!
2  *  @file flavor.c
3  *  @brief オブジェクトの記述処理 / Mbject flavor code
4  *  @date 2014/01/03
5  *  @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7  *\n
8  * This software may be copied and distributed for educational, research,\n
9  * and not for profit purposes provided that this copyright and statement\n
10  * are included in all such copies.  Other copyrights may also apply.\n
11  */
12
13 #include "angband.h"
14 #include "player-status.h"
15
16 /*!
17  * @brief 最初から簡易な名称が明らかになるベースアイテムの判定。 /  Certain items, if aware, are known instantly 
18  * @param i ベースアイテムID
19  * @return 簡易名称を明らかにするならTRUEを返す。
20  * @details
21  * This function is used only by "flavor_init()"
22  */
23 static bool object_easy_know(int i)
24 {
25         object_kind *k_ptr = &k_info[i];
26
27         /* Analyze the "tval" */
28         switch (k_ptr->tval)
29         {
30                 /* Spellbooks */
31                 case TV_LIFE_BOOK:
32                 case TV_SORCERY_BOOK:
33                 case TV_NATURE_BOOK:
34                 case TV_CHAOS_BOOK:
35                 case TV_DEATH_BOOK:
36                 case TV_TRUMP_BOOK:
37                 case TV_ARCANE_BOOK:
38                 case TV_CRAFT_BOOK:
39                 case TV_DAEMON_BOOK:
40                 case TV_CRUSADE_BOOK:
41                 case TV_MUSIC_BOOK:
42                 case TV_HISSATSU_BOOK:
43                 case TV_HEX_BOOK:
44                 {
45                         return (TRUE);
46                 }
47
48                 /* Simple items */
49                 case TV_FLASK:
50                 case TV_JUNK:
51                 case TV_BOTTLE:
52                 case TV_SKELETON:
53                 case TV_SPIKE:
54                 case TV_WHISTLE:
55                 {
56                         return (TRUE);
57                 }
58
59                 /* All Food, Potions, Scrolls, Rods */
60                 case TV_FOOD:
61                 case TV_POTION:
62                 case TV_SCROLL:
63                 case TV_ROD:
64                 {
65                         return (TRUE);
66                 }
67         }
68
69         return (FALSE);
70 }
71
72 /*!
73  * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts.
74  * @param out_string 作成した名を保管する参照ポインタ
75  * @return なし
76  * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
77  * syllables 配列と elvish.txt を組み合わせる。\n
78  */
79 void get_table_name_aux(char *out_string)
80 {
81 #ifdef JP
82         char Syllable[80];
83         get_rnd_line("aname_j.txt", 1, Syllable);
84         strcpy(out_string, Syllable);
85         get_rnd_line("aname_j.txt", 2, Syllable);
86         strcat(out_string, Syllable);
87 #else
88 #define MAX_SYLLABLES 164       /* Used with scrolls (see below) */
89
90         static concptr syllables[MAX_SYLLABLES] = {
91                 "a", "ab", "ag", "aks", "ala", "an", "ankh", "app",
92                 "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
93                 "bie", "bin", "bit", "bjor", "blu", "bot", "bu",
94                 "byt", "comp", "con", "cos", "cre", "dalf", "dan",
95                 "den", "der", "doe", "dok", "eep", "el", "eng", "er", "ere", "erk",
96                 "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan",
97                 "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i",
98                 "ing", "ion", "ip", "ish", "it", "ite", "iv", "jo",
99                 "kho", "kli", "klis", "la", "lech", "man", "mar",
100                 "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
101                 "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o",
102                 "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet",
103                 "ple", "plu", "po", "pot", "prok", "re", "rea", "rhov",
104                 "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat",
105                 "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik",
106                 "sno", "so", "sol", "sri", "sta", "sun", "ta", "tab",
107                 "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
108                 "ulk", "um", "un", "uni", "ur", "val", "viv", "vly",
109                 "vom", "wah", "wed", "werg", "wex", "whon", "wun", "x",
110                 "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on",
111                 "foo", "ju", "xuxu"
112         };
113
114         int testcounter = randint1(3) + 1;
115
116         strcpy(out_string, "");
117
118         if (randint1(3) == 2)
119         {
120                 while (testcounter--)
121                         strcat(out_string, syllables[randint0(MAX_SYLLABLES)]);
122         }
123         else
124         {
125                 char Syllable[80];
126                 testcounter = randint1(2) + 1;
127                 while (testcounter--)
128                 {
129                         (void)get_rnd_line("elvish.txt", 0, Syllable);
130                         strcat(out_string, Syllable);
131                 }
132         }
133
134         out_string[0] = toupper(out_string[1]);
135
136         out_string[16] = '\0';
137 #endif
138 }
139
140 /*!
141  * @brief ランダムな名前をアーティファクト銘として整形する。 / Create a name from random parts with quotes.
142  * @param out_string 作成した名を保管する参照ポインタ
143  * @return なし
144  * @details get_table_name_aux()ほぼ完全に実装を依存している。
145  */
146 void get_table_name(char *out_string)
147 {
148         char buff[80];
149         get_table_name_aux(buff);
150         sprintf(out_string, _("『%s』", "'%s'"), buff);
151 }
152
153 /*!
154  * @brief ランダムなシンダリン銘を作成する / Make random Sindarin name
155  * @param out_string 作成した名を保管する参照ポインタ
156  * @return なし
157  * @details sname.txtが語幹の辞書となっている。
158  */
159 void get_table_sindarin_aux(char *out_string)
160 {
161         char Syllable[80];
162 #ifdef JP
163         char tmp[80];
164 #endif
165
166         get_rnd_line("sname.txt", 1, Syllable);
167 #ifdef JP
168         strcpy(tmp, Syllable);
169 #else
170         strcpy(out_string, Syllable);
171 #endif
172
173         get_rnd_line("sname.txt", 2, Syllable);
174 #ifdef JP
175         strcat(tmp, Syllable);
176         sindarin_to_kana(out_string, tmp);
177 #else
178         strcat(out_string, Syllable);
179 #endif
180 }
181
182 /*!
183  * @brief シンダリン銘をアーティファクト用に整形する。 / Make random Sindarin name with quotes
184  * @param out_string 作成した名を保管する参照ポインタ
185  * @return なし
186  * @details get_table_sindarin_aux()ほぼ完全に実装を依存している。
187  */
188 void get_table_sindarin(char *out_string)
189 {
190         char buff[80];
191         get_table_sindarin_aux(buff);
192         sprintf(out_string, _("『%s』", "'%s'"), buff);
193 }
194
195
196 /*!
197  * @brief ベースアイテムの未確定名を共通tval間でシャッフルする / Shuffle flavor indices of a group of objects with given tval
198  * @param tval シャッフルしたいtval
199  * @return なし
200  * @details 巻物、各種魔道具などに利用される。
201  */
202 static void shuffle_flavors(OBJECT_TYPE_VALUE tval)
203 {
204         KIND_OBJECT_IDX *k_idx_list;
205         KIND_OBJECT_IDX k_idx_list_num = 0;
206         KIND_OBJECT_IDX i;
207
208         /* Allocate an array for a list of k_idx */
209         C_MAKE(k_idx_list, max_k_idx, KIND_OBJECT_IDX);
210
211         /* Search objects with given tval for shuffle */
212         for (i = 0; i < max_k_idx; i++)
213         {
214                 object_kind *k_ptr = &k_info[i];
215
216                 /* Skip non-Rings */
217                 if (k_ptr->tval != tval) continue;
218
219                 /* Paranoia -- Skip objects without flavor */
220                 if (!k_ptr->flavor) continue;
221
222                 /* Skip objects with a fixed flavor name */
223                 if (have_flag(k_ptr->flags, TR_FIXED_FLAVOR)) continue;
224
225                 /* Remember k_idx */
226                 k_idx_list[k_idx_list_num] = i;
227
228                 /* Increase number of remembered indices */
229                 k_idx_list_num++;
230         }
231
232         /* Shuffle flavors */
233         for (i = 0; i < k_idx_list_num; i++)
234         {
235                 object_kind *k1_ptr = &k_info[k_idx_list[i]];
236                 object_kind *k2_ptr = &k_info[k_idx_list[randint0(k_idx_list_num)]];
237
238                 /* Swap flavors of this pair */
239                 s16b tmp = k1_ptr->flavor;
240                 k1_ptr->flavor = k2_ptr->flavor;
241                 k2_ptr->flavor = tmp;
242         }
243
244         /* Free an array for a list of k_idx */
245         C_KILL(k_idx_list, max_k_idx, s16b);
246 }
247
248 /*!
249  * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン / Prepare the "variable" part of the "k_info" array.
250  * @return なし
251  * @details
252  * Prepare the "variable" part of the "k_info" array.\n
253  *\n
254  * The "color"/"metal"/"type" of an item is its "flavor".\n
255  * For the most part, flavors are assigned randomly each game.\n
256  *\n
257  * Initialize descriptions for the "colored" objects, including:\n
258  * Rings, Amulets, Staffs, Wands, Rods, Food, Potions, Scrolls.\n
259  *\n
260  * The first 4 entries for potions are fixed (Water, Apple Juice,\n
261  * Slime Mold Juice, Unused Potion).\n
262  *\n
263  * Scroll titles are always between 6 and 14 letters long.  This is\n
264  * ensured because every title is composed of whole words, where every\n
265  * word is from 1 to 8 letters long (one or two syllables of 1 to 4\n
266  * letters each), and that no scroll is finished until it attempts to\n
267  * grow beyond 15 letters.  The first time this can happen is when the\n
268  * current title has 6 letters and the new word has 8 letters, which\n
269  * would result in a 6 letter scroll title.\n
270  *\n
271  * Duplicate titles are avoided by requiring that no two scrolls share\n
272  * the same first four letters (not the most efficient method, and not\n
273  * the least efficient method, but it will always work).\n
274  *\n
275  * Hack -- make sure everything stays the same for each saved game\n
276  * This is accomplished by the use of a saved "random seed", as in\n
277  * "town_gen()".  Since no other functions are called while the special\n
278  * seed is in effect, so this function is pretty "safe".\n
279  *\n
280  * Note that the "hacked seed" may provide an RNG with alternating parity!\n
281  */
282 void flavor_init(void)
283 {
284         KIND_OBJECT_IDX i;
285         u32b state_backup[4];
286
287         /* Hack -- Backup the RNG state */
288         Rand_state_backup(state_backup);
289
290         /* Hack -- Induce consistant flavors */
291         Rand_state_set(seed_flavor);
292
293
294         /* Initialize flavor index of each object by itself */
295         for (i = 0; i < max_k_idx; i++)
296         {
297                 object_kind *k_ptr = &k_info[i];
298
299                 /* Skip objects without flavor name */
300                 if (!k_ptr->flavor_name) continue;
301
302                 /*
303                  * Initialize flavor index to itself
304                  *  -> Shuffle it later
305                  */
306                 k_ptr->flavor = i;
307         }
308
309         /* Shuffle Rings */
310         shuffle_flavors(TV_RING);
311
312         /* Shuffle Amulets */
313         shuffle_flavors(TV_AMULET);
314
315         /* Shuffle Staves */
316         shuffle_flavors(TV_STAFF);
317
318         /* Shuffle Wands */
319         shuffle_flavors(TV_WAND);
320
321         /* Shuffle Rods */
322         shuffle_flavors(TV_ROD);
323
324         /* Shuffle Mushrooms */
325         shuffle_flavors(TV_FOOD);
326
327         /* Shuffle Potions */
328         shuffle_flavors(TV_POTION);
329
330         /* Shuffle Scrolls */
331         shuffle_flavors(TV_SCROLL);
332
333
334         /* Hack -- Restore the RNG state */
335         Rand_state_restore(state_backup);
336
337         /* Analyze every object */
338         for (i = 1; i < max_k_idx; i++)
339         {
340                 object_kind *k_ptr = &k_info[i];
341
342                 /* Skip "empty" objects */
343                 if (!k_ptr->name) continue;
344
345                 /* No flavor yields aware */
346                 if (!k_ptr->flavor) k_ptr->aware = TRUE;
347
348                 /* Check for "easily known" */
349                 k_ptr->easy_know = object_easy_know(i);
350         }
351 }
352
353
354 /*!
355  * @brief 対象文字配列に一文字だけをコピーする。
356  * @param t 保管先文字列ポインタ
357  * @param c 保管したい1文字
358  * @return なし
359  * @details
360  * Print a char "c" into a string "t", as if by sprintf(t, "%c", c),\n
361  * and return a pointer to the terminator (t + 1).\n
362  */
363 static char *object_desc_chr(char *t, char c)
364 {
365         /* Copy the char */
366         *t++ = c;
367
368         /* Terminate */
369         *t = '\0';
370         return (t);
371 }
372
373 /*!
374  * @brief 対象文字配列に文字列をコピーする。
375  * @param t 保管先文字列ポインタ
376  * @param s コピーしたい文字列ポインタ
377  * @return 保管先の末尾アドレス
378  * @details
379  * Print a string "s" into a string "t", as if by strcpy(t, s),
380  * and return a pointer to the terminator.
381  */
382 static char *object_desc_str(char *t, concptr s)
383 {
384         /* Copy the string */
385         while (*s) *t++ = *s++;
386
387         /* Terminate */
388         *t = '\0';
389         return (t);
390 }
391
392 /*!
393  * @brief 対象文字配列に符号なし整数値をコピーする。
394  * @param t 保管先文字列ポインタ
395  * @param n コピーしたい数値
396  * @return なし
397  * @details
398  * Print an unsigned number "n" into a string "t", as if by
399  * sprintf(t, "%u", n), and return a pointer to the terminator.
400  */
401 static char *object_desc_num(char *t, uint n)
402 {
403         uint p;
404
405         /* Find "size" of "n" */
406         for (p = 1; n >= p * 10; p = p * 10) /* loop */;
407
408         /* Dump each digit */
409         while (p >= 1)
410         {
411                 /* Dump the digit */
412                 *t++ = '0' + n / p;
413
414                 /* Remove the digit */
415                 n = n % p;
416
417                 /* Process next digit */
418                 p = p / 10;
419         }
420
421         /* Terminate */
422         *t = '\0';
423         return (t);
424 }
425
426
427
428
429 #ifdef JP
430 /*!
431  * @brief 日本語の個数表示ルーチン
432  * @param t 保管先文字列ポインタ
433  * @param o_ptr 記述したいオブジェクトの構造体参照ポインタ
434  * @return なし
435  * @details
436  * cmd1.c で流用するために object_desc_japanese から移動した。
437  */
438 char *object_desc_kosuu(char *t, object_type *o_ptr)
439 {
440     t = object_desc_num(t, o_ptr->number);
441
442     switch (o_ptr->tval)
443     {
444       case TV_BOLT:
445       case TV_ARROW:
446       case TV_POLEARM:
447       case TV_STAFF:
448       case TV_WAND:
449       case TV_ROD:
450       case TV_DIGGING:
451       {
452           t = object_desc_str(t, "本");
453           break;
454       }
455       case TV_SCROLL:
456       {
457           t = object_desc_str(t, "巻");
458           break;
459       }
460       case TV_POTION:
461       {
462           t = object_desc_str(t, "服");
463           break;
464       }
465       case  TV_LIFE_BOOK:
466       case  TV_SORCERY_BOOK:
467       case  TV_NATURE_BOOK:
468       case  TV_CHAOS_BOOK:
469       case  TV_DEATH_BOOK:
470       case  TV_TRUMP_BOOK:
471       case  TV_ARCANE_BOOK:
472       case  TV_CRAFT_BOOK:
473       case  TV_DAEMON_BOOK:
474       case  TV_CRUSADE_BOOK:
475       case  TV_MUSIC_BOOK:
476       case  TV_HISSATSU_BOOK:
477           case TV_HEX_BOOK:
478       {
479           t = object_desc_str(t, "冊");
480           break;
481       }
482       case TV_SOFT_ARMOR:
483       case TV_HARD_ARMOR:
484       case TV_DRAG_ARMOR:
485       case TV_CLOAK:
486       {
487           t = object_desc_str(t, "着");
488           break;
489       }
490       case TV_SWORD:
491       case TV_HAFTED:
492       case TV_BOW:
493       {
494           t = object_desc_str(t, "振");
495           break;
496       }
497       case TV_BOOTS:
498       {
499           t = object_desc_str(t, "足");
500           break;
501       }
502       case TV_CARD:
503       {
504           t = object_desc_str(t, "枚");
505           break;
506       }
507             /* 食べもの by ita */
508       case TV_FOOD:
509       {
510           if(o_ptr->sval == SV_FOOD_JERKY)
511           {
512               t = object_desc_str(t, "切れ");
513               break;
514           }
515       }
516       default:
517       {
518           if (o_ptr->number < 10)
519           {
520               t = object_desc_str(t, "つ");
521           }
522           else
523           {
524               t = object_desc_str(t, "個");
525           }
526           break;
527       }
528   }
529   return (t);                  
530 }
531 #endif
532
533 /*!
534  * @brief 対象文字配列に符号あり整数値をコピーする。
535  * @param t 保管先文字列ポインタ
536  * @param v コピーしたい数値
537  * @return なし
538  * @details
539  * Print an signed number "v" into a string "t", as if by
540  * sprintf(t, "%+d", n), and return a pointer to the terminator.
541  * Note that we always print a sign, either "+" or "-".
542  */
543 static char *object_desc_int(char *t, sint v)
544 {
545         uint p, n;
546
547         /* Negative */
548         if (v < 0)
549         {
550                 /* Take the absolute value */
551                 n = 0 - v;
552
553                 /* Use a "minus" sign */
554                 *t++ = '-';
555         }
556
557         /* Positive (or zero) */
558         else
559         {
560                 /* Use the actual number */
561                 n = v;
562
563                 /* Use a "plus" sign */
564                 *t++ = '+';
565         }
566
567         /* Find "size" of "n" */
568         for (p = 1; n >= p * 10; p = p * 10) /* loop */;
569
570         /* Dump each digit */
571         while (p >= 1)
572         {
573                 /* Dump the digit */
574                 *t++ = '0' + n / p;
575
576                 /* Remove the digit */
577                 n = n % p;
578
579                 /* Process next digit */
580                 p = p / 10;
581         }
582
583         /* Terminate */
584         *t = '\0';
585         return (t);
586 }
587
588
589 /*!
590  * オブジェクトの特性表示記号テーブルの構造体 / Structs and tables for Auto Inscription for flags
591  */
592 typedef struct flag_insc_table
593 {
594 #ifdef JP
595         concptr japanese;
596 #endif
597         concptr english;
598         int flag;
599         int except_flag;
600 } flag_insc_table;
601
602 #ifdef JP
603 /*! オブジェクトの特性表示記号テーブルの定義(pval要素) */
604 static flag_insc_table flag_insc_plus[] =
605 {
606         { "攻", "At", TR_BLOWS, -1 },
607         { "速", "Sp", TR_SPEED, -1 },
608         { "腕", "St", TR_STR, -1 },
609         { "知", "In", TR_INT, -1 },
610         { "賢", "Wi", TR_WIS, -1 },
611         { "器", "Dx", TR_DEX, -1 },
612         { "耐", "Cn", TR_CON, -1 },
613         { "魅", "Ch", TR_CHR, -1 },
614         { "道", "Md", TR_MAGIC_MASTERY, -1 },
615         { "隠", "Sl", TR_STEALTH, -1 },
616         { "探", "Sr", TR_SEARCH, -1 },
617         { "赤", "If", TR_INFRA, -1 },
618         { "掘", "Dg", TR_TUNNEL, -1 },
619         { NULL, NULL, 0, -1 }
620 };
621
622 /*! オブジェクトの特性表示記号テーブルの定義(免疫) */
623 static flag_insc_table flag_insc_immune[] =
624 {
625         { "酸", "Ac", TR_IM_ACID, -1 },
626         { "電", "El", TR_IM_ELEC, -1 },
627         { "火", "Fi", TR_IM_FIRE, -1 },
628         { "冷", "Co", TR_IM_COLD, -1 },
629         { NULL, NULL, 0, -1 }
630 };
631
632 /*! オブジェクトの特性表示記号テーブルの定義(耐性) */
633 static flag_insc_table flag_insc_resistance[] =
634 {
635         { "酸", "Ac", TR_RES_ACID, TR_IM_ACID },
636         { "電", "El", TR_RES_ELEC, TR_IM_ELEC },
637         { "火", "Fi", TR_RES_FIRE, TR_IM_FIRE },
638         { "冷", "Co", TR_RES_COLD, TR_IM_COLD },
639         { "毒", "Po", TR_RES_POIS, -1 },
640         { "閃", "Li", TR_RES_LITE, -1 },
641         { "暗", "Dk", TR_RES_DARK, -1 },
642         { "破", "Sh", TR_RES_SHARDS, -1 },
643         { "盲", "Bl", TR_RES_BLIND, -1 },
644         { "乱", "Cf", TR_RES_CONF, -1 },
645         { "轟", "So", TR_RES_SOUND, -1 },
646         { "獄", "Nt", TR_RES_NETHER, -1 },
647         { "因", "Nx", TR_RES_NEXUS, -1 },
648         { "沌", "Ca", TR_RES_CHAOS, -1 },
649         { "劣", "Di", TR_RES_DISEN, -1 },
650         { "恐", "Fe", TR_RES_FEAR, -1 },
651         { NULL, NULL, 0, -1 }
652 };
653
654 /*! オブジェクトの特性表示記号テーブルの定義(その他特性) */
655 static flag_insc_table flag_insc_misc[] =
656 {
657         { "易", "Es", TR_EASY_SPELL, -1 },
658         { "減", "Dm", TR_DEC_MANA, -1 },
659         { "投", "Th", TR_THROW, -1 },
660         { "反", "Rf", TR_REFLECT, -1 },
661         { "麻", "Fa", TR_FREE_ACT, -1 },
662         { "視", "Si", TR_SEE_INVIS, -1 },
663         { "経", "Hl", TR_HOLD_EXP, -1 },
664         { "遅", "Sd", TR_SLOW_DIGEST, -1 },
665         { "活", "Rg", TR_REGEN, -1 },
666         { "浮", "Lv", TR_LEVITATION, -1 },
667         { "明", "Lu", TR_LITE_1, -1 },
668         { "明", "Lu", TR_LITE_2, -1 },
669         { "明", "Lu", TR_LITE_3, -1 },
670         { "闇", "Dl", TR_LITE_M1, -1 },
671         { "闇", "Dl", TR_LITE_M2, -1 },
672         { "闇", "Dl", TR_LITE_M3, -1 },
673         { "警", "Wr", TR_WARNING, -1 },
674         { "倍", "Xm", TR_XTRA_MIGHT, -1 },
675         { "射", "Xs", TR_XTRA_SHOTS, -1 },
676         { "瞬", "Te", TR_TELEPORT, -1 },
677         { "怒", "Ag", TR_AGGRAVATE, -1 },
678         { "祝", "Bs", TR_BLESSED, -1 },
679         { "忌", "Ty", TR_TY_CURSE, -1 },
680         { "呪", "C-", TR_ADD_L_CURSE, -1 },
681         { "詛", "C+", TR_ADD_H_CURSE, -1 },
682         { NULL, NULL, 0, -1 }
683 };
684
685 /*! オブジェクトの特性表示記号テーブルの定義(オーラ) */
686 static flag_insc_table flag_insc_aura[] =
687 {
688         { "炎", "F", TR_SH_FIRE, -1 },
689         { "電", "E", TR_SH_ELEC, -1 },
690         { "冷", "C", TR_SH_COLD, -1 },
691         { "魔", "M", TR_NO_MAGIC, -1 },
692         { "瞬", "T", TR_NO_TELE, -1 },
693         { NULL, NULL, 0, -1 }
694 };
695
696 /*! オブジェクトの特性表示記号テーブルの定義(属性スレイ) */
697 static flag_insc_table flag_insc_brand[] =
698 {
699         { "酸", "A", TR_BRAND_ACID, -1 },
700         { "電", "E", TR_BRAND_ELEC, -1 },
701         { "焼", "F", TR_BRAND_FIRE, -1 },
702         { "凍", "Co", TR_BRAND_COLD, -1 },
703         { "毒", "P", TR_BRAND_POIS, -1 },
704         { "沌", "Ca", TR_CHAOTIC, -1 },
705         { "吸", "V", TR_VAMPIRIC, -1 },
706         { "震", "Q", TR_IMPACT, -1 },
707         { "切", "S", TR_VORPAL, -1 },
708         { "理", "M", TR_FORCE_WEAPON, -1 },
709         { NULL, NULL, 0, -1 }
710 };
711
712 /*! オブジェクトの特性表示記号テーブルの定義(種族スレイ) */
713 static flag_insc_table flag_insc_kill[] =
714 {
715         { "邪", "*", TR_KILL_EVIL, -1 },
716         { "人", "p", TR_KILL_HUMAN, -1 },
717         { "龍", "D", TR_KILL_DRAGON, -1 },
718         { "オ", "o", TR_KILL_ORC, -1 },
719         { "ト", "T", TR_KILL_TROLL, -1 },
720         { "巨", "P", TR_KILL_GIANT, -1 },
721         { "デ", "U", TR_KILL_DEMON, -1 },
722         { "死", "L", TR_KILL_UNDEAD, -1 },
723         { "動", "Z", TR_KILL_ANIMAL, -1 },
724         { NULL, NULL, 0, -1 }
725 };
726
727 /*! オブジェクトの特性表示記号テーブルの定義(種族*スレイ*) */
728 static flag_insc_table flag_insc_slay[] =
729 {
730         { "邪", "*", TR_SLAY_EVIL, TR_KILL_EVIL },
731         { "人", "p", TR_SLAY_HUMAN, TR_KILL_HUMAN },
732         { "竜", "D", TR_SLAY_DRAGON, TR_KILL_DRAGON },
733         { "オ", "o", TR_SLAY_ORC, TR_KILL_ORC },
734         { "ト", "T", TR_SLAY_TROLL, TR_KILL_TROLL },
735         { "巨", "P", TR_SLAY_GIANT, TR_KILL_GIANT },
736         { "デ", "U", TR_SLAY_DEMON, TR_KILL_DEMON },
737         { "死", "L", TR_SLAY_UNDEAD, TR_KILL_UNDEAD },
738         { "動", "Z", TR_SLAY_ANIMAL, TR_KILL_ANIMAL },
739         { NULL, NULL, 0, -1 }
740 };
741
742 /*! オブジェクトの特性表示記号テーブルの定義(ESP1) */
743 static flag_insc_table flag_insc_esp1[] =
744 {
745         { "感", "Tele", TR_TELEPATHY, -1 },
746         { "邪", "Evil", TR_ESP_EVIL, -1 },
747         { "善", "Good", TR_ESP_GOOD, -1 },
748         { "無", "Nolv", TR_ESP_NONLIVING, -1 },
749         { "個", "Uniq", TR_ESP_UNIQUE, -1 },
750         { NULL, NULL, 0, -1 }
751 };
752
753 /*! オブジェクトの特性表示記号テーブルの定義(ESP2) */
754 static flag_insc_table flag_insc_esp2[] =
755 {
756         { "人", "p", TR_ESP_HUMAN, -1 },
757         { "竜", "D", TR_ESP_DRAGON, -1 },
758         { "オ", "o", TR_ESP_ORC, -1 },
759         { "ト", "T", TR_ESP_TROLL, -1 },
760         { "巨", "P", TR_ESP_GIANT, -1 },
761         { "デ", "U", TR_ESP_DEMON, -1 },
762         { "死", "L", TR_ESP_UNDEAD, -1 },
763         { "動", "Z", TR_ESP_ANIMAL, -1 },
764         { NULL, NULL, 0, -1 }
765 };
766
767 /*! オブジェクトの特性表示記号テーブルの定義(能力維持) */
768 static flag_insc_table flag_insc_sust[] =
769 {
770         { "腕", "St", TR_SUST_STR, -1 },
771         { "知", "In", TR_SUST_INT, -1 },
772         { "賢", "Wi", TR_SUST_WIS, -1 },
773         { "器", "Dx", TR_SUST_DEX, -1 },
774         { "耐", "Cn", TR_SUST_CON, -1 },
775         { "魅", "Ch", TR_SUST_CHR, -1 },
776         { NULL, NULL, 0, -1 }
777 };
778
779 #else
780 static flag_insc_table flag_insc_plus[] =
781 {
782         { "At", TR_BLOWS, -1 },
783         { "Sp", TR_SPEED, -1 },
784         { "St", TR_STR, -1 },
785         { "In", TR_INT, -1 },
786         { "Wi", TR_WIS, -1 },
787         { "Dx", TR_DEX, -1 },
788         { "Cn", TR_CON, -1 },
789         { "Ch", TR_CHR, -1 },
790         { "Md", TR_MAGIC_MASTERY, -1 },
791         { "Sl", TR_STEALTH, -1 },
792         { "Sr", TR_SEARCH, -1 },
793         { "If", TR_INFRA, -1 },
794         { "Dg", TR_TUNNEL, -1 },
795         { NULL, 0, -1 }
796 };
797
798 static flag_insc_table flag_insc_immune[] =
799 {
800         { "Ac", TR_IM_ACID, -1 },
801         { "El", TR_IM_ELEC, -1 },
802         { "Fi", TR_IM_FIRE, -1 },
803         { "Co", TR_IM_COLD, -1 },
804         { NULL, 0, -1 }
805 };
806
807 static flag_insc_table flag_insc_resistance[] =
808 {
809         { "Ac", TR_RES_ACID, TR_IM_ACID },
810         { "El", TR_RES_ELEC, TR_IM_ELEC },
811         { "Fi", TR_RES_FIRE, TR_IM_FIRE },
812         { "Co", TR_RES_COLD, TR_IM_COLD },
813         { "Po", TR_RES_POIS, -1 },
814         { "Li", TR_RES_LITE, -1 },
815         { "Dk", TR_RES_DARK, -1 },
816         { "Sh", TR_RES_SHARDS, -1 },
817         { "Bl", TR_RES_BLIND, -1 },
818         { "Cf", TR_RES_CONF, -1 },
819         { "So", TR_RES_SOUND, -1 },
820         { "Nt", TR_RES_NETHER, -1 },
821         { "Nx", TR_RES_NEXUS, -1 },
822         { "Ca", TR_RES_CHAOS, -1 },
823         { "Di", TR_RES_DISEN, -1 },
824         { "Fe", TR_RES_FEAR, -1 },
825         { NULL, 0, -1 }
826 };
827
828 static flag_insc_table flag_insc_misc[] =
829 {
830         { "Es", TR_EASY_SPELL, -1 },
831         { "Dm", TR_DEC_MANA, -1 },
832         { "Th", TR_THROW, -1 },
833         { "Rf", TR_REFLECT, -1 },
834         { "Fa", TR_FREE_ACT, -1 },
835         { "Si", TR_SEE_INVIS, -1 },
836         { "Hl", TR_HOLD_EXP, -1 },
837         { "Sd", TR_SLOW_DIGEST, -1 },
838         { "Rg", TR_REGEN, -1 },
839         { "Lv", TR_LEVITATION, -1 },
840         { "Lu", TR_LITE_1, -1 },
841         { "Lu", TR_LITE_2, -1 },
842         { "Lu", TR_LITE_3, -1 },
843         { "Dl", TR_LITE_M1, -1 },
844         { "Dl", TR_LITE_M2, -1 },
845         { "Dl", TR_LITE_M3, -1 },
846         { "Wr", TR_WARNING, -1 },
847         { "Xm", TR_XTRA_MIGHT, -1 },
848         { "Xs", TR_XTRA_SHOTS, -1 },
849         { "Te", TR_TELEPORT, -1 },
850         { "Ag", TR_AGGRAVATE, -1 },
851         { "Bs", TR_BLESSED, -1 },
852         { "Ty", TR_TY_CURSE, -1 },
853         { "C-", TR_ADD_L_CURSE, -1 },
854         { "C+", TR_ADD_H_CURSE, -1 },
855         { NULL, 0, -1 }
856 };
857
858 static flag_insc_table flag_insc_aura[] =
859 {
860         { "F", TR_SH_FIRE, -1 },
861         { "E", TR_SH_ELEC, -1 },
862         { "C", TR_SH_COLD, -1 },
863         { "M", TR_NO_MAGIC, -1 },
864         { "T", TR_NO_TELE, -1 },
865         { NULL, 0, -1 }
866 };
867
868 static flag_insc_table flag_insc_brand[] =
869 {
870         { "A", TR_BRAND_ACID, -1 },
871         { "E", TR_BRAND_ELEC, -1 },
872         { "F", TR_BRAND_FIRE, -1 },
873         { "Co", TR_BRAND_COLD, -1 },
874         { "P", TR_BRAND_POIS, -1 },
875         { "Ca", TR_CHAOTIC, -1 },
876         { "V", TR_VAMPIRIC, -1 },
877         { "Q", TR_IMPACT, -1 },
878         { "S", TR_VORPAL, -1 },
879         { "M", TR_FORCE_WEAPON, -1 },
880         { NULL, 0, -1 }
881 };
882
883 static flag_insc_table flag_insc_kill[] =
884 {
885         { "*", TR_KILL_EVIL, -1 },
886         { "p", TR_KILL_HUMAN, -1 },
887         { "D", TR_KILL_DRAGON, -1 },
888         { "o", TR_KILL_ORC, -1 },
889         { "T", TR_KILL_TROLL, -1 },
890         { "P", TR_KILL_GIANT, -1 },
891         { "U", TR_KILL_DEMON, -1 },
892         { "L", TR_KILL_UNDEAD, -1 },
893         { "Z", TR_KILL_ANIMAL, -1 },
894         { NULL, 0, -1 }
895 };
896
897 static flag_insc_table flag_insc_slay[] =
898 {
899         { "*", TR_SLAY_EVIL, TR_KILL_EVIL },
900         { "p", TR_SLAY_HUMAN, TR_KILL_HUMAN },
901         { "D", TR_SLAY_DRAGON, TR_KILL_DRAGON },
902         { "o", TR_SLAY_ORC, TR_KILL_ORC },
903         { "T", TR_SLAY_TROLL, TR_KILL_TROLL },
904         { "P", TR_SLAY_GIANT, TR_KILL_GIANT },
905         { "U", TR_SLAY_DEMON, TR_KILL_DEMON },
906         { "L", TR_SLAY_UNDEAD, TR_KILL_UNDEAD },
907         { "Z", TR_SLAY_ANIMAL, TR_KILL_ANIMAL },
908         { NULL, 0, -1 }
909 };
910
911 static flag_insc_table flag_insc_esp1[] =
912 {
913         { "Tele", TR_TELEPATHY, -1 },
914         { "Evil", TR_ESP_EVIL, -1 },
915         { "Good", TR_ESP_GOOD, -1 },
916         { "Nolv", TR_ESP_NONLIVING, -1 },
917         { "Uniq", TR_ESP_UNIQUE, -1 },
918         { NULL, 0, -1 }
919 };
920
921 static flag_insc_table flag_insc_esp2[] =
922 {
923         { "p", TR_ESP_HUMAN, -1 },
924         { "D", TR_ESP_DRAGON, -1 },
925         { "o", TR_ESP_ORC, -1 },
926         { "T", TR_ESP_TROLL, -1 },
927         { "P", TR_ESP_GIANT, -1 },
928         { "U", TR_ESP_DEMON, -1 },
929         { "L", TR_ESP_UNDEAD, -1 },
930         { "Z", TR_ESP_ANIMAL, -1 },
931         { NULL, 0, -1 }
932 };
933
934 static flag_insc_table flag_insc_sust[] =
935 {
936         { "St", TR_SUST_STR, -1 },
937         { "In", TR_SUST_INT, -1 },
938         { "Wi", TR_SUST_WIS, -1 },
939         { "Dx", TR_SUST_DEX, -1 },
940         { "Cn", TR_SUST_CON, -1 },
941         { "Ch", TR_SUST_CHR, -1 },
942         { NULL, 0, -1 }
943 };
944 #endif
945
946 /* オブジェクトフラグを追加するための簡易なマクロ / Simple macro for get_inscription() */
947 #define ADD_INSC(STR) (void)(ptr = object_desc_str(ptr, (STR)))
948
949 /*!
950  * @brief get_inscriptionのサブセットとしてオブジェクトの特性フラグを返す / Helper function for get_inscription()
951  * @param fi_ptr 参照する特性表示記号テーブル
952  * @param flgs 対応するオブジェクトのフラグ文字列
953  * @param kanji TRUEならば漢字記述/FALSEならば英語記述
954  * @param ptr フラグ群を保管する文字列参照ポインタ
955  * @return フラグ群を保管する文字列参照ポインタ(ptrと同じ)
956  * @details
957  * Print an signed number "v" into a string "t", as if by
958  * sprintf(t, "%+d", n), and return a pointer to the terminator.
959  * Note that we always print a sign, either "+" or "-".
960  */
961 static char *inscribe_flags_aux(flag_insc_table *fi_ptr, BIT_FLAGS flgs[TR_FLAG_SIZE], bool kanji, char *ptr)
962 {
963 #ifndef JP
964         (void)kanji;
965 #endif
966
967         while (fi_ptr->english)
968         {
969                 if (have_flag(flgs, fi_ptr->flag) &&
970                     (fi_ptr->except_flag == -1 || !have_flag(flgs, fi_ptr->except_flag)))
971 #ifdef JP
972                         ADD_INSC(kanji ? fi_ptr->japanese : fi_ptr->english);
973 #else
974                         ADD_INSC(fi_ptr->english);
975 #endif
976                 fi_ptr++;
977         }
978
979         return ptr;
980 }
981
982
983 /*!
984  * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of have_flag for auto-inscription
985  * @param fi_ptr 参照する特性表示記号テーブル
986  * @param flgs 対応するオブジェクトのフラグ文字列
987  * @return 1つでも該当の特性があったらTRUEを返す。
988  */
989 static bool have_flag_of(flag_insc_table *fi_ptr, BIT_FLAGS flgs[TR_FLAG_SIZE])
990 {
991         while (fi_ptr->english)
992         {
993                 if (have_flag(flgs, fi_ptr->flag) &&
994                    (fi_ptr->except_flag == -1 || !have_flag(flgs, fi_ptr->except_flag)))
995                         return (TRUE);
996                 fi_ptr++;
997         }
998
999         return (FALSE);
1000 }
1001
1002 /*!
1003  * @brief オブジェクト名の特性短縮表記をまとめて提示する。
1004  * @param ptr 特性短縮表記を格納する文字列ポインタ
1005  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1006  * @param kanji TRUEならば漢字表記 / FALSEなら英語表記
1007  * @param all TRUEならばベースアイテム上で明らかなフラグは省略する
1008  * @return ptrと同じアドレス
1009  */
1010 static char *get_ability_abbreviation(char *ptr, object_type *o_ptr, bool kanji, bool all)
1011 {
1012         char *prev_ptr = ptr;
1013         BIT_FLAGS flgs[TR_FLAG_SIZE];
1014         object_flags(o_ptr, flgs);
1015
1016         /* Remove obvious flags */
1017         if (!all)
1018         {
1019                 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1020                 int j;
1021                                 
1022                 /* Base object */
1023                 for (j = 0; j < TR_FLAG_SIZE; j++)
1024                         flgs[j] &= ~k_ptr->flags[j];
1025
1026                 if (object_is_fixed_artifact(o_ptr))
1027                 {
1028                         artifact_type *a_ptr = &a_info[o_ptr->name1];
1029                                         
1030                         for (j = 0; j < TR_FLAG_SIZE; j++)
1031                                 flgs[j] &= ~a_ptr->flags[j];
1032                 }
1033
1034                 if (object_is_ego(o_ptr))
1035                 {
1036                         ego_item_type *e_ptr = &e_info[o_ptr->name2];
1037                                         
1038                         for (j = 0; j < TR_FLAG_SIZE; j++)
1039                                 flgs[j] &= ~e_ptr->flags[j];
1040                 }
1041         }
1042
1043         /* Remove lite flags when this is a dark lite object */
1044         if (have_dark_flag(flgs))
1045         {
1046                 if (have_flag(flgs, TR_LITE_1)) remove_flag(flgs, TR_LITE_1);
1047                 if (have_flag(flgs, TR_LITE_2)) remove_flag(flgs, TR_LITE_2);
1048                 if (have_flag(flgs, TR_LITE_3)) remove_flag(flgs, TR_LITE_3);
1049         }
1050         else if (have_lite_flag(flgs))
1051         {
1052                 add_flag(flgs, TR_LITE_1);
1053                 if (have_flag(flgs, TR_LITE_2)) remove_flag(flgs, TR_LITE_2);
1054                 if (have_flag(flgs, TR_LITE_3)) remove_flag(flgs, TR_LITE_3);
1055         }
1056
1057         /* Plusses */
1058         if (have_flag_of(flag_insc_plus, flgs))
1059         {
1060                 if (kanji)
1061                         ADD_INSC("+");
1062         }
1063         ptr = inscribe_flags_aux(flag_insc_plus, flgs, kanji, ptr);
1064
1065         /* Immunity */
1066         if (have_flag_of(flag_insc_immune, flgs))
1067         {
1068                 if (!kanji && ptr != prev_ptr)
1069                 {
1070                         ADD_INSC(";");
1071                         prev_ptr = ptr;
1072                 }
1073                 ADD_INSC("*");
1074         }
1075         ptr = inscribe_flags_aux(flag_insc_immune, flgs, kanji, ptr);
1076
1077         /* Resistance */
1078         if (have_flag_of(flag_insc_resistance, flgs))
1079         {
1080                 if (kanji)
1081                         ADD_INSC("r");
1082                 else if (ptr != prev_ptr)
1083                 {
1084                         ADD_INSC(";");
1085                         prev_ptr = ptr;
1086                 }
1087         }
1088         ptr = inscribe_flags_aux(flag_insc_resistance, flgs, kanji, ptr);
1089
1090         /* Misc Ability */
1091         if (have_flag_of(flag_insc_misc, flgs))
1092         {
1093                 if (ptr != prev_ptr)
1094                 {
1095                         ADD_INSC(";");
1096                         prev_ptr = ptr;
1097                 }
1098         }
1099         ptr = inscribe_flags_aux(flag_insc_misc, flgs, kanji, ptr);
1100
1101         /* Aura */
1102         if (have_flag_of(flag_insc_aura, flgs))
1103         {
1104                 ADD_INSC("[");
1105         }
1106         ptr = inscribe_flags_aux(flag_insc_aura, flgs, kanji, ptr);
1107
1108         /* Brand Weapon */
1109         if (have_flag_of(flag_insc_brand, flgs))
1110                 ADD_INSC("|");
1111         ptr = inscribe_flags_aux(flag_insc_brand, flgs, kanji, ptr);
1112
1113         /* Kill Weapon */
1114         if (have_flag_of(flag_insc_kill, flgs))
1115                 ADD_INSC("/X");
1116         ptr = inscribe_flags_aux(flag_insc_kill, flgs, kanji, ptr);
1117
1118         /* Slay Weapon */
1119         if (have_flag_of(flag_insc_slay, flgs))
1120                 ADD_INSC("/");
1121         ptr = inscribe_flags_aux(flag_insc_slay, flgs, kanji, ptr);
1122
1123         /* Esp */
1124         if (kanji)
1125         {
1126                 if (have_flag_of(flag_insc_esp1, flgs) ||
1127                     have_flag_of(flag_insc_esp2, flgs))
1128                         ADD_INSC("~");
1129                 ptr = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, ptr);
1130                 ptr = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, ptr);
1131         }
1132         else
1133         {
1134                 if (have_flag_of(flag_insc_esp1, flgs))
1135                         ADD_INSC("~");
1136                 ptr = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, ptr);
1137                 if (have_flag_of(flag_insc_esp2, flgs))
1138                         ADD_INSC("~");
1139                 ptr = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, ptr);
1140         }
1141
1142         /* sustain */
1143         if (have_flag_of(flag_insc_sust, flgs))
1144         {
1145                 ADD_INSC("(");
1146         }
1147         ptr = inscribe_flags_aux(flag_insc_sust, flgs, kanji, ptr);
1148
1149         *ptr = '\0';
1150
1151         return ptr;
1152 }
1153
1154
1155 /*!
1156  * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
1157  * @param buff 特性短縮表記を格納する文字列ポインタ
1158  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1159  * @return なし
1160  */
1161 static void get_inscription(char *buff, object_type *o_ptr)
1162 {
1163         concptr insc = quark_str(o_ptr->inscription);
1164         char *ptr = buff;
1165
1166         /* Not fully identified */
1167         if (!(o_ptr->ident & IDENT_MENTAL))
1168         {
1169                 /* Copy until end of line or '#' */
1170                 while (*insc)
1171                 {
1172                         if (*insc == '#') break;
1173 #ifdef JP
1174                         if (iskanji(*insc)) *buff++ = *insc++;
1175 #endif
1176                         *buff++ = *insc++;
1177                 }
1178
1179                 *buff = '\0';
1180                 return;
1181         }
1182
1183         *buff = '\0';
1184         for (; *insc; insc++)
1185         {
1186                 /* Ignore fake artifact inscription */
1187                 if (*insc == '#') break;
1188
1189                 /* {%} will be automatically converted */
1190                 else if ('%' == *insc)
1191                 {
1192                         bool kanji = FALSE;
1193                         bool all;
1194                         concptr start = ptr;
1195
1196                         /* check for too long inscription */
1197                         if (ptr >= buff + MAX_NLEN) continue;
1198
1199 #ifdef JP
1200                         if ('%' == insc[1])
1201                         {
1202                                 insc++;
1203                                 kanji = FALSE;
1204                         }
1205                         else
1206                         {
1207                                 kanji = TRUE;
1208                         }
1209 #endif
1210                         if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3])
1211                         {
1212                                 all = TRUE;
1213                                 insc += 3;
1214                         }
1215                         else
1216                         {
1217                                 all = FALSE;
1218                         }
1219
1220                         ptr = get_ability_abbreviation(ptr, o_ptr, kanji, all);
1221
1222                         if (ptr == start)
1223                                 ADD_INSC(" ");
1224                 }
1225                 else
1226                 {
1227                         *ptr++ = *insc;
1228                 }
1229         }
1230         *ptr = '\0';
1231 }
1232
1233 /*!
1234  * @brief オブジェクトがクエストの達成目的か否かを返す。
1235  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1236  * @return 現在クエスト達成目的のアイテムならばTRUEを返す。
1237  */
1238 bool object_is_quest_target(object_type *o_ptr)
1239 {
1240         if (p_ptr->inside_quest)
1241         {
1242                 ARTIFACT_IDX a_idx = quest[p_ptr->inside_quest].k_idx;
1243                 if (a_idx)
1244                 {
1245                         artifact_type *a_ptr = &a_info[a_idx];
1246                         if (!(a_ptr->gen_flags & TRG_INSTA_ART))
1247                         {
1248                                 if((o_ptr->tval == a_ptr->tval) && (o_ptr->sval == a_ptr->sval))
1249                                 {
1250                                         return TRUE;
1251                                 }
1252                         }
1253                 }
1254         }
1255         return FALSE;
1256 }
1257
1258
1259 /*!
1260  * @brief オブジェクトの各表記を返すメイン関数 / Creates a description of the item "o_ptr", and stores it in "out_val".
1261  * @param buf 表記を返すための文字列参照ポインタ
1262  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1263  * @param mode 表記に関するオプション指定
1264  * @return 現在クエスト達成目的のアイテムならばTRUEを返す。
1265  * @details
1266  * One can choose the "verbosity" of the description, including whether\n
1267  * or not the "number" of items should be described, and how much detail\n
1268  * should be used when describing the item.\n
1269  *\n
1270  * The given "buf" must be MAX_NLEN chars long to hold the longest possible\n
1271  * description, which can get pretty long, including incriptions, such as:\n
1272  * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".\n
1273  * Note that the inscription will be clipped to keep the total description\n
1274  * under MAX_NLEN-1 chars (plus a terminator).\n
1275  *\n
1276  * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient,\n
1277  * portable, versions of some common "sprintf()" commands.\n
1278  *\n
1279  * Note that all ego-items (when known) append an "Ego-Item Name", unless\n
1280  * the item is also an artifact, which should NEVER happen.\n
1281  *\n
1282  * Note that all artifacts (when known) append an "Artifact Name", so we\n
1283  * have special processing for "Specials" (artifact Lites, Rings, Amulets).\n
1284  * The "Specials" never use "modifiers" if they are "known", since they\n
1285  * have special "descriptions", such as "The Necklace of the Dwarves".\n
1286  *\n
1287  * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),\n
1288  * plus the artifact name, just like any other artifact, if known.\n
1289  *\n
1290  * Special Ring's and Amulet's, if not "aware", use the same code as normal\n
1291  * rings and amulets, and if "aware", use the "k_info" base-name (Ring or\n
1292  * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,\n
1293  * they will append the artifact name, just like any artifact, if known.\n
1294  *\n
1295  * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.\n
1296  *\n
1297  * Mode:\n
1298  *   OD_NAME_ONLY        : The Cloak of Death\n
1299  *   OD_NAME_AND_ENCHANT : The Cloak of Death [1,+3]\n
1300  *   OD_OMIT_INSCRIPTION : The Cloak of Death [1,+3] (+2 to Stealth)\n
1301  *   0                   : The Cloak of Death [1,+3] (+2 to Stealth) {nifty}\n
1302  *\n
1303  *   OD_OMIT_PREFIX      : Forbidden numeric prefix\n
1304  *   OD_NO_PLURAL        : Forbidden use of plural \n
1305  *   OD_STORE            : Assume to be aware and known\n
1306  *   OD_NO_FLAVOR        : Allow to hidden flavor\n
1307  *   OD_FORCE_FLAVOR     : Get un-shuffled flavor name\n
1308  */
1309 void object_desc(char *buf, object_type *o_ptr, BIT_FLAGS mode)
1310 {
1311         /* Extract object kind name */
1312         concptr            kindname = k_name + k_info[o_ptr->k_idx].name;
1313
1314         /* Extract default "base" string */
1315         concptr            basenm = kindname;
1316
1317         /* Assume no "modifier" string */
1318         concptr            modstr = "";
1319
1320         int power;
1321         int fire_rate;
1322
1323         bool            aware = FALSE;
1324         bool            known = FALSE;
1325         bool            flavor = TRUE;
1326
1327         bool            show_weapon = FALSE;
1328         bool            show_armour = FALSE;
1329
1330         concptr            s, s0;
1331         char            *t;
1332
1333         char            p1 = '(', p2 = ')';
1334         char            b1 = '[', b2 = ']';
1335         char            c1 = '{', c2 = '}';
1336
1337         char            tmp_val[MAX_NLEN+160];
1338         char            tmp_val2[MAX_NLEN+10];
1339         char            fake_insc_buf[30];
1340
1341         BIT_FLAGS flgs[TR_FLAG_SIZE];
1342
1343         object_type *bow_ptr;
1344
1345         object_kind *k_ptr = &k_info[o_ptr->k_idx];
1346         object_kind *flavor_k_ptr = &k_info[k_ptr->flavor];
1347
1348         /* Extract some flags */
1349         object_flags(o_ptr, flgs);
1350
1351         /* See if the object is "aware" */
1352         if (object_is_aware(o_ptr)) aware = TRUE;
1353
1354         /* See if the object is "known" */
1355         if (object_is_known(o_ptr)) known = TRUE;
1356
1357         /* Allow flavors to be hidden when aware */
1358         if (aware && ((mode & OD_NO_FLAVOR) || plain_descriptions)) flavor = FALSE;
1359
1360         /* Object is in the inventory of a store or spoiler */
1361         if ((mode & OD_STORE) || (o_ptr->ident & IDENT_STORE))
1362         {
1363                 /* Don't show flavors */
1364                 flavor = FALSE;
1365
1366                 /* Pretend known and aware */
1367                 aware = TRUE;
1368                 known = TRUE;
1369         }
1370
1371         /* Force to be flavor name only */
1372         if (mode & OD_FORCE_FLAVOR)
1373         {
1374                 aware = FALSE;
1375                 flavor = TRUE;
1376                 known = FALSE;
1377
1378                 /* Cancel shuffling */
1379                 flavor_k_ptr = k_ptr;
1380         }
1381
1382         /* Analyze the object */
1383         switch (o_ptr->tval)
1384         {
1385                 /* Some objects are easy to describe */
1386                 case TV_SKELETON:
1387                 case TV_BOTTLE:
1388                 case TV_JUNK:
1389                 case TV_SPIKE:
1390                 case TV_FLASK:
1391                 case TV_CHEST:
1392                 case TV_WHISTLE:
1393                 {
1394                         break;
1395                 }
1396
1397                 case TV_CAPTURE:
1398                 {
1399                         monster_race *r_ptr = &r_info[o_ptr->pval];
1400
1401                         if (known)
1402                         {
1403                                 if (!o_ptr->pval)
1404                                 {
1405                                         modstr = _(" (空)", " (empty)");
1406                                 }
1407                                 else
1408                                 {
1409 #ifdef JP
1410                                         sprintf(tmp_val2, " (%s)",r_name + r_ptr->name);
1411                                         modstr = tmp_val2;
1412 #else
1413                                         concptr t = r_name + r_ptr->name;
1414
1415                                         if (!(r_ptr->flags1 & RF1_UNIQUE))
1416                                         {
1417                                                 sprintf(tmp_val2, " (%s%s)", (is_a_vowel(*t) ? "an " : "a "), t);
1418
1419                                                 modstr = tmp_val2;
1420                                         }
1421                                         else
1422                                         {
1423                                                 sprintf(tmp_val2, "(%s)", t);
1424
1425                                                 modstr = t;
1426                                         }
1427 #endif
1428                                 }
1429                         }
1430                         break;
1431                 }
1432
1433                 /* Figurines/Statues */
1434                 case TV_FIGURINE:
1435                 case TV_STATUE:
1436                 {
1437                         monster_race *r_ptr = &r_info[o_ptr->pval];
1438
1439 #ifdef JP
1440                         modstr = r_name + r_ptr->name;
1441 #else
1442                         concptr t = r_name + r_ptr->name;
1443
1444                         if (!(r_ptr->flags1 & RF1_UNIQUE))
1445                         {
1446                                 sprintf(tmp_val2, "%s%s", (is_a_vowel(*t) ? "an " : "a "), t);
1447
1448                                 modstr = tmp_val2;
1449                         }
1450                         else
1451                         {
1452                                 modstr = t;
1453                         }
1454 #endif
1455
1456
1457                         break;
1458                 }
1459
1460                 /* Corpses */
1461                 case TV_CORPSE:
1462                 {
1463                         monster_race *r_ptr = &r_info[o_ptr->pval];
1464
1465                         modstr = r_name + r_ptr->name;
1466
1467 #ifdef JP
1468                         basenm = "#%";
1469 #else
1470                         if (r_ptr->flags1 & RF1_UNIQUE)
1471                                 basenm = "& % of #";
1472                         else
1473                                 basenm = "& # %";
1474 #endif
1475
1476                         break;
1477                 }
1478
1479                 /* Missiles/ Bows/ Weapons */
1480                 case TV_SHOT:
1481                 case TV_BOLT:
1482                 case TV_ARROW:
1483                 case TV_BOW:
1484                 case TV_HAFTED:
1485                 case TV_POLEARM:
1486                 case TV_SWORD:
1487                 case TV_DIGGING:
1488                 {
1489                         show_weapon = TRUE;
1490                         break;
1491                 }
1492
1493                 /* Armour */
1494                 case TV_BOOTS:
1495                 case TV_GLOVES:
1496                 case TV_CLOAK:
1497                 case TV_CROWN:
1498                 case TV_HELM:
1499                 case TV_SHIELD:
1500                 case TV_SOFT_ARMOR:
1501                 case TV_HARD_ARMOR:
1502                 case TV_DRAG_ARMOR:
1503                 {
1504                         show_armour = TRUE;
1505                         break;
1506                 }
1507
1508                 /* Lites (including a few "Specials") */
1509                 case TV_LITE:
1510                 {
1511                         break;
1512                 }
1513
1514                 /* Amulets (including a few "Specials") */
1515                 case TV_AMULET:
1516                 {
1517                         /* Known artifacts */
1518                         if (aware)
1519                         {
1520                                 if (object_is_fixed_artifact(o_ptr)) break;
1521                                 if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1522                         }
1523
1524                         /* Color the object */
1525                         modstr = k_name + flavor_k_ptr->flavor_name;
1526
1527 #ifdef JP
1528                         if (!flavor)    basenm = "%のアミュレット";
1529                         else if (aware) basenm = "%の#アミュレット";
1530                         else            basenm = "#アミュレット";
1531 #else
1532                         if (!flavor)    basenm = "& Amulet~ of %";
1533                         else if (aware) basenm = "& # Amulet~ of %";
1534                         else            basenm = "& # Amulet~";
1535 #endif
1536
1537                         break;
1538                 }
1539
1540                 /* Rings (including a few "Specials") */
1541                 case TV_RING:
1542                 {
1543                         /* Known artifacts */
1544                         if (aware)
1545                         {
1546                                 if (object_is_fixed_artifact(o_ptr)) break;
1547                                 if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1548                         }
1549
1550                         /* Color the object */
1551                         modstr = k_name + flavor_k_ptr->flavor_name;
1552
1553 #ifdef JP
1554                         if (!flavor)    basenm = "%の指輪";
1555                         else if (aware) basenm = "%の#指輪";
1556                         else            basenm = "#指輪";
1557 #else
1558                         if (!flavor)    basenm = "& Ring~ of %";
1559                         else if (aware) basenm = "& # Ring~ of %";
1560                         else            basenm = "& # Ring~";
1561 #endif
1562
1563                         if (!k_ptr->to_h && !k_ptr->to_d && (o_ptr->to_h || o_ptr->to_d)) show_weapon = TRUE;
1564
1565                         break;
1566                 }
1567
1568                 case TV_CARD:
1569                 {
1570                         break;
1571                 }
1572
1573                 case TV_STAFF:
1574                 {
1575                         /* Color the object */
1576                         modstr = k_name + flavor_k_ptr->flavor_name;
1577
1578 #ifdef JP
1579                         if (!flavor)    basenm = "%の杖";
1580                         else if (aware) basenm = "%の#杖";
1581                         else            basenm = "#杖";
1582 #else
1583                         if (!flavor)    basenm = "& Staff~ of %";
1584                         else if (aware) basenm = "& # Staff~ of %";
1585                         else            basenm = "& # Staff~";
1586 #endif
1587
1588                         break;
1589                 }
1590
1591                 case TV_WAND:
1592                 {
1593                         /* Color the object */
1594                         modstr = k_name + flavor_k_ptr->flavor_name;
1595
1596 #ifdef JP
1597                         if (!flavor)    basenm = "%の魔法棒";
1598                         else if (aware) basenm = "%の#魔法棒";
1599                         else            basenm = "#魔法棒";
1600 #else
1601                         if (!flavor)    basenm = "& Wand~ of %";
1602                         else if (aware) basenm = "& # Wand~ of %";
1603                         else            basenm = "& # Wand~";
1604 #endif
1605
1606                         break;
1607                 }
1608
1609                 case TV_ROD:
1610                 {
1611                         /* Color the object */
1612                         modstr = k_name + flavor_k_ptr->flavor_name;
1613
1614 #ifdef JP
1615                         if (!flavor)    basenm = "%のロッド";
1616                         else if (aware) basenm = "%の#ロッド";
1617                         else            basenm = "#ロッド";
1618 #else
1619                         if (!flavor)    basenm = "& Rod~ of %";
1620                         else if (aware) basenm = "& # Rod~ of %";
1621                         else            basenm = "& # Rod~";
1622 #endif
1623
1624                         break;
1625                 }
1626
1627                 case TV_SCROLL:
1628                 {
1629                         /* Color the object */
1630                         modstr = k_name + flavor_k_ptr->flavor_name;
1631
1632 #ifdef JP
1633                         if (!flavor)    basenm = "%の巻物";
1634                         else if (aware) basenm = "「#」と書かれた%の巻物";
1635                         else            basenm = "「#」と書かれた巻物";
1636 #else
1637                         if (!flavor)    basenm = "& Scroll~ of %";
1638                         else if (aware) basenm = "& Scroll~ titled \"#\" of %";
1639                         else            basenm = "& Scroll~ titled \"#\"";
1640 #endif
1641
1642                         break;
1643                 }
1644
1645                 case TV_POTION:
1646                 {
1647                         /* Color the object */
1648                         modstr = k_name + flavor_k_ptr->flavor_name;
1649
1650 #ifdef JP
1651                         if (!flavor)    basenm = "%の薬";
1652                         else if (aware) basenm = "%の#薬";
1653                         else            basenm = "#薬";
1654 #else
1655                         if (!flavor)    basenm = "& Potion~ of %";
1656                         else if (aware) basenm = "& # Potion~ of %";
1657                         else            basenm = "& # Potion~";
1658 #endif
1659
1660                         break;
1661                 }
1662
1663                 case TV_FOOD:
1664                 {
1665                         /* Ordinary food is "boring" */
1666                         if (!k_ptr->flavor_name) break;
1667
1668                         /* Color the object */
1669                         modstr = k_name + flavor_k_ptr->flavor_name;
1670
1671 #ifdef JP
1672                         if (!flavor)    basenm = "%のキノコ";
1673                         else if (aware) basenm = "%の#キノコ";
1674                         else            basenm = "#キノコ";
1675 #else
1676                         if (!flavor)    basenm = "& Mushroom~ of %";
1677                         else if (aware) basenm = "& # Mushroom~ of %";
1678                         else            basenm = "& # Mushroom~";
1679 #endif
1680
1681                         break;
1682                 }
1683
1684                 case TV_PARCHMENT:
1685                 {
1686                         basenm = _("羊皮紙 - %", "& Parchment~ - %");
1687                         break;
1688                 }
1689
1690                 /* Magic Books */
1691                 case TV_LIFE_BOOK:
1692                 {
1693 #ifdef JP
1694                         basenm = "生命の魔法書%";
1695 #else
1696                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1697                                 basenm = "& Book~ of Life Magic %";
1698                         else
1699                                 basenm = "& Life Spellbook~ %";
1700 #endif
1701
1702                         break;
1703                 }
1704
1705                 case TV_SORCERY_BOOK:
1706                 {
1707 #ifdef JP
1708                         basenm = "仙術の魔法書%";
1709 #else
1710                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1711                                 basenm = "& Book~ of Sorcery %";
1712                         else
1713                                 basenm = "& Sorcery Spellbook~ %";
1714 #endif
1715
1716                         break;
1717                 }
1718
1719                 case TV_NATURE_BOOK:
1720                 {
1721 #ifdef JP
1722                         basenm = "自然の魔法書%";
1723 #else
1724                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1725                                 basenm = "& Book~ of Nature Magic %";
1726                         else
1727                                 basenm = "& Nature Spellbook~ %";
1728 #endif
1729
1730                         break;
1731                 }
1732
1733                 case TV_CHAOS_BOOK:
1734                 {
1735 #ifdef JP
1736                         basenm = "カオスの魔法書%";
1737 #else
1738                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1739                                 basenm = "& Book~ of Chaos Magic %";
1740                         else
1741                                 basenm = "& Chaos Spellbook~ %";
1742 #endif
1743
1744                         break;
1745                 }
1746
1747                 case TV_DEATH_BOOK:
1748                 {
1749 #ifdef JP
1750                         basenm = "暗黒の魔法書%";
1751 #else
1752                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1753                                 basenm = "& Book~ of Death Magic %";
1754                         else
1755                                 basenm = "& Death Spellbook~ %";
1756 #endif
1757
1758                         break;
1759                 }
1760
1761                 case TV_TRUMP_BOOK:
1762                 {
1763 #ifdef JP
1764                         basenm = "トランプの魔法書%";
1765 #else
1766                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1767                                 basenm = "& Book~ of Trump Magic %";
1768                         else
1769                                 basenm = "& Trump Spellbook~ %";
1770 #endif
1771
1772                         break;
1773                 }
1774
1775                 case TV_ARCANE_BOOK:
1776                 {
1777 #ifdef JP
1778                         basenm = "秘術の魔法書%";
1779 #else
1780                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1781                                 basenm = "& Book~ of Arcane Magic %";
1782                         else
1783                                 basenm = "& Arcane Spellbook~ %";
1784 #endif
1785
1786                         break;
1787                 }
1788
1789                 case TV_CRAFT_BOOK:
1790                 {
1791 #ifdef JP
1792                         basenm = "匠の魔法書%";
1793 #else
1794                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1795                                 basenm = "& Book~ of Craft Magic %";
1796                         else
1797                                 basenm = "& Craft Spellbook~ %";
1798 #endif
1799
1800                         break;
1801                 }
1802
1803                 case TV_DAEMON_BOOK:
1804                 {
1805 #ifdef JP
1806                         basenm = "悪魔の魔法書%";
1807 #else
1808                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1809                                 basenm = "& Book~ of Daemon Magic %";
1810                         else
1811                                 basenm = "& Daemon Spellbook~ %";
1812 #endif
1813
1814                         break;
1815                 }
1816
1817                 case TV_CRUSADE_BOOK:
1818                 {
1819 #ifdef JP
1820                         basenm = "破邪の魔法書%";
1821 #else
1822                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1823                                 basenm = "& Book~ of Crusade Magic %";
1824                         else
1825                                 basenm = "& Crusade Spellbook~ %";
1826 #endif
1827
1828                         break;
1829                 }
1830
1831                 case TV_MUSIC_BOOK:
1832                 {
1833                         basenm = _("歌集%", "& Song Book~ %");
1834                         break;
1835                 }
1836
1837                 case TV_HISSATSU_BOOK:
1838                 {
1839                         basenm = _("& 武芸の書%", "Book~ of Kendo %");
1840                         break;
1841                 }
1842
1843                 case TV_HEX_BOOK:
1844                 {
1845 #ifdef JP
1846                         basenm = "呪術の魔法書%";
1847 #else
1848                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1849                                 basenm = "& Book~ of Hex Magic %";
1850                         else
1851                                 basenm = "& Hex Spellbook~ %";
1852 #endif
1853
1854                         break;
1855                 }
1856
1857                 /* Hack -- Gold/Gems */
1858                 case TV_GOLD:
1859                 {
1860                         strcpy(buf, basenm);
1861                         return;
1862                 }
1863
1864                 /* Used in the "inventory" routine */
1865                 default:
1866                 {
1867                         strcpy(buf, _("(なし)", "(nothing)"));
1868                         return;
1869                 }
1870         }
1871
1872         /* Use full name from k_info or a_info */
1873         if (aware && have_flag(flgs, TR_FULL_NAME))
1874         {
1875                 if (known && o_ptr->name1) basenm = a_name + a_info[o_ptr->name1].name;
1876                 else basenm = kindname;
1877         }
1878
1879         /* Start dumping the result */
1880         t = tmp_val;
1881
1882 #ifdef JP
1883         if (basenm[0] == '&')
1884                 s = basenm + 2;
1885         else
1886                 s = basenm;
1887
1888         /* No prefix */
1889         if (mode & OD_OMIT_PREFIX)
1890         {
1891                 /* Nothing */
1892         }
1893         else if (o_ptr->number > 1)
1894         {
1895                 t = object_desc_kosuu(t, o_ptr);
1896                 t = object_desc_str(t, "の ");
1897         }
1898
1899         /* 英語の場合アーティファクトは The が付くので分かるが
1900          * 日本語では分からないのでマークをつける 
1901          */
1902         if (known)
1903         {
1904                 if (object_is_fixed_artifact(o_ptr)) t = object_desc_str(t, "★");
1905                 else if (o_ptr->art_name) t = object_desc_str(t, "☆");
1906         }
1907
1908 #else
1909
1910         /* The object "expects" a "number" */
1911         if (basenm[0] == '&')
1912         {
1913                 /* Skip the ampersand (and space) */
1914                 s = basenm + 2;
1915
1916                 /* No prefix */
1917                 if (mode & OD_OMIT_PREFIX)
1918                 {
1919                         /* Nothing */
1920                 }
1921
1922                 /* Hack -- None left */
1923                 else if (o_ptr->number <= 0)
1924                 {
1925                         t = object_desc_str(t, "no more ");
1926                 }
1927
1928                 /* Extract the number */
1929                 else if (o_ptr->number > 1)
1930                 {
1931                         t = object_desc_num(t, o_ptr->number);
1932                         t = object_desc_chr(t, ' ');
1933                 }
1934
1935                 /* Hack -- The only one of its kind */
1936                 else if ((known && object_is_artifact(o_ptr)) ||
1937                          ((o_ptr->tval == TV_CORPSE) &&
1938                           (r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
1939                 {
1940                         t = object_desc_str(t, "The ");
1941                 }
1942
1943                 /* A single one */
1944                 else
1945                 {
1946                         bool vowel;
1947
1948                         switch (*s)
1949                         {
1950                         case '#': vowel = is_a_vowel(modstr[0]); break;
1951                         case '%': vowel = is_a_vowel(*kindname); break;
1952                         default:  vowel = is_a_vowel(*s); break;
1953                         }
1954
1955                         if (vowel)
1956                         {
1957                                 /* A single one, with a vowel */
1958                                 t = object_desc_str(t, "an ");
1959                         }
1960                         else
1961                         {
1962                                 /* A single one, without a vowel */
1963                                 t = object_desc_str(t, "a ");
1964                         }
1965                 }
1966         }
1967
1968         /* Hack -- objects that "never" take an article */
1969         else
1970         {
1971                 /* No ampersand */
1972                 s = basenm;
1973
1974                 /* No pref */
1975                 if (mode & OD_OMIT_PREFIX)
1976                 {
1977                         /* Nothing */
1978                 }
1979
1980                 /* Hack -- all gone */
1981                 else if (o_ptr->number <= 0)
1982                 {
1983                         t = object_desc_str(t, "no more ");
1984                 }
1985
1986                 /* Prefix a number if required */
1987                 else if (o_ptr->number > 1)
1988                 {
1989                         t = object_desc_num(t, o_ptr->number);
1990                         t = object_desc_chr(t, ' ');
1991                 }
1992
1993                 /* Hack -- The only one of its kind */
1994                 else if (known && object_is_artifact(o_ptr))
1995                 {
1996                         t = object_desc_str(t, "The ");
1997                 }
1998
1999                 /* Hack -- single items get no prefix */
2000                 else
2001                 {
2002                         /* Nothing */
2003                 }
2004         }
2005 #endif
2006
2007         /* Paranoia -- skip illegal tildes */
2008         /* while (*s == '~') s++; */
2009
2010 #ifdef JP
2011         if (object_is_smith(o_ptr))
2012         {
2013                 t = object_desc_str(t, format("鍛冶師%sの", p_ptr->name));
2014         }
2015
2016         /* 伝説のアイテム、名のあるアイテムの名前を付加する */
2017         if (known)
2018         {
2019                 /* ランダム・アーティファクト */
2020                 if (o_ptr->art_name)
2021                 {
2022                         concptr temp = quark_str(o_ptr->art_name);
2023
2024                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2025                         /* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */
2026                         if (strncmp(temp, "of ", 3) == 0)
2027                         {
2028                                 t = object_desc_str(t, &temp[3]);
2029                                 t = object_desc_str(t, "の");
2030                         }
2031                         else if ((strncmp(temp, "『", 2) != 0) &&
2032                                  (strncmp(temp, "《", 2) != 0) &&
2033                                  (temp[0] != '\''))
2034                                 t = object_desc_str(t, temp);
2035                 }
2036                 /* 伝説のアイテム */
2037                 else if (o_ptr->name1 && !have_flag(flgs, TR_FULL_NAME))
2038                 {
2039                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2040                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2041                         if (strncmp(a_name + a_ptr->name, "『", 2) != 0)
2042                         {
2043                                 t = object_desc_str(t, a_name + a_ptr->name);
2044                         }
2045                 }
2046                 /* 名のあるアイテム */
2047                 else if (object_is_ego(o_ptr))
2048                 {
2049                         ego_item_type *e_ptr = &e_info[o_ptr->name2];
2050                         t = object_desc_str(t, e_name + e_ptr->name);
2051                 }
2052         }
2053 #endif
2054
2055         /* Copy the string */
2056         for (s0 = NULL; *s || s0; )
2057         {
2058                 /* The end of the flavour/kind string. */
2059                 if (!*s)
2060                 {
2061                         s = s0 + 1;
2062                         s0 = NULL;
2063                 }
2064
2065                 /* Begin to append the modifier (flavor) */
2066                 else if ((*s == '#') && !s0)
2067                 {
2068                         s0 = s;
2069                         s = modstr;
2070
2071                         /* Paranoia -- Never append multiple modstrs */
2072                         modstr = "";
2073                 }
2074
2075                 /* Begin to append the kind name */
2076                 else if ((*s == '%') && !s0)
2077                 {
2078                         s0 = s;
2079                         s = kindname;
2080
2081                         /* Paranoia -- Never append multiple kindnames */
2082                         kindname = "";
2083                 }
2084
2085 #ifndef JP
2086                 /* Pluralizer */
2087                 else if (*s == '~')
2088                 {
2089                         /* Add a plural if needed */
2090                         if (!(mode & OD_NO_PLURAL) && (o_ptr->number != 1))
2091                         {
2092                                 char k = t[-1];
2093
2094                                 /* Mega-Hack */
2095
2096                                 /* Hack -- "Cutlass-es" and "Torch-es" */
2097                                 if ((k == 's') || (k == 'h')) *t++ = 'e';
2098
2099                                 /* Add an 's' */
2100                                 *t++ = 's';
2101                         }
2102                         s++;
2103                 }
2104 #endif
2105
2106                 /* Normal */
2107                 else
2108                 {
2109                         /* Copy */
2110                         *t++ = *s++;
2111                 }
2112         }
2113
2114         /* Terminate */
2115         *t = '\0';
2116
2117
2118 #ifdef JP
2119         /* '『'から始まる伝説のアイテムの名前は最後に付加する */
2120         if (known)
2121         {
2122                 /* ランダムアーティファクトの名前はセーブファイルに記録
2123                    されるので、英語版の名前もそれらしく変換する */
2124                 if (o_ptr->art_name)
2125                 {
2126                         char temp[256];
2127                         int itemp;
2128                         strcpy(temp, quark_str(o_ptr->art_name));
2129                         /* MEGA HACK by ita */
2130                         if (strncmp(temp, "『", 2) == 0 ||
2131                             strncmp(temp, "《", 2) == 0)
2132                                 t = object_desc_str(t, temp);
2133                         else if (temp[0] == '\'')
2134                         {
2135                                 itemp = strlen(temp);
2136                                 temp[itemp - 1] = 0;
2137                                 t = object_desc_str(t, "『");
2138                                 t = object_desc_str(t, &temp[1]);
2139                                 t = object_desc_str(t, "』");
2140                         }
2141                 }
2142                 else if (object_is_fixed_artifact(o_ptr))
2143                 {
2144                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2145                         if (strncmp(a_name + a_ptr->name, "『", 2) == 0)
2146                         {
2147                                 t = object_desc_str(t, a_name + a_ptr->name);
2148                         }
2149                 }
2150                 else if (o_ptr->inscription)
2151                 {
2152                         concptr str = quark_str(o_ptr->inscription);
2153
2154                         while(*str)
2155                         {
2156                                 if (iskanji(*str))
2157                                 {
2158                                         str += 2;
2159                                         continue;
2160                                 }
2161                                 if (*str == '#') break;
2162                                 str++;
2163                         }
2164                         if (*str)
2165                         {
2166                                 /* Find the '#' */
2167                                 concptr str_aux = my_strchr(quark_str(o_ptr->inscription), '#');
2168
2169                                 /* Add the false name */
2170                                 t = object_desc_str(t,"『");
2171                                 t = object_desc_str(t, &str_aux[1]);
2172                                 t = object_desc_str(t,"』");
2173                         }
2174                 }
2175         }
2176 #else
2177         if (object_is_smith(o_ptr))
2178         {
2179                 t = object_desc_str(t,format(" of %s the Smith",p_ptr->name));
2180         }
2181
2182         /* Hack -- Append "Artifact" or "Special" names */
2183         if (known && !have_flag(flgs, TR_FULL_NAME))
2184         {
2185                 /* Is it a new random artifact ? */
2186                 if (o_ptr->art_name)
2187                 {
2188                         t = object_desc_chr(t, ' ');
2189                         t = object_desc_str(t, quark_str(o_ptr->art_name));
2190                 }
2191
2192                 /* Grab any artifact name */
2193                 else if (object_is_fixed_artifact(o_ptr))
2194                 {
2195                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2196
2197                         t = object_desc_chr(t, ' ');
2198                         t = object_desc_str(t, a_name + a_ptr->name);
2199                 }
2200
2201                 /* Grab any ego-item name */
2202                 else
2203                 {
2204                         if (object_is_ego(o_ptr))
2205                         {
2206                                 ego_item_type *e_ptr = &e_info[o_ptr->name2];
2207
2208                                 t = object_desc_chr(t, ' ');
2209                                 t = object_desc_str(t, e_name + e_ptr->name);
2210                         }
2211
2212                         if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '#'))
2213                         {
2214                                 /* Find the '#' */
2215                                 concptr str = my_strchr(quark_str(o_ptr->inscription), '#');
2216
2217                                 /* Add the false name */
2218                                 t = object_desc_chr(t, ' ');
2219                                 t = object_desc_str(t, &str[1]);
2220                         }
2221                 }
2222         }
2223 #endif
2224
2225
2226         /* No more details wanted */
2227         if (mode & OD_NAME_ONLY) goto object_desc_done;
2228
2229         /* Hack -- Chests must be described in detail */
2230         if (o_ptr->tval == TV_CHEST)
2231         {
2232                 /* Not searched yet */
2233                 if (!known)
2234                 {
2235                         /* Nothing */
2236                 }
2237
2238                 /* May be "empty" */
2239                 else if (!o_ptr->pval)
2240                 {
2241                         t = object_desc_str(t, _("(空)", " (empty)"));
2242                 }
2243
2244                 /* May be "disarmed" */
2245                 else if (o_ptr->pval < 0)
2246                 {
2247                         if (chest_traps[0 - o_ptr->pval])
2248                         {
2249                                 t = object_desc_str(t, _("(解除済)", " (disarmed)"));
2250                         }
2251                         else
2252                         {
2253                                 t = object_desc_str(t, _("(非施錠)", " (unlocked)"));
2254                         }
2255                 }
2256
2257                 /* Describe the traps, if any */
2258                 else
2259                 {
2260                         /* Describe the traps */
2261                         switch (chest_traps[o_ptr->pval])
2262                         {
2263                                 case 0:
2264                                 {
2265                                         t = object_desc_str(t, _("(施錠)", " (Locked)"));
2266                                         break;
2267                                 }
2268                                 case CHEST_LOSE_STR:
2269                                 {
2270                                         t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2271                                         break;
2272                                 }
2273                                 case CHEST_LOSE_CON:
2274                                 {
2275                                         t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2276                                         break;
2277                                 }
2278                                 case CHEST_POISON:
2279                                 {
2280                                         t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2281                                         break;
2282                                 }
2283                                 case CHEST_PARALYZE:
2284                                 {
2285                                         t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2286                                         break;
2287                                 }
2288                                 case CHEST_EXPLODE:
2289                                 {
2290                                         t = object_desc_str(t, _("(爆発装置)", " (Explosion Device)"));
2291                                         break;
2292                                 }
2293                                 case CHEST_SUMMON:
2294                                 case CHEST_BIRD_STORM:
2295                                 case CHEST_E_SUMMON:
2296                                 case CHEST_H_SUMMON:
2297                                 {
2298                                         t = object_desc_str(t, _("(召喚のルーン)", " (Summoning Runes)"));
2299                                         break;
2300                                 }
2301                                 case CHEST_RUNES_OF_EVIL:
2302                                 {
2303                                         t = object_desc_str(t, _("(邪悪なルーン)", " (Gleaming Black Runes)"));
2304                                         break;
2305                                 }
2306                                 case CHEST_ALARM:
2307                                 {
2308                                         t = object_desc_str(t, _("(警報装置)", " (Alarm)"));
2309                                         break;
2310                                 }
2311                                 default:
2312                                 {
2313                                         t = object_desc_str(t, _("(マルチ・トラップ)", " (Multiple Traps)"));
2314                                         break;
2315                                 }
2316                         }
2317                 }
2318         }
2319
2320
2321         /* Display the item like a weapon */
2322         if (have_flag(flgs, TR_SHOW_MODS)) show_weapon = TRUE;
2323
2324         /* Display the item like a weapon */
2325         if (object_is_smith(o_ptr) && (o_ptr->xtra3 == 1 + ESSENCE_SLAY_GLOVE))
2326                 show_weapon = TRUE;
2327
2328         /* Display the item like a weapon */
2329         if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;
2330
2331         /* Display the item like armour */
2332         if (o_ptr->ac) show_armour = TRUE;
2333
2334
2335         /* Dump base weapon info */
2336         switch (o_ptr->tval)
2337         {
2338                 /* Missiles and Weapons */
2339                 case TV_SHOT:
2340                 case TV_BOLT:
2341                 case TV_ARROW:
2342                 case TV_HAFTED:
2343                 case TV_POLEARM:
2344                 case TV_SWORD:
2345             case TV_DIGGING:
2346                 
2347                 /* In Vault Quest, hide the dice of target weapon. */
2348                 if(object_is_quest_target(o_ptr) && !known)
2349                 {
2350                         break;
2351                 }
2352
2353                 /* Append a "damage" string */
2354                 t = object_desc_chr(t, ' ');
2355                 t = object_desc_chr(t, p1);
2356                 t = object_desc_num(t, o_ptr->dd);
2357                 t = object_desc_chr(t, 'd');
2358                 t = object_desc_num(t, o_ptr->ds);
2359                 t = object_desc_chr(t, p2);
2360
2361                 /* All done */
2362                 break;
2363
2364
2365                 /* Bows get a special "damage string" */
2366                 case TV_BOW:
2367
2368                 /* Mega-Hack -- Extract the "base power" */
2369                 power = bow_tmul(o_ptr->sval);
2370
2371                 /* Apply the "Extra Might" flag */
2372                 if (have_flag(flgs, TR_XTRA_MIGHT)) power++;
2373
2374                 /* Append a special "damage" string */
2375                 t = object_desc_chr(t, ' ');
2376                 t = object_desc_chr(t, p1);
2377                 t = object_desc_chr(t, 'x');
2378                 t = object_desc_num(t, power);
2379                 t = object_desc_chr(t, p2);
2380                 
2381                 fire_rate = calc_num_fire(o_ptr);
2382                 /* Show Fire rate */
2383                 if (fire_rate != 0 && power > 0 && known)
2384                 {       
2385                         fire_rate = bow_energy(o_ptr->sval) / fire_rate;
2386                         
2387                         t = object_desc_chr(t, ' ');
2388                         t = object_desc_chr(t, p1);                     
2389                         t = object_desc_num(t,  fire_rate/100);
2390                         t = object_desc_chr(t,  '.');
2391                         t = object_desc_num(t,  fire_rate%100);
2392                         t = object_desc_str(t, "turn");
2393                         t = object_desc_chr(t, p2);
2394                 }
2395                 
2396                 /* All done */
2397                 break;
2398         }
2399
2400
2401         /* Add the weapon bonuses */
2402         if (known)
2403         {
2404                 /* Show the tohit/todam on request */
2405                 if (show_weapon)
2406                 {
2407                         t = object_desc_chr(t, ' ');
2408                         t = object_desc_chr(t, p1);
2409                         t = object_desc_int(t, o_ptr->to_h);
2410                         t = object_desc_chr(t, ',');
2411                         t = object_desc_int(t, o_ptr->to_d);
2412                         t = object_desc_chr(t, p2);
2413                 }
2414
2415                 /* Show the tohit if needed */
2416                 else if (o_ptr->to_h)
2417                 {
2418                         t = object_desc_chr(t, ' ');
2419                         t = object_desc_chr(t, p1);
2420                         t = object_desc_int(t, o_ptr->to_h);
2421                         t = object_desc_chr(t, p2);
2422                 }
2423
2424                 /* Show the todam if needed */
2425                 else if (o_ptr->to_d)
2426                 {
2427                         t = object_desc_chr(t, ' ');
2428                         t = object_desc_chr(t, p1);
2429                         t = object_desc_int(t, o_ptr->to_d);
2430                         t = object_desc_chr(t, p2);
2431                 }
2432         }
2433
2434         bow_ptr = &inventory[INVEN_BOW];
2435
2436         /* If have a firing weapon + ammo matches bow */
2437         if (bow_ptr->k_idx && (o_ptr->tval == p_ptr->tval_ammo))
2438         {
2439                 int avgdam = o_ptr->dd * (o_ptr->ds + 1) * 10 / 2;
2440                 int tmul = bow_tmul(bow_ptr->sval);
2441                 ENERGY energy_fire = bow_energy(bow_ptr->sval);
2442
2443                 /* See if the bow is "known" - then set damage bonus */
2444                 if (object_is_known(bow_ptr)) avgdam += (bow_ptr->to_d * 10);
2445
2446                 /* Effect of ammo */
2447                 if (known) avgdam += (o_ptr->to_d * 10);
2448
2449                 /* Get extra "power" from "extra might" */
2450                 if (p_ptr->xtra_might) tmul++;
2451
2452                 tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
2453
2454                 /* Launcher multiplier */
2455                 avgdam *= tmul;
2456                 avgdam /= (100 * 10);
2457
2458                 /* Get extra damage from concentration */
2459                 if (p_ptr->concent) avgdam = boost_concentration_damage(avgdam);
2460                 
2461                 if (avgdam < 0) avgdam = 0;
2462
2463                 /* Display (shot damage/ shot damage with critical/ avg damage with critical) */
2464                 t = object_desc_chr(t, ' ');
2465                 t = object_desc_chr(t, p1);
2466                 
2467                 if(show_ammo_no_crit)
2468                 {
2469                         /* Damage with no-crit */
2470                         t = object_desc_num(t, avgdam);
2471                         t = object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2472                 }
2473                 
2474                 /* Apply Expect damage of Critical */
2475                 avgdam = calc_expect_crit_shot(o_ptr->weight, o_ptr->to_h, bow_ptr->to_h, avgdam);
2476                 t = object_desc_num(t, avgdam);
2477                 
2478                 t = show_ammo_no_crit ? object_desc_str(t, show_ammo_detail ? "/crit " : "/")
2479                                                           : object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2480         
2481                 if (p_ptr->num_fire == 0)
2482                 {
2483                         t = object_desc_chr(t, '0');
2484                 }
2485                 else
2486                 {
2487                         /* Calc effects of energy */
2488                         avgdam *= (p_ptr->num_fire * 100);
2489                         avgdam /= energy_fire;
2490                         t = object_desc_num(t, avgdam);
2491                         t = object_desc_str(t, show_ammo_detail ? "/turn" : "");
2492                         
2493                         if(show_ammo_crit_ratio)
2494                         {
2495                                 int percent = calc_crit_ratio_shot(known ? o_ptr->to_h : 0, known ? bow_ptr->to_h : 0);
2496                                 
2497                                 t = object_desc_chr(t, '/');
2498                                 t = object_desc_num(t, percent / 100);
2499                                 t = object_desc_chr(t, '.');
2500                 if(percent % 100 < 10)
2501                 {
2502                                     t = object_desc_chr(t, '0');
2503                 }
2504                                 t = object_desc_num(t, percent % 100);
2505                                 t = object_desc_str(t, show_ammo_detail ? "% crit" : "%");
2506                         }
2507                 }
2508
2509                 t = object_desc_chr(t, p2);
2510         }
2511         else if ((p_ptr->pclass == CLASS_NINJA) && (o_ptr->tval == TV_SPIKE))
2512         {
2513                 int avgdam = p_ptr->mighty_throw ? (1 + 3) : 1;
2514                 s16b energy_fire = 100 - p_ptr->lev;
2515
2516                 avgdam += ((p_ptr->lev + 30) * (p_ptr->lev + 30) - 900) / 55;
2517
2518                 /* Display (shot damage/ avg damage) */
2519                 t = object_desc_chr(t, ' ');
2520                 t = object_desc_chr(t, p1);
2521                 t = object_desc_num(t, avgdam);
2522                 t = object_desc_chr(t, '/');
2523
2524                 /* Calc effects of energy */
2525                 avgdam = 100 * avgdam / energy_fire;
2526
2527                 t = object_desc_num(t, avgdam);
2528                 t = object_desc_chr(t, p2);
2529         }
2530
2531         /* Add the armor bonuses */
2532         if (known)
2533         {
2534                 /* Show the armor class info */
2535                 if (show_armour)
2536                 {
2537                         t = object_desc_chr(t, ' ');
2538                         t = object_desc_chr(t, b1);
2539                         t = object_desc_num(t, o_ptr->ac);
2540                         t = object_desc_chr(t, ',');
2541                         t = object_desc_int(t, o_ptr->to_a);
2542                         t = object_desc_chr(t, b2);
2543                 }
2544
2545                 /* No base armor, but does increase armor */
2546                 else if (o_ptr->to_a)
2547                 {
2548                         t = object_desc_chr(t, ' ');
2549                         t = object_desc_chr(t, b1);
2550                         t = object_desc_int(t, o_ptr->to_a);
2551                         t = object_desc_chr(t, b2);
2552                 }
2553         }
2554
2555         /* Hack -- always show base armor */
2556         else if (show_armour)
2557         {
2558                 t = object_desc_chr(t, ' ');
2559                 t = object_desc_chr(t, b1);
2560                 t = object_desc_num(t, o_ptr->ac);
2561                 t = object_desc_chr(t, b2);
2562         }
2563
2564
2565         /* No more details wanted */
2566         if (mode & OD_NAME_AND_ENCHANT) goto object_desc_done;
2567
2568
2569         if (known) /* Known item only */
2570         {
2571                 /*
2572                  * Hack -- Wands and Staffs have charges.  Make certain how many charges
2573                  * a stack of staffs really has is clear. -LM-
2574                  */
2575                 if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
2576                 {
2577                         /* Dump " (N charges)" */
2578                         t = object_desc_chr(t, ' ');
2579                         t = object_desc_chr(t, p1);
2580
2581                         /* Clear explaination for staffs. */
2582                         if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
2583                         {
2584                                 t = object_desc_num(t, o_ptr->number);
2585                                 t = object_desc_str(t, "x ");
2586                         }
2587                         t = object_desc_num(t, o_ptr->pval);
2588 #ifdef JP
2589                         t = object_desc_str(t, "回分");
2590 #else
2591                         t = object_desc_str(t, " charge");
2592                         if (o_ptr->pval != 1) t = object_desc_chr(t, 's');
2593 #endif
2594
2595                         t = object_desc_chr(t, p2);
2596                 }
2597                 /* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
2598                  * be in any state of charge or discharge, this now includes a number. -LM-
2599                  */
2600                 else if (o_ptr->tval == TV_ROD)
2601                 {
2602                         /* Hack -- Dump " (# charging)" if relevant */
2603                         if (o_ptr->timeout)
2604                         {
2605                                 /* Stacks of rods display an exact count of charging rods. */
2606                                 if (o_ptr->number > 1)
2607                                 {
2608                                         /* Paranoia. */
2609                                         if (k_ptr->pval == 0) k_ptr->pval = 1;
2610
2611                                         /* Find out how many rods are charging, by dividing
2612                                          * current timeout by each rod's maximum timeout.
2613                                          * Ensure that any remainder is rounded up.  Display
2614                                          * very discharged stacks as merely fully discharged.
2615                                          */
2616                                         power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
2617                                         if (power > o_ptr->number) power = o_ptr->number;
2618
2619                                         /* Display prettily. */
2620                                         t = object_desc_str(t, " (");
2621                                         t = object_desc_num(t, power);
2622                                         t = object_desc_str(t, _("本 充填中)", " charging)"));
2623                                 }
2624
2625                                 /* "one Rod of Perception (1 charging)" would look tacky. */
2626                                 else
2627                                 {
2628                                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2629                                 }
2630                         }
2631                 }
2632
2633                 /* Dump "pval" flags for wearable items */
2634                 if (have_pval_flags(flgs))
2635                 {
2636                         /* Start the display */
2637                         t = object_desc_chr(t, ' ');
2638                         t = object_desc_chr(t, p1);
2639
2640                         /* Dump the "pval" itself */
2641                         t = object_desc_int(t, o_ptr->pval);
2642
2643                         /* Do not display the "pval" flags */
2644                         if (have_flag(flgs, TR_HIDE_TYPE))
2645                         {
2646                                 /* Nothing */
2647                         }
2648
2649                         /* Speed */
2650                         else if (have_flag(flgs, TR_SPEED))
2651                         {
2652                                 /* Dump " to speed" */
2653                                 t = object_desc_str(t, _("加速", " to speed"));
2654                         }
2655
2656                         /* Attack speed */
2657                         else if (have_flag(flgs, TR_BLOWS))
2658                         {
2659                                 /* Add " attack" */
2660 #ifdef JP
2661                                 t = object_desc_str(t, "攻撃");
2662 #else
2663                                 t = object_desc_str(t, " attack");
2664
2665                                 /* Add "attacks" */
2666                                 if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's');
2667 #endif
2668                         }
2669
2670                         /* Stealth */
2671                         else if (have_flag(flgs, TR_STEALTH))
2672                         {
2673                                 /* Dump " to stealth" */
2674                                 t = object_desc_str(t, _("隠密", " to stealth"));
2675                         }
2676
2677                         /* Search */
2678                         else if (have_flag(flgs, TR_SEARCH))
2679                         {
2680                                 /* Dump " to searching" */
2681                                 t = object_desc_str(t, _("探索", " to searching"));
2682                         }
2683
2684                         /* Infravision */
2685                         else if (have_flag(flgs, TR_INFRA))
2686                         {
2687                                 /* Dump " to infravision" */
2688                                 t = object_desc_str(t, _("赤外線視力", " to infravision"));
2689                         }
2690
2691                         /* Finish the display */
2692                         t = object_desc_chr(t, p2);
2693                 }
2694
2695                 /* Hack -- Process Lanterns/Torches */
2696                 if ((o_ptr->tval == TV_LITE) && (!(object_is_fixed_artifact(o_ptr) || (o_ptr->sval == SV_LITE_FEANOR))))
2697                 {
2698                         /* Hack -- Turns of light for normal lites */
2699 #ifdef JP
2700                         t = object_desc_chr(t, '(');
2701 #else
2702                         t = object_desc_str(t, " (with ");
2703 #endif
2704
2705                         if (o_ptr->name2 == EGO_LITE_LONG) t = object_desc_num(t, o_ptr->xtra4 * 2);
2706                         else t = object_desc_num(t, o_ptr->xtra4);
2707                         t = object_desc_str(t, _("ターンの寿命)", " turns of light)"));
2708                 }
2709
2710                 /* Indicate charging objects, but not rods. */
2711                 if (o_ptr->timeout && (o_ptr->tval != TV_ROD))
2712                 {
2713                         /* Hack -- Dump " (charging)" if relevant */
2714                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2715                 }
2716         }
2717
2718
2719         /* No more details wanted */
2720         if (mode & OD_OMIT_INSCRIPTION) goto object_desc_done;
2721
2722
2723         /* Prepare real inscriptions in a buffer */
2724         tmp_val2[0] = '\0';
2725
2726         /* Auto abbreviation inscribe */
2727         if ((abbrev_extra || abbrev_all) && (o_ptr->ident & IDENT_MENTAL))
2728         {
2729                 if (!o_ptr->inscription || !my_strchr(quark_str(o_ptr->inscription), '%'))
2730                 {
2731                         bool kanji, all;
2732
2733 #ifdef JP
2734                         kanji = TRUE;
2735 #else
2736                         kanji = FALSE;
2737 #endif
2738                         all = abbrev_all;
2739
2740                         get_ability_abbreviation(tmp_val2, o_ptr, kanji, all);
2741                 }
2742         }
2743
2744         /* Use the standard inscription if available */
2745         if (o_ptr->inscription)
2746         {
2747                 char buff[1024];
2748
2749                 if (tmp_val2[0]) strcat(tmp_val2, ", ");
2750
2751                 /* Get inscription and convert {%} */
2752                 get_inscription(buff, o_ptr);
2753
2754                 /* strcat with correct treating of kanji */
2755                 my_strcat(tmp_val2, buff, sizeof(tmp_val2));
2756         }
2757
2758
2759         /* No fake inscription yet */
2760         fake_insc_buf[0] = '\0';
2761
2762         /* Use the game-generated "feeling" otherwise, if available */
2763         if (o_ptr->feeling)
2764         {
2765                 strcpy(fake_insc_buf, game_inscriptions[o_ptr->feeling]);
2766         }
2767
2768         /* Note "cursed" if the item is known to be cursed */
2769         else if (object_is_cursed(o_ptr) && (known || (o_ptr->ident & IDENT_SENSE)))
2770         {
2771                 strcpy(fake_insc_buf, _("呪われている", "cursed"));
2772         }
2773
2774         /* Note "unidentified" if the item is unidentified */
2775         else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET)
2776                    || (o_ptr->tval == TV_LITE) || (o_ptr->tval == TV_FIGURINE))
2777                  && aware && !known
2778                  && !(o_ptr->ident & IDENT_SENSE))
2779         {
2780                 strcpy(fake_insc_buf, _("未鑑定", "unidentified"));
2781         }
2782
2783         /* Mega-Hack -- note empty wands/staffs */
2784         else if (!known && (o_ptr->ident & IDENT_EMPTY))
2785         {
2786                 strcpy(fake_insc_buf, _("空", "empty"));
2787         }
2788
2789         /* Note "tried" if the object has been tested unsuccessfully */
2790         else if (!aware && object_is_tried(o_ptr))
2791         {
2792                 strcpy(fake_insc_buf, _("未判明", "tried"));
2793         }
2794
2795         /* Note the discount, if any */
2796         if (o_ptr->discount)
2797         {
2798                 /* Hidden by real inscription unless in a store */
2799                 if (!tmp_val2[0] || (o_ptr->ident & IDENT_STORE))
2800                 {
2801                         char discount_num_buf[4];
2802
2803                         /* Append to other fake inscriptions if any */
2804                         if (fake_insc_buf[0]) strcat(fake_insc_buf, ", ");
2805
2806                         (void)object_desc_num(discount_num_buf, o_ptr->discount);
2807                         strcat(fake_insc_buf, discount_num_buf);
2808                         strcat(fake_insc_buf, _("%引き", "% off"));
2809                 }
2810         }
2811
2812
2813         /* Append the inscription, if any */
2814         if (fake_insc_buf[0] || tmp_val2[0])
2815         {
2816                 /* Append the inscription */
2817                 t = object_desc_chr(t, ' ');
2818                 t = object_desc_chr(t, c1);
2819
2820                 /* Append fake inscriptions */
2821                 if (fake_insc_buf[0])
2822                 {
2823                         t = object_desc_str(t, fake_insc_buf);
2824                 }
2825
2826                 /* Append a separater */
2827                 if (fake_insc_buf[0] && tmp_val2[0])
2828                 {
2829                         t = object_desc_chr(t, ',');
2830                         t = object_desc_chr(t, ' ');
2831                 }
2832
2833                 /* Append real inscriptions */
2834                 if (tmp_val2[0])
2835                 {
2836                         t = object_desc_str(t, tmp_val2);
2837                 }
2838
2839                 t = object_desc_chr(t, c2);
2840         }
2841
2842 object_desc_done:
2843         my_strcpy(buf, tmp_val, MAX_NLEN);
2844 }
2845
2846