OSDN Git Service

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