OSDN Git Service

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