OSDN Git Service

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