OSDN Git Service

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