OSDN Git Service

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