OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / perception / identification.cpp
1 #include "perception/identification.h"
2 #include "artifact/fixed-art-types.h"
3 #include "flavor/flavor-describer.h"
4 #include "flavor/object-flavor-types.h"
5 #include "game-option/special-options.h"
6 #include "io/input-key-acceptor.h"
7 #include "monster-race/monster-race.h"
8 #include "monster-race/race-flags2.h"
9 #include "monster-race/race-indice-types.h"
10 #include "object-enchant/object-ego.h"
11 #include "object-enchant/tr-types.h"
12 #include "object-enchant/trc-types.h"
13 #include "object-hook/hook-weapon.h"
14 #include "object/object-flags.h"
15 #include "object/object-info.h"
16 #include "sv-definition/sv-amulet-types.h"
17 #include "sv-definition/sv-other-types.h"
18 #include "sv-definition/sv-ring-types.h"
19 #include "sv-definition/sv-weapon-types.h"
20 #include "system/artifact-type-definition.h"
21 #include "system/baseitem-info.h"
22 #include "system/item-entity.h"
23 #include "system/monster-race-info.h"
24 #include "term/screen-processor.h"
25 #include "util/bit-flags-calculator.h"
26 #include "util/buffer-shaper.h"
27 #include "util/enum-converter.h"
28 #include <algorithm>
29 #include <array>
30 #include <string>
31
32 /*!
33  * @brief オブジェクトの*鑑定*内容を詳述して表示する /
34  * Describe a "fully identified" item
35  * @param player_ptr プレイヤーへの参照ポインタ
36  * @param o_ptr *鑑定*情報を取得する元のオブジェクト構造体参照ポインタ
37  * @param mode 表示オプション
38  * @return 特筆すべき情報が一つでもあった場合TRUE、一つもなく表示がキャンセルされた場合FALSEを返す。
39  */
40 bool screen_object(PlayerType *player_ptr, ItemEntity *o_ptr, BIT_FLAGS mode)
41 {
42     std::array<std::string, 128> info{};
43     int trivial_info = 0;
44     auto flags = object_flags(o_ptr);
45
46     const auto item_text = o_ptr->is_fixed_artifact() ? o_ptr->get_fixed_artifact().text.data() : o_ptr->get_baseitem().text.data();
47     const auto item_text_lines = shape_buffer(item_text, 77 - 15);
48
49     int i = 0;
50     std::transform(item_text_lines.begin(), item_text_lines.end(), &info[i], [](const auto &line) { return line.data(); });
51     i += item_text_lines.size();
52
53     if (o_ptr->is_equipment()) {
54         trivial_info = i;
55     }
56
57     if (flags.has(TR_ACTIVATE)) {
58         info[i++] = _("始動したときの効果...", "It can be activated for...");
59         info[i++] = activation_explanation(o_ptr);
60         info[i++] = _("...ただし装備していなければならない。", "...if it is being worn.");
61     }
62
63     const auto &bi_key = o_ptr->bi_key;
64     if (bi_key.tval() == ItemKindType::FIGURINE) {
65         info[i++] = _("それは投げた時ペットに変化する。", "It will transform into a pet when thrown.");
66     }
67
68     if (o_ptr->is_specific_artifact(FixedArtifactId::STONEMASK)) {
69         info[i++] = _("それを装備した者は吸血鬼になる。", "It makes you turn into a vampire permanently.");
70     }
71
72     if (bi_key == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE)) {
73         info[i++] = _("それは相手を一撃で倒すことがある。", "It will attempt to instantly kill a monster.");
74     }
75
76     if (bi_key == BaseitemKey(ItemKindType::POLEARM, SV_DEATH_SCYTHE)) {
77         info[i++] = _("それは自分自身に攻撃が返ってくることがある。", "It causes you to strike yourself sometimes.");
78         info[i++] = _("それは無敵のバリアを切り裂く。", "It always penetrates invulnerability barriers.");
79     }
80
81     if (flags.has(TR_EASY2_WEAPON)) {
82         info[i++] = _("それは二刀流での命中率を向上させる。", "It affects your ability to hit when you are wielding two weapons.");
83     }
84
85     if (flags.has(TR_INVULN_ARROW)) {
86         info[i++] = _("それは視界がある限り物理的な飛び道具の一切をはねのける。", "It repels all physical missiles as long as there is visibility.");
87     }
88
89     if (flags.has(TR_NO_AC)) {
90         info[i++] = _("それは物理的防護の一切を奪う。", "It robs you of any physical protection.");
91     }
92
93     if (flags.has(TR_EASY_SPELL)) {
94         info[i++] = _("それは魔法の難易度を下げる。", "It affects your ability to cast spells.");
95     }
96
97     if (flags.has(TR_HEAVY_SPELL)) {
98         info[i++] = _("それは魔法の難易度を上げる。", "It interferes with casting spells.");
99     }
100
101     if (flags.has(TR_MIGHTY_THROW)) {
102         info[i++] = _("それは物を強く投げることを可能にする。", "It provides great strength when you throw an item.");
103     }
104
105     if (bi_key.tval() == ItemKindType::STATUE) {
106         auto statue_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
107         auto *r_ptr = &monraces_info[statue_r_idx];
108         if (statue_r_idx == MonsterRaceId::BULLGATES) {
109             info[i++] = _("それは部屋に飾ると恥ずかしい。", "It is shameful.");
110         } else if (r_ptr->flags2 & (RF2_ELDRITCH_HORROR)) {
111             info[i++] = _("それは部屋に飾ると恐い。", "It is fearful.");
112         } else {
113             info[i++] = _("それは部屋に飾ると楽しい。", "It is cheerful.");
114         }
115     }
116
117     if (flags.has(TR_DARK_SOURCE)) {
118         info[i++] = _("それは全く光らない。", "It provides no light.");
119     }
120
121     POSITION rad = 0;
122     if (flags.has(TR_LITE_1) && flags.has_not(TR_DARK_SOURCE)) {
123         rad += 1;
124     }
125     if (flags.has(TR_LITE_2) && flags.has_not(TR_DARK_SOURCE)) {
126         rad += 2;
127     }
128     if (flags.has(TR_LITE_3) && flags.has_not(TR_DARK_SOURCE)) {
129         rad += 3;
130     }
131     if (flags.has(TR_LITE_M1)) {
132         rad -= 1;
133     }
134     if (flags.has(TR_LITE_M2)) {
135         rad -= 2;
136     }
137     if (flags.has(TR_LITE_M3)) {
138         rad -= 3;
139     }
140
141     if (o_ptr->ego_idx == EgoType::LITE_SHINE) {
142         rad++;
143     }
144
145     std::string desc;
146     if (flags.has(TR_LITE_FUEL) && flags.has_not(TR_DARK_SOURCE)) {
147         if (rad > 0) {
148             desc = _("それは燃料補給によって明かり(半径 ", "It provides light (radius ");
149             desc.append(std::to_string((int)rad)).append(_(")を授ける。", ") when fueled."));
150         }
151     } else {
152         if (rad > 0) {
153             desc = _("それは永遠なる明かり(半径 ", "It provides light (radius ");
154             desc.append(std::to_string((int)rad)).append(_(")を授ける。", ") forever."));
155         }
156         if (rad < 0) {
157             desc = _("それは明かりの半径を狭める(半径に-", "It decreases the radius of your light by");
158             desc.append(std::to_string((int)-rad)).append(_(")。", "."));
159         }
160     }
161
162     if (rad != 0) {
163         info[i++] = desc.data();
164     }
165
166     if (o_ptr->ego_idx == EgoType::LITE_LONG) {
167         info[i++] = _("それは長いターン明かりを授ける。", "It provides light for much longer time.");
168     }
169
170     if (flags.has(TR_RIDING)) {
171         if (o_ptr->is_lance()) {
172             info[i++] = _("それは乗馬中は非常に使いやすい。", "It is made for use while riding.");
173         } else {
174             info[i++] = _("それは乗馬中でも使いやすい。", "It is suitable for use while riding.");
175             trivial_info++;
176         }
177     }
178
179     if (flags.has(TR_SUPPORTIVE)) {
180         info[i++] = _("それは武器の補助として扱いやすい。", "It is easy to treat it as assistance to weapon.");
181     }
182
183     if (flags.has(TR_STR)) {
184         info[i++] = _("それは腕力に影響を及ぼす。", "It affects your strength.");
185     }
186
187     if (flags.has(TR_INT)) {
188         info[i++] = _("それは知能に影響を及ぼす。", "It affects your intelligence.");
189     }
190
191     if (flags.has(TR_WIS)) {
192         info[i++] = _("それは賢さに影響を及ぼす。", "It affects your wisdom.");
193     }
194
195     if (flags.has(TR_DEX)) {
196         info[i++] = _("それは器用さに影響を及ぼす。", "It affects your dexterity.");
197     }
198
199     if (flags.has(TR_CON)) {
200         info[i++] = _("それは耐久力に影響を及ぼす。", "It affects your constitution.");
201     }
202
203     if (flags.has(TR_CHR)) {
204         info[i++] = _("それは魅力に影響を及ぼす。", "It affects your charisma.");
205     }
206
207     if (flags.has(TR_MAGIC_MASTERY)) {
208         info[i++] = _("それは魔法道具使用能力に影響を及ぼす。", "It affects your ability to use magic devices.");
209     }
210
211     if (flags.has(TR_STEALTH)) {
212         info[i++] = _("それは隠密行動能力に影響を及ぼす。", "It affects your stealth.");
213     }
214
215     if (flags.has(TR_SEARCH)) {
216         info[i++] = _("それは探索能力に影響を及ぼす。", "It affects your searching.");
217     }
218
219     if (flags.has(TR_INFRA)) {
220         info[i++] = _("それは赤外線視力に影響を及ぼす。", "It affects your infravision.");
221     }
222
223     if (flags.has(TR_TUNNEL)) {
224         info[i++] = _("それは採掘能力に影響を及ぼす。", "It affects your ability to tunnel.");
225     }
226
227     if (flags.has(TR_SPEED)) {
228         info[i++] = _("それはスピードに影響を及ぼす。", "It affects your speed.");
229     }
230
231     if (flags.has(TR_BLOWS)) {
232         info[i++] = _("それは打撃回数に影響を及ぼす。", "It affects your attack speed.");
233     }
234
235     if (flags.has(TR_BRAND_ACID)) {
236         info[i++] = _("それは酸によって大きなダメージを与える。", "It does extra damage from acid.");
237     }
238
239     if (flags.has(TR_BRAND_ELEC)) {
240         info[i++] = _("それは電撃によって大きなダメージを与える。", "It does extra damage from electricity.");
241     }
242
243     if (flags.has(TR_BRAND_FIRE)) {
244         info[i++] = _("それは火炎によって大きなダメージを与える。", "It does extra damage from fire.");
245     }
246
247     if (flags.has(TR_BRAND_COLD)) {
248         info[i++] = _("それは冷気によって大きなダメージを与える。", "It does extra damage from frost.");
249     }
250
251     if (flags.has(TR_BRAND_POIS)) {
252         info[i++] = _("それは敵を毒する。", "It poisons your foes.");
253     }
254
255     if (flags.has(TR_CHAOTIC)) {
256         info[i++] = _("それはカオス的な効果を及ぼす。", "It produces chaotic effects.");
257     }
258
259     if (flags.has(TR_BRAND_MAGIC)) {
260         info[i++] = _("それは魔術的な効果を及ぼす。", "It produces magical effects.");
261     }
262
263     if (flags.has(TR_VAMPIRIC)) {
264         info[i++] = _("それは敵から生命力を吸収する。", "It drains life from your foes.");
265     }
266
267     if (flags.has(TR_EARTHQUAKE)) {
268         info[i++] = _("それは地震を起こすことができる。", "It can cause earthquakes.");
269     }
270
271     if (flags.has(TR_VORPAL)) {
272         info[i++] = _("それは非常に切れ味が鋭く敵を切断することができる。", "It is very sharp and can cut your foes.");
273     }
274
275     if (flags.has(TR_IMPACT)) {
276         info[i++] = _("それは非常に強く敵を攻撃することができる。", "It can hit your foes strongly.");
277     }
278
279     if (flags.has(TR_KILL_DRAGON)) {
280         info[i++] = _("それはドラゴンにとっての天敵である。", "It is a great bane of dragons.");
281     } else if (flags.has(TR_SLAY_DRAGON)) {
282         info[i++] = _("それはドラゴンに対して特に恐るべき力を発揮する。", "It is especially deadly against dragons.");
283     }
284
285     if (flags.has(TR_KILL_ORC)) {
286         info[i++] = _("それはオークにとっての天敵である。", "It is a great bane of orcs.");
287     }
288
289     if (flags.has(TR_SLAY_ORC)) {
290         info[i++] = _("それはオークに対して特に恐るべき力を発揮する。", "It is especially deadly against orcs.");
291     }
292
293     if (flags.has(TR_KILL_TROLL)) {
294         info[i++] = _("それはトロルにとっての天敵である。", "It is a great bane of trolls.");
295     }
296
297     if (flags.has(TR_SLAY_TROLL)) {
298         info[i++] = _("それはトロルに対して特に恐るべき力を発揮する。", "It is especially deadly against trolls.");
299     }
300
301     if (flags.has(TR_KILL_GIANT)) {
302         info[i++] = _("それは巨人にとっての天敵である。", "It is a great bane of giants.");
303     } else if (flags.has(TR_SLAY_GIANT)) {
304         info[i++] = _("それは巨人に対して特に恐るべき力を発揮する。", "It is especially deadly against giants.");
305     }
306
307     if (flags.has(TR_KILL_DEMON)) {
308         info[i++] = _("それはデーモンにとっての天敵である。", "It is a great bane of demons.");
309     }
310
311     if (flags.has(TR_SLAY_DEMON)) {
312         info[i++] = _("それはデーモンに対して聖なる力を発揮する。", "It strikes at demons with holy wrath.");
313     }
314
315     if (flags.has(TR_KILL_UNDEAD)) {
316         info[i++] = _("それはアンデッドにとっての天敵である。", "It is a great bane of undead.");
317     }
318
319     if (flags.has(TR_SLAY_UNDEAD)) {
320         info[i++] = _("それはアンデッドに対して聖なる力を発揮する。", "It strikes at undead with holy wrath.");
321     }
322
323     if (flags.has(TR_KILL_EVIL)) {
324         info[i++] = _("それは邪悪なる存在にとっての天敵である。", "It is a great bane of evil monsters.");
325     }
326
327     if (flags.has(TR_SLAY_EVIL)) {
328         info[i++] = _("それは邪悪なる存在に対して聖なる力で攻撃する。", "It fights against evil with holy fury.");
329     }
330
331     if (flags.has(TR_KILL_GOOD)) {
332         info[i++] = _("それは善良なる存在にとっての天敵である。", "It is a great bane of good monsters.");
333     }
334
335     if (flags.has(TR_SLAY_GOOD)) {
336         info[i++] = _("それは善良なる存在に対して邪悪なる力で攻撃する。", "It fights against good with evil fury.");
337     }
338
339     if (flags.has(TR_KILL_ANIMAL)) {
340         info[i++] = _("それは自然界の動物にとっての天敵である。", "It is a great bane of natural creatures.");
341     }
342
343     if (flags.has(TR_SLAY_ANIMAL)) {
344         info[i++] = _("それは自然界の動物に対して特に恐るべき力を発揮する。", "It is especially deadly against natural creatures.");
345     }
346
347     if (flags.has(TR_KILL_HUMAN)) {
348         info[i++] = _("それは人間にとっての天敵である。", "It is a great bane of humans.");
349     }
350
351     if (flags.has(TR_SLAY_HUMAN)) {
352         info[i++] = _("それは人間に対して特に恐るべき力を発揮する。", "It is especially deadly against humans.");
353     }
354
355     if (flags.has(TR_FORCE_WEAPON)) {
356         info[i++] = _("それは使用者の魔力を使って攻撃する。", "It powerfully strikes at a monster using your mana.");
357     }
358
359     if (flags.has(TR_DEC_MANA)) {
360         info[i++] = _("それは魔力の消費を押さえる。", "It decreases your mana consumption.");
361     }
362
363     if (flags.has(TR_SUST_STR)) {
364         info[i++] = _("それはあなたの腕力を維持する。", "It sustains your strength.");
365     }
366
367     if (flags.has(TR_SUST_INT)) {
368         info[i++] = _("それはあなたの知能を維持する。", "It sustains your intelligence.");
369     }
370
371     if (flags.has(TR_SUST_WIS)) {
372         info[i++] = _("それはあなたの賢さを維持する。", "It sustains your wisdom.");
373     }
374
375     if (flags.has(TR_SUST_DEX)) {
376         info[i++] = _("それはあなたの器用さを維持する。", "It sustains your dexterity.");
377     }
378
379     if (flags.has(TR_SUST_CON)) {
380         info[i++] = _("それはあなたの耐久力を維持する。", "It sustains your constitution.");
381     }
382
383     if (flags.has(TR_SUST_CHR)) {
384         info[i++] = _("それはあなたの魅力を維持する。", "It sustains your charisma.");
385     }
386
387     if (flags.has(TR_IM_ACID)) {
388         info[i++] = _("それは酸に対する完全な免疫を授ける。", "It provides immunity to acid.");
389     } else if (flags.has(TR_VUL_ACID)) {
390         info[i++] = _("それは酸に対する弱点を授ける。", "It provides vulnerability to acid.");
391     }
392
393     if (flags.has(TR_IM_ELEC)) {
394         info[i++] = _("それは電撃に対する完全な免疫を授ける。", "It provides immunity to electricity.");
395     } else if (flags.has(TR_VUL_ELEC)) {
396         info[i++] = _("それは電撃に対する弱点を授ける。", "It provides vulnerability to electricity.");
397     }
398
399     if (flags.has(TR_IM_FIRE)) {
400         info[i++] = _("それは火に対する完全な免疫を授ける。", "It provides immunity to fire.");
401     } else if (flags.has(TR_VUL_FIRE)) {
402         info[i++] = _("それは火に対する弱点を授ける。", "It provides vulnerability to fire.");
403     }
404
405     if (flags.has(TR_IM_COLD)) {
406         info[i++] = _("それは寒さに対する完全な免疫を授ける。", "It provides immunity to cold.");
407     } else if (flags.has(TR_VUL_COLD)) {
408         info[i++] = _("それは寒さに対する弱点を授ける。", "It provides vulnerability to cold.");
409     }
410
411     if (flags.has(TR_IM_DARK)) {
412         info[i++] = _("それは暗黒に対する完全な免疫を授ける。", "It provides immunity to dark.");
413     }
414
415     if (flags.has(TR_VUL_LITE)) {
416         info[i++] = _("それは閃光に対する弱点を授ける。", "It provides vulnerability to cold.");
417     }
418
419     if (flags.has(TR_THROW)) {
420         info[i++] = _("それは敵に投げて大きなダメージを与えることができる。", "It is perfectly balanced for throwing.");
421     }
422
423     if (flags.has(TR_FREE_ACT)) {
424         info[i++] = _("それは麻痺に対する完全な免疫を授ける。", "It provides immunity to paralysis.");
425     }
426
427     if (flags.has(TR_HOLD_EXP)) {
428         info[i++] = _("それは経験値吸収に対する耐性を授ける。", "It provides resistance to experience draining.");
429     }
430
431     if (flags.has(TR_RES_FEAR)) {
432         info[i++] = _("それは恐怖への完全な耐性を授ける。", "It makes you completely fearless.");
433     }
434
435     if (flags.has(TR_RES_ACID)) {
436         info[i++] = _("それは酸への耐性を授ける。", "It provides resistance to acid.");
437     }
438
439     if (flags.has(TR_RES_ELEC)) {
440         info[i++] = _("それは電撃への耐性を授ける。", "It provides resistance to electricity.");
441     }
442
443     if (flags.has(TR_RES_FIRE)) {
444         info[i++] = _("それは火への耐性を授ける。", "It provides resistance to fire.");
445     }
446
447     if (flags.has(TR_RES_COLD)) {
448         info[i++] = _("それは寒さへの耐性を授ける。", "It provides resistance to cold.");
449     }
450
451     if (flags.has(TR_RES_POIS)) {
452         info[i++] = _("それは毒への耐性を授ける。", "It provides resistance to poison.");
453     }
454
455     if (flags.has(TR_RES_LITE)) {
456         info[i++] = _("それは閃光への耐性を授ける。", "It provides resistance to light.");
457     }
458
459     if (flags.has(TR_RES_DARK)) {
460         info[i++] = _("それは暗黒への耐性を授ける。", "It provides resistance to dark.");
461     }
462
463     if (flags.has(TR_RES_BLIND)) {
464         info[i++] = _("それは盲目への耐性を授ける。", "It provides resistance to blindness.");
465     }
466
467     if (flags.has(TR_RES_CONF)) {
468         info[i++] = _("それは混乱への耐性を授ける。", "It provides resistance to confusion.");
469     }
470
471     if (flags.has(TR_RES_SOUND)) {
472         info[i++] = _("それは轟音への耐性を授ける。", "It provides resistance to sound.");
473     }
474
475     if (flags.has(TR_RES_SHARDS)) {
476         info[i++] = _("それは破片への耐性を授ける。", "It provides resistance to shards.");
477     }
478
479     if (flags.has(TR_RES_NETHER)) {
480         info[i++] = _("それは地獄への耐性を授ける。", "It provides resistance to nether.");
481     }
482
483     if (flags.has(TR_RES_NEXUS)) {
484         info[i++] = _("それは因果混乱への耐性を授ける。", "It provides resistance to nexus.");
485     }
486
487     if (flags.has(TR_RES_CHAOS)) {
488         info[i++] = _("それはカオスへの耐性を授ける。", "It provides resistance to chaos.");
489     }
490
491     if (flags.has(TR_RES_TIME)) {
492         info[i++] = _("それは時間逆転への耐性を授ける。", "It provides resistance to time stream.");
493     }
494
495     if (flags.has(TR_RES_WATER)) {
496         info[i++] = _("それは水流への耐性を授ける。", "It provides resistance to water stream.");
497     }
498
499     if (flags.has(TR_RES_DISEN)) {
500         info[i++] = _("それは劣化への耐性を授ける。", "It provides resistance to disenchantment.");
501     }
502
503     if (flags.has(TR_LEVITATION)) {
504         info[i++] = _("それは宙に浮くことを可能にする。", "It allows you to levitate.");
505     }
506
507     if (flags.has(TR_SEE_INVIS)) {
508         info[i++] = _("それは透明なモンスターを見ることを可能にする。", "It allows you to see invisible monsters.");
509     }
510
511     if (flags.has(TR_TELEPATHY)) {
512         info[i++] = _("それはテレパシー能力を授ける。", "It gives telepathic powers.");
513     }
514
515     if (flags.has(TR_ESP_ANIMAL)) {
516         info[i++] = _("それは自然界の生物を感知する。", "It senses natural creatures.");
517     }
518
519     if (flags.has(TR_ESP_UNDEAD)) {
520         info[i++] = _("それはアンデッドを感知する。", "It senses undead.");
521     }
522
523     if (flags.has(TR_ESP_DEMON)) {
524         info[i++] = _("それは悪魔を感知する。", "It senses demons.");
525     }
526
527     if (flags.has(TR_ESP_ORC)) {
528         info[i++] = _("それはオークを感知する。", "It senses orcs.");
529     }
530
531     if (flags.has(TR_ESP_TROLL)) {
532         info[i++] = _("それはトロルを感知する。", "It senses trolls.");
533     }
534
535     if (flags.has(TR_ESP_GIANT)) {
536         info[i++] = _("それは巨人を感知する。", "It senses giants.");
537     }
538
539     if (flags.has(TR_ESP_DRAGON)) {
540         info[i++] = _("それはドラゴンを感知する。", "It senses dragons.");
541     }
542
543     if (flags.has(TR_ESP_HUMAN)) {
544         info[i++] = _("それは人間を感知する。", "It senses humans.");
545     }
546
547     if (flags.has(TR_ESP_EVIL)) {
548         info[i++] = _("それは邪悪な存在を感知する。", "It senses evil creatures.");
549     }
550
551     if (flags.has(TR_ESP_GOOD)) {
552         info[i++] = _("それは善良な存在を感知する。", "It senses good creatures.");
553     }
554
555     if (flags.has(TR_ESP_NONLIVING)) {
556         info[i++] = _("それは活動する無生物体を感知する。", "It senses non-living creatures.");
557     }
558
559     if (flags.has(TR_ESP_UNIQUE)) {
560         info[i++] = _("それは特別な強敵を感知する。", "It senses unique monsters.");
561     }
562
563     if (flags.has(TR_SLOW_DIGEST)) {
564         info[i++] = _("それはあなたの新陳代謝を遅くする。", "It slows your metabolism.");
565     }
566
567     if (flags.has(TR_REGEN)) {
568         info[i++] = _("それは体力回復力を強化する。", "It speeds your regenerative powers.");
569     }
570
571     if (flags.has(TR_WARNING)) {
572         info[i++] = _("それは危険に対して警告を発する。", "It warns you of danger");
573     }
574
575     if (flags.has(TR_REFLECT)) {
576         info[i++] = _("それは矢の呪文を反射する。", "It reflects bolt spells.");
577     }
578
579     if (flags.has(TR_RES_CURSE)) {
580         info[i++] = _("それは呪いへの抵抗力を高める。", "It increases your resistance to curses.");
581     }
582
583     if (flags.has(TR_SH_FIRE)) {
584         info[i++] = _("それは炎のバリアを張る。", "It produces a fiery sheath.");
585     }
586
587     if (flags.has(TR_SH_ELEC)) {
588         info[i++] = _("それは電気のバリアを張る。", "It produces an electric sheath.");
589     }
590
591     if (flags.has(TR_SH_COLD)) {
592         info[i++] = _("それは冷気のバリアを張る。", "It produces a sheath of coldness.");
593     }
594
595     if (flags.has(TR_SELF_FIRE)) {
596         info[i++] = _("それはあなたを燃やす。", "It burns you.");
597     }
598
599     if (flags.has(TR_SELF_ELEC)) {
600         info[i++] = _("それはあなたを電撃で包む。", "It electrocutes you.");
601     }
602
603     if (flags.has(TR_SELF_COLD)) {
604         info[i++] = _("それはあなたを凍らせる。", "It freezes you.");
605     }
606
607     if (flags.has(TR_NO_MAGIC)) {
608         info[i++] = _("それは反魔法バリアを張る。", "It produces an anti-magic shell.");
609     }
610
611     if (flags.has(TR_NO_TELE)) {
612         info[i++] = _("それはテレポートを邪魔する。", "It prevents teleportation.");
613     }
614
615     if (flags.has(TR_XTRA_MIGHT)) {
616         info[i++] = _("それは矢/ボルト/弾をより強力に発射することができる。", "It fires missiles with extra might.");
617     }
618
619     if (flags.has(TR_XTRA_SHOTS)) {
620         info[i++] = _("それは矢/ボルト/弾を非常に早く発射することができる。", "It fires missiles excessively fast.");
621     }
622
623     if (flags.has(TR_BLESSED)) {
624         info[i++] = _("それは神に祝福されている。", "It has been blessed by the gods.");
625     }
626
627     if (o_ptr->is_cursed()) {
628         if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
629             info[i++] = _("それは永遠の呪いがかけられている。", "It is permanently cursed.");
630         } else if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
631             info[i++] = _("それは強力な呪いがかけられている。", "It is heavily cursed.");
632         } else {
633             info[i++] = _("それは呪われている。", "It is cursed.");
634
635             /*
636              * It's a trivial infomation since there is
637              * fake inscription {cursed}
638              */
639             trivial_info++;
640         }
641     }
642
643     if ((flags.has(TR_TY_CURSE)) || o_ptr->curse_flags.has(CurseTraitType::TY_CURSE)) {
644         info[i++] = _("それは太古の禍々しい怨念が宿っている。", "It carries an ancient foul curse.");
645     }
646
647     if ((flags.has(TR_AGGRAVATE)) || o_ptr->curse_flags.has(CurseTraitType::AGGRAVATE)) {
648         info[i++] = _("それは付近のモンスターを怒らせる。", "It aggravates nearby creatures.");
649     }
650
651     if ((flags.has(TR_DRAIN_EXP)) || o_ptr->curse_flags.has(CurseTraitType::DRAIN_EXP)) {
652         info[i++] = _("それは経験値を吸い取る。", "It drains experience.");
653     }
654
655     if (o_ptr->curse_flags.has(CurseTraitType::SLOW_REGEN)) {
656         info[i++] = _("それは回復力を弱める。", "It slows your regenerative powers.");
657     }
658
659     if (o_ptr->curse_flags.has(CurseTraitType::ADD_L_CURSE) || flags.has(TR_ADD_L_CURSE)) {
660         info[i++] = _("それは弱い呪いを増やす。", "It adds weak curses.");
661     }
662
663     if (o_ptr->curse_flags.has(CurseTraitType::ADD_H_CURSE) || flags.has(TR_ADD_H_CURSE)) {
664         info[i++] = _("それは強力な呪いを増やす。", "It adds heavy curses.");
665     }
666
667     if (o_ptr->curse_flags.has(CurseTraitType::PERSISTENT_CURSE) || flags.has(TR_PERSISTENT_CURSE)) {
668         info[i++] = _("それは頻繁に呪いをかけなおす。", "It curses itself persistently.");
669     }
670
671     if ((flags.has(TR_CALL_ANIMAL)) || o_ptr->curse_flags.has(CurseTraitType::CALL_ANIMAL)) {
672         info[i++] = _("それは動物を呼び寄せる。", "It attracts animals.");
673     }
674
675     if ((flags.has(TR_CALL_DEMON)) || o_ptr->curse_flags.has(CurseTraitType::CALL_DEMON)) {
676         info[i++] = _("それは悪魔を呼び寄せる。", "It attracts demons.");
677     }
678
679     if ((flags.has(TR_CALL_DRAGON)) || o_ptr->curse_flags.has(CurseTraitType::CALL_DRAGON)) {
680         info[i++] = _("それはドラゴンを呼び寄せる。", "It attracts dragons.");
681     }
682
683     if ((flags.has(TR_CALL_UNDEAD)) || o_ptr->curse_flags.has(CurseTraitType::CALL_UNDEAD)) {
684         info[i++] = _("それは死霊を呼び寄せる。", "It attracts undead.");
685     }
686
687     if ((flags.has(TR_COWARDICE)) || o_ptr->curse_flags.has(CurseTraitType::COWARDICE)) {
688         info[i++] = _("それは恐怖感を引き起こす。", "It makes you subject to cowardice.");
689     }
690
691     if (flags.has(TR_BERS_RAGE) || o_ptr->curse_flags.has(CurseTraitType::BERS_RAGE)) {
692         info[i++] = _("それは狂戦士化の発作を引き起こす。", "It makes you subject to berserker fits.");
693     }
694
695     if ((flags.has(TR_TELEPORT)) || o_ptr->curse_flags.has(CurseTraitType::TELEPORT)) {
696         info[i++] = _("それはランダムなテレポートを引き起こす。", "It induces random teleportation.");
697     }
698
699     if ((flags.has(TR_LOW_MELEE)) || o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
700         info[i++] = _("それは攻撃を外しやすい。", "It causes you to miss blows.");
701     }
702
703     if ((flags.has(TR_LOW_AC)) || o_ptr->curse_flags.has(CurseTraitType::LOW_AC)) {
704         info[i++] = _("それは攻撃を受けやすい。", "It helps your enemies' blows.");
705     }
706
707     if (o_ptr->curse_flags.has(CurseTraitType::VUL_CURSE) || flags.has(TR_VUL_CURSE)) {
708         info[i++] = _("それは呪いへの抵抗力を下げる。", "It decreases your resistance to curses.");
709     }
710
711     if (flags.has(TR_DOWN_SAVING)) {
712         info[i++] = _("それは魔法抵抗力を半減させる。", "It halves your magic resistance.");
713     }
714
715     if ((flags.has(TR_HARD_SPELL)) || o_ptr->curse_flags.has(CurseTraitType::HARD_SPELL)) {
716         info[i++] = _("それは魔法を唱えにくくする。", "It encumbers you while spellcasting.");
717     }
718
719     if ((flags.has(TR_FAST_DIGEST)) || o_ptr->curse_flags.has(CurseTraitType::FAST_DIGEST)) {
720         info[i++] = _("それはあなたの新陳代謝を速くする。", "It speeds your metabolism.");
721     }
722
723     if ((flags.has(TR_DRAIN_HP)) || o_ptr->curse_flags.has(CurseTraitType::DRAIN_HP)) {
724         info[i++] = _("それはあなたの体力を吸い取る。", "It drains you.");
725     }
726
727     if ((flags.has(TR_DRAIN_MANA)) || o_ptr->curse_flags.has(CurseTraitType::DRAIN_MANA)) {
728         info[i++] = _("それはあなたの魔力を吸い取る。", "It drains your mana.");
729     }
730
731     if (mode & SCROBJ_FAKE_OBJECT) {
732         const auto sval = o_ptr->bi_key.sval().value();
733         switch (o_ptr->bi_key.tval()) {
734         case ItemKindType::RING:
735             switch (sval) {
736             case SV_RING_LORDLY:
737                 info[i++] = _("それは幾つかのランダムな耐性を授ける。", "It provides some random resistances.");
738                 break;
739             case SV_RING_WARNING:
740                 info[i++] = _("それはひとつの低級なESPを授ける事がある。", "It may provide a low rank ESP.");
741                 break;
742             }
743
744             break;
745
746         case ItemKindType::AMULET:
747             switch (sval) {
748             case SV_AMULET_RESISTANCE:
749                 info[i++] = _("それは毒への耐性を授ける事がある。", "It may provides resistance to poison.");
750                 info[i++] = _("それはランダムな耐性を授ける事がある。", "It may provide a random resistances.");
751                 break;
752             case SV_AMULET_THE_MAGI:
753                 info[i++] = _("それは最大で3つまでの低級なESPを授ける。", "It provides up to three low rank ESPs.");
754                 break;
755             }
756
757             break;
758
759         default:
760             break;
761         }
762     }
763
764     if (flags.has(TR_IGNORE_ACID) && flags.has(TR_IGNORE_ELEC) && flags.has(TR_IGNORE_FIRE) && flags.has(TR_IGNORE_COLD)) {
765         info[i++] = _("それは酸・電撃・火炎・冷気では傷つかない。", "It cannot be harmed by the elements.");
766     } else {
767         if (flags.has(TR_IGNORE_ACID)) {
768             info[i++] = _("それは酸では傷つかない。", "It cannot be harmed by acid.");
769         }
770
771         if (flags.has(TR_IGNORE_ELEC)) {
772             info[i++] = _("それは電撃では傷つかない。", "It cannot be harmed by electricity.");
773         }
774
775         if (flags.has(TR_IGNORE_FIRE)) {
776             info[i++] = _("それは火炎では傷つかない。", "It cannot be harmed by fire.");
777         }
778
779         if (flags.has(TR_IGNORE_COLD)) {
780             info[i++] = _("それは冷気では傷つかない。", "It cannot be harmed by cold.");
781         }
782     }
783
784     if (mode & SCROBJ_FORCE_DETAIL) {
785         trivial_info = 0;
786     }
787
788     if (i <= trivial_info) {
789         return false;
790     }
791
792     screen_save();
793     const auto [wid, hgt] = term_get_size();
794     std::string item_name;
795     if (!(mode & SCROBJ_FAKE_OBJECT)) {
796         item_name = describe_flavor(player_ptr, o_ptr, 0);
797     } else {
798         item_name = describe_flavor(player_ptr, o_ptr, (OD_NAME_ONLY | OD_STORE));
799     }
800
801     prt(item_name, 0, 0);
802     for (int k = 1; k < hgt; k++) {
803         prt("", k, 13);
804     }
805
806     if (bi_key == BaseitemKey(ItemKindType::STATUE, SV_PHOTO)) {
807         auto statue_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
808         auto *r_ptr = &monraces_info[statue_r_idx];
809         int namelen = strlen(r_ptr->name.data());
810         prt(format("%s: '", r_ptr->name.data()), 1, 15);
811         term_queue_bigchar(18 + namelen, 1, r_ptr->x_attr, r_ptr->x_char, 0, 0);
812         prt("'", 1, (use_bigtile ? 20 : 19) + namelen);
813     } else {
814         prt(_("     アイテムの能力:", "     Item Attributes:"), 1, 15);
815     }
816
817     int k = 2;
818     for (int j = 0; j < i; j++) {
819         prt(info[j], k++, 15);
820         if ((k == hgt - 2) && (j + 1 < i)) {
821             prt(_("-- 続く --", "-- more --"), k, 15);
822             inkey();
823             for (; k > 2; k--) {
824                 prt("", k, 15);
825             }
826         }
827     }
828
829     prt(_("[何かキーを押すとゲームに戻ります]", "[Press any key to continue]"), k, 15);
830     inkey();
831     screen_load();
832     return true;
833 }