OSDN Git Service

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