OSDN Git Service

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