OSDN Git Service

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