OSDN Git Service

[Refactor] #38862 Moved floor*.c to floor/
[hengband/hengband.git] / src / object / 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 "object/object-kind.h"
22 #include "object/object-hook.h"
23 #include "object/object-flavor.h"
24 #include "trap.h"
25 #include "snipe.h"
26 #include "files.h"
27 #include "world/world.h"
28 #include "monsterrace.h"
29 #include "object/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 Staffs */
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                 /* Fall through */
564         default:
565         {
566                 if (o_ptr->number < 10)
567                 {
568                         t = object_desc_str(t, "つ");
569                 }
570                 else
571                 {
572                         t = object_desc_str(t, "個");
573                 }
574                 break;
575         }
576         }
577         return (t);
578 }
579 #endif
580
581 /*!
582  * @brief 対象文字配列に符号あり整数値をコピーする。
583  * @param t 保管先文字列ポインタ
584  * @param v コピーしたい数値
585  * @return なし
586  * @details
587  * Print an signed number "v" into a string "t", as if by
588  * sprintf(t, "%+d", n), and return a pointer to the terminator.
589  * Note that we always print a sign, either "+" or "-".
590  */
591 static char *object_desc_int(char *t, sint v)
592 {
593         uint p, n;
594
595         /* Negative */
596         if (v < 0)
597         {
598                 /* Take the absolute value */
599                 n = 0 - v;
600
601                 /* Use a "minus" sign */
602                 *t++ = '-';
603         }
604
605         /* Positive (or zero) */
606         else
607         {
608                 /* Use the actual number */
609                 n = v;
610
611                 /* Use a "plus" sign */
612                 *t++ = '+';
613         }
614
615         /* Find "size" of "n" */
616         for (p = 1; n >= p * 10; p = p * 10) /* loop */;
617
618         /* Dump each digit */
619         while (p >= 1)
620         {
621                 /* Dump the digit */
622                 *t++ = '0' + n / p;
623
624                 /* Remove the digit */
625                 n = n % p;
626
627                 /* Process next digit */
628                 p = p / 10;
629         }
630
631         /* Terminate */
632         *t = '\0';
633         return (t);
634 }
635
636
637 /*!
638  * オブジェクトの特性表示記号テーブルの構造体 / Structs and tables for Auto Inscription for flags
639  */
640 typedef struct flag_insc_table
641 {
642 #ifdef JP
643         concptr japanese;
644 #endif
645         concptr english;
646         int flag;
647         int except_flag;
648 } flag_insc_table;
649
650 #ifdef JP
651 /*! オブジェクトの特性表示記号テーブルの定義(pval要素) */
652 static flag_insc_table flag_insc_plus[] =
653 {
654         { "攻", "At", TR_BLOWS, -1 },
655         { "速", "Sp", TR_SPEED, -1 },
656         { "腕", "St", TR_STR, -1 },
657         { "知", "In", TR_INT, -1 },
658         { "賢", "Wi", TR_WIS, -1 },
659         { "器", "Dx", TR_DEX, -1 },
660         { "耐", "Cn", TR_CON, -1 },
661         { "魅", "Ch", TR_CHR, -1 },
662         { "道", "Md", TR_MAGIC_MASTERY, -1 },
663         { "隠", "Sl", TR_STEALTH, -1 },
664         { "探", "Sr", TR_SEARCH, -1 },
665         { "赤", "If", TR_INFRA, -1 },
666         { "掘", "Dg", TR_TUNNEL, -1 },
667         { NULL, NULL, 0, -1 }
668 };
669
670 /*! オブジェクトの特性表示記号テーブルの定義(免疫) */
671 static flag_insc_table flag_insc_immune[] =
672 {
673         { "酸", "Ac", TR_IM_ACID, -1 },
674         { "電", "El", TR_IM_ELEC, -1 },
675         { "火", "Fi", TR_IM_FIRE, -1 },
676         { "冷", "Co", TR_IM_COLD, -1 },
677         { NULL, NULL, 0, -1 }
678 };
679
680 /*! オブジェクトの特性表示記号テーブルの定義(耐性) */
681 static flag_insc_table flag_insc_resistance[] =
682 {
683         { "酸", "Ac", TR_RES_ACID, TR_IM_ACID },
684         { "電", "El", TR_RES_ELEC, TR_IM_ELEC },
685         { "火", "Fi", TR_RES_FIRE, TR_IM_FIRE },
686         { "冷", "Co", TR_RES_COLD, TR_IM_COLD },
687         { "毒", "Po", TR_RES_POIS, -1 },
688         { "閃", "Li", TR_RES_LITE, -1 },
689         { "暗", "Dk", TR_RES_DARK, -1 },
690         { "破", "Sh", TR_RES_SHARDS, -1 },
691         { "盲", "Bl", TR_RES_BLIND, -1 },
692         { "乱", "Cf", TR_RES_CONF, -1 },
693         { "轟", "So", TR_RES_SOUND, -1 },
694         { "獄", "Nt", TR_RES_NETHER, -1 },
695         { "因", "Nx", TR_RES_NEXUS, -1 },
696         { "沌", "Ca", TR_RES_CHAOS, -1 },
697         { "劣", "Di", TR_RES_DISEN, -1 },
698         { "恐", "Fe", TR_RES_FEAR, -1 },
699         { NULL, NULL, 0, -1 }
700 };
701
702 /*! オブジェクトの特性表示記号テーブルの定義(その他特性) */
703 static flag_insc_table flag_insc_misc[] =
704 {
705         { "易", "Es", TR_EASY_SPELL, -1 },
706         { "減", "Dm", TR_DEC_MANA, -1 },
707         { "投", "Th", TR_THROW, -1 },
708         { "反", "Rf", TR_REFLECT, -1 },
709         { "麻", "Fa", TR_FREE_ACT, -1 },
710         { "視", "Si", TR_SEE_INVIS, -1 },
711         { "経", "Hl", TR_HOLD_EXP, -1 },
712         { "遅", "Sd", TR_SLOW_DIGEST, -1 },
713         { "活", "Rg", TR_REGEN, -1 },
714         { "浮", "Lv", TR_LEVITATION, -1 },
715         { "明", "Lu", TR_LITE_1, -1 },
716         { "明", "Lu", TR_LITE_2, -1 },
717         { "明", "Lu", TR_LITE_3, -1 },
718         { "闇", "Dl", TR_LITE_M1, -1 },
719         { "闇", "Dl", TR_LITE_M2, -1 },
720         { "闇", "Dl", TR_LITE_M3, -1 },
721         { "警", "Wr", TR_WARNING, -1 },
722         { "倍", "Xm", TR_XTRA_MIGHT, -1 },
723         { "射", "Xs", TR_XTRA_SHOTS, -1 },
724         { "瞬", "Te", TR_TELEPORT, -1 },
725         { "怒", "Ag", TR_AGGRAVATE, -1 },
726         { "祝", "Bs", TR_BLESSED, -1 },
727         { "忌", "Ty", TR_TY_CURSE, -1 },
728         { "呪", "C-", TR_ADD_L_CURSE, -1 },
729         { "詛", "C+", TR_ADD_H_CURSE, -1 },
730         { NULL, NULL, 0, -1 }
731 };
732
733 /*! オブジェクトの特性表示記号テーブルの定義(オーラ) */
734 static flag_insc_table flag_insc_aura[] =
735 {
736         { "炎", "F", TR_SH_FIRE, -1 },
737         { "電", "E", TR_SH_ELEC, -1 },
738         { "冷", "C", TR_SH_COLD, -1 },
739         { "魔", "M", TR_NO_MAGIC, -1 },
740         { "瞬", "T", TR_NO_TELE, -1 },
741         { NULL, NULL, 0, -1 }
742 };
743
744 /*! オブジェクトの特性表示記号テーブルの定義(属性スレイ) */
745 static flag_insc_table flag_insc_brand[] =
746 {
747         { "酸", "A", TR_BRAND_ACID, -1 },
748         { "電", "E", TR_BRAND_ELEC, -1 },
749         { "焼", "F", TR_BRAND_FIRE, -1 },
750         { "凍", "Co", TR_BRAND_COLD, -1 },
751         { "毒", "P", TR_BRAND_POIS, -1 },
752         { "沌", "Ca", TR_CHAOTIC, -1 },
753         { "吸", "V", TR_VAMPIRIC, -1 },
754         { "震", "Q", TR_IMPACT, -1 },
755         { "切", "S", TR_VORPAL, -1 },
756         { "理", "M", TR_FORCE_WEAPON, -1 },
757         { NULL, NULL, 0, -1 }
758 };
759
760 /*! オブジェクトの特性表示記号テーブルの定義(種族スレイ) */
761 static flag_insc_table flag_insc_kill[] =
762 {
763         { "邪", "*", TR_KILL_EVIL, -1 },
764         { "人", "p", TR_KILL_HUMAN, -1 },
765         { "龍", "D", TR_KILL_DRAGON, -1 },
766         { "オ", "o", TR_KILL_ORC, -1 },
767         { "ト", "T", TR_KILL_TROLL, -1 },
768         { "巨", "P", TR_KILL_GIANT, -1 },
769         { "デ", "U", TR_KILL_DEMON, -1 },
770         { "死", "L", TR_KILL_UNDEAD, -1 },
771         { "動", "Z", TR_KILL_ANIMAL, -1 },
772         { NULL, NULL, 0, -1 }
773 };
774
775 /*! オブジェクトの特性表示記号テーブルの定義(種族*スレイ*) */
776 static flag_insc_table flag_insc_slay[] =
777 {
778         { "邪", "*", TR_SLAY_EVIL, TR_KILL_EVIL },
779         { "人", "p", TR_SLAY_HUMAN, TR_KILL_HUMAN },
780         { "竜", "D", TR_SLAY_DRAGON, TR_KILL_DRAGON },
781         { "オ", "o", TR_SLAY_ORC, TR_KILL_ORC },
782         { "ト", "T", TR_SLAY_TROLL, TR_KILL_TROLL },
783         { "巨", "P", TR_SLAY_GIANT, TR_KILL_GIANT },
784         { "デ", "U", TR_SLAY_DEMON, TR_KILL_DEMON },
785         { "死", "L", TR_SLAY_UNDEAD, TR_KILL_UNDEAD },
786         { "動", "Z", TR_SLAY_ANIMAL, TR_KILL_ANIMAL },
787         { NULL, NULL, 0, -1 }
788 };
789
790 /*! オブジェクトの特性表示記号テーブルの定義(ESP1) */
791 static flag_insc_table flag_insc_esp1[] =
792 {
793         { "感", "Tele", TR_TELEPATHY, -1 },
794         { "邪", "Evil", TR_ESP_EVIL, -1 },
795         { "善", "Good", TR_ESP_GOOD, -1 },
796         { "無", "Nolv", TR_ESP_NONLIVING, -1 },
797         { "個", "Uniq", TR_ESP_UNIQUE, -1 },
798         { NULL, NULL, 0, -1 }
799 };
800
801 /*! オブジェクトの特性表示記号テーブルの定義(ESP2) */
802 static flag_insc_table flag_insc_esp2[] =
803 {
804         { "人", "p", TR_ESP_HUMAN, -1 },
805         { "竜", "D", TR_ESP_DRAGON, -1 },
806         { "オ", "o", TR_ESP_ORC, -1 },
807         { "ト", "T", TR_ESP_TROLL, -1 },
808         { "巨", "P", TR_ESP_GIANT, -1 },
809         { "デ", "U", TR_ESP_DEMON, -1 },
810         { "死", "L", TR_ESP_UNDEAD, -1 },
811         { "動", "Z", TR_ESP_ANIMAL, -1 },
812         { NULL, NULL, 0, -1 }
813 };
814
815 /*! オブジェクトの特性表示記号テーブルの定義(能力維持) */
816 static flag_insc_table flag_insc_sust[] =
817 {
818         { "腕", "St", TR_SUST_STR, -1 },
819         { "知", "In", TR_SUST_INT, -1 },
820         { "賢", "Wi", TR_SUST_WIS, -1 },
821         { "器", "Dx", TR_SUST_DEX, -1 },
822         { "耐", "Cn", TR_SUST_CON, -1 },
823         { "魅", "Ch", TR_SUST_CHR, -1 },
824         { NULL, NULL, 0, -1 }
825 };
826
827 #else
828 static flag_insc_table flag_insc_plus[] =
829 {
830         { "At", TR_BLOWS, -1 },
831         { "Sp", TR_SPEED, -1 },
832         { "St", TR_STR, -1 },
833         { "In", TR_INT, -1 },
834         { "Wi", TR_WIS, -1 },
835         { "Dx", TR_DEX, -1 },
836         { "Cn", TR_CON, -1 },
837         { "Ch", TR_CHR, -1 },
838         { "Md", TR_MAGIC_MASTERY, -1 },
839         { "Sl", TR_STEALTH, -1 },
840         { "Sr", TR_SEARCH, -1 },
841         { "If", TR_INFRA, -1 },
842         { "Dg", TR_TUNNEL, -1 },
843         { NULL, 0, -1 }
844 };
845
846 static flag_insc_table flag_insc_immune[] =
847 {
848         { "Ac", TR_IM_ACID, -1 },
849         { "El", TR_IM_ELEC, -1 },
850         { "Fi", TR_IM_FIRE, -1 },
851         { "Co", TR_IM_COLD, -1 },
852         { NULL, 0, -1 }
853 };
854
855 static flag_insc_table flag_insc_resistance[] =
856 {
857         { "Ac", TR_RES_ACID, TR_IM_ACID },
858         { "El", TR_RES_ELEC, TR_IM_ELEC },
859         { "Fi", TR_RES_FIRE, TR_IM_FIRE },
860         { "Co", TR_RES_COLD, TR_IM_COLD },
861         { "Po", TR_RES_POIS, -1 },
862         { "Li", TR_RES_LITE, -1 },
863         { "Dk", TR_RES_DARK, -1 },
864         { "Sh", TR_RES_SHARDS, -1 },
865         { "Bl", TR_RES_BLIND, -1 },
866         { "Cf", TR_RES_CONF, -1 },
867         { "So", TR_RES_SOUND, -1 },
868         { "Nt", TR_RES_NETHER, -1 },
869         { "Nx", TR_RES_NEXUS, -1 },
870         { "Ca", TR_RES_CHAOS, -1 },
871         { "Di", TR_RES_DISEN, -1 },
872         { "Fe", TR_RES_FEAR, -1 },
873         { NULL, 0, -1 }
874 };
875
876 static flag_insc_table flag_insc_misc[] =
877 {
878         { "Es", TR_EASY_SPELL, -1 },
879         { "Dm", TR_DEC_MANA, -1 },
880         { "Th", TR_THROW, -1 },
881         { "Rf", TR_REFLECT, -1 },
882         { "Fa", TR_FREE_ACT, -1 },
883         { "Si", TR_SEE_INVIS, -1 },
884         { "Hl", TR_HOLD_EXP, -1 },
885         { "Sd", TR_SLOW_DIGEST, -1 },
886         { "Rg", TR_REGEN, -1 },
887         { "Lv", TR_LEVITATION, -1 },
888         { "Lu", TR_LITE_1, -1 },
889         { "Lu", TR_LITE_2, -1 },
890         { "Lu", TR_LITE_3, -1 },
891         { "Dl", TR_LITE_M1, -1 },
892         { "Dl", TR_LITE_M2, -1 },
893         { "Dl", TR_LITE_M3, -1 },
894         { "Wr", TR_WARNING, -1 },
895         { "Xm", TR_XTRA_MIGHT, -1 },
896         { "Xs", TR_XTRA_SHOTS, -1 },
897         { "Te", TR_TELEPORT, -1 },
898         { "Ag", TR_AGGRAVATE, -1 },
899         { "Bs", TR_BLESSED, -1 },
900         { "Ty", TR_TY_CURSE, -1 },
901         { "C-", TR_ADD_L_CURSE, -1 },
902         { "C+", TR_ADD_H_CURSE, -1 },
903         { NULL, 0, -1 }
904 };
905
906 static flag_insc_table flag_insc_aura[] =
907 {
908         { "F", TR_SH_FIRE, -1 },
909         { "E", TR_SH_ELEC, -1 },
910         { "C", TR_SH_COLD, -1 },
911         { "M", TR_NO_MAGIC, -1 },
912         { "T", TR_NO_TELE, -1 },
913         { NULL, 0, -1 }
914 };
915
916 static flag_insc_table flag_insc_brand[] =
917 {
918         { "A", TR_BRAND_ACID, -1 },
919         { "E", TR_BRAND_ELEC, -1 },
920         { "F", TR_BRAND_FIRE, -1 },
921         { "Co", TR_BRAND_COLD, -1 },
922         { "P", TR_BRAND_POIS, -1 },
923         { "Ca", TR_CHAOTIC, -1 },
924         { "V", TR_VAMPIRIC, -1 },
925         { "Q", TR_IMPACT, -1 },
926         { "S", TR_VORPAL, -1 },
927         { "M", TR_FORCE_WEAPON, -1 },
928         { NULL, 0, -1 }
929 };
930
931 static flag_insc_table flag_insc_kill[] =
932 {
933         { "*", TR_KILL_EVIL, -1 },
934         { "p", TR_KILL_HUMAN, -1 },
935         { "D", TR_KILL_DRAGON, -1 },
936         { "o", TR_KILL_ORC, -1 },
937         { "T", TR_KILL_TROLL, -1 },
938         { "P", TR_KILL_GIANT, -1 },
939         { "U", TR_KILL_DEMON, -1 },
940         { "L", TR_KILL_UNDEAD, -1 },
941         { "Z", TR_KILL_ANIMAL, -1 },
942         { NULL, 0, -1 }
943 };
944
945 static flag_insc_table flag_insc_slay[] =
946 {
947         { "*", TR_SLAY_EVIL, TR_KILL_EVIL },
948         { "p", TR_SLAY_HUMAN, TR_KILL_HUMAN },
949         { "D", TR_SLAY_DRAGON, TR_KILL_DRAGON },
950         { "o", TR_SLAY_ORC, TR_KILL_ORC },
951         { "T", TR_SLAY_TROLL, TR_KILL_TROLL },
952         { "P", TR_SLAY_GIANT, TR_KILL_GIANT },
953         { "U", TR_SLAY_DEMON, TR_KILL_DEMON },
954         { "L", TR_SLAY_UNDEAD, TR_KILL_UNDEAD },
955         { "Z", TR_SLAY_ANIMAL, TR_KILL_ANIMAL },
956         { NULL, 0, -1 }
957 };
958
959 static flag_insc_table flag_insc_esp1[] =
960 {
961         { "Tele", TR_TELEPATHY, -1 },
962         { "Evil", TR_ESP_EVIL, -1 },
963         { "Good", TR_ESP_GOOD, -1 },
964         { "Nolv", TR_ESP_NONLIVING, -1 },
965         { "Uniq", TR_ESP_UNIQUE, -1 },
966         { NULL, 0, -1 }
967 };
968
969 static flag_insc_table flag_insc_esp2[] =
970 {
971         { "p", TR_ESP_HUMAN, -1 },
972         { "D", TR_ESP_DRAGON, -1 },
973         { "o", TR_ESP_ORC, -1 },
974         { "T", TR_ESP_TROLL, -1 },
975         { "P", TR_ESP_GIANT, -1 },
976         { "U", TR_ESP_DEMON, -1 },
977         { "L", TR_ESP_UNDEAD, -1 },
978         { "Z", TR_ESP_ANIMAL, -1 },
979         { NULL, 0, -1 }
980 };
981
982 static flag_insc_table flag_insc_sust[] =
983 {
984         { "St", TR_SUST_STR, -1 },
985         { "In", TR_SUST_INT, -1 },
986         { "Wi", TR_SUST_WIS, -1 },
987         { "Dx", TR_SUST_DEX, -1 },
988         { "Cn", TR_SUST_CON, -1 },
989         { "Ch", TR_SUST_CHR, -1 },
990         { NULL, 0, -1 }
991 };
992 #endif
993
994 /* オブジェクトフラグを追加するための簡易なマクロ / Simple macro for get_inscription() */
995 #define ADD_INSC(STR) (void)(ptr = object_desc_str(ptr, (STR)))
996
997 /*!
998  * @brief get_inscriptionのサブセットとしてオブジェクトの特性フラグを返す / Helper function for get_inscription()
999  * @param fi_ptr 参照する特性表示記号テーブル
1000  * @param flgs 対応するオブジェクトのフラグ文字列
1001  * @param kanji TRUEならば漢字記述/FALSEならば英語記述
1002  * @param ptr フラグ群を保管する文字列参照ポインタ
1003  * @return フラグ群を保管する文字列参照ポインタ(ptrと同じ)
1004  * @details
1005  * Print an signed number "v" into a string "t", as if by
1006  * sprintf(t, "%+d", n), and return a pointer to the terminator.
1007  * Note that we always print a sign, either "+" or "-".
1008  */
1009 static char *inscribe_flags_aux(flag_insc_table *fi_ptr, BIT_FLAGS flgs[TR_FLAG_SIZE], bool kanji, char *ptr)
1010 {
1011 #ifdef JP
1012 #else
1013
1014         (void)kanji;
1015 #endif
1016
1017         while (fi_ptr->english)
1018         {
1019                 if (have_flag(flgs, fi_ptr->flag) &&
1020                         (fi_ptr->except_flag == -1 || !have_flag(flgs, fi_ptr->except_flag)))
1021 #ifdef JP
1022                         ADD_INSC(kanji ? fi_ptr->japanese : fi_ptr->english);
1023 #else
1024                         ADD_INSC(fi_ptr->english);
1025 #endif
1026                 fi_ptr++;
1027         }
1028
1029         return ptr;
1030 }
1031
1032
1033 /*!
1034  * @brief オブジェクトの特性表示記号テーブル1つに従いオブジェクトの特性フラグ配列に1つでも該当の特性があるかを返す / Special variation of have_flag for auto-inscription
1035  * @param fi_ptr 参照する特性表示記号テーブル
1036  * @param flgs 対応するオブジェクトのフラグ文字列
1037  * @return 1つでも該当の特性があったらTRUEを返す。
1038  */
1039 static bool have_flag_of(flag_insc_table *fi_ptr, BIT_FLAGS flgs[TR_FLAG_SIZE])
1040 {
1041         while (fi_ptr->english)
1042         {
1043                 if (have_flag(flgs, fi_ptr->flag) &&
1044                         (fi_ptr->except_flag == -1 || !have_flag(flgs, fi_ptr->except_flag)))
1045                         return TRUE;
1046                 fi_ptr++;
1047         }
1048
1049         return FALSE;
1050 }
1051
1052 /*!
1053  * @brief オブジェクト名の特性短縮表記をまとめて提示する。
1054  * @param ptr 特性短縮表記を格納する文字列ポインタ
1055  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1056  * @param kanji TRUEならば漢字表記 / FALSEなら英語表記
1057  * @param all TRUEならばベースアイテム上で明らかなフラグは省略する
1058  * @return ptrと同じアドレス
1059  */
1060 static char *get_ability_abbreviation(char *ptr, object_type *o_ptr, bool kanji, bool all)
1061 {
1062         char *prev_ptr = ptr;
1063         BIT_FLAGS flgs[TR_FLAG_SIZE];
1064         object_flags(o_ptr, flgs);
1065
1066         /* Remove obvious flags */
1067         if (!all)
1068         {
1069                 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1070                 int j;
1071
1072                 /* Base object */
1073                 for (j = 0; j < TR_FLAG_SIZE; j++)
1074                         flgs[j] &= ~k_ptr->flags[j];
1075
1076                 if (object_is_fixed_artifact(o_ptr))
1077                 {
1078                         artifact_type *a_ptr = &a_info[o_ptr->name1];
1079
1080                         for (j = 0; j < TR_FLAG_SIZE; j++)
1081                                 flgs[j] &= ~a_ptr->flags[j];
1082                 }
1083
1084                 if (object_is_ego(o_ptr))
1085                 {
1086                         ego_item_type *e_ptr = &e_info[o_ptr->name2];
1087
1088                         for (j = 0; j < TR_FLAG_SIZE; j++)
1089                                 flgs[j] &= ~e_ptr->flags[j];
1090                 }
1091         }
1092
1093         /* Remove lite flags when this is a dark lite object */
1094         if (HAVE_DARK_FLAG(flgs))
1095         {
1096                 if (have_flag(flgs, TR_LITE_1)) remove_flag(flgs, TR_LITE_1);
1097                 if (have_flag(flgs, TR_LITE_2)) remove_flag(flgs, TR_LITE_2);
1098                 if (have_flag(flgs, TR_LITE_3)) remove_flag(flgs, TR_LITE_3);
1099         }
1100         else if (HAVE_LITE_FLAG(flgs))
1101         {
1102                 add_flag(flgs, TR_LITE_1);
1103                 if (have_flag(flgs, TR_LITE_2)) remove_flag(flgs, TR_LITE_2);
1104                 if (have_flag(flgs, TR_LITE_3)) remove_flag(flgs, TR_LITE_3);
1105         }
1106
1107         /* Plusses */
1108         if (have_flag_of(flag_insc_plus, flgs))
1109         {
1110                 if (kanji)
1111                         ADD_INSC("+");
1112         }
1113         ptr = inscribe_flags_aux(flag_insc_plus, flgs, kanji, ptr);
1114
1115         /* Immunity */
1116         if (have_flag_of(flag_insc_immune, flgs))
1117         {
1118                 if (!kanji && ptr != prev_ptr)
1119                 {
1120                         ADD_INSC(";");
1121                         prev_ptr = ptr;
1122                 }
1123                 ADD_INSC("*");
1124         }
1125         ptr = inscribe_flags_aux(flag_insc_immune, flgs, kanji, ptr);
1126
1127         /* Resistance */
1128         if (have_flag_of(flag_insc_resistance, flgs))
1129         {
1130                 if (kanji)
1131                         ADD_INSC("r");
1132                 else if (ptr != prev_ptr)
1133                 {
1134                         ADD_INSC(";");
1135                         prev_ptr = ptr;
1136                 }
1137         }
1138         ptr = inscribe_flags_aux(flag_insc_resistance, flgs, kanji, ptr);
1139
1140         /* Misc Ability */
1141         if (have_flag_of(flag_insc_misc, flgs))
1142         {
1143                 if (ptr != prev_ptr)
1144                 {
1145                         ADD_INSC(";");
1146                         prev_ptr = ptr;
1147                 }
1148         }
1149         ptr = inscribe_flags_aux(flag_insc_misc, flgs, kanji, ptr);
1150
1151         /* Aura */
1152         if (have_flag_of(flag_insc_aura, flgs))
1153         {
1154                 ADD_INSC("[");
1155         }
1156         ptr = inscribe_flags_aux(flag_insc_aura, flgs, kanji, ptr);
1157
1158         /* Brand Weapon */
1159         if (have_flag_of(flag_insc_brand, flgs))
1160                 ADD_INSC("|");
1161         ptr = inscribe_flags_aux(flag_insc_brand, flgs, kanji, ptr);
1162
1163         /* Kill Weapon */
1164         if (have_flag_of(flag_insc_kill, flgs))
1165                 ADD_INSC("/X");
1166         ptr = inscribe_flags_aux(flag_insc_kill, flgs, kanji, ptr);
1167
1168         /* Slay Weapon */
1169         if (have_flag_of(flag_insc_slay, flgs))
1170                 ADD_INSC("/");
1171         ptr = inscribe_flags_aux(flag_insc_slay, flgs, kanji, ptr);
1172
1173         /* Esp */
1174         if (kanji)
1175         {
1176                 if (have_flag_of(flag_insc_esp1, flgs) ||
1177                         have_flag_of(flag_insc_esp2, flgs))
1178                         ADD_INSC("~");
1179                 ptr = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, ptr);
1180                 ptr = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, ptr);
1181         }
1182         else
1183         {
1184                 if (have_flag_of(flag_insc_esp1, flgs))
1185                         ADD_INSC("~");
1186                 ptr = inscribe_flags_aux(flag_insc_esp1, flgs, kanji, ptr);
1187                 if (have_flag_of(flag_insc_esp2, flgs))
1188                         ADD_INSC("~");
1189                 ptr = inscribe_flags_aux(flag_insc_esp2, flgs, kanji, ptr);
1190         }
1191
1192         /* sustain */
1193         if (have_flag_of(flag_insc_sust, flgs))
1194         {
1195                 ADD_INSC("(");
1196         }
1197         ptr = inscribe_flags_aux(flag_insc_sust, flgs, kanji, ptr);
1198
1199         *ptr = '\0';
1200
1201         return ptr;
1202 }
1203
1204
1205 /*!
1206  * @brief オブジェクト名の特性短縮表記+刻み内容を提示する。 / Get object inscription with auto inscription of object flags.
1207  * @param buff 特性短縮表記を格納する文字列ポインタ
1208  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1209  * @return なし
1210  */
1211 static void get_inscription(char *buff, object_type *o_ptr)
1212 {
1213         concptr insc = quark_str(o_ptr->inscription);
1214         char *ptr = buff;
1215
1216         /* Not fully identified */
1217         if (!OBJECT_IS_FULL_KNOWN(o_ptr))
1218         {
1219                 /* Copy until end of line or '#' */
1220                 while (*insc)
1221                 {
1222                         if (*insc == '#') break;
1223 #ifdef JP
1224                         if (iskanji(*insc)) *buff++ = *insc++;
1225 #endif
1226                         *buff++ = *insc++;
1227                 }
1228
1229                 *buff = '\0';
1230                 return;
1231         }
1232
1233         *buff = '\0';
1234         for (; *insc; insc++)
1235         {
1236                 /* Ignore fake artifact inscription */
1237                 if (*insc == '#') break;
1238
1239                 /* {%} will be automatically converted */
1240                 else if ('%' == *insc)
1241                 {
1242                         bool kanji = FALSE;
1243                         bool all;
1244                         concptr start = ptr;
1245
1246                         /* check for too long inscription */
1247                         if (ptr >= buff + MAX_NLEN) continue;
1248
1249 #ifdef JP
1250                         if ('%' == insc[1])
1251                         {
1252                                 insc++;
1253                                 kanji = FALSE;
1254                         }
1255                         else
1256                         {
1257                                 kanji = TRUE;
1258                         }
1259 #endif
1260                         if ('a' == insc[1] && 'l' == insc[2] && 'l' == insc[3])
1261                         {
1262                                 all = TRUE;
1263                                 insc += 3;
1264                         }
1265                         else
1266                         {
1267                                 all = FALSE;
1268                         }
1269
1270                         ptr = get_ability_abbreviation(ptr, o_ptr, kanji, all);
1271
1272                         if (ptr == start)
1273                                 ADD_INSC(" ");
1274                 }
1275                 else
1276                 {
1277                         *ptr++ = *insc;
1278                 }
1279         }
1280         *ptr = '\0';
1281 }
1282
1283
1284 /*!
1285  * @brief オブジェクトの各表記を返すメイン関数 / Creates a description of the item "o_ptr", and stores it in "out_val".
1286  * @param player_ptr プレーヤーへの参照ポインタ
1287  * @param buf 表記を返すための文字列参照ポインタ
1288  * @param o_ptr 特性短縮表記を得たいオブジェクト構造体の参照ポインタ
1289  * @param mode 表記に関するオプション指定
1290  * @return 現在クエスト達成目的のアイテムならばTRUEを返す。
1291  * @details
1292  * One can choose the "verbosity" of the description, including whether\n
1293  * or not the "number" of items should be described, and how much detail\n
1294  * should be used when describing the item.\n
1295  *\n
1296  * The given "buf" must be MAX_NLEN chars long to hold the longest possible\n
1297  * description, which can get pretty long, including incriptions, such as:\n
1298  * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".\n
1299  * Note that the inscription will be clipped to keep the total description\n
1300  * under MAX_NLEN-1 chars (plus a terminator).\n
1301  *\n
1302  * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient,\n
1303  * portable, versions of some common "sprintf()" commands.\n
1304  *\n
1305  * Note that all ego-items (when known) append an "Ego-Item Name", unless\n
1306  * the item is also an artifact, which should NEVER happen.\n
1307  *\n
1308  * Note that all artifacts (when known) append an "Artifact Name", so we\n
1309  * have special processing for "Specials" (artifact Lites, Rings, Amulets).\n
1310  * The "Specials" never use "modifiers" if they are "known", since they\n
1311  * have special "descriptions", such as "The Necklace of the Dwarves".\n
1312  *\n
1313  * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),\n
1314  * plus the artifact name, just like any other artifact, if known.\n
1315  *\n
1316  * Special Ring's and Amulet's, if not "aware", use the same code as normal\n
1317  * rings and amulets, and if "aware", use the "k_info" base-name (Ring or\n
1318  * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,\n
1319  * they will append the artifact name, just like any artifact, if known.\n
1320  *\n
1321  * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.\n
1322  *\n
1323  * Mode:\n
1324  *   OD_NAME_ONLY        : The Cloak of Death\n
1325  *   OD_NAME_AND_ENCHANT : The Cloak of Death [1,+3]\n
1326  *   OD_OMIT_INSCRIPTION : The Cloak of Death [1,+3] (+2 to Stealth)\n
1327  *   0                   : The Cloak of Death [1,+3] (+2 to Stealth) {nifty}\n
1328  *\n
1329  *   OD_OMIT_PREFIX      : Forbidden numeric prefix\n
1330  *   OD_NO_PLURAL        : Forbidden use of plural \n
1331  *   OD_STORE            : Assume to be aware and known\n
1332  *   OD_NO_FLAVOR        : Allow to hidden flavor\n
1333  *   OD_FORCE_FLAVOR     : Get un-shuffled flavor name\n
1334  */
1335 void object_desc(player_type *player_ptr, char *buf, object_type *o_ptr, BIT_FLAGS mode)
1336 {
1337         /* Extract object kind name */
1338         concptr            kindname = k_name + k_info[o_ptr->k_idx].name;
1339
1340         /* Extract default "base" string */
1341         concptr            basenm = kindname;
1342
1343         /* Assume no "modifier" string */
1344         concptr            modstr = "";
1345
1346         int power;
1347         int fire_rate;
1348
1349         bool            aware = FALSE;
1350         bool            known = FALSE;
1351         bool            flavor = TRUE;
1352
1353         bool            show_weapon = FALSE;
1354         bool            show_armour = FALSE;
1355
1356         concptr            s, s0;
1357         char            *t;
1358
1359         char            p1 = '(', p2 = ')';
1360         char            b1 = '[', b2 = ']';
1361         char            c1 = '{', c2 = '}';
1362
1363         char            tmp_val[MAX_NLEN + 160];
1364         char            tmp_val2[MAX_NLEN + 10];
1365         char            fake_insc_buf[30];
1366
1367         BIT_FLAGS flgs[TR_FLAG_SIZE];
1368
1369         object_type *bow_ptr;
1370
1371         object_kind *k_ptr = &k_info[o_ptr->k_idx];
1372         object_kind *flavor_k_ptr = &k_info[k_ptr->flavor];
1373
1374         /* Extract some flags */
1375         object_flags(o_ptr, flgs);
1376
1377         /* See if the object is "aware" */
1378         if (object_is_aware(o_ptr)) aware = TRUE;
1379
1380         /* See if the object is "known" */
1381         if (object_is_known(o_ptr)) known = TRUE;
1382
1383         /* Allow flavors to be hidden when aware */
1384         if (aware && ((mode & OD_NO_FLAVOR) || plain_descriptions)) flavor = FALSE;
1385
1386         if ((mode & OD_STORE) || (o_ptr->ident & IDENT_STORE))
1387         {
1388                 /* Don't show flavors */
1389                 flavor = FALSE;
1390
1391                 /* Pretend known and aware */
1392                 aware = TRUE;
1393                 known = TRUE;
1394         }
1395
1396         /* Force to be flavor name only */
1397         if (mode & OD_FORCE_FLAVOR)
1398         {
1399                 aware = FALSE;
1400                 flavor = TRUE;
1401                 known = FALSE;
1402
1403                 /* Cancel shuffling */
1404                 flavor_k_ptr = k_ptr;
1405         }
1406
1407         /* Analyze the object */
1408         switch (o_ptr->tval)
1409         {
1410                 /* Some objects are easy to describe */
1411         case TV_SKELETON:
1412         case TV_BOTTLE:
1413         case TV_JUNK:
1414         case TV_SPIKE:
1415         case TV_FLASK:
1416         case TV_CHEST:
1417         case TV_WHISTLE:
1418         {
1419                 break;
1420         }
1421
1422         case TV_CAPTURE:
1423         {
1424                 monster_race *r_ptr = &r_info[o_ptr->pval];
1425
1426                 if (known)
1427                 {
1428                         if (!o_ptr->pval)
1429                         {
1430                                 modstr = _(" (空)", " (empty)");
1431                         }
1432                         else
1433                         {
1434 #ifdef JP
1435                                 sprintf(tmp_val2, " (%s)", r_name + r_ptr->name);
1436                                 modstr = tmp_val2;
1437 #else
1438                                 t = r_name + r_ptr->name;
1439
1440                                 if (!(r_ptr->flags1 & RF1_UNIQUE))
1441                                 {
1442                                         sprintf(tmp_val2, " (%s%s)", (is_a_vowel(*t) ? "an " : "a "), t);
1443
1444                                         modstr = tmp_val2;
1445                                 }
1446                                 else
1447                                 {
1448                                         sprintf(tmp_val2, "(%s)", t);
1449
1450                                         modstr = t;
1451                                 }
1452 #endif
1453                         }
1454                 }
1455                 break;
1456         }
1457
1458         /* Figurines/Statues */
1459         case TV_FIGURINE:
1460         case TV_STATUE:
1461         {
1462                 monster_race *r_ptr = &r_info[o_ptr->pval];
1463
1464 #ifdef JP
1465                 modstr = r_name + r_ptr->name;
1466 #else
1467                 t = r_name + r_ptr->name;
1468
1469                 if (!(r_ptr->flags1 & RF1_UNIQUE))
1470                 {
1471                         sprintf(tmp_val2, "%s%s", (is_a_vowel(*t) ? "an " : "a "), t);
1472
1473                         modstr = tmp_val2;
1474                 }
1475                 else
1476                 {
1477                         modstr = t;
1478                 }
1479 #endif
1480
1481
1482                 break;
1483         }
1484
1485         /* Corpses */
1486         case TV_CORPSE:
1487         {
1488                 monster_race *r_ptr = &r_info[o_ptr->pval];
1489
1490                 modstr = r_name + r_ptr->name;
1491
1492 #ifdef JP
1493                 basenm = "#%";
1494 #else
1495                 if (r_ptr->flags1 & RF1_UNIQUE)
1496                         basenm = "& % of #";
1497                 else
1498                         basenm = "& # %";
1499 #endif
1500
1501                 break;
1502         }
1503
1504         /* Missiles/ Bows/ Weapons */
1505         case TV_SHOT:
1506         case TV_BOLT:
1507         case TV_ARROW:
1508         case TV_BOW:
1509         case TV_HAFTED:
1510         case TV_POLEARM:
1511         case TV_SWORD:
1512         case TV_DIGGING:
1513         {
1514                 show_weapon = TRUE;
1515                 break;
1516         }
1517
1518         /* Armour */
1519         case TV_BOOTS:
1520         case TV_GLOVES:
1521         case TV_CLOAK:
1522         case TV_CROWN:
1523         case TV_HELM:
1524         case TV_SHIELD:
1525         case TV_SOFT_ARMOR:
1526         case TV_HARD_ARMOR:
1527         case TV_DRAG_ARMOR:
1528         {
1529                 show_armour = TRUE;
1530                 break;
1531         }
1532
1533         /* Lites (including a few "Specials") */
1534         case TV_LITE:
1535         {
1536                 break;
1537         }
1538
1539         /* Amulets (including a few "Specials") */
1540         case TV_AMULET:
1541         {
1542                 /* Known artifacts */
1543                 if (aware)
1544                 {
1545                         if (object_is_fixed_artifact(o_ptr)) break;
1546                         if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1547                 }
1548
1549                 /* Color the object */
1550                 modstr = k_name + flavor_k_ptr->flavor_name;
1551
1552 #ifdef JP
1553                 if (!flavor)    basenm = "%のアミュレット";
1554                 else if (aware) basenm = "%の#アミュレット";
1555                 else            basenm = "#アミュレット";
1556 #else
1557                 if (!flavor)    basenm = "& Amulet~ of %";
1558                 else if (aware) basenm = "& # Amulet~ of %";
1559                 else            basenm = "& # Amulet~";
1560 #endif
1561
1562                 break;
1563         }
1564
1565         /* Rings (including a few "Specials") */
1566         case TV_RING:
1567         {
1568                 /* Known artifacts */
1569                 if (aware)
1570                 {
1571                         if (object_is_fixed_artifact(o_ptr)) break;
1572                         if (k_ptr->gen_flags & TRG_INSTA_ART) break;
1573                 }
1574
1575                 /* Color the object */
1576                 modstr = k_name + flavor_k_ptr->flavor_name;
1577
1578 #ifdef JP
1579                 if (!flavor)    basenm = "%の指輪";
1580                 else if (aware) basenm = "%の#指輪";
1581                 else            basenm = "#指輪";
1582 #else
1583                 if (!flavor)    basenm = "& Ring~ of %";
1584                 else if (aware) basenm = "& # Ring~ of %";
1585                 else            basenm = "& # Ring~";
1586 #endif
1587
1588                 if (!k_ptr->to_h && !k_ptr->to_d && (o_ptr->to_h || o_ptr->to_d)) show_weapon = TRUE;
1589
1590                 break;
1591         }
1592
1593         case TV_CARD:
1594         {
1595                 break;
1596         }
1597
1598         case TV_STAFF:
1599         {
1600                 /* Color the object */
1601                 modstr = k_name + flavor_k_ptr->flavor_name;
1602
1603 #ifdef JP
1604                 if (!flavor)    basenm = "%の杖";
1605                 else if (aware) basenm = "%の#杖";
1606                 else            basenm = "#杖";
1607 #else
1608                 if (!flavor)    basenm = "& Staff~ of %";
1609                 else if (aware) basenm = "& # Staff~ of %";
1610                 else            basenm = "& # Staff~";
1611 #endif
1612
1613                 break;
1614         }
1615
1616         case TV_WAND:
1617         {
1618                 /* Color the object */
1619                 modstr = k_name + flavor_k_ptr->flavor_name;
1620
1621 #ifdef JP
1622                 if (!flavor)    basenm = "%の魔法棒";
1623                 else if (aware) basenm = "%の#魔法棒";
1624                 else            basenm = "#魔法棒";
1625 #else
1626                 if (!flavor)    basenm = "& Wand~ of %";
1627                 else if (aware) basenm = "& # Wand~ of %";
1628                 else            basenm = "& # Wand~";
1629 #endif
1630
1631                 break;
1632         }
1633
1634         case TV_ROD:
1635         {
1636                 /* Color the object */
1637                 modstr = k_name + flavor_k_ptr->flavor_name;
1638
1639 #ifdef JP
1640                 if (!flavor)    basenm = "%のロッド";
1641                 else if (aware) basenm = "%の#ロッド";
1642                 else            basenm = "#ロッド";
1643 #else
1644                 if (!flavor)    basenm = "& Rod~ of %";
1645                 else if (aware) basenm = "& # Rod~ of %";
1646                 else            basenm = "& # Rod~";
1647 #endif
1648
1649                 break;
1650         }
1651
1652         case TV_SCROLL:
1653         {
1654                 /* Color the object */
1655                 modstr = k_name + flavor_k_ptr->flavor_name;
1656
1657 #ifdef JP
1658                 if (!flavor)    basenm = "%の巻物";
1659                 else if (aware) basenm = "「#」と書かれた%の巻物";
1660                 else            basenm = "「#」と書かれた巻物";
1661 #else
1662                 if (!flavor)    basenm = "& Scroll~ of %";
1663                 else if (aware) basenm = "& Scroll~ titled \"#\" of %";
1664                 else            basenm = "& Scroll~ titled \"#\"";
1665 #endif
1666
1667                 break;
1668         }
1669
1670         case TV_POTION:
1671         {
1672                 /* Color the object */
1673                 modstr = k_name + flavor_k_ptr->flavor_name;
1674
1675 #ifdef JP
1676                 if (!flavor)    basenm = "%の薬";
1677                 else if (aware) basenm = "%の#薬";
1678                 else            basenm = "#薬";
1679 #else
1680                 if (!flavor)    basenm = "& Potion~ of %";
1681                 else if (aware) basenm = "& # Potion~ of %";
1682                 else            basenm = "& # Potion~";
1683 #endif
1684
1685                 break;
1686         }
1687
1688         case TV_FOOD:
1689         {
1690                 /* Ordinary food is "boring" */
1691                 if (!k_ptr->flavor_name) break;
1692
1693                 /* Color the object */
1694                 modstr = k_name + flavor_k_ptr->flavor_name;
1695
1696 #ifdef JP
1697                 if (!flavor)    basenm = "%のキノコ";
1698                 else if (aware) basenm = "%の#キノコ";
1699                 else            basenm = "#キノコ";
1700 #else
1701                 if (!flavor)    basenm = "& Mushroom~ of %";
1702                 else if (aware) basenm = "& # Mushroom~ of %";
1703                 else            basenm = "& # Mushroom~";
1704 #endif
1705
1706                 break;
1707         }
1708
1709         case TV_PARCHMENT:
1710         {
1711                 basenm = _("羊皮紙 - %", "& Parchment~ - %");
1712                 break;
1713         }
1714
1715         /* Magic Books */
1716         case TV_LIFE_BOOK:
1717         {
1718 #ifdef JP
1719                 basenm = "生命の魔法書%";
1720 #else
1721                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1722                         basenm = "& Book~ of Life Magic %";
1723                 else
1724                         basenm = "& Life Spellbook~ %";
1725 #endif
1726
1727                 break;
1728         }
1729
1730         case TV_SORCERY_BOOK:
1731         {
1732 #ifdef JP
1733                 basenm = "仙術の魔法書%";
1734 #else
1735                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1736                         basenm = "& Book~ of Sorcery %";
1737                 else
1738                         basenm = "& Sorcery Spellbook~ %";
1739 #endif
1740
1741                 break;
1742         }
1743
1744         case TV_NATURE_BOOK:
1745         {
1746 #ifdef JP
1747                 basenm = "自然の魔法書%";
1748 #else
1749                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1750                         basenm = "& Book~ of Nature Magic %";
1751                 else
1752                         basenm = "& Nature Spellbook~ %";
1753 #endif
1754
1755                 break;
1756         }
1757
1758         case TV_CHAOS_BOOK:
1759         {
1760 #ifdef JP
1761                 basenm = "カオスの魔法書%";
1762 #else
1763                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1764                         basenm = "& Book~ of Chaos Magic %";
1765                 else
1766                         basenm = "& Chaos Spellbook~ %";
1767 #endif
1768
1769                 break;
1770         }
1771
1772         case TV_DEATH_BOOK:
1773         {
1774 #ifdef JP
1775                 basenm = "暗黒の魔法書%";
1776 #else
1777                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1778                         basenm = "& Book~ of Death Magic %";
1779                 else
1780                         basenm = "& Death Spellbook~ %";
1781 #endif
1782
1783                 break;
1784         }
1785
1786         case TV_TRUMP_BOOK:
1787         {
1788 #ifdef JP
1789                 basenm = "トランプの魔法書%";
1790 #else
1791                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1792                         basenm = "& Book~ of Trump Magic %";
1793                 else
1794                         basenm = "& Trump Spellbook~ %";
1795 #endif
1796
1797                 break;
1798         }
1799
1800         case TV_ARCANE_BOOK:
1801         {
1802 #ifdef JP
1803                 basenm = "秘術の魔法書%";
1804 #else
1805                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1806                         basenm = "& Book~ of Arcane Magic %";
1807                 else
1808                         basenm = "& Arcane Spellbook~ %";
1809 #endif
1810
1811                 break;
1812         }
1813
1814         case TV_CRAFT_BOOK:
1815         {
1816 #ifdef JP
1817                 basenm = "匠の魔法書%";
1818 #else
1819                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1820                         basenm = "& Book~ of Craft Magic %";
1821                 else
1822                         basenm = "& Craft Spellbook~ %";
1823 #endif
1824
1825                 break;
1826         }
1827
1828         case TV_DAEMON_BOOK:
1829         {
1830 #ifdef JP
1831                 basenm = "悪魔の魔法書%";
1832 #else
1833                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1834                         basenm = "& Book~ of Daemon Magic %";
1835                 else
1836                         basenm = "& Daemon Spellbook~ %";
1837 #endif
1838
1839                 break;
1840         }
1841
1842         case TV_CRUSADE_BOOK:
1843         {
1844 #ifdef JP
1845                 basenm = "破邪の魔法書%";
1846 #else
1847                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1848                         basenm = "& Book~ of Crusade Magic %";
1849                 else
1850                         basenm = "& Crusade Spellbook~ %";
1851 #endif
1852
1853                 break;
1854         }
1855
1856         case TV_MUSIC_BOOK:
1857         {
1858                 basenm = _("歌集%", "& Song Book~ %");
1859                 break;
1860         }
1861
1862         case TV_HISSATSU_BOOK:
1863         {
1864                 basenm = _("& 武芸の書%", "Book~ of Kendo %");
1865                 break;
1866         }
1867
1868         case TV_HEX_BOOK:
1869         {
1870 #ifdef JP
1871                 basenm = "呪術の魔法書%";
1872 #else
1873                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
1874                         basenm = "& Book~ of Hex Magic %";
1875                 else
1876                         basenm = "& Hex Spellbook~ %";
1877 #endif
1878
1879                 break;
1880         }
1881
1882         /* Hack -- Gold/Gems */
1883         case TV_GOLD:
1884         {
1885                 strcpy(buf, basenm);
1886                 return;
1887         }
1888
1889         default:
1890         {
1891                 strcpy(buf, _("(なし)", "(nothing)"));
1892                 return;
1893         }
1894         }
1895
1896         /* Use full name from k_info or a_info */
1897         if (aware && have_flag(flgs, TR_FULL_NAME))
1898         {
1899                 if (known && o_ptr->name1) basenm = a_name + a_info[o_ptr->name1].name;
1900                 else basenm = kindname;
1901         }
1902
1903         /* Start dumping the result */
1904         t = tmp_val;
1905
1906 #ifdef JP
1907         if (basenm[0] == '&')
1908                 s = basenm + 2;
1909         else
1910                 s = basenm;
1911
1912         /* No prefix */
1913         if (mode & OD_OMIT_PREFIX)
1914         {
1915                 /* Nothing */
1916         }
1917         else if (o_ptr->number > 1)
1918         {
1919                 t = object_desc_kosuu(t, o_ptr);
1920                 t = object_desc_str(t, "の ");
1921         }
1922
1923         /* 英語の場合アーティファクトは The が付くので分かるが
1924          * 日本語では分からないのでマークをつける
1925          */
1926         if (known)
1927         {
1928                 if (object_is_fixed_artifact(o_ptr)) t = object_desc_str(t, "★");
1929                 else if (o_ptr->art_name) t = object_desc_str(t, "☆");
1930         }
1931
1932 #else
1933
1934         /* The object "expects" a "number" */
1935         if (basenm[0] == '&')
1936         {
1937                 /* Skip the ampersand (and space) */
1938                 s = basenm + 2;
1939
1940                 /* No prefix */
1941                 if (mode & OD_OMIT_PREFIX)
1942                 {
1943                         /* Nothing */
1944                 }
1945
1946                 /* Hack -- None left */
1947                 else if (o_ptr->number <= 0)
1948                 {
1949                         t = object_desc_str(t, "no more ");
1950                 }
1951
1952                 /* Extract the number */
1953                 else if (o_ptr->number > 1)
1954                 {
1955                         t = object_desc_num(t, o_ptr->number);
1956                         t = object_desc_chr(t, ' ');
1957                 }
1958
1959                 /* Hack -- The only one of its kind */
1960                 else if ((known && object_is_artifact(o_ptr)) ||
1961                         ((o_ptr->tval == TV_CORPSE) &&
1962                         (r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
1963                 {
1964                         t = object_desc_str(t, "The ");
1965                 }
1966
1967                 /* A single one */
1968                 else
1969                 {
1970                         bool vowel;
1971
1972                         switch (*s)
1973                         {
1974                         case '#': vowel = is_a_vowel(modstr[0]); break;
1975                         case '%': vowel = is_a_vowel(*kindname); break;
1976                         default:  vowel = is_a_vowel(*s); break;
1977                         }
1978
1979                         if (vowel)
1980                         {
1981                                 /* A single one, with a vowel */
1982                                 t = object_desc_str(t, "an ");
1983                         }
1984                         else
1985                         {
1986                                 /* A single one, without a vowel */
1987                                 t = object_desc_str(t, "a ");
1988                         }
1989                 }
1990         }
1991
1992         /* Hack -- objects that "never" take an article */
1993         else
1994         {
1995                 /* No ampersand */
1996                 s = basenm;
1997
1998                 /* No pref */
1999                 if (mode & OD_OMIT_PREFIX)
2000                 {
2001                         /* Nothing */
2002                 }
2003
2004                 /* Hack -- all gone */
2005                 else if (o_ptr->number <= 0)
2006                 {
2007                         t = object_desc_str(t, "no more ");
2008                 }
2009
2010                 /* Prefix a number if required */
2011                 else if (o_ptr->number > 1)
2012                 {
2013                         t = object_desc_num(t, o_ptr->number);
2014                         t = object_desc_chr(t, ' ');
2015                 }
2016
2017                 /* Hack -- The only one of its kind */
2018                 else if (known && object_is_artifact(o_ptr))
2019                 {
2020                         t = object_desc_str(t, "The ");
2021                 }
2022
2023                 /* Hack -- single items get no prefix */
2024                 else
2025                 {
2026                         /* Nothing */
2027                 }
2028         }
2029 #endif
2030
2031         /* Paranoia -- skip illegal tildes */
2032         /* while (*s == '~') s++; */
2033
2034 #ifdef JP
2035         if (object_is_smith(o_ptr))
2036         {
2037                 t = object_desc_str(t, format("鍛冶師%sの", player_ptr->name));
2038         }
2039
2040         /* 伝説のアイテム、名のあるアイテムの名前を付加する */
2041         if (known)
2042         {
2043                 /* ランダム・アーティファクト */
2044                 if (o_ptr->art_name)
2045                 {
2046                         concptr temp = quark_str(o_ptr->art_name);
2047
2048                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2049                         /* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */
2050                         if (strncmp(temp, "of ", 3) == 0)
2051                         {
2052                                 t = object_desc_str(t, &temp[3]);
2053                                 t = object_desc_str(t, "の");
2054                         }
2055                         else if ((strncmp(temp, "『", 2) != 0) &&
2056                                 (strncmp(temp, "《", 2) != 0) &&
2057                                 (temp[0] != '\''))
2058                                 t = object_desc_str(t, temp);
2059                 }
2060                 /* 伝説のアイテム */
2061                 else if (o_ptr->name1 && !have_flag(flgs, TR_FULL_NAME))
2062                 {
2063                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2064                         /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
2065                         if (strncmp(a_name + a_ptr->name, "『", 2) != 0)
2066                         {
2067                                 t = object_desc_str(t, a_name + a_ptr->name);
2068                         }
2069                 }
2070                 /* 名のあるアイテム */
2071                 else if (object_is_ego(o_ptr))
2072                 {
2073                         ego_item_type *e_ptr = &e_info[o_ptr->name2];
2074                         t = object_desc_str(t, e_name + e_ptr->name);
2075                 }
2076         }
2077 #endif
2078
2079         /* Copy the string */
2080         for (s0 = NULL; *s || s0; )
2081         {
2082                 /* The end of the flavour/kind string. */
2083                 if (!*s)
2084                 {
2085                         s = s0 + 1;
2086                         s0 = NULL;
2087                 }
2088
2089                 /* Begin to append the modifier (flavor) */
2090                 else if ((*s == '#') && !s0)
2091                 {
2092                         s0 = s;
2093                         s = modstr;
2094
2095                         /* Paranoia -- Never append multiple modstrs */
2096                         modstr = "";
2097                 }
2098
2099                 /* Begin to append the kind name */
2100                 else if ((*s == '%') && !s0)
2101                 {
2102                         s0 = s;
2103                         s = kindname;
2104
2105                         /* Paranoia -- Never append multiple kindnames */
2106                         kindname = "";
2107                 }
2108
2109 #ifdef JP
2110 #else
2111
2112                 /* Pluralizer */
2113                 else if (*s == '~')
2114                 {
2115                         /* Add a plural if needed */
2116                         if (!(mode & OD_NO_PLURAL) && (o_ptr->number != 1))
2117                         {
2118                                 char k = t[-1];
2119
2120                                 /* Mega-Hack */
2121
2122                                 /* Hack -- "Cutlass-es" and "Torch-es" */
2123                                 if ((k == 's') || (k == 'h')) *t++ = 'e';
2124
2125                                 /* Add an 's' */
2126                                 *t++ = 's';
2127                         }
2128                         s++;
2129                 }
2130 #endif
2131
2132                 /* Normal */
2133                 else
2134                 {
2135                         /* Copy */
2136                         *t++ = *s++;
2137                 }
2138         }
2139
2140         /* Terminate */
2141         *t = '\0';
2142
2143
2144 #ifdef JP
2145         /* '『'から始まる伝説のアイテムの名前は最後に付加する */
2146         if (known)
2147         {
2148                 /* ランダムアーティファクトの名前はセーブファイルに記録
2149                    されるので、英語版の名前もそれらしく変換する */
2150                 if (o_ptr->art_name)
2151                 {
2152                         char temp[256];
2153                         int itemp;
2154                         strcpy(temp, quark_str(o_ptr->art_name));
2155                         /* MEGA HACK by ita */
2156                         if (strncmp(temp, "『", 2) == 0 ||
2157                                 strncmp(temp, "《", 2) == 0)
2158                                 t = object_desc_str(t, temp);
2159                         else if (temp[0] == '\'')
2160                         {
2161                                 itemp = strlen(temp);
2162                                 temp[itemp - 1] = 0;
2163                                 t = object_desc_str(t, "『");
2164                                 t = object_desc_str(t, &temp[1]);
2165                                 t = object_desc_str(t, "』");
2166                         }
2167                 }
2168                 else if (object_is_fixed_artifact(o_ptr))
2169                 {
2170                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2171                         if (strncmp(a_name + a_ptr->name, "『", 2) == 0)
2172                         {
2173                                 t = object_desc_str(t, a_name + a_ptr->name);
2174                         }
2175                 }
2176                 else if (o_ptr->inscription)
2177                 {
2178                         concptr str = quark_str(o_ptr->inscription);
2179
2180                         while (*str)
2181                         {
2182                                 if (iskanji(*str))
2183                                 {
2184                                         str += 2;
2185                                         continue;
2186                                 }
2187                                 if (*str == '#') break;
2188                                 str++;
2189                         }
2190                         if (*str)
2191                         {
2192                                 /* Find the '#' */
2193                                 concptr str_aux = my_strchr(quark_str(o_ptr->inscription), '#');
2194
2195                                 /* Add the false name */
2196                                 t = object_desc_str(t, "『");
2197                                 t = object_desc_str(t, &str_aux[1]);
2198                                 t = object_desc_str(t, "』");
2199                         }
2200                 }
2201         }
2202 #else
2203         if (object_is_smith(o_ptr))
2204         {
2205                 t = object_desc_str(t, format(" of %s the Smith", player_ptr->name));
2206         }
2207
2208         /* Hack -- Append "Artifact" or "Special" names */
2209         if (known && !have_flag(flgs, TR_FULL_NAME))
2210         {
2211                 /* Is it a new random artifact ? */
2212                 if (o_ptr->art_name)
2213                 {
2214                         t = object_desc_chr(t, ' ');
2215                         t = object_desc_str(t, quark_str(o_ptr->art_name));
2216                 }
2217
2218                 /* Grab any artifact name */
2219                 else if (object_is_fixed_artifact(o_ptr))
2220                 {
2221                         artifact_type *a_ptr = &a_info[o_ptr->name1];
2222
2223                         t = object_desc_chr(t, ' ');
2224                         t = object_desc_str(t, a_name + a_ptr->name);
2225                 }
2226
2227                 /* Grab any ego-item name */
2228                 else
2229                 {
2230                         if (object_is_ego(o_ptr))
2231                         {
2232                                 ego_item_type *e_ptr = &e_info[o_ptr->name2];
2233
2234                                 t = object_desc_chr(t, ' ');
2235                                 t = object_desc_str(t, e_name + e_ptr->name);
2236                         }
2237
2238                         if (o_ptr->inscription && my_strchr(quark_str(o_ptr->inscription), '#'))
2239                         {
2240                                 /* Find the '#' */
2241                                 concptr str = my_strchr(quark_str(o_ptr->inscription), '#');
2242
2243                                 /* Add the false name */
2244                                 t = object_desc_chr(t, ' ');
2245                                 t = object_desc_str(t, &str[1]);
2246                         }
2247                 }
2248         }
2249 #endif
2250
2251
2252         /* No more details wanted */
2253         if (mode & OD_NAME_ONLY)
2254         {
2255                 my_strcpy(buf, tmp_val, MAX_NLEN);
2256                 return;
2257         }
2258
2259         /* Hack -- Chests must be described in detail */
2260         if (o_ptr->tval == TV_CHEST)
2261         {
2262                 /* Not searched yet */
2263                 if (!known)
2264                 {
2265                         /* Nothing */
2266                 }
2267
2268                 /* May be "empty" */
2269                 else if (!o_ptr->pval)
2270                 {
2271                         t = object_desc_str(t, _("(空)", " (empty)"));
2272                 }
2273
2274                 /* May be "disarmed" */
2275                 else if (o_ptr->pval < 0)
2276                 {
2277                         if (chest_traps[0 - o_ptr->pval])
2278                         {
2279                                 t = object_desc_str(t, _("(解除済)", " (disarmed)"));
2280                         }
2281                         else
2282                         {
2283                                 t = object_desc_str(t, _("(非施錠)", " (unlocked)"));
2284                         }
2285                 }
2286
2287                 /* Describe the traps, if any */
2288                 else
2289                 {
2290                         /* Describe the traps */
2291                         switch (chest_traps[o_ptr->pval])
2292                         {
2293                         case 0:
2294                         {
2295                                 t = object_desc_str(t, _("(施錠)", " (Locked)"));
2296                                 break;
2297                         }
2298                         case CHEST_LOSE_STR:
2299                         {
2300                                 t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2301                                 break;
2302                         }
2303                         case CHEST_LOSE_CON:
2304                         {
2305                                 t = object_desc_str(t, _("(毒針)", " (Poison Needle)"));
2306                                 break;
2307                         }
2308                         case CHEST_POISON:
2309                         {
2310                                 t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2311                                 break;
2312                         }
2313                         case CHEST_PARALYZE:
2314                         {
2315                                 t = object_desc_str(t, _("(ガス・トラップ)", " (Gas Trap)"));
2316                                 break;
2317                         }
2318                         case CHEST_EXPLODE:
2319                         {
2320                                 t = object_desc_str(t, _("(爆発装置)", " (Explosion Device)"));
2321                                 break;
2322                         }
2323                         case CHEST_SUMMON:
2324                         case CHEST_BIRD_STORM:
2325                         case CHEST_E_SUMMON:
2326                         case CHEST_H_SUMMON:
2327                         {
2328                                 t = object_desc_str(t, _("(召喚のルーン)", " (Summoning Runes)"));
2329                                 break;
2330                         }
2331                         case CHEST_RUNES_OF_EVIL:
2332                         {
2333                                 t = object_desc_str(t, _("(邪悪なルーン)", " (Gleaming Black Runes)"));
2334                                 break;
2335                         }
2336                         case CHEST_ALARM:
2337                         {
2338                                 t = object_desc_str(t, _("(警報装置)", " (Alarm)"));
2339                                 break;
2340                         }
2341                         default:
2342                         {
2343                                 t = object_desc_str(t, _("(マルチ・トラップ)", " (Multiple Traps)"));
2344                                 break;
2345                         }
2346                         }
2347                 }
2348         }
2349
2350
2351         /* Display the item like a weapon */
2352         if (have_flag(flgs, TR_SHOW_MODS)) show_weapon = TRUE;
2353
2354         /* Display the item like a weapon */
2355         if (object_is_smith(o_ptr) && (o_ptr->xtra3 == 1 + ESSENCE_SLAY_GLOVE))
2356                 show_weapon = TRUE;
2357
2358         /* Display the item like a weapon */
2359         if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;
2360
2361         /* Display the item like armour */
2362         if (o_ptr->ac) show_armour = TRUE;
2363
2364
2365         /* Dump base weapon info */
2366         switch (o_ptr->tval)
2367         {
2368                 /* Missiles and Weapons */
2369         case TV_SHOT:
2370         case TV_BOLT:
2371         case TV_ARROW:
2372         case TV_HAFTED:
2373         case TV_POLEARM:
2374         case TV_SWORD:
2375         case TV_DIGGING:
2376
2377                 /* In Vault Quest, hide the dice of target weapon. */
2378                 if (object_is_quest_target(o_ptr) && !known)
2379                 {
2380                         break;
2381                 }
2382
2383                 /* Append a "damage" string */
2384                 t = object_desc_chr(t, ' ');
2385                 t = object_desc_chr(t, p1);
2386                 t = object_desc_num(t, o_ptr->dd);
2387                 t = object_desc_chr(t, 'd');
2388                 t = object_desc_num(t, o_ptr->ds);
2389                 t = object_desc_chr(t, p2);
2390
2391                 /* All done */
2392                 break;
2393
2394                 /* Bows get a special "damage string" */
2395         case TV_BOW:
2396
2397                 /* Mega-Hack -- Extract the "base power" */
2398                 power = bow_tmul(o_ptr->sval);
2399
2400                 /* Apply the "Extra Might" flag */
2401                 if (have_flag(flgs, TR_XTRA_MIGHT)) power++;
2402
2403                 /* Append a special "damage" string */
2404                 t = object_desc_chr(t, ' ');
2405                 t = object_desc_chr(t, p1);
2406                 t = object_desc_chr(t, 'x');
2407                 t = object_desc_num(t, power);
2408                 t = object_desc_chr(t, p2);
2409
2410                 fire_rate = calc_num_fire(player_ptr, o_ptr);
2411                 /* Show Fire rate */
2412                 if (fire_rate != 0 && power > 0 && known)
2413                 {
2414                         fire_rate = bow_energy(o_ptr->sval) / fire_rate;
2415
2416                         t = object_desc_chr(t, ' ');
2417                         t = object_desc_chr(t, p1);
2418                         t = object_desc_num(t, fire_rate / 100);
2419                         t = object_desc_chr(t, '.');
2420                         t = object_desc_num(t, fire_rate % 100);
2421                         t = object_desc_str(t, "turn");
2422                         t = object_desc_chr(t, p2);
2423                 }
2424
2425                 /* All done */
2426                 break;
2427         }
2428
2429
2430         /* Add the weapon bonuses */
2431         if (known)
2432         {
2433                 /* Show the tohit/todam on request */
2434                 if (show_weapon)
2435                 {
2436                         t = object_desc_chr(t, ' ');
2437                         t = object_desc_chr(t, p1);
2438                         t = object_desc_int(t, o_ptr->to_h);
2439                         t = object_desc_chr(t, ',');
2440                         t = object_desc_int(t, o_ptr->to_d);
2441                         t = object_desc_chr(t, p2);
2442                 }
2443
2444                 /* Show the tohit if needed */
2445                 else if (o_ptr->to_h)
2446                 {
2447                         t = object_desc_chr(t, ' ');
2448                         t = object_desc_chr(t, p1);
2449                         t = object_desc_int(t, o_ptr->to_h);
2450                         t = object_desc_chr(t, p2);
2451                 }
2452
2453                 /* Show the todam if needed */
2454                 else if (o_ptr->to_d)
2455                 {
2456                         t = object_desc_chr(t, ' ');
2457                         t = object_desc_chr(t, p1);
2458                         t = object_desc_int(t, o_ptr->to_d);
2459                         t = object_desc_chr(t, p2);
2460                 }
2461         }
2462
2463         bow_ptr = &player_ptr->inventory_list[INVEN_BOW];
2464
2465         /* If have a firing weapon + ammo matches bow */
2466         if (bow_ptr->k_idx && (o_ptr->tval == player_ptr->tval_ammo))
2467         {
2468                 int avgdam = o_ptr->dd * (o_ptr->ds + 1) * 10 / 2;
2469                 int tmul = bow_tmul(bow_ptr->sval);
2470                 ENERGY energy_fire = bow_energy(bow_ptr->sval);
2471
2472                 /* See if the bow is "known" - then set damage bonus */
2473                 if (object_is_known(bow_ptr)) avgdam += (bow_ptr->to_d * 10);
2474
2475                 /* Effect of ammo */
2476                 if (known) avgdam += (o_ptr->to_d * 10);
2477
2478                 /* Get extra "power" from "extra might" */
2479                 if (player_ptr->xtra_might) tmul++;
2480
2481                 tmul = tmul * (100 + (int)(adj_str_td[player_ptr->stat_ind[A_STR]]) - 128);
2482
2483                 /* Launcher multiplier */
2484                 avgdam *= tmul;
2485                 avgdam /= (100 * 10);
2486
2487                 /* Get extra damage from concentration */
2488                 if (player_ptr->concent) avgdam = boost_concentration_damage(player_ptr, avgdam);
2489
2490                 if (avgdam < 0) avgdam = 0;
2491
2492                 /* Display (shot damage/ shot damage with critical/ avg damage with critical) */
2493                 t = object_desc_chr(t, ' ');
2494                 t = object_desc_chr(t, p1);
2495
2496                 if (show_ammo_no_crit)
2497                 {
2498                         /* Damage with no-crit */
2499                         t = object_desc_num(t, avgdam);
2500                         t = object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2501                 }
2502
2503                 /* Apply Expect damage of Critical */
2504                 avgdam = calc_expect_crit_shot(player_ptr, o_ptr->weight, o_ptr->to_h, bow_ptr->to_h, avgdam);
2505                 t = object_desc_num(t, avgdam);
2506
2507                 t = show_ammo_no_crit ? object_desc_str(t, show_ammo_detail ? "/crit " : "/")
2508                         : object_desc_str(t, show_ammo_detail ? "/shot " : "/");
2509
2510                 if (player_ptr->num_fire == 0)
2511                 {
2512                         t = object_desc_chr(t, '0');
2513                 }
2514                 else
2515                 {
2516                         /* Calc effects of energy */
2517                         avgdam *= (player_ptr->num_fire * 100);
2518                         avgdam /= energy_fire;
2519                         t = object_desc_num(t, avgdam);
2520                         t = object_desc_str(t, show_ammo_detail ? "/turn" : "");
2521
2522                         if (show_ammo_crit_ratio)
2523                         {
2524                                 int percent = calc_crit_ratio_shot(player_ptr, known ? o_ptr->to_h : 0, known ? bow_ptr->to_h : 0);
2525
2526                                 t = object_desc_chr(t, '/');
2527                                 t = object_desc_num(t, percent / 100);
2528                                 t = object_desc_chr(t, '.');
2529                                 if (percent % 100 < 10)
2530                                 {
2531                                         t = object_desc_chr(t, '0');
2532                                 }
2533                                 t = object_desc_num(t, percent % 100);
2534                                 t = object_desc_str(t, show_ammo_detail ? "% crit" : "%");
2535                         }
2536                 }
2537
2538                 t = object_desc_chr(t, p2);
2539         }
2540         else if ((player_ptr->pclass == CLASS_NINJA) && (o_ptr->tval == TV_SPIKE))
2541         {
2542                 int avgdam = player_ptr->mighty_throw ? (1 + 3) : 1;
2543                 s16b energy_fire = 100 - player_ptr->lev;
2544
2545                 avgdam += ((player_ptr->lev + 30) * (player_ptr->lev + 30) - 900) / 55;
2546
2547                 /* Display (shot damage/ avg damage) */
2548                 t = object_desc_chr(t, ' ');
2549                 t = object_desc_chr(t, p1);
2550                 t = object_desc_num(t, avgdam);
2551                 t = object_desc_chr(t, '/');
2552
2553                 /* Calc effects of energy */
2554                 avgdam = 100 * avgdam / energy_fire;
2555
2556                 t = object_desc_num(t, avgdam);
2557                 t = object_desc_chr(t, p2);
2558         }
2559
2560         /* Add the armor bonuses */
2561         if (known)
2562         {
2563                 /* Show the armor class info */
2564                 if (show_armour)
2565                 {
2566                         t = object_desc_chr(t, ' ');
2567                         t = object_desc_chr(t, b1);
2568                         t = object_desc_num(t, o_ptr->ac);
2569                         t = object_desc_chr(t, ',');
2570                         t = object_desc_int(t, o_ptr->to_a);
2571                         t = object_desc_chr(t, b2);
2572                 }
2573
2574                 /* No base armor, but does increase armor */
2575                 else if (o_ptr->to_a)
2576                 {
2577                         t = object_desc_chr(t, ' ');
2578                         t = object_desc_chr(t, b1);
2579                         t = object_desc_int(t, o_ptr->to_a);
2580                         t = object_desc_chr(t, b2);
2581                 }
2582         }
2583
2584         /* Hack -- always show base armor */
2585         else if (show_armour)
2586         {
2587                 t = object_desc_chr(t, ' ');
2588                 t = object_desc_chr(t, b1);
2589                 t = object_desc_num(t, o_ptr->ac);
2590                 t = object_desc_chr(t, b2);
2591         }
2592
2593
2594         /* No more details wanted */
2595         if (mode & OD_NAME_AND_ENCHANT)
2596         {
2597                 my_strcpy(buf, tmp_val, MAX_NLEN);
2598                 return;
2599         }
2600
2601         if (known) /* Known item only */
2602         {
2603                 /*
2604                  * Hack -- Wands and Staffs have charges.  Make certain how many charges
2605                  * a stack of staffs really has is clear. -LM-
2606                  */
2607                 if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
2608                 {
2609                         /* Dump " (N charges)" */
2610                         t = object_desc_chr(t, ' ');
2611                         t = object_desc_chr(t, p1);
2612
2613                         /* Clear explaination for staffs. */
2614                         if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
2615                         {
2616                                 t = object_desc_num(t, o_ptr->number);
2617                                 t = object_desc_str(t, "x ");
2618                         }
2619                         t = object_desc_num(t, o_ptr->pval);
2620 #ifdef JP
2621                         t = object_desc_str(t, "回分");
2622 #else
2623                         t = object_desc_str(t, " charge");
2624                         if (o_ptr->pval != 1) t = object_desc_chr(t, 's');
2625 #endif
2626
2627                         t = object_desc_chr(t, p2);
2628                 }
2629                 /* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
2630                  * be in any state of charge or discharge, this now includes a number. -LM-
2631                  */
2632                 else if (o_ptr->tval == TV_ROD)
2633                 {
2634                         /* Hack -- Dump " (# charging)" if relevant */
2635                         if (o_ptr->timeout)
2636                         {
2637                                 /* Stacks of rods display an exact count of charging rods. */
2638                                 if (o_ptr->number > 1)
2639                                 {
2640                                         /* Paranoia. */
2641                                         if (k_ptr->pval == 0) k_ptr->pval = 1;
2642
2643                                         /* Find out how many rods are charging, by dividing
2644                                          * current timeout by each rod's maximum timeout.
2645                                          * Ensure that any remainder is rounded up.  Display
2646                                          * very discharged stacks as merely fully discharged.
2647                                          */
2648                                         power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
2649                                         if (power > o_ptr->number) power = o_ptr->number;
2650
2651                                         /* Display prettily. */
2652                                         t = object_desc_str(t, " (");
2653                                         t = object_desc_num(t, power);
2654                                         t = object_desc_str(t, _("本 充填中)", " charging)"));
2655                                 }
2656
2657                                 /* "one Rod of Perception (1 charging)" would look tacky. */
2658                                 else
2659                                 {
2660                                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2661                                 }
2662                         }
2663                 }
2664
2665                 /* Dump "pval" flags for wearable items */
2666                 if (have_pval_flags(flgs))
2667                 {
2668                         /* Start the display */
2669                         t = object_desc_chr(t, ' ');
2670                         t = object_desc_chr(t, p1);
2671
2672                         /* Dump the "pval" itself */
2673                         t = object_desc_int(t, o_ptr->pval);
2674
2675                         /* Do not display the "pval" flags */
2676                         if (have_flag(flgs, TR_HIDE_TYPE))
2677                         {
2678                                 /* Nothing */
2679                         }
2680
2681                         else if (have_flag(flgs, TR_SPEED))
2682                         {
2683                                 t = object_desc_str(t, _("加速", " to speed"));
2684                         }
2685                         else if (have_flag(flgs, TR_BLOWS))
2686                         {
2687                                 t = object_desc_str(t, _("攻撃", " attack"));
2688 #ifdef JP
2689 #else
2690
2691                                 if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's');
2692 #endif
2693                         }
2694                         else if (have_flag(flgs, TR_STEALTH))
2695                         {
2696                                 t = object_desc_str(t, _("隠密", " to stealth"));
2697                         }
2698                         else if (have_flag(flgs, TR_SEARCH))
2699                         {
2700                                 t = object_desc_str(t, _("探索", " to searching"));
2701                         }
2702                         else if (have_flag(flgs, TR_INFRA))
2703                         {
2704                                 t = object_desc_str(t, _("赤外線視力", " to infravision"));
2705                         }
2706                         t = object_desc_chr(t, p2);
2707                 }
2708
2709                 /* Hack -- Process Lanterns/Torches */
2710                 if ((o_ptr->tval == TV_LITE) && (!(object_is_fixed_artifact(o_ptr) || (o_ptr->sval == SV_LITE_FEANOR))))
2711                 {
2712                         /* Hack -- Turns of light for normal lites */
2713                         t = object_desc_str(t, _("(", " (with "));
2714                         if (o_ptr->name2 == EGO_LITE_LONG) t = object_desc_num(t, o_ptr->xtra4 * 2);
2715                         else t = object_desc_num(t, o_ptr->xtra4);
2716                         t = object_desc_str(t, _("ターンの寿命)", " turns of light)"));
2717                 }
2718
2719                 /* Indicate charging objects, but not rods. */
2720                 if (o_ptr->timeout && (o_ptr->tval != TV_ROD))
2721                 {
2722                         t = object_desc_str(t, _("(充填中)", " (charging)"));
2723                 }
2724         }
2725
2726         /* No more details wanted */
2727         if (mode & OD_OMIT_INSCRIPTION)
2728         {
2729                 my_strcpy(buf, tmp_val, MAX_NLEN);
2730                 return;
2731         }
2732
2733         /* Prepare real inscriptions in a buffer */
2734         tmp_val2[0] = '\0';
2735
2736         /* Auto abbreviation inscribe */
2737         if ((abbrev_extra || abbrev_all) && OBJECT_IS_FULL_KNOWN(o_ptr))
2738         {
2739                 if (!o_ptr->inscription || !my_strchr(quark_str(o_ptr->inscription), '%'))
2740                 {
2741                         bool kanji, all;
2742
2743 #ifdef JP
2744                         kanji = TRUE;
2745 #else
2746                         kanji = FALSE;
2747 #endif
2748                         all = abbrev_all;
2749
2750                         get_ability_abbreviation(tmp_val2, o_ptr, kanji, all);
2751                 }
2752         }
2753
2754         /* Use the standard inscription if available */
2755         if (o_ptr->inscription)
2756         {
2757                 char buff[1024];
2758                 if (tmp_val2[0]) strcat(tmp_val2, ", ");
2759                 get_inscription(buff, o_ptr);
2760                 my_strcat(tmp_val2, buff, sizeof(tmp_val2));
2761         }
2762
2763
2764         /* No fake inscription yet */
2765         fake_insc_buf[0] = '\0';
2766
2767         /* Use the game-generated "feeling" otherwise, if available */
2768         if (o_ptr->feeling)
2769         {
2770                 strcpy(fake_insc_buf, game_inscriptions[o_ptr->feeling]);
2771         }
2772
2773         /* Note "cursed" if the item is known to be cursed */
2774         else if (object_is_cursed(o_ptr) && (known || (o_ptr->ident & IDENT_SENSE)))
2775         {
2776                 strcpy(fake_insc_buf, _("呪われている", "cursed"));
2777         }
2778
2779         /* Note "unidentified" if the item is unidentified */
2780         else if (((o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET)
2781                 || (o_ptr->tval == TV_LITE) || (o_ptr->tval == TV_FIGURINE))
2782                 && aware && !known
2783                 && !(o_ptr->ident & IDENT_SENSE))
2784         {
2785                 strcpy(fake_insc_buf, _("未鑑定", "unidentified"));
2786         }
2787
2788         /* Mega-Hack -- note empty wands/staffs */
2789         else if (!known && (o_ptr->ident & IDENT_EMPTY))
2790         {
2791                 strcpy(fake_insc_buf, _("空", "empty"));
2792         }
2793
2794         /* Note "tried" if the object has been tested unsuccessfully */
2795         else if (!aware && object_is_tried(o_ptr))
2796         {
2797                 strcpy(fake_insc_buf, _("未判明", "tried"));
2798         }
2799
2800         /* Note the discount, if any */
2801         if (o_ptr->discount)
2802         {
2803                 /* Hidden by real inscription unless in a store */
2804                 if (!tmp_val2[0] || (o_ptr->ident & IDENT_STORE))
2805                 {
2806                         char discount_num_buf[4];
2807
2808                         /* Append to other fake inscriptions if any */
2809                         if (fake_insc_buf[0]) strcat(fake_insc_buf, ", ");
2810
2811                         (void)object_desc_num(discount_num_buf, o_ptr->discount);
2812                         strcat(fake_insc_buf, discount_num_buf);
2813                         strcat(fake_insc_buf, _("%引き", "% off"));
2814                 }
2815         }
2816
2817
2818         /* Append the inscription, if any */
2819         if (fake_insc_buf[0] || tmp_val2[0])
2820         {
2821                 /* Append the inscription */
2822                 t = object_desc_chr(t, ' ');
2823                 t = object_desc_chr(t, c1);
2824
2825                 /* Append fake inscriptions */
2826                 if (fake_insc_buf[0])
2827                 {
2828                         t = object_desc_str(t, fake_insc_buf);
2829                 }
2830
2831                 /* Append a separater */
2832                 if (fake_insc_buf[0] && tmp_val2[0])
2833                 {
2834                         t = object_desc_chr(t, ',');
2835                         t = object_desc_chr(t, ' ');
2836                 }
2837
2838                 /* Append real inscriptions */
2839                 if (tmp_val2[0])
2840                 {
2841                         t = object_desc_str(t, tmp_val2);
2842                 }
2843
2844                 t = object_desc_chr(t, c2);
2845         }
2846
2847         my_strcpy(buf, tmp_val, MAX_NLEN);
2848 }
2849
2850
2851 /*!
2852  * @brief nameバッファ内からベースアイテム名を返す / Strip an "object name" into a buffer
2853  * @param buf ベースアイテム格納先の参照ポインタ
2854  * @param k_idx ベースアイテムID
2855  * @return なし
2856  */
2857 void strip_name(char *buf, KIND_OBJECT_IDX k_idx)
2858 {
2859         char *t;
2860
2861         object_kind *k_ptr = &k_info[k_idx];
2862
2863         concptr str = (k_name + k_ptr->name);
2864
2865
2866         /* Skip past leading characters */
2867         while ((*str == ' ') || (*str == '&')) str++;
2868
2869         /* Copy useful chars */
2870         for (t = buf; *str; str++)
2871         {
2872 #ifdef JP
2873                 if (iskanji(*str)) { *t++ = *str++; *t++ = *str; continue; }
2874 #endif
2875                 if (*str != '~') *t++ = *str;
2876         }
2877
2878         /* Terminate the new name */
2879         *t = '\0';
2880 }
2881
2882