OSDN Git Service

08518601225f25e7b6fa660bc3b743b59ae65990
[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  * @brief オブジェクトがクエストの達成目的か否かを返す。
1237  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1238  * @return 現在クエスト達成目的のアイテムならばTRUEを返す。
1239  */
1240 bool object_is_quest_target(object_type *o_ptr)
1241 {
1242         if (p_ptr->inside_quest)
1243         {
1244                 ARTIFACT_IDX a_idx = quest[p_ptr->inside_quest].k_idx;
1245                 if (a_idx)
1246                 {
1247                         artifact_type *a_ptr = &a_info[a_idx];
1248                         if (!(a_ptr->gen_flags & TRG_INSTA_ART))
1249                         {
1250                                 if((o_ptr->tval == a_ptr->tval) && (o_ptr->sval == a_ptr->sval))
1251                                 {
1252                                         return TRUE;
1253                                 }
1254                         }
1255                 }
1256         }
1257         return FALSE;
1258 }
1259
1260
1261 /*!
1262  * @brief オブジェクトの各表記を返すメイン関数 / Creates a description of the item "o_ptr", and stores it in "out_val".
1263  * @param buf 表記を返すための文字列参照ポインタ
1264  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1265  * @param mode 表記に関するオプション指定
1266  * @return 現在クエスト達成目的のアイテムならばTRUEを返す。
1267  * @details
1268  * One can choose the "verbosity" of the description, including whether\n
1269  * or not the "number" of items should be described, and how much detail\n
1270  * should be used when describing the item.\n
1271  *\n
1272  * The given "buf" must be MAX_NLEN chars long to hold the longest possible\n
1273  * description, which can get pretty long, including incriptions, such as:\n
1274  * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".\n
1275  * Note that the inscription will be clipped to keep the total description\n
1276  * under MAX_NLEN-1 chars (plus a terminator).\n
1277  *\n
1278  * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient,\n
1279  * portable, versions of some common "sprintf()" commands.\n
1280  *\n
1281  * Note that all ego-items (when known) append an "Ego-Item Name", unless\n
1282  * the item is also an artifact, which should NEVER happen.\n
1283  *\n
1284  * Note that all artifacts (when known) append an "Artifact Name", so we\n
1285  * have special processing for "Specials" (artifact Lites, Rings, Amulets).\n
1286  * The "Specials" never use "modifiers" if they are "known", since they\n
1287  * have special "descriptions", such as "The Necklace of the Dwarves".\n
1288  *\n
1289  * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),\n
1290  * plus the artifact name, just like any other artifact, if known.\n
1291  *\n
1292  * Special Ring's and Amulet's, if not "aware", use the same code as normal\n
1293  * rings and amulets, and if "aware", use the "k_info" base-name (Ring or\n
1294  * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,\n
1295  * they will append the artifact name, just like any artifact, if known.\n
1296  *\n
1297  * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.\n
1298  *\n
1299  * Mode:\n
1300  *   OD_NAME_ONLY        : The Cloak of Death\n
1301  *   OD_NAME_AND_ENCHANT : The Cloak of Death [1,+3]\n
1302  *   OD_OMIT_INSCRIPTION : The Cloak of Death [1,+3] (+2 to Stealth)\n
1303  *   0                   : The Cloak of Death [1,+3] (+2 to Stealth) {nifty}\n
1304  *\n
1305  *   OD_OMIT_PREFIX      : Forbidden numeric prefix\n
1306  *   OD_NO_PLURAL        : Forbidden use of plural \n
1307  *   OD_STORE            : Assume to be aware and known\n
1308  *   OD_NO_FLAVOR        : Allow to hidden flavor\n
1309  *   OD_FORCE_FLAVOR     : Get un-shuffled flavor name\n
1310  */
1311 void object_desc(char *buf, object_type *o_ptr, BIT_FLAGS mode)
1312 {
1313         /* Extract object kind name */
1314         concptr            kindname = k_name + k_info[o_ptr->k_idx].name;
1315
1316         /* Extract default "base" string */
1317         concptr            basenm = kindname;
1318
1319         /* Assume no "modifier" string */
1320         concptr            modstr = "";
1321
1322         int power;
1323         int fire_rate;
1324
1325         bool            aware = FALSE;
1326         bool            known = FALSE;
1327         bool            flavor = TRUE;
1328
1329         bool            show_weapon = FALSE;
1330         bool            show_armour = FALSE;
1331
1332         concptr            s, s0;
1333         char            *t;
1334
1335         char            p1 = '(', p2 = ')';
1336         char            b1 = '[', b2 = ']';
1337         char            c1 = '{', c2 = '}';
1338
1339         char            tmp_val[MAX_NLEN+160];
1340         char            tmp_val2[MAX_NLEN+10];
1341         char            fake_insc_buf[30];
1342
1343         BIT_FLAGS flgs[TR_FLAG_SIZE];
1344
1345         object_type *bow_ptr;
1346
1347         object_kind *k_ptr = &k_info[o_ptr->k_idx];
1348         object_kind *flavor_k_ptr = &k_info[k_ptr->flavor];
1349
1350         /* Extract some flags */
1351         object_flags(o_ptr, flgs);
1352
1353         /* See if the object is "aware" */
1354         if (object_is_aware(o_ptr)) aware = TRUE;
1355
1356         /* See if the object is "known" */
1357         if (object_is_known(o_ptr)) known = TRUE;
1358
1359         /* Allow flavors to be hidden when aware */
1360         if (aware && ((mode & OD_NO_FLAVOR) || plain_descriptions)) flavor = FALSE;
1361
1362         /* Object is in the inventory of a store or spoiler */
1363         if ((mode & OD_STORE) || (o_ptr->ident & IDENT_STORE))
1364         {
1365                 /* Don't show flavors */
1366                 flavor = FALSE;
1367
1368                 /* Pretend known and aware */
1369                 aware = TRUE;
1370                 known = TRUE;
1371         }
1372
1373         /* Force to be flavor name only */
1374         if (mode & OD_FORCE_FLAVOR)
1375         {
1376                 aware = FALSE;
1377                 flavor = TRUE;
1378                 known = FALSE;
1379
1380                 /* Cancel shuffling */
1381                 flavor_k_ptr = k_ptr;
1382         }
1383
1384         /* Analyze the object */
1385         switch (o_ptr->tval)
1386         {
1387                 /* Some objects are easy to describe */
1388                 case TV_SKELETON:
1389                 case TV_BOTTLE:
1390                 case TV_JUNK:
1391                 case TV_SPIKE:
1392                 case TV_FLASK:
1393                 case TV_CHEST:
1394                 case TV_WHISTLE:
1395                 {
1396                         break;
1397                 }
1398
1399                 case TV_CAPTURE:
1400                 {
1401                         monster_race *r_ptr = &r_info[o_ptr->pval];
1402
1403                         if (known)
1404                         {
1405                                 if (!o_ptr->pval)
1406                                 {
1407                                         modstr = _(" (空)", " (empty)");
1408                                 }
1409                                 else
1410                                 {
1411 #ifdef JP
1412                                         sprintf(tmp_val2, " (%s)",r_name + r_ptr->name);
1413                                         modstr = tmp_val2;
1414 #else
1415                                         concptr t = r_name + r_ptr->name;
1416
1417                                         if (!(r_ptr->flags1 & RF1_UNIQUE))
1418                                         {
1419                                                 sprintf(tmp_val2, " (%s%s)", (is_a_vowel(*t) ? "an " : "a "), t);
1420
1421                                                 modstr = tmp_val2;
1422                                         }
1423                                         else
1424                                         {
1425                                                 sprintf(tmp_val2, "(%s)", t);
1426
1427                                                 modstr = t;
1428                                         }
1429 #endif
1430                                 }
1431                         }
1432                         break;
1433                 }
1434
1435                 /* Figurines/Statues */
1436                 case TV_FIGURINE:
1437                 case TV_STATUE:
1438                 {
1439                         monster_race *r_ptr = &r_info[o_ptr->pval];
1440
1441 #ifdef JP
1442                         modstr = r_name + r_ptr->name;
1443 #else
1444                         concptr t = r_name + r_ptr->name;
1445
1446                         if (!(r_ptr->flags1 & RF1_UNIQUE))
1447                         {
1448                                 sprintf(tmp_val2, "%s%s", (is_a_vowel(*t) ? "an " : "a "), t);
1449
1450                                 modstr = tmp_val2;
1451                         }
1452                         else
1453                         {
1454                                 modstr = t;
1455                         }
1456 #endif
1457
1458
1459                         break;
1460                 }
1461
1462                 /* Corpses */
1463                 case TV_CORPSE:
1464                 {
1465                         monster_race *r_ptr = &r_info[o_ptr->pval];
1466
1467                         modstr = r_name + r_ptr->name;
1468
1469 #ifdef JP
1470                         basenm = "#%";
1471 #else
1472                         if (r_ptr->flags1 & RF1_UNIQUE)
1473                                 basenm = "& % of #";
1474                         else
1475                                 basenm = "& # %";
1476 #endif
1477
1478                         break;
1479                 }
1480
1481                 /* Missiles/ Bows/ Weapons */
1482                 case TV_SHOT:
1483                 case TV_BOLT:
1484                 case TV_ARROW:
1485                 case TV_BOW:
1486                 case TV_HAFTED:
1487                 case TV_POLEARM:
1488                 case TV_SWORD:
1489                 case TV_DIGGING:
1490                 {
1491                         show_weapon = TRUE;
1492                         break;
1493                 }
1494
1495                 /* Armour */
1496                 case TV_BOOTS:
1497                 case TV_GLOVES:
1498                 case TV_CLOAK:
1499                 case TV_CROWN:
1500                 case TV_HELM:
1501                 case TV_SHIELD:
1502                 case TV_SOFT_ARMOR:
1503                 case TV_HARD_ARMOR:
1504                 case TV_DRAG_ARMOR:
1505                 {
1506                         show_armour = TRUE;
1507                         break;
1508                 }
1509
1510                 /* Lites (including a few "Specials") */
1511                 case TV_LITE:
1512                 {
1513                         break;
1514                 }
1515
1516                 /* Amulets (including a few "Specials") */
1517                 case TV_AMULET:
1518                 {
1519                         /* Known artifacts */
1520                         if (aware)
1521                         {
1522                                 if (object_is_fixed_artifact(o_ptr)) break;
1523                                 if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1524                         }
1525
1526                         /* Color the object */
1527                         modstr = k_name + flavor_k_ptr->flavor_name;
1528
1529 #ifdef JP
1530                         if (!flavor)    basenm = "%のアミュレット";
1531                         else if (aware) basenm = "%の#アミュレット";
1532                         else            basenm = "#アミュレット";
1533 #else
1534                         if (!flavor)    basenm = "& Amulet~ of %";
1535                         else if (aware) basenm = "& # Amulet~ of %";
1536                         else            basenm = "& # Amulet~";
1537 #endif
1538
1539                         break;
1540                 }
1541
1542                 /* Rings (including a few "Specials") */
1543                 case TV_RING:
1544                 {
1545                         /* Known artifacts */
1546                         if (aware)
1547                         {
1548                                 if (object_is_fixed_artifact(o_ptr)) break;
1549                                 if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1550                         }
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 = "& Ring~ of %";
1561                         else if (aware) basenm = "& # Ring~ of %";
1562                         else            basenm = "& # Ring~";
1563 #endif
1564
1565                         if (!k_ptr->to_h && !k_ptr->to_d && (o_ptr->to_h || o_ptr->to_d)) show_weapon = TRUE;
1566
1567                         break;
1568                 }
1569
1570                 case TV_CARD:
1571                 {
1572                         break;
1573                 }
1574
1575                 case TV_STAFF:
1576                 {
1577                         /* Color the object */
1578                         modstr = k_name + flavor_k_ptr->flavor_name;
1579
1580 #ifdef JP
1581                         if (!flavor)    basenm = "%の杖";
1582                         else if (aware) basenm = "%の#杖";
1583                         else            basenm = "#杖";
1584 #else
1585                         if (!flavor)    basenm = "& Staff~ of %";
1586                         else if (aware) basenm = "& # Staff~ of %";
1587                         else            basenm = "& # Staff~";
1588 #endif
1589
1590                         break;
1591                 }
1592
1593                 case TV_WAND:
1594                 {
1595                         /* Color the object */
1596                         modstr = k_name + flavor_k_ptr->flavor_name;
1597
1598 #ifdef JP
1599                         if (!flavor)    basenm = "%の魔法棒";
1600                         else if (aware) basenm = "%の#魔法棒";
1601                         else            basenm = "#魔法棒";
1602 #else
1603                         if (!flavor)    basenm = "& Wand~ of %";
1604                         else if (aware) basenm = "& # Wand~ of %";
1605                         else            basenm = "& # Wand~";
1606 #endif
1607
1608                         break;
1609                 }
1610
1611                 case TV_ROD:
1612                 {
1613                         /* Color the object */
1614                         modstr = k_name + flavor_k_ptr->flavor_name;
1615
1616 #ifdef JP
1617                         if (!flavor)    basenm = "%のロッド";
1618                         else if (aware) basenm = "%の#ロッド";
1619                         else            basenm = "#ロッド";
1620 #else
1621                         if (!flavor)    basenm = "& Rod~ of %";
1622                         else if (aware) basenm = "& # Rod~ of %";
1623                         else            basenm = "& # Rod~";
1624 #endif
1625
1626                         break;
1627                 }
1628
1629                 case TV_SCROLL:
1630                 {
1631                         /* Color the object */
1632                         modstr = k_name + flavor_k_ptr->flavor_name;
1633
1634 #ifdef JP
1635                         if (!flavor)    basenm = "%の巻物";
1636                         else if (aware) basenm = "「#」と書かれた%の巻物";
1637                         else            basenm = "「#」と書かれた巻物";
1638 #else
1639                         if (!flavor)    basenm = "& Scroll~ of %";
1640                         else if (aware) basenm = "& Scroll~ titled \"#\" of %";
1641                         else            basenm = "& Scroll~ titled \"#\"";
1642 #endif
1643
1644                         break;
1645                 }
1646
1647                 case TV_POTION:
1648                 {
1649                         /* Color the object */
1650                         modstr = k_name + flavor_k_ptr->flavor_name;
1651
1652 #ifdef JP
1653                         if (!flavor)    basenm = "%の薬";
1654                         else if (aware) basenm = "%の#薬";
1655                         else            basenm = "#薬";
1656 #else
1657                         if (!flavor)    basenm = "& Potion~ of %";
1658                         else if (aware) basenm = "& # Potion~ of %";
1659                         else            basenm = "& # Potion~";
1660 #endif
1661
1662                         break;
1663                 }
1664
1665                 case TV_FOOD:
1666                 {
1667                         /* Ordinary food is "boring" */
1668                         if (!k_ptr->flavor_name) break;
1669
1670                         /* Color the object */
1671                         modstr = k_name + flavor_k_ptr->flavor_name;
1672
1673 #ifdef JP
1674                         if (!flavor)    basenm = "%のキノコ";
1675                         else if (aware) basenm = "%の#キノコ";
1676                         else            basenm = "#キノコ";
1677 #else
1678                         if (!flavor)    basenm = "& Mushroom~ of %";
1679                         else if (aware) basenm = "& # Mushroom~ of %";
1680                         else            basenm = "& # Mushroom~";
1681 #endif
1682
1683                         break;
1684                 }
1685
1686                 case TV_PARCHMENT:
1687                 {
1688                         basenm = _("羊皮紙 - %", "& Parchment~ - %");
1689                         break;
1690                 }
1691
1692                 /* Magic Books */
1693                 case TV_LIFE_BOOK:
1694                 {
1695 #ifdef JP
1696                         basenm = "生命の魔法書%";
1697 #else
1698                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1699                                 basenm = "& Book~ of Life Magic %";
1700                         else
1701                                 basenm = "& Life Spellbook~ %";
1702 #endif
1703
1704                         break;
1705                 }
1706
1707                 case TV_SORCERY_BOOK:
1708                 {
1709 #ifdef JP
1710                         basenm = "仙術の魔法書%";
1711 #else
1712                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1713                                 basenm = "& Book~ of Sorcery %";
1714                         else
1715                                 basenm = "& Sorcery Spellbook~ %";
1716 #endif
1717
1718                         break;
1719                 }
1720
1721                 case TV_NATURE_BOOK:
1722                 {
1723 #ifdef JP
1724                         basenm = "自然の魔法書%";
1725 #else
1726                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1727                                 basenm = "& Book~ of Nature Magic %";
1728                         else
1729                                 basenm = "& Nature Spellbook~ %";
1730 #endif
1731
1732                         break;
1733                 }
1734
1735                 case TV_CHAOS_BOOK:
1736                 {
1737 #ifdef JP
1738                         basenm = "カオスの魔法書%";
1739 #else
1740                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1741                                 basenm = "& Book~ of Chaos Magic %";
1742                         else
1743                                 basenm = "& Chaos Spellbook~ %";
1744 #endif
1745
1746                         break;
1747                 }
1748
1749                 case TV_DEATH_BOOK:
1750                 {
1751 #ifdef JP
1752                         basenm = "暗黒の魔法書%";
1753 #else
1754                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1755                                 basenm = "& Book~ of Death Magic %";
1756                         else
1757                                 basenm = "& Death Spellbook~ %";
1758 #endif
1759
1760                         break;
1761                 }
1762
1763                 case TV_TRUMP_BOOK:
1764                 {
1765 #ifdef JP
1766                         basenm = "トランプの魔法書%";
1767 #else
1768                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1769                                 basenm = "& Book~ of Trump Magic %";
1770                         else
1771                                 basenm = "& Trump Spellbook~ %";
1772 #endif
1773
1774                         break;
1775                 }
1776
1777                 case TV_ARCANE_BOOK:
1778                 {
1779 #ifdef JP
1780                         basenm = "秘術の魔法書%";
1781 #else
1782                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1783                                 basenm = "& Book~ of Arcane Magic %";
1784                         else
1785                                 basenm = "& Arcane Spellbook~ %";
1786 #endif
1787
1788                         break;
1789                 }
1790
1791                 case TV_CRAFT_BOOK:
1792                 {
1793 #ifdef JP
1794                         basenm = "匠の魔法書%";
1795 #else
1796                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1797                                 basenm = "& Book~ of Craft Magic %";
1798                         else
1799                                 basenm = "& Craft Spellbook~ %";
1800 #endif
1801
1802                         break;
1803                 }
1804
1805                 case TV_DAEMON_BOOK:
1806                 {
1807 #ifdef JP
1808                         basenm = "悪魔の魔法書%";
1809 #else
1810                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1811                                 basenm = "& Book~ of Daemon Magic %";
1812                         else
1813                                 basenm = "& Daemon Spellbook~ %";
1814 #endif
1815
1816                         break;
1817                 }
1818
1819                 case TV_CRUSADE_BOOK:
1820                 {
1821 #ifdef JP
1822                         basenm = "破邪の魔法書%";
1823 #else
1824                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1825                                 basenm = "& Book~ of Crusade Magic %";
1826                         else
1827                                 basenm = "& Crusade Spellbook~ %";
1828 #endif
1829
1830                         break;
1831                 }
1832
1833                 case TV_MUSIC_BOOK:
1834                 {
1835                         basenm = _("歌集%", "& Song Book~ %");
1836                         break;
1837                 }
1838
1839                 case TV_HISSATSU_BOOK:
1840                 {
1841                         basenm = _("& 武芸の書%", "Book~ of Kendo %");
1842                         break;
1843                 }
1844
1845                 case TV_HEX_BOOK:
1846                 {
1847 #ifdef JP
1848                         basenm = "呪術の魔法書%";
1849 #else
1850                         if (mp_ptr->spell_book == TV_LIFE_BOOK)
1851                                 basenm = "& Book~ of Hex Magic %";
1852                         else
1853                                 basenm = "& Hex Spellbook~ %";
1854 #endif
1855
1856                         break;
1857                 }
1858
1859                 /* Hack -- Gold/Gems */
1860                 case TV_GOLD:
1861                 {
1862                         strcpy(buf, basenm);
1863                         return;
1864                 }
1865
1866                 /* Used in the "inventory" routine */
1867                 default:
1868                 {
1869                         strcpy(buf, _("(なし)", "(nothing)"));
1870                         return;
1871                 }
1872         }
1873
1874         /* Use full name from k_info or a_info */
1875         if (aware && have_flag(flgs, TR_FULL_NAME))
1876         {
1877                 if (known && o_ptr->name1) basenm = a_name + a_info[o_ptr->name1].name;
1878                 else basenm = kindname;
1879         }
1880
1881         /* Start dumping the result */
1882         t = tmp_val;
1883
1884 #ifdef JP
1885         if (basenm[0] == '&')
1886                 s = basenm + 2;
1887         else
1888                 s = basenm;
1889
1890         /* No prefix */
1891         if (mode & OD_OMIT_PREFIX)
1892         {
1893                 /* Nothing */
1894         }
1895         else if (o_ptr->number > 1)
1896         {
1897                 t = object_desc_kosuu(t, o_ptr);
1898                 t = object_desc_str(t, "の ");
1899         }
1900
1901         /* 英語の場合アーティファクトは The が付くので分かるが
1902          * 日本語では分からないのでマークをつける 
1903          */
1904         if (known)
1905         {
1906                 if (object_is_fixed_artifact(o_ptr)) t = object_desc_str(t, "★");
1907                 else if (o_ptr->art_name) t = object_desc_str(t, "☆");
1908         }
1909
1910 #else
1911
1912         /* The object "expects" a "number" */
1913         if (basenm[0] == '&')
1914         {
1915                 /* Skip the ampersand (and space) */
1916                 s = basenm + 2;
1917
1918                 /* No prefix */
1919                 if (mode & OD_OMIT_PREFIX)
1920                 {
1921                         /* Nothing */
1922                 }
1923
1924                 /* Hack -- None left */
1925                 else if (o_ptr->number <= 0)
1926                 {
1927                         t = object_desc_str(t, "no more ");
1928                 }
1929
1930                 /* Extract the number */
1931                 else if (o_ptr->number > 1)
1932                 {
1933                         t = object_desc_num(t, o_ptr->number);
1934                         t = object_desc_chr(t, ' ');
1935                 }
1936
1937                 /* Hack -- The only one of its kind */
1938                 else if ((known && object_is_artifact(o_ptr)) ||
1939                          ((o_ptr->tval == TV_CORPSE) &&
1940                           (r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
1941                 {
1942                         t = object_desc_str(t, "The ");
1943                 }
1944
1945                 /* A single one */
1946                 else
1947                 {
1948                         bool vowel;
1949
1950                         switch (*s)
1951                         {
1952                         case '#': vowel = is_a_vowel(modstr[0]); break;
1953                         case '%': vowel = is_a_vowel(*kindname); break;
1954                         default:  vowel = is_a_vowel(*s); break;
1955                         }
1956
1957                         if (vowel)
1958                         {
1959                                 /* A single one, with a vowel */
1960                                 t = object_desc_str(t, "an ");
1961                         }
1962                         else
1963                         {
1964                                 /* A single one, without a vowel */
1965                                 t = object_desc_str(t, "a ");
1966                         }
1967                 }
1968         }
1969
1970         /* Hack -- objects that "never" take an article */
1971         else
1972         {
1973                 /* No ampersand */
1974                 s = basenm;
1975
1976                 /* No pref */
1977                 if (mode & OD_OMIT_PREFIX)
1978                 {
1979                         /* Nothing */
1980                 }
1981
1982                 /* Hack -- all gone */
1983                 else if (o_ptr->number <= 0)
1984                 {
1985                         t = object_desc_str(t, "no more ");
1986                 }
1987
1988                 /* Prefix a number if required */
1989                 else if (o_ptr->number > 1)
1990                 {
1991                         t = object_desc_num(t, o_ptr->number);
1992                         t = object_desc_chr(t, ' ');
1993                 }
1994
1995                 /* Hack -- The only one of its kind */
1996                 else if (known && object_is_artifact(o_ptr))
1997                 {
1998                         t = object_desc_str(t, "The ");
1999                 }
2000
2001                 /* Hack -- single items get no prefix */
2002                 else
2003                 {
2004                         /* Nothing */
2005                 }
2006         }
2007 #endif
2008
2009         /* Paranoia -- skip illegal tildes */
2010         /* while (*s == '~') s++; */
2011
2012 #ifdef JP
2013         if (object_is_smith(o_ptr))
2014         {
2015                 t = object_desc_str(t, format("鍛冶師%sの", p_ptr->name));
2016         }
2017
2018         /* 伝説のアイテム、名のあるアイテムの名前を付加する */
2019         if (known)
2020         {
2021                 /* ランダム・アーティファクト */
2022                 if (o_ptr->art_name)
2023                 {
2024                         concptr temp = quark_str(o_ptr->art_name);
2025
2026                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2027                         /* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */
2028                         if (strncmp(temp, "of ", 3) == 0)
2029                         {
2030                                 t = object_desc_str(t, &temp[3]);
2031                                 t = object_desc_str(t, "の");
2032                         }
2033                         else if ((strncmp(temp, "『", 2) != 0) &&
2034                                  (strncmp(temp, "《", 2) != 0) &&
2035                                  (temp[0] != '\''))
2036                                 t = object_desc_str(t, temp);
2037                 }
2038                 /* 伝説のアイテム */
2039                 else if (o_ptr->name1 && !have_flag(flgs, TR_FULL_NAME))
2040                 {
2041                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2042                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2043                         if (strncmp(a_name + a_ptr->name, "『", 2) != 0)
2044                         {
2045                                 t = object_desc_str(t, a_name + a_ptr->name);
2046                         }
2047                 }
2048                 /* 名のあるアイテム */
2049                 else if (object_is_ego(o_ptr))
2050                 {
2051                         ego_item_type *e_ptr = &e_info[o_ptr->name2];
2052                         t = object_desc_str(t, e_name + e_ptr->name);
2053                 }
2054         }
2055 #endif
2056
2057         /* Copy the string */
2058         for (s0 = NULL; *s || s0; )
2059         {
2060                 /* The end of the flavour/kind string. */
2061                 if (!*s)
2062                 {
2063                         s = s0 + 1;
2064                         s0 = NULL;
2065                 }
2066
2067                 /* Begin to append the modifier (flavor) */
2068                 else if ((*s == '#') && !s0)
2069                 {
2070                         s0 = s;
2071                         s = modstr;
2072
2073                         /* Paranoia -- Never append multiple modstrs */
2074                         modstr = "";
2075                 }
2076
2077                 /* Begin to append the kind name */
2078                 else if ((*s == '%') && !s0)
2079                 {
2080                         s0 = s;
2081                         s = kindname;
2082
2083                         /* Paranoia -- Never append multiple kindnames */
2084                         kindname = "";
2085                 }
2086
2087 #ifndef JP
2088                 /* Pluralizer */
2089                 else if (*s == '~')
2090                 {
2091                         /* Add a plural if needed */
2092                         if (!(mode & OD_NO_PLURAL) && (o_ptr->number != 1))
2093                         {
2094                                 char k = t[-1];
2095
2096                                 /* Mega-Hack */
2097
2098                                 /* Hack -- "Cutlass-es" and "Torch-es" */
2099                                 if ((k == 's') || (k == 'h')) *t++ = 'e';
2100
2101                                 /* Add an 's' */
2102                                 *t++ = 's';
2103                         }
2104                         s++;
2105                 }
2106 #endif
2107
2108                 /* Normal */
2109                 else
2110                 {
2111                         /* Copy */
2112                         *t++ = *s++;
2113                 }
2114         }
2115
2116         /* Terminate */
2117         *t = '\0';
2118
2119
2120 #ifdef JP
2121         /* '『'から始まる伝説のアイテムの名前は最後に付加する */
2122         if (known)
2123         {
2124                 /* ランダムアーティファクトの名前はセーブファイルに記録
2125                    されるので、英語版の名前もそれらしく変換する */
2126                 if (o_ptr->art_name)
2127                 {
2128                         char temp[256];
2129                         int itemp;
2130                         strcpy(temp, quark_str(o_ptr->art_name));
2131                         /* MEGA HACK by ita */
2132                         if (strncmp(temp, "『", 2) == 0 ||
2133                             strncmp(temp, "《", 2) == 0)
2134                                 t = object_desc_str(t, temp);
2135                         else if (temp[0] == '\'')
2136                         {
2137                                 itemp = strlen(temp);
2138                                 temp[itemp - 1] = 0;
2139                                 t = object_desc_str(t, "『");
2140                                 t = object_desc_str(t, &temp[1]);
2141                                 t = object_desc_str(t, "』");
2142                         }
2143                 }
2144                 else if (object_is_fixed_artifact(o_ptr))
2145                 {
2146                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2147                         if (strncmp(a_name + a_ptr->name, "『", 2) == 0)
2148                         {
2149                                 t = object_desc_str(t, a_name + a_ptr->name);
2150                         }
2151                 }
2152                 else if (o_ptr->inscription)
2153                 {
2154                         concptr str = quark_str(o_ptr->inscription);
2155
2156                         while(*str)
2157                         {
2158                                 if (iskanji(*str))
2159                                 {
2160                                         str += 2;
2161                                         continue;
2162                                 }
2163                                 if (*str == '#') break;
2164                                 str++;
2165                         }
2166                         if (*str)
2167                         {
2168                                 /* Find the '#' */
2169                                 concptr str_aux = my_strchr(quark_str(o_ptr->inscription), '#');
2170
2171                                 /* Add the false name */
2172                                 t = object_desc_str(t,"『");
2173                                 t = object_desc_str(t, &str_aux[1]);
2174                                 t = object_desc_str(t,"』");
2175                         }
2176                 }
2177         }
2178 #else
2179         if (object_is_smith(o_ptr))
2180         {
2181                 t = object_desc_str(t,format(" of %s the Smith",p_ptr->name));
2182         }
2183
2184         /* Hack -- Append "Artifact" or "Special" names */
2185         if (known && !have_flag(flgs, TR_FULL_NAME))
2186         {
2187                 /* Is it a new random artifact ? */
2188                 if (o_ptr->art_name)
2189                 {
2190                         t = object_desc_chr(t, ' ');
2191                         t = object_desc_str(t, quark_str(o_ptr->art_name));
2192                 }
2193
2194                 /* Grab any artifact name */
2195                 else if (object_is_fixed_artifact(o_ptr))
2196                 {
2197                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2198
2199                         t = object_desc_chr(t, ' ');
2200                         t = object_desc_str(t, a_name + a_ptr->name);
2201                 }
2202
2203                 /* Grab any ego-item name */
2204                 else
2205                 {
2206                         if (object_is_ego(o_ptr))
2207                         {
2208                                 ego_item_type *e_ptr = &e_info[o_ptr->name2];
2209
2210                                 t = object_desc_chr(t, ' ');
2211                                 t = object_desc_str(t, e_name + e_ptr->name);
2212                         }
2213
2214                         if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '#'))
2215                         {
2216                                 /* Find the '#' */
2217                                 concptr str = my_strchr(quark_str(o_ptr->inscription), '#');
2218
2219                                 /* Add the false name */
2220                                 t = object_desc_chr(t, ' ');
2221                                 t = object_desc_str(t, &str[1]);
2222                         }
2223                 }
2224         }
2225 #endif
2226
2227
2228         /* No more details wanted */
2229         if (mode & OD_NAME_ONLY) goto object_desc_done;
2230
2231         /* Hack -- Chests must be described in detail */
2232         if (o_ptr->tval == TV_CHEST)
2233         {
2234                 /* Not searched yet */
2235                 if (!known)
2236                 {
2237                         /* Nothing */
2238                 }
2239
2240                 /* May be "empty" */
2241                 else if (!o_ptr->pval)
2242                 {
2243                         t = object_desc_str(t, _("(空)", " (empty)"));
2244                 }
2245
2246                 /* May be "disarmed" */
2247                 else if (o_ptr->pval < 0)
2248                 {
2249                         if (chest_traps[0 - o_ptr->pval])
2250                         {
2251                                 t = object_desc_str(t, _("(解除済)", " (disarmed)"));
2252                         }
2253                         else
2254                         {
2255                                 t = object_desc_str(t, _("(非施錠)", " (unlocked)"));
2256                         }
2257                 }
2258
2259                 /* Describe the traps, if any */
2260                 else
2261                 {
2262                         /* Describe the traps */
2263                         switch (chest_traps[o_ptr->pval])
2264                         {
2265                                 case 0:
2266                                 {
2267                                         t = object_desc_str(t, _("(施錠)", " (Locked)"));
2268                                         break;
2269                                 }
2270                                 case CHEST_LOSE_STR:
2271                                 {
2272                                         t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2273                                         break;
2274                                 }
2275                                 case CHEST_LOSE_CON:
2276                                 {
2277                                         t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2278                                         break;
2279                                 }
2280                                 case CHEST_POISON:
2281                                 {
2282                                         t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2283                                         break;
2284                                 }
2285                                 case CHEST_PARALYZE:
2286                                 {
2287                                         t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2288                                         break;
2289                                 }
2290                                 case CHEST_EXPLODE:
2291                                 {
2292                                         t = object_desc_str(t, _("(爆発装置)", " (Explosion Device)"));
2293                                         break;
2294                                 }
2295                                 case CHEST_SUMMON:
2296                                 case CHEST_BIRD_STORM:
2297                                 case CHEST_E_SUMMON:
2298                                 case CHEST_H_SUMMON:
2299                                 {
2300                                         t = object_desc_str(t, _("(召喚のルーン)", " (Summoning Runes)"));
2301                                         break;
2302                                 }
2303                                 case CHEST_RUNES_OF_EVIL:
2304                                 {
2305                                         t = object_desc_str(t, _("(邪悪なルーン)", " (Gleaming Black Runes)"));
2306                                         break;
2307                                 }
2308                                 case CHEST_ALARM:
2309                                 {
2310                                         t = object_desc_str(t, _("(警報装置)", " (Alarm)"));
2311                                         break;
2312                                 }
2313                                 default:
2314                                 {
2315                                         t = object_desc_str(t, _("(マルチ・トラップ)", " (Multiple Traps)"));
2316                                         break;
2317                                 }
2318                         }
2319                 }
2320         }
2321
2322
2323         /* Display the item like a weapon */
2324         if (have_flag(flgs, TR_SHOW_MODS)) show_weapon = TRUE;
2325
2326         /* Display the item like a weapon */
2327         if (object_is_smith(o_ptr) && (o_ptr->xtra3 == 1 + ESSENCE_SLAY_GLOVE))
2328                 show_weapon = TRUE;
2329
2330         /* Display the item like a weapon */
2331         if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;
2332
2333         /* Display the item like armour */
2334         if (o_ptr->ac) show_armour = TRUE;
2335
2336
2337         /* Dump base weapon info */
2338         switch (o_ptr->tval)
2339         {
2340                 /* Missiles and Weapons */
2341                 case TV_SHOT:
2342                 case TV_BOLT:
2343                 case TV_ARROW:
2344                 case TV_HAFTED:
2345                 case TV_POLEARM:
2346                 case TV_SWORD:
2347             case TV_DIGGING:
2348                 
2349                 /* In Vault Quest, hide the dice of target weapon. */
2350                 if(object_is_quest_target(o_ptr) && !known)
2351                 {
2352                         break;
2353                 }
2354
2355                 /* Append a "damage" string */
2356                 t = object_desc_chr(t, ' ');
2357                 t = object_desc_chr(t, p1);
2358                 t = object_desc_num(t, o_ptr->dd);
2359                 t = object_desc_chr(t, 'd');
2360                 t = object_desc_num(t, o_ptr->ds);
2361                 t = object_desc_chr(t, p2);
2362
2363                 /* All done */
2364                 break;
2365
2366
2367                 /* Bows get a special "damage string" */
2368                 case TV_BOW:
2369
2370                 /* Mega-Hack -- Extract the "base power" */
2371                 power = bow_tmul(o_ptr->sval);
2372
2373                 /* Apply the "Extra Might" flag */
2374                 if (have_flag(flgs, TR_XTRA_MIGHT)) power++;
2375
2376                 /* Append a special "damage" string */
2377                 t = object_desc_chr(t, ' ');
2378                 t = object_desc_chr(t, p1);
2379                 t = object_desc_chr(t, 'x');
2380                 t = object_desc_num(t, power);
2381                 t = object_desc_chr(t, p2);
2382                 
2383                 fire_rate = calc_num_fire(o_ptr);
2384                 /* Show Fire rate */
2385                 if (fire_rate != 0 && power > 0 && known)
2386                 {       
2387                         fire_rate = bow_energy(o_ptr->sval) / fire_rate;
2388                         
2389                         t = object_desc_chr(t, ' ');
2390                         t = object_desc_chr(t, p1);                     
2391                         t = object_desc_num(t,  fire_rate/100);
2392                         t = object_desc_chr(t,  '.');
2393                         t = object_desc_num(t,  fire_rate%100);
2394                         t = object_desc_str(t, "turn");
2395                         t = object_desc_chr(t, p2);
2396                 }
2397                 
2398                 /* All done */
2399                 break;
2400         }
2401
2402
2403         /* Add the weapon bonuses */
2404         if (known)
2405         {
2406                 /* Show the tohit/todam on request */
2407                 if (show_weapon)
2408                 {
2409                         t = object_desc_chr(t, ' ');
2410                         t = object_desc_chr(t, p1);
2411                         t = object_desc_int(t, o_ptr->to_h);
2412                         t = object_desc_chr(t, ',');
2413                         t = object_desc_int(t, o_ptr->to_d);
2414                         t = object_desc_chr(t, p2);
2415                 }
2416
2417                 /* Show the tohit if needed */
2418                 else if (o_ptr->to_h)
2419                 {
2420                         t = object_desc_chr(t, ' ');
2421                         t = object_desc_chr(t, p1);
2422                         t = object_desc_int(t, o_ptr->to_h);
2423                         t = object_desc_chr(t, p2);
2424                 }
2425
2426                 /* Show the todam if needed */
2427                 else if (o_ptr->to_d)
2428                 {
2429                         t = object_desc_chr(t, ' ');
2430                         t = object_desc_chr(t, p1);
2431                         t = object_desc_int(t, o_ptr->to_d);
2432                         t = object_desc_chr(t, p2);
2433                 }
2434         }
2435
2436         bow_ptr = &inventory[INVEN_BOW];
2437
2438         /* If have a firing weapon + ammo matches bow */
2439         if (bow_ptr->k_idx && (o_ptr->tval == p_ptr->tval_ammo))
2440         {
2441                 int avgdam = o_ptr->dd * (o_ptr->ds + 1) * 10 / 2;
2442                 int tmul = bow_tmul(bow_ptr->sval);
2443                 ENERGY energy_fire = bow_energy(bow_ptr->sval);
2444
2445                 /* See if the bow is "known" - then set damage bonus */
2446                 if (object_is_known(bow_ptr)) avgdam += (bow_ptr->to_d * 10);
2447
2448                 /* Effect of ammo */
2449                 if (known) avgdam += (o_ptr->to_d * 10);
2450
2451                 /* Get extra "power" from "extra might" */
2452                 if (p_ptr->xtra_might) tmul++;
2453
2454                 tmul = tmul * (100 + (int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
2455
2456                 /* Launcher multiplier */
2457                 avgdam *= tmul;
2458                 avgdam /= (100 * 10);
2459
2460                 /* Get extra damage from concentration */
2461                 if (p_ptr->concent) avgdam = boost_concentration_damage(avgdam);
2462                 
2463                 if (avgdam < 0) avgdam = 0;
2464
2465                 /* Display (shot damage/ shot damage with critical/ avg damage with critical) */
2466                 t = object_desc_chr(t, ' ');
2467                 t = object_desc_chr(t, p1);
2468                 
2469                 if(show_ammo_no_crit)
2470                 {
2471                         /* Damage with no-crit */
2472                         t = object_desc_num(t, avgdam);
2473                         t = object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2474                 }
2475                 
2476                 /* Apply Expect damage of Critical */
2477                 avgdam = calc_expect_crit_shot(o_ptr->weight, o_ptr->to_h, bow_ptr->to_h, avgdam);
2478                 t = object_desc_num(t, avgdam);
2479                 
2480                 t = show_ammo_no_crit ? object_desc_str(t, show_ammo_detail ? "/crit " : "/")
2481                                                           : object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2482         
2483                 if (p_ptr->num_fire == 0)
2484                 {
2485                         t = object_desc_chr(t, '0');
2486                 }
2487                 else
2488                 {
2489                         /* Calc effects of energy */
2490                         avgdam *= (p_ptr->num_fire * 100);
2491                         avgdam /= energy_fire;
2492                         t = object_desc_num(t, avgdam);
2493                         t = object_desc_str(t, show_ammo_detail ? "/turn" : "");
2494                         
2495                         if(show_ammo_crit_ratio)
2496                         {
2497                                 int percent = calc_crit_ratio_shot(known ? o_ptr->to_h : 0, known ? bow_ptr->to_h : 0);
2498                                 
2499                                 t = object_desc_chr(t, '/');
2500                                 t = object_desc_num(t, percent / 100);
2501                                 t = object_desc_chr(t, '.');
2502                 if(percent % 100 < 10)
2503                 {
2504                                     t = object_desc_chr(t, '0');
2505                 }
2506                                 t = object_desc_num(t, percent % 100);
2507                                 t = object_desc_str(t, show_ammo_detail ? "% crit" : "%");
2508                         }
2509                 }
2510
2511                 t = object_desc_chr(t, p2);
2512         }
2513         else if ((p_ptr->pclass == CLASS_NINJA) && (o_ptr->tval == TV_SPIKE))
2514         {
2515                 int avgdam = p_ptr->mighty_throw ? (1 + 3) : 1;
2516                 s16b energy_fire = 100 - p_ptr->lev;
2517
2518                 avgdam += ((p_ptr->lev + 30) * (p_ptr->lev + 30) - 900) / 55;
2519
2520                 /* Display (shot damage/ avg damage) */
2521                 t = object_desc_chr(t, ' ');
2522                 t = object_desc_chr(t, p1);
2523                 t = object_desc_num(t, avgdam);
2524                 t = object_desc_chr(t, '/');
2525
2526                 /* Calc effects of energy */
2527                 avgdam = 100 * avgdam / energy_fire;
2528
2529                 t = object_desc_num(t, avgdam);
2530                 t = object_desc_chr(t, p2);
2531         }
2532
2533         /* Add the armor bonuses */
2534         if (known)
2535         {
2536                 /* Show the armor class info */
2537                 if (show_armour)
2538                 {
2539                         t = object_desc_chr(t, ' ');
2540                         t = object_desc_chr(t, b1);
2541                         t = object_desc_num(t, o_ptr->ac);
2542                         t = object_desc_chr(t, ',');
2543                         t = object_desc_int(t, o_ptr->to_a);
2544                         t = object_desc_chr(t, b2);
2545                 }
2546
2547                 /* No base armor, but does increase armor */
2548                 else if (o_ptr->to_a)
2549                 {
2550                         t = object_desc_chr(t, ' ');
2551                         t = object_desc_chr(t, b1);
2552                         t = object_desc_int(t, o_ptr->to_a);
2553                         t = object_desc_chr(t, b2);
2554                 }
2555         }
2556
2557         /* Hack -- always show base armor */
2558         else if (show_armour)
2559         {
2560                 t = object_desc_chr(t, ' ');
2561                 t = object_desc_chr(t, b1);
2562                 t = object_desc_num(t, o_ptr->ac);
2563                 t = object_desc_chr(t, b2);
2564         }
2565
2566
2567         /* No more details wanted */
2568         if (mode & OD_NAME_AND_ENCHANT) goto object_desc_done;
2569
2570
2571         if (known) /* Known item only */
2572         {
2573                 /*
2574                  * Hack -- Wands and Staffs have charges.  Make certain how many charges
2575                  * a stack of staffs really has is clear. -LM-
2576                  */
2577                 if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
2578                 {
2579                         /* Dump " (N charges)" */
2580                         t = object_desc_chr(t, ' ');
2581                         t = object_desc_chr(t, p1);
2582
2583                         /* Clear explaination for staffs. */
2584                         if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
2585                         {
2586                                 t = object_desc_num(t, o_ptr->number);
2587                                 t = object_desc_str(t, "x ");
2588                         }
2589                         t = object_desc_num(t, o_ptr->pval);
2590 #ifdef JP
2591                         t = object_desc_str(t, "回分");
2592 #else
2593                         t = object_desc_str(t, " charge");
2594                         if (o_ptr->pval != 1) t = object_desc_chr(t, 's');
2595 #endif
2596
2597                         t = object_desc_chr(t, p2);
2598                 }
2599                 /* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
2600                  * be in any state of charge or discharge, this now includes a number. -LM-
2601                  */
2602                 else if (o_ptr->tval == TV_ROD)
2603                 {
2604                         /* Hack -- Dump " (# charging)" if relevant */
2605                         if (o_ptr->timeout)
2606                         {
2607                                 /* Stacks of rods display an exact count of charging rods. */
2608                                 if (o_ptr->number > 1)
2609                                 {
2610                                         /* Paranoia. */
2611                                         if (k_ptr->pval == 0) k_ptr->pval = 1;
2612
2613                                         /* Find out how many rods are charging, by dividing
2614                                          * current timeout by each rod's maximum timeout.
2615                                          * Ensure that any remainder is rounded up.  Display
2616                                          * very discharged stacks as merely fully discharged.
2617                                          */
2618                                         power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
2619                                         if (power > o_ptr->number) power = o_ptr->number;
2620
2621                                         /* Display prettily. */
2622                                         t = object_desc_str(t, " (");
2623                                         t = object_desc_num(t, power);
2624                                         t = object_desc_str(t, _("本 充填中)", " charging)"));
2625                                 }
2626
2627                                 /* "one Rod of Perception (1 charging)" would look tacky. */
2628                                 else
2629                                 {
2630                                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2631                                 }
2632                         }
2633                 }
2634
2635                 /* Dump "pval" flags for wearable items */
2636                 if (have_pval_flags(flgs))
2637                 {
2638                         /* Start the display */
2639                         t = object_desc_chr(t, ' ');
2640                         t = object_desc_chr(t, p1);
2641
2642                         /* Dump the "pval" itself */
2643                         t = object_desc_int(t, o_ptr->pval);
2644
2645                         /* Do not display the "pval" flags */
2646                         if (have_flag(flgs, TR_HIDE_TYPE))
2647                         {
2648                                 /* Nothing */
2649                         }
2650
2651                         /* Speed */
2652                         else if (have_flag(flgs, TR_SPEED))
2653                         {
2654                                 /* Dump " to speed" */
2655                                 t = object_desc_str(t, _("加速", " to speed"));
2656                         }
2657
2658                         /* Attack speed */
2659                         else if (have_flag(flgs, TR_BLOWS))
2660                         {
2661                                 /* Add " attack" */
2662 #ifdef JP
2663                                 t = object_desc_str(t, "攻撃");
2664 #else
2665                                 t = object_desc_str(t, " attack");
2666
2667                                 /* Add "attacks" */
2668                                 if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's');
2669 #endif
2670                         }
2671
2672                         /* Stealth */
2673                         else if (have_flag(flgs, TR_STEALTH))
2674                         {
2675                                 /* Dump " to stealth" */
2676                                 t = object_desc_str(t, _("隠密", " to stealth"));
2677                         }
2678
2679                         /* Search */
2680                         else if (have_flag(flgs, TR_SEARCH))
2681                         {
2682                                 /* Dump " to searching" */
2683                                 t = object_desc_str(t, _("探索", " to searching"));
2684                         }
2685
2686                         /* Infravision */
2687                         else if (have_flag(flgs, TR_INFRA))
2688                         {
2689                                 /* Dump " to infravision" */
2690                                 t = object_desc_str(t, _("赤外線視力", " to infravision"));
2691                         }
2692
2693                         /* Finish the display */
2694                         t = object_desc_chr(t, p2);
2695                 }
2696
2697                 /* Hack -- Process Lanterns/Torches */
2698                 if ((o_ptr->tval == TV_LITE) && (!(object_is_fixed_artifact(o_ptr) || (o_ptr->sval == SV_LITE_FEANOR))))
2699                 {
2700                         /* Hack -- Turns of light for normal lites */
2701 #ifdef JP
2702                         t = object_desc_chr(t, '(');
2703 #else
2704                         t = object_desc_str(t, " (with ");
2705 #endif
2706
2707                         if (o_ptr->name2 == EGO_LITE_LONG) t = object_desc_num(t, o_ptr->xtra4 * 2);
2708                         else t = object_desc_num(t, o_ptr->xtra4);
2709                         t = object_desc_str(t, _("ターンの寿命)", " turns of light)"));
2710                 }
2711
2712                 /* Indicate charging objects, but not rods. */
2713                 if (o_ptr->timeout && (o_ptr->tval != TV_ROD))
2714                 {
2715                         /* Hack -- Dump " (charging)" if relevant */
2716                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2717                 }
2718         }
2719
2720
2721         /* No more details wanted */
2722         if (mode & OD_OMIT_INSCRIPTION) goto object_desc_done;
2723
2724
2725         /* Prepare real inscriptions in a buffer */
2726         tmp_val2[0] = '\0';
2727
2728         /* Auto abbreviation inscribe */
2729         if ((abbrev_extra || abbrev_all) && (o_ptr->ident & IDENT_MENTAL))
2730         {
2731                 if (!o_ptr->inscription || !my_strchr(quark_str(o_ptr->inscription), '%'))
2732                 {
2733                         bool kanji, all;
2734
2735 #ifdef JP
2736                         kanji = TRUE;
2737 #else
2738                         kanji = FALSE;
2739 #endif
2740                         all = abbrev_all;
2741
2742                         get_ability_abbreviation(tmp_val2, o_ptr, kanji, all);
2743                 }
2744         }
2745
2746         /* Use the standard inscription if available */
2747         if (o_ptr->inscription)
2748         {
2749                 char buff[1024];
2750
2751                 if (tmp_val2[0]) strcat(tmp_val2, ", ");
2752
2753                 /* Get inscription and convert {%} */
2754                 get_inscription(buff, o_ptr);
2755
2756                 /* strcat with correct treating of kanji */
2757                 my_strcat(tmp_val2, buff, sizeof(tmp_val2));
2758         }
2759
2760
2761         /* No fake inscription yet */
2762         fake_insc_buf[0] = '\0';
2763
2764         /* Use the game-generated "feeling" otherwise, if available */
2765         if (o_ptr->feeling)
2766         {
2767                 strcpy(fake_insc_buf, game_inscriptions[o_ptr->feeling]);
2768         }
2769
2770         /* Note "cursed" if the item is known to be cursed */
2771         else if (object_is_cursed(o_ptr) && (known || (o_ptr->ident & IDENT_SENSE)))
2772         {
2773                 strcpy(fake_insc_buf, _("呪われている", "cursed"));
2774         }
2775
2776         /* Note "unidentified" if the item is unidentified */
2777         else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET)
2778                    || (o_ptr->tval == TV_LITE) || (o_ptr->tval == TV_FIGURINE))
2779                  && aware && !known
2780                  && !(o_ptr->ident & IDENT_SENSE))
2781         {
2782                 strcpy(fake_insc_buf, _("未鑑定", "unidentified"));
2783         }
2784
2785         /* Mega-Hack -- note empty wands/staffs */
2786         else if (!known && (o_ptr->ident & IDENT_EMPTY))
2787         {
2788                 strcpy(fake_insc_buf, _("空", "empty"));
2789         }
2790
2791         /* Note "tried" if the object has been tested unsuccessfully */
2792         else if (!aware && object_is_tried(o_ptr))
2793         {
2794                 strcpy(fake_insc_buf, _("未判明", "tried"));
2795         }
2796
2797         /* Note the discount, if any */
2798         if (o_ptr->discount)
2799         {
2800                 /* Hidden by real inscription unless in a store */
2801                 if (!tmp_val2[0] || (o_ptr->ident & IDENT_STORE))
2802                 {
2803                         char discount_num_buf[4];
2804
2805                         /* Append to other fake inscriptions if any */
2806                         if (fake_insc_buf[0]) strcat(fake_insc_buf, ", ");
2807
2808                         (void)object_desc_num(discount_num_buf, o_ptr->discount);
2809                         strcat(fake_insc_buf, discount_num_buf);
2810                         strcat(fake_insc_buf, _("%引き", "% off"));
2811                 }
2812         }
2813
2814
2815         /* Append the inscription, if any */
2816         if (fake_insc_buf[0] || tmp_val2[0])
2817         {
2818                 /* Append the inscription */
2819                 t = object_desc_chr(t, ' ');
2820                 t = object_desc_chr(t, c1);
2821
2822                 /* Append fake inscriptions */
2823                 if (fake_insc_buf[0])
2824                 {
2825                         t = object_desc_str(t, fake_insc_buf);
2826                 }
2827
2828                 /* Append a separater */
2829                 if (fake_insc_buf[0] && tmp_val2[0])
2830                 {
2831                         t = object_desc_chr(t, ',');
2832                         t = object_desc_chr(t, ' ');
2833                 }
2834
2835                 /* Append real inscriptions */
2836                 if (tmp_val2[0])
2837                 {
2838                         t = object_desc_str(t, tmp_val2);
2839                 }
2840
2841                 t = object_desc_chr(t, c2);
2842         }
2843
2844 object_desc_done:
2845         my_strcpy(buf, tmp_val, MAX_NLEN);
2846 }
2847
2848