OSDN Git Service

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