OSDN Git Service

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