OSDN Git Service

Merge pull request #3814 from Slimebreath6078/feature/Add_Laffey_II
[hengbandforosx/hengbandosx.git] / src / spell / spells-object.cpp
1 /*!
2  * @brief アイテムに影響のある魔法の処理
3  * @date 2019/01/22
4  * @author deskull
5  */
6
7 #include "spell/spells-object.h"
8 #include "artifact/fixed-art-types.h"
9 #include "avatar/avatar.h"
10 #include "core/window-redrawer.h"
11 #include "flavor/flavor-describer.h"
12 #include "flavor/object-flavor-types.h"
13 #include "floor/floor-object.h"
14 #include "game-option/disturbance-options.h"
15 #include "inventory/inventory-slot-types.h"
16 #include "monster-race/monster-race.h"
17 #include "object-enchant/item-apply-magic.h"
18 #include "object-enchant/item-feeling.h"
19 #include "object-enchant/item-magic-applier.h"
20 #include "object-enchant/object-boost.h"
21 #include "object-enchant/object-ego.h"
22 #include "object-enchant/special-object-flags.h"
23 #include "object-enchant/trc-types.h"
24 #include "object-enchant/trg-types.h"
25 #include "object-hook/hook-armor.h"
26 #include "object-hook/hook-weapon.h"
27 #include "object/item-tester-hooker.h"
28 #include "object/item-use-flags.h"
29 #include "object/object-kind-hook.h"
30 #include "perception/object-perception.h"
31 #include "player-info/class-info.h"
32 #include "racial/racial-android.h"
33 #include "sv-definition/sv-other-types.h"
34 #include "sv-definition/sv-scroll-types.h"
35 #include "sv-definition/sv-weapon-types.h"
36 #include "system/artifact-type-definition.h"
37 #include "system/baseitem-info.h"
38 #include "system/floor-type-definition.h"
39 #include "system/item-entity.h"
40 #include "system/monster-race-info.h"
41 #include "system/player-type-definition.h"
42 #include "system/redrawing-flags-updater.h"
43 #include "term/screen-processor.h"
44 #include "util/bit-flags-calculator.h"
45 #include "util/probability-table.h"
46 #include "view/display-messages.h"
47
48 /*!
49  * @brief 装備強化処理の失敗率定数 (千分率)
50  * @details 強化値が負値から0までは必ず成功する
51  * 正値は+15までしか鍛えることができず、+16以上への強化を試みると確実に失敗する
52  */
53 static constexpr std::array<int, 16> enchant_table = { { 0, 10, 50, 100, 200, 300, 400, 500, 650, 800, 950, 987, 993, 995, 998, 1000 } };
54
55 /*
56  * Scatter some "amusing" objects near the player
57  */
58 enum class AmusementFlagType : byte {
59     NOTHING, /* No restriction */
60     NO_UNIQUE, /* Don't make the amusing object of uniques */
61     FIXED_ART, /* Make a fixed artifact based on the amusing object */
62     MULTIPLE, /* Drop 1-3 objects for one type */
63     PILE, /* Drop 1-99 pile objects for one type */
64 };
65
66 class AmuseDefinition {
67 public:
68     AmuseDefinition(const BaseitemKey &key, PERCENTAGE prob, AmusementFlagType flag)
69         : key(key)
70         , prob(prob)
71         , flag(flag)
72     {
73     }
74
75     BaseitemKey key;
76     PERCENTAGE prob;
77     AmusementFlagType flag;
78 };
79
80 static const std::array<AmuseDefinition, 13> amuse_info = { {
81     { { ItemKindType::BOTTLE }, 5, AmusementFlagType::NOTHING },
82     { { ItemKindType::JUNK }, 3, AmusementFlagType::MULTIPLE },
83     { { ItemKindType::SPIKE }, 10, AmusementFlagType::PILE },
84     { { ItemKindType::STATUE }, 15, AmusementFlagType::NOTHING },
85     { { ItemKindType::CORPSE }, 15, AmusementFlagType::NO_UNIQUE },
86     { { ItemKindType::SKELETON }, 10, AmusementFlagType::NO_UNIQUE },
87     { { ItemKindType::FIGURINE }, 10, AmusementFlagType::NO_UNIQUE },
88     { { ItemKindType::PARCHMENT }, 1, AmusementFlagType::NOTHING },
89     { { ItemKindType::POLEARM, SV_TSURIZAO }, 3, AmusementFlagType::NOTHING }, // Fishing Pole of Taikobo
90     { { ItemKindType::SWORD, SV_BROKEN_DAGGER }, 3, AmusementFlagType::FIXED_ART }, // Broken Dagger of Magician
91     { { ItemKindType::SWORD, SV_BROKEN_DAGGER }, 10, AmusementFlagType::NOTHING },
92     { { ItemKindType::SWORD, SV_BROKEN_SWORD }, 5, AmusementFlagType::NOTHING },
93     { { ItemKindType::SCROLL, SV_SCROLL_AMUSEMENT }, 10, AmusementFlagType::NOTHING },
94 } };
95
96 static std::optional<FixedArtifactId> sweep_amusement_artifact(const bool insta_art, const short bi_id)
97 {
98     for (const auto &[a_idx, artifact] : artifacts_info) {
99         if (a_idx == FixedArtifactId::NONE) {
100             continue;
101         }
102
103         if (insta_art && !artifact.gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
104             continue;
105         }
106
107         if (artifact.bi_key != baseitems_info[bi_id].bi_key) {
108             continue;
109         }
110
111         if (artifact.is_generated) {
112             continue;
113         }
114
115         return a_idx;
116     }
117
118     return std::nullopt;
119 }
120
121 /*!
122  * @brief 誰得ドロップを行う。
123  * @param player_ptr プレイヤーへの参照ポインタ
124  * @param num 誰得の処理回数
125  * @param known TRUEならばオブジェクトが必ず*鑑定*済になる
126  */
127 void generate_amusement(PlayerType *player_ptr, int num, bool known)
128 {
129     ProbabilityTable<const AmuseDefinition *> pt;
130     for (const auto &am_ref : amuse_info) {
131         pt.entry_item(&am_ref, am_ref.prob);
132     }
133
134     for (auto i = 0; i < num; i++) {
135         auto am_ptr = pt.pick_one_at_random();
136         const auto bi_id = lookup_baseitem_id(am_ptr->key);
137         if (bi_id == 0) {
138             continue;
139         }
140
141         const auto insta_art = baseitems_info[bi_id].gen_flags.has(ItemGenerationTraitType::INSTA_ART);
142         const auto flag = am_ptr->flag;
143         const auto fixed_art = flag == AmusementFlagType::FIXED_ART;
144         std::optional<FixedArtifactId> opt_a_idx(std::nullopt);
145         if (insta_art || fixed_art) {
146             opt_a_idx = sweep_amusement_artifact(insta_art, bi_id);
147             if (!opt_a_idx) {
148                 continue;
149             }
150         }
151
152         ItemEntity item;
153         item.prep(bi_id);
154         if (opt_a_idx) {
155             item.fixed_artifact_idx = *opt_a_idx;
156         }
157
158         ItemMagicApplier(player_ptr, &item, 1, AM_NO_FIXED_ART).execute();
159         if (flag == AmusementFlagType::NO_UNIQUE) {
160             if (monraces_info[i2enum<MonsterRaceId>(item.pval)].kind_flags.has(MonsterKindType::UNIQUE)) {
161                 continue;
162             }
163         }
164
165         if (flag == AmusementFlagType::MULTIPLE) {
166             item.number = randint1(3);
167         }
168
169         if (flag == AmusementFlagType::PILE) {
170             item.number = randint1(99);
171         }
172
173         if (known) {
174             object_aware(player_ptr, &item);
175             item.mark_as_known();
176         }
177
178         (void)drop_near(player_ptr, &item, -1, player_ptr->y, player_ptr->x);
179     }
180 }
181
182 /*!
183  * @brief 獲得ドロップを行う。
184  * Scatter some "great" objects near the player
185  * @param player_ptr プレイヤーへの参照ポインタ
186  * @param y1 配置したいフロアのY座標
187  * @param x1 配置したいフロアのX座標
188  * @param num 獲得の処理回数
189  * @param great TRUEならば必ず高級品以上を落とす
190  */
191 void acquirement(PlayerType *player_ptr, POSITION y1, POSITION x1, int num, bool great)
192 {
193     auto mode = AM_GOOD | (great ? AM_GREAT : AM_NONE);
194     for (auto i = 0; i < num; i++) {
195         ItemEntity item;
196         if (!make_object(player_ptr, &item, mode)) {
197             continue;
198         }
199
200         (void)drop_near(player_ptr, &item, -1, y1, x1);
201     }
202 }
203
204 /*!
205  * @brief 防具呪縛処理 /
206  * Curse the players armor
207  * @return 何も持っていない場合を除き、常にTRUEを返す
208  * @todo 元のreturnは間違っているが、修正後の↓文がどれくらい正しいかは要チェック
209  */
210 bool curse_armor(PlayerType *player_ptr)
211 {
212     /* Curse the body armor */
213     auto *o_ptr = &player_ptr->inventory_list[INVEN_BODY];
214     if (!o_ptr->is_valid()) {
215         return false;
216     }
217
218     const auto item_name = describe_flavor(player_ptr, o_ptr, OD_OMIT_PREFIX);
219
220     if (o_ptr->is_fixed_or_random_artifact() && one_in_(2)) {
221 #ifdef JP
222         msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!", "恐怖の暗黒オーラ", "防具", item_name.data());
223 #else
224         msg_format("A %s tries to %s, but your %s resists the effects!", "terrible black aura", "surround your armor", item_name.data());
225 #endif
226         return true;
227     }
228
229     msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), item_name.data());
230     chg_virtue(player_ptr, Virtue::ENCHANT, -5);
231     o_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
232     o_ptr->ego_idx = EgoType::BLASTED;
233     o_ptr->to_a = 0 - randint1(5) - randint1(5);
234     o_ptr->to_h = 0;
235     o_ptr->to_d = 0;
236     o_ptr->ac = 0;
237     o_ptr->dd = 0;
238     o_ptr->ds = 0;
239     o_ptr->art_flags.clear();
240     o_ptr->curse_flags.set(CurseTraitType::CURSED);
241     o_ptr->ident |= IDENT_BROKEN;
242     auto &rfu = RedrawingFlagsUpdater::get_instance();
243     static constexpr auto flags_srf = {
244         StatusRecalculatingFlag::BONUS,
245         StatusRecalculatingFlag::MP,
246     };
247     rfu.set_flags(flags_srf);
248     static constexpr auto flags_swrf = {
249         SubWindowRedrawingFlag::INVENTORY,
250         SubWindowRedrawingFlag::EQUIPMENT,
251         SubWindowRedrawingFlag::PLAYER,
252     };
253     rfu.set_flags(flags_swrf);
254     return true;
255 }
256
257 /*!
258  * @brief 武器呪縛処理 /
259  * Curse the players weapon
260  * @param player_ptr 所持者の参照ポインタ
261  * @param force 無条件に呪縛を行うならばTRUE
262  * @param o_ptr 呪縛する武器のアイテム情報参照ポインタ
263  * @return 何も持っていない場合を除き、常にTRUEを返す
264  * @todo 元のreturnは間違っているが、修正後の↓文がどれくらい正しいかは要チェック
265  */
266 bool curse_weapon_object(PlayerType *player_ptr, bool force, ItemEntity *o_ptr)
267 {
268     if (!o_ptr->is_valid()) {
269         return false;
270     }
271
272     const auto item_name = describe_flavor(player_ptr, o_ptr, OD_OMIT_PREFIX);
273     if (o_ptr->is_fixed_or_random_artifact() && one_in_(2) && !force) {
274 #ifdef JP
275         msg_format("%sが%sを包み込もうとしたが、%sはそれを跳ね返した!", "恐怖の暗黒オーラ", "武器", item_name.data());
276 #else
277         msg_format("A %s tries to %s, but your %s resists the effects!", "terrible black aura", "surround your weapon", item_name.data());
278 #endif
279         return true;
280     }
281
282     if (!force) {
283         msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), item_name.data());
284     }
285
286     chg_virtue(player_ptr, Virtue::ENCHANT, -5);
287     o_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
288     o_ptr->ego_idx = EgoType::SHATTERED;
289     o_ptr->to_h = 0 - randint1(5) - randint1(5);
290     o_ptr->to_d = 0 - randint1(5) - randint1(5);
291     o_ptr->to_a = 0;
292     o_ptr->ac = 0;
293     o_ptr->dd = 0;
294     o_ptr->ds = 0;
295     o_ptr->art_flags.clear();
296     o_ptr->curse_flags.set(CurseTraitType::CURSED);
297     o_ptr->ident |= IDENT_BROKEN;
298     auto &rfu = RedrawingFlagsUpdater::get_instance();
299     static constexpr auto flags_srf = {
300         StatusRecalculatingFlag::BONUS,
301         StatusRecalculatingFlag::MP,
302     };
303     rfu.set_flags(flags_srf);
304     static constexpr auto flags_swrf = {
305         SubWindowRedrawingFlag::INVENTORY,
306         SubWindowRedrawingFlag::EQUIPMENT,
307         SubWindowRedrawingFlag::PLAYER,
308     };
309     rfu.set_flags(flags_swrf);
310     return true;
311 }
312
313 /*!
314  * @brief ボルトのエゴ化処理(火炎エゴのみ) /
315  * Enchant some bolts
316  * @param player_ptr プレイヤーへの参照ポインタ
317  */
318 void brand_bolts(PlayerType *player_ptr)
319 {
320     for (auto i = 0; i < INVEN_PACK; i++) {
321         auto *o_ptr = &player_ptr->inventory_list[i];
322         if (o_ptr->bi_key.tval() != ItemKindType::BOLT) {
323             continue;
324         }
325
326         if (o_ptr->is_fixed_or_random_artifact() || o_ptr->is_ego()) {
327             continue;
328         }
329
330         if (o_ptr->is_cursed() || o_ptr->is_broken()) {
331             continue;
332         }
333
334         if (randint0(100) < 75) {
335             continue;
336         }
337
338         msg_print(_("クロスボウの矢が炎のオーラに包まれた!", "Your bolts are covered in a fiery aura!"));
339         o_ptr->ego_idx = EgoType::FLAME;
340         enchant_equipment(o_ptr, randint0(3) + 4, ENCH_TOHIT | ENCH_TODAM);
341         return;
342     }
343
344     if (flush_failure) {
345         flush();
346     }
347
348     msg_print(_("炎で強化するのに失敗した。", "The fiery enchantment failed."));
349 }
350
351 /*!
352  * @brief 呪いの打ち破り処理 /
353  * Break the curse of an item
354  * @param o_ptr 呪い装備情報の参照ポインタ
355  */
356 static void break_curse(ItemEntity *o_ptr)
357 {
358     const auto has_heavier_curse = o_ptr->curse_flags.has_any_of({ CurseTraitType::PERMA_CURSE, CurseTraitType::HEAVY_CURSE });
359     const auto is_curse_broken = o_ptr->is_cursed() && !has_heavier_curse && one_in_(4);
360     if (!is_curse_broken) {
361         return;
362     }
363
364     msg_print(_("かけられていた呪いが打ち破られた!", "The curse is broken!"));
365     o_ptr->curse_flags.clear();
366     o_ptr->ident |= IDENT_SENSE;
367     o_ptr->feeling = FEEL_NONE;
368 }
369
370 /*!
371  * @brief 装備修正強化処理
372  * @param o_ptr 強化するアイテムの参照ポインタ
373  * @param n 強化基本量
374  * @param eflag 強化オプション(命中/ダメージ/AC)
375  * @return 強化に成功した場合TRUEを返す
376  */
377 bool enchant_equipment(ItemEntity *o_ptr, int n, int eflag)
378 {
379     auto prob = o_ptr->number * 100;
380     if (o_ptr->is_ammo()) {
381         prob = prob / 20;
382     }
383
384     int chance;
385     auto res = false;
386     auto a = o_ptr->is_fixed_or_random_artifact();
387     auto force = (eflag & ENCH_FORCE);
388     for (int i = 0; i < n; i++) {
389         if (!force && randint0(prob) >= 100) {
390             continue;
391         }
392
393         if (eflag & ENCH_TOHIT) {
394             if (o_ptr->to_h < 0) {
395                 chance = 0;
396             } else if (o_ptr->to_h > 15) {
397                 chance = 1000;
398             } else {
399                 chance = enchant_table[o_ptr->to_h];
400             }
401
402             if (force || ((randint1(1000) > chance) && (!a || (randint0(100) < 50)))) {
403                 o_ptr->to_h++;
404                 res = true;
405                 if (o_ptr->to_h >= 0) {
406                     break_curse(o_ptr);
407                 }
408             }
409         }
410
411         if (eflag & ENCH_TODAM) {
412             if (o_ptr->to_d < 0) {
413                 chance = 0;
414             } else if (o_ptr->to_d > 15) {
415                 chance = 1000;
416             } else {
417                 chance = enchant_table[o_ptr->to_d];
418             }
419
420             if (force || ((randint1(1000) > chance) && (!a || (randint0(100) < 50)))) {
421                 o_ptr->to_d++;
422                 res = true;
423                 if (o_ptr->to_d >= 0) {
424                     break_curse(o_ptr);
425                 }
426             }
427         }
428
429         if (!(eflag & ENCH_TOAC)) {
430             continue;
431         }
432
433         if (o_ptr->to_a < 0) {
434             chance = 0;
435         } else if (o_ptr->to_a > 15) {
436             chance = 1000;
437         } else {
438             chance = enchant_table[o_ptr->to_a];
439         }
440
441         if (force || ((randint1(1000) > chance) && (!a || (randint0(100) < 50)))) {
442             o_ptr->to_a++;
443             res = true;
444             if (o_ptr->to_a >= 0) {
445                 break_curse(o_ptr);
446             }
447         }
448     }
449
450     if (!res) {
451         return false;
452     }
453
454     auto &rfu = RedrawingFlagsUpdater::get_instance();
455     static constexpr auto flags_srf = {
456         StatusRecalculatingFlag::BONUS,
457         StatusRecalculatingFlag::COMBINATION,
458         StatusRecalculatingFlag::REORDER,
459     };
460     rfu.set_flags(flags_srf);
461     static constexpr auto flags_swrf = {
462         SubWindowRedrawingFlag::INVENTORY,
463         SubWindowRedrawingFlag::EQUIPMENT,
464         SubWindowRedrawingFlag::PLAYER,
465         SubWindowRedrawingFlag::FLOOR_ITEMS,
466         SubWindowRedrawingFlag::FOUND_ITEMS,
467     };
468     rfu.set_flags(flags_swrf);
469     return true;
470 }
471
472 /*!
473  * @brief 装備修正強化処理のメインルーチン
474  * @param player_ptr プレイヤーへの参照ポインタ
475  * @param num_hit 命中修正量
476  * @param num_dam ダメージ修正量
477  * @param num_ac AC修正量
478  * @return 強化に成功した場合TRUEを返す
479  */
480 bool enchant_spell(PlayerType *player_ptr, HIT_PROB num_hit, int num_dam, ARMOUR_CLASS num_ac)
481 {
482     FuncItemTester item_tester(&ItemEntity::allow_enchant_weapon);
483     if (num_ac) {
484         item_tester = FuncItemTester(&ItemEntity::is_protector);
485     }
486
487     constexpr auto q = _("どのアイテムを強化しますか? ", "Enchant which item? ");
488     constexpr auto s = _("強化できるアイテムがない。", "You have nothing to enchant.");
489     short i_idx;
490     const auto options = USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT;
491     auto *o_ptr = choose_object(player_ptr, &i_idx, q, s, options, item_tester);
492     if (!o_ptr) {
493         return false;
494     }
495
496     const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
497 #ifdef JP
498     msg_format("%s は明るく輝いた!", item_name.data());
499 #else
500     msg_format("%s %s glow%s brightly!", ((i_idx >= 0) ? "Your" : "The"), item_name.data(), ((o_ptr->number > 1) ? "" : "s"));
501 #endif
502
503     auto is_enchant_successful = false;
504     if (enchant_equipment(o_ptr, num_hit, ENCH_TOHIT)) {
505         is_enchant_successful = true;
506     }
507
508     if (enchant_equipment(o_ptr, num_dam, ENCH_TODAM)) {
509         is_enchant_successful = true;
510     }
511
512     if (enchant_equipment(o_ptr, num_ac, ENCH_TOAC)) {
513         is_enchant_successful = true;
514     }
515
516     if (!is_enchant_successful) {
517         if (flush_failure) {
518             flush();
519         }
520         msg_print(_("強化に失敗した。", "The enchantment failed."));
521         if (one_in_(3)) {
522             chg_virtue(player_ptr, Virtue::ENCHANT, -1);
523         }
524     } else {
525         chg_virtue(player_ptr, Virtue::ENCHANT, 1);
526     }
527
528     calc_android_exp(player_ptr);
529     return true;
530 }
531
532 /*!
533  * @brief 武器へのエゴ付加処理
534  * @param player_ptr プレイヤーへの参照ポインタ
535  * @param brand_type エゴ化ID(EgoDefinitionsとは連動していない)
536  */
537 void brand_weapon(PlayerType *player_ptr, int brand_type)
538 {
539     constexpr auto q = _("どの武器を強化しますか? ", "Enchant which weapon? ");
540     constexpr auto s = _("強化できる武器がない。", "You have nothing to enchant.");
541     short i_idx;
542     const auto options = USE_EQUIP | IGNORE_BOTHHAND_SLOT;
543     auto *o_ptr = choose_object(player_ptr, &i_idx, q, s, options, FuncItemTester(&ItemEntity::allow_enchant_melee_weapon));
544     if (o_ptr == nullptr) {
545         return;
546     }
547
548     const auto &bi_key = o_ptr->bi_key;
549     auto special_weapon = bi_key == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE);
550     special_weapon |= bi_key == BaseitemKey(ItemKindType::POLEARM, SV_DEATH_SCYTHE);
551     special_weapon |= bi_key == BaseitemKey(ItemKindType::SWORD, SV_DIAMOND_EDGE);
552     const auto is_normal_item = o_ptr->is_valid() && !o_ptr->is_fixed_or_random_artifact() && !o_ptr->is_ego() && !o_ptr->is_cursed() && !special_weapon;
553     if (!is_normal_item) {
554         if (flush_failure) {
555             flush();
556         }
557
558         msg_print(_("属性付加に失敗した。", "The branding failed."));
559         chg_virtue(player_ptr, Virtue::ENCHANT, -2);
560         calc_android_exp(player_ptr);
561         return;
562     }
563
564     const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
565     concptr act = nullptr;
566     switch (brand_type) {
567     case 17:
568         if (o_ptr->bi_key.tval() == ItemKindType::SWORD) {
569             act = _("は鋭さを増した!", "becomes very sharp!");
570             o_ptr->ego_idx = EgoType::SHARPNESS;
571             o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, player_ptr->current_floor_ptr->dun_level) + 1;
572             if ((o_ptr->bi_key.sval() == SV_HAYABUSA) && (o_ptr->pval > 2)) {
573                 o_ptr->pval = 2;
574             }
575         } else {
576             act = _("は破壊力を増した!", "seems very powerful.");
577             o_ptr->ego_idx = EgoType::EARTHQUAKES;
578             o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, player_ptr->current_floor_ptr->dun_level);
579         }
580
581         break;
582     case 16:
583         act = _("は人間の血を求めている!", "seems to be looking for humans!");
584         o_ptr->ego_idx = EgoType::KILL_HUMAN;
585         break;
586     case 15:
587         act = _("は電撃に覆われた!", "covered with lightning!");
588         o_ptr->ego_idx = EgoType::BRAND_ELEC;
589         break;
590     case 14:
591         act = _("は酸に覆われた!", "coated with acid!");
592         o_ptr->ego_idx = EgoType::BRAND_ACID;
593         break;
594     case 13:
595         act = _("は邪悪なる怪物を求めている!", "seems to be looking for evil monsters!");
596         o_ptr->ego_idx = EgoType::KILL_EVIL;
597         break;
598     case 12:
599         act = _("は異世界の住人の肉体を求めている!", "seems to be looking for demons!");
600         o_ptr->ego_idx = EgoType::KILL_DEMON;
601         break;
602     case 11:
603         act = _("は屍を求めている!", "seems to be looking for undead!");
604         o_ptr->ego_idx = EgoType::KILL_UNDEAD;
605         break;
606     case 10:
607         act = _("は動物の血を求めている!", "seems to be looking for animals!");
608         o_ptr->ego_idx = EgoType::KILL_ANIMAL;
609         break;
610     case 9:
611         act = _("はドラゴンの血を求めている!", "seems to be looking for dragons!");
612         o_ptr->ego_idx = EgoType::KILL_DRAGON;
613         break;
614     case 8:
615         act = _("はトロルの血を求めている!", "seems to be looking for troll!s");
616         o_ptr->ego_idx = EgoType::KILL_TROLL;
617         break;
618     case 7:
619         act = _("はオークの血を求めている!", "seems to be looking for orcs!");
620         o_ptr->ego_idx = EgoType::KILL_ORC;
621         break;
622     case 6:
623         act = _("は巨人の血を求めている!", "seems to be looking for giants!");
624         o_ptr->ego_idx = EgoType::KILL_GIANT;
625         break;
626     case 5:
627         act = _("は非常に不安定になったようだ。", "seems very unstable now.");
628         o_ptr->ego_idx = EgoType::TRUMP;
629         o_ptr->pval = randint1(2);
630         break;
631     case 4:
632         act = _("は血を求めている!", "thirsts for blood!");
633         o_ptr->ego_idx = EgoType::VAMPIRIC;
634         break;
635     case 3:
636         act = _("は毒に覆われた。", "is coated with poison.");
637         o_ptr->ego_idx = EgoType::BRAND_POIS;
638         break;
639     case 2:
640         act = _("は純ログルスに飲み込まれた。", "is engulfed in raw Logrus!");
641         o_ptr->ego_idx = EgoType::CHAOTIC;
642         break;
643     case 1:
644         act = _("は炎のシールドに覆われた!", "is covered in a fiery shield!");
645         o_ptr->ego_idx = EgoType::BRAND_FIRE;
646         break;
647     default:
648         act = _("は深く冷たいブルーに輝いた!", "glows deep, icy blue!");
649         o_ptr->ego_idx = EgoType::BRAND_COLD;
650         break;
651     }
652
653     msg_format(_("あなたの%s%s", "Your %s %s"), item_name.data(), act);
654     enchant_equipment(o_ptr, randint0(3) + 4, ENCH_TOHIT | ENCH_TODAM);
655     o_ptr->discount = 99;
656     chg_virtue(player_ptr, Virtue::ENCHANT, 2);
657     calc_android_exp(player_ptr);
658 }