OSDN Git Service

Merge pull request #1534 from Hourier/experiment/Remove-Wizard-Mode
[hengbandforosx/hengbandosx.git] / src / realm / realm-hex.cpp
1 /*!
2  * @brief 呪術の処理実装 / Hex code
3  * @date 2014/01/14
4  * @author
5  * 2014 Deskull rearranged comment for Doxygen.\n
6  */
7
8 #include "realm/realm-hex.h"
9 #include "cmd-action/cmd-spell.h"
10 #include "cmd-item/cmd-quaff.h"
11 #include "core/asking-player.h"
12 #include "core/player-redraw-types.h"
13 #include "core/player-update-types.h"
14 #include "effect/effect-characteristics.h"
15 #include "effect/effect-processor.h"
16 #include "flavor/flavor-describer.h"
17 #include "flavor/object-flavor-types.h"
18 #include "floor/cave.h"
19 #include "floor/floor-object.h"
20 #include "floor/geometry.h"
21 #include "game-option/game-play-options.h"
22 #include "inventory/inventory-slot-types.h"
23 #include "io/input-key-requester.h"
24 #include "monster-race/monster-race.h"
25 #include "object-enchant/object-curse.h"
26 #include "object-enchant/tr-types.h"
27 #include "object-enchant/trc-types.h"
28 #include "object-hook/hook-armor.h"
29 #include "object/item-tester-hooker.h"
30 #include "object/item-use-flags.h"
31 #include "object/object-flags.h"
32 #include "player/attack-defense-types.h"
33 #include "player/player-skill.h"
34 #include "player/player-status.h"
35 #include "spell-kind/magic-item-recharger.h"
36 #include "spell-kind/spells-launcher.h"
37 #include "spell-kind/spells-neighbor.h"
38 #include "spell-kind/spells-sight.h"
39 #include "spell-kind/spells-teleport.h"
40 #include "spell-realm/spells-hex.h"
41 #include "spell/spell-types.h"
42 #include "spell/spells-execution.h"
43 #include "spell/spells-status.h"
44 #include "spell/technic-info-table.h"
45 #include "status/action-setter.h"
46 #include "system/floor-type-definition.h"
47 #include "system/grid-type-definition.h"
48 #include "system/object-type-definition.h"
49 #include "system/player-type-definition.h"
50 #include "target/grid-selector.h"
51 #include "target/target-getter.h"
52 #include "term/screen-processor.h"
53 #include "util/bit-flags-calculator.h"
54 #include "view/display-messages.h"
55
56 #ifdef JP
57 #else
58 #include "player-info/equipment-info.h"
59 #endif
60
61 /*!
62  * @brief 呪術領域の武器呪縛の対象にできる武器かどうかを返す。 / An "item_tester_hook" for offer
63  * @param o_ptr オブジェクト構造体の参照ポインタ
64  * @return 呪縛可能な武器ならばTRUEを返す
65  */
66 static bool item_tester_hook_weapon_except_bow(const object_type *o_ptr)
67 {
68     switch (o_ptr->tval) {
69     case TV_SWORD:
70     case TV_HAFTED:
71     case TV_POLEARM:
72     case TV_DIGGING:
73         return true;
74     default:
75         return false;
76     }
77 }
78
79 /*!
80  * @brief 呪術領域魔法の各処理を行う
81  * @param spell 魔法ID
82  * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_INFO / SPELL_CAST / SPELL_CONT / SPELL_STOP)
83  * @return SPELL_NAME / SPELL_DESC / SPELL_INFO 時には文字列ポインタを返す。SPELL_CAST / SPELL_CONT / SPELL_STOP 時はnullptr文字列を返す。
84  */
85 concptr do_hex_spell(player_type *player_ptr, spell_hex_type spell, spell_type mode)
86 {
87     auto name = mode == SPELL_NAME;
88     auto description = mode == SPELL_DESCRIPTION;
89     auto info = mode == SPELL_INFO;
90     auto cast = mode == SPELL_CAST;
91     auto continuation = mode == SPELL_CONTNUATION;
92     auto stop = mode == SPELL_STOP;
93     auto should_continue = true;
94     HIT_POINT power;
95     switch (spell) {
96         /*** 1st book (0-7) ***/
97     case HEX_BLESS:
98         if (name)
99             return _("邪なる祝福", "Evily blessing");
100         if (description)
101             return _("祝福により攻撃精度と防御力が上がる。", "Attempts to increase +to_hit of a weapon and AC");
102         if (cast) {
103             if (!player_ptr->blessed) {
104                 msg_print(_("高潔な気分になった!", "You feel righteous!"));
105             }
106         }
107         if (stop) {
108             if (!player_ptr->blessed) {
109                 msg_print(_("高潔な気分が消え失せた。", "The prayer has expired."));
110             }
111         }
112         break;
113
114     case HEX_CURE_LIGHT:
115         if (name)
116             return _("軽傷の治癒", "Cure light wounds");
117         if (description)
118             return _("HPや傷を少し回復させる。", "Heals cuts and HP a little.");
119         if (info)
120             return info_heal(1, 10, 0);
121         if (cast) {
122             msg_print(_("気分が良くなってくる。", "You feel a little better."));
123         }
124         if (cast || continuation)
125             (void)cure_light_wounds(player_ptr, 1, 10);
126         break;
127
128     case HEX_DEMON_AURA:
129         if (name)
130             return _("悪魔のオーラ", "Demonic aura");
131         if (description)
132             return _("炎のオーラを身にまとい、回復速度が速くなる。", "Gives fire aura and regeneration.");
133         if (cast) {
134             msg_print(_("体が炎のオーラで覆われた。", "You are enveloped by a fiery aura!"));
135         }
136         if (stop) {
137             msg_print(_("炎のオーラが消え去った。", "The fiery aura disappeared."));
138         }
139         break;
140
141     case HEX_STINKING_MIST:
142         if (name)
143             return _("悪臭霧", "Stinking mist");
144         if (description)
145             return _("視界内のモンスターに微弱量の毒のダメージを与える。", "Deals a little poison damage to all monsters in your sight.");
146         power = player_ptr->lev / 2 + 5;
147         if (info)
148             return info_damage(1, power, 0);
149         if (cast || continuation) {
150             project_all_los(player_ptr, GF_POIS, randint1(power));
151         }
152         break;
153
154     case HEX_XTRA_MIGHT:
155         if (name)
156             return _("腕力強化", "Extra might");
157         if (description)
158             return _("術者の腕力を上昇させる。", "Attempts to increase your strength.");
159         if (cast) {
160             msg_print(_("何だか力が湧いて来る。", "You feel stronger."));
161         }
162         break;
163
164     case HEX_CURSE_WEAPON:
165         if (name)
166             return _("武器呪縛", "Curse weapon");
167         if (description)
168             return _("装備している武器を呪う。", "Curses your weapon.");
169         if (cast) {
170             OBJECT_IDX item;
171             concptr q, s;
172             GAME_TEXT o_name[MAX_NLEN];
173             object_type *o_ptr;
174
175             q = _("どれを呪いますか?", "Which weapon do you curse?");
176             s = _("武器を装備していない。", "You're not wielding a weapon.");
177
178             o_ptr = choose_object(player_ptr, &item, q, s, (USE_EQUIP), FuncItemTester(item_tester_hook_weapon_except_bow));
179             if (!o_ptr)
180                 return "";
181
182             describe_flavor(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
183             auto f = object_flags(o_ptr);
184
185             if (!get_check(format(_("本当に %s を呪いますか?", "Do you curse %s, really?"), o_name)))
186                 return "";
187
188             if (!one_in_(3) && (o_ptr->is_artifact() || f.has(TR_BLESSED))) {
189                 msg_format(_("%s は呪いを跳ね返した。", "%s resists the effect."), o_name);
190                 if (one_in_(3)) {
191                     if (o_ptr->to_d > 0) {
192                         o_ptr->to_d -= randint1(3) % 2;
193                         if (o_ptr->to_d < 0)
194                             o_ptr->to_d = 0;
195                     }
196                     if (o_ptr->to_h > 0) {
197                         o_ptr->to_h -= randint1(3) % 2;
198                         if (o_ptr->to_h < 0)
199                             o_ptr->to_h = 0;
200                     }
201                     if (o_ptr->to_a > 0) {
202                         o_ptr->to_a -= randint1(3) % 2;
203                         if (o_ptr->to_a < 0)
204                             o_ptr->to_a = 0;
205                     }
206                     msg_format(_("%s は劣化してしまった。", "Your %s was disenchanted!"), o_name);
207                 }
208             } else {
209                 int curse_rank = 0;
210                 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
211                 o_ptr->curse_flags.set(TRC::CURSED);
212
213                 if (o_ptr->is_artifact() || o_ptr->is_ego()) {
214
215                     if (one_in_(3))
216                         o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
217                     if (one_in_(666)) {
218                         o_ptr->curse_flags.set(TRC::TY_CURSE);
219                         if (one_in_(666))
220                             o_ptr->curse_flags.set(TRC::PERMA_CURSE);
221
222                         o_ptr->art_flags.set(TR_AGGRAVATE);
223                         o_ptr->art_flags.set(TR_VORPAL);
224                         o_ptr->art_flags.set(TR_VAMPIRIC);
225                         msg_print(_("血だ!血だ!血だ!", "Blood, Blood, Blood!"));
226                         curse_rank = 2;
227                     }
228                 }
229
230                 o_ptr->curse_flags.set(get_curse(curse_rank, o_ptr));
231             }
232
233             player_ptr->update |= (PU_BONUS);
234             should_continue = false;
235         }
236         break;
237
238     case HEX_DETECT_EVIL:
239         if (name)
240             return _("邪悪感知", "Evil detection");
241         if (description)
242             return _("周囲の邪悪なモンスターを感知する。", "Detects evil monsters.");
243         if (info)
244             return info_range(MAX_SIGHT);
245         if (cast) {
246             msg_print(_("邪悪な生物の存在を感じ取ろうとした。", "You sense the presence of evil creatures."));
247         }
248         break;
249
250     case HEX_PATIENCE: {
251         if (name) {
252             return _("我慢", "Patience");
253         }
254
255         if (description) {
256             return _("数ターン攻撃を耐えた後、受けたダメージを地獄の業火として周囲に放出する。", "Bursts hell fire strongly after enduring damage for a few turns.");
257         }
258
259         SpellHex spell_hex(player_ptr);
260         power = MIN(200, spell_hex.get_revenge_power() * 2);
261         if (info) {
262             return info_damage(0, 0, power);
263         }
264
265         if (cast) {
266             int a = 3 - (player_ptr->pspeed - 100) / 10;
267             byte r = 3 + randint1(3) + MAX(0, MIN(3, a));
268
269             if (spell_hex.get_revenge_turn() > 0) {
270                 msg_print(_("すでに我慢をしている。", "You are already biding your time for vengeance."));
271                 return nullptr;
272             }
273
274             spell_hex.set_revenge_type(SpellHexRevengeType::PATIENCE);
275             spell_hex.set_revenge_turn(r, true);
276             spell_hex.set_revenge_power(0, true);
277             msg_print(_("じっと耐えることにした。", "You decide to endure damage for future retribution."));
278             should_continue = false;
279         }
280
281         if (continuation) {
282             POSITION rad = 2 + (power / 50);
283             spell_hex.set_revenge_turn(1, false);
284             if ((spell_hex.get_revenge_turn() == 0) || (power >= 200)) {
285                 msg_print(_("我慢が解かれた!", "My patience is at an end!"));
286                 if (power) {
287                     project(player_ptr, 0, rad, player_ptr->y, player_ptr->x, power, GF_HELL_FIRE, (PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL));
288                 }
289
290                 if (allow_debug_options) {
291                     msg_format(_("%d点のダメージを返した。", "You return %d damage."), power);
292                 }
293
294                 spell_hex.set_revenge_type(SpellHexRevengeType::NONE);
295                 spell_hex.set_revenge_turn(0, true);
296                 spell_hex.set_revenge_power(0, true);
297             }
298         }
299         break;
300     }
301
302         /*** 2nd book (8-15) ***/
303     case HEX_ICE_ARMOR:
304         if (name)
305             return _("氷の鎧", "Armor of ice");
306         if (description)
307             return _("氷のオーラを身にまとい、防御力が上昇する。", "Surrounds you with an icy aura and gives a bonus to AC.");
308         if (cast) {
309             msg_print(_("体が氷の鎧で覆われた。", "You are enveloped by icy armor!"));
310         }
311         if (stop) {
312             msg_print(_("氷の鎧が消え去った。", "The icy armor disappeared."));
313         }
314         break;
315
316     case HEX_CURE_SERIOUS:
317         if (name)
318             return _("重傷の治癒", "Cure serious wounds");
319         if (description)
320             return _("体力や傷を多少回復させる。", "Heals cuts and HP.");
321         if (info)
322             return info_heal(2, 10, 0);
323         if (cast) {
324             msg_print(_("気分が良くなってくる。", "You feel better."));
325         }
326         if (cast || continuation)
327             (void)cure_serious_wounds(player_ptr, 2, 10);
328         break;
329
330     case HEX_INHALE: {
331         if (name) {
332             return _("薬品吸入", "Inhale potion");
333         }
334
335         if (description) {
336             return _("呪文詠唱を中止することなく、薬の効果を得ることができる。", "Quaffs a potion without canceling spell casting.");
337         }
338
339         SpellHex spell_hex(player_ptr);
340         if (cast) {
341             spell_hex.set_casting_flag(HEX_INHALE);
342             do_cmd_quaff_potion(player_ptr);
343             spell_hex.reset_casting_flag(HEX_INHALE);
344             should_continue = false;
345         }
346
347         break;
348     }    
349     case HEX_VAMP_MIST:
350         if (name)
351             return _("衰弱の霧", "Hypodynamic mist");
352         if (description)
353             return _("視界内のモンスターに微弱量の衰弱属性のダメージを与える。", "Deals a little life-draining damage to all monsters in your sight.");
354         power = (player_ptr->lev / 2) + 5;
355         if (info)
356             return info_damage(1, power, 0);
357         if (cast || continuation) {
358             project_all_los(player_ptr, GF_HYPODYNAMIA, randint1(power));
359         }
360         break;
361
362     case HEX_RUNESWORD:
363         if (name)
364             return _("魔剣化", "Swords to runeswords");
365         if (description)
366             return _("武器の攻撃力を上げる。切れ味を得、呪いに応じて与えるダメージが上昇し、善良なモンスターに対するダメージが2倍になる。",
367                 "Gives vorpal ability to your weapon. Increases damage from your weapon acccording to curse of your weapon.");
368         if (cast) {
369 #ifdef JP
370             msg_print("あなたの武器が黒く輝いた。");
371 #else
372             if (!empty_hands(player_ptr, false))
373                 msg_print("Your weapons glow bright black.");
374             else
375                 msg_print("Your weapon glows bright black.");
376 #endif
377         }
378         if (stop) {
379 #ifdef JP
380             msg_print("武器の輝きが消え去った。");
381 #else
382             msg_format("Your weapon%s.", (empty_hands(player_ptr, false)) ? " no longer glows" : "s no longer glow");
383 #endif
384         }
385         break;
386
387     case HEX_CONFUSION:
388         if (name)
389             return _("混乱の手", "Touch of confusion");
390         if (description)
391             return _("攻撃した際モンスターを混乱させる。", "Confuses a monster when you attack.");
392         if (cast) {
393             msg_print(_("あなたの手が赤く輝き始めた。", "Your hands glow bright red."));
394         }
395         if (stop) {
396             msg_print(_("手の輝きがなくなった。", "Your hands no longer glow."));
397         }
398         break;
399
400     case HEX_BUILDING:
401         if (name)
402             return _("肉体強化", "Building up");
403         if (description)
404             return _(
405                 "術者の腕力、器用さ、耐久力を上昇させる。攻撃回数の上限を 1 増加させる。", "Attempts to increases your strength, dexterity and constitusion.");
406         if (cast) {
407             msg_print(_("身体が強くなった気がした。", "You feel your body is more developed now."));
408         }
409         break;
410
411     case HEX_ANTI_TELE:
412         if (name)
413             return _("反テレポート結界", "Anti teleport barrier");
414         if (description)
415             return _("視界内のモンスターのテレポートを阻害するバリアを張る。", "Obstructs all teleportations by monsters in your sight.");
416         power = player_ptr->lev * 3 / 2;
417         if (info)
418             return info_power(power);
419         if (cast) {
420             msg_print(_("テレポートを防ぐ呪いをかけた。", "You feel anyone can not teleport except you."));
421         }
422         break;
423
424         /*** 3rd book (16-23) ***/
425     case HEX_SHOCK_CLOAK:
426         if (name)
427             return _("衝撃のクローク", "Cloak of shock");
428         if (description)
429             return _("電気のオーラを身にまとい、動きが速くなる。", "Gives lightning aura and a bonus to speed.");
430         if (cast) {
431             msg_print(_("体が稲妻のオーラで覆われた。", "You are enveloped by an electrical aura!"));
432         }
433         if (stop) {
434             msg_print(_("稲妻のオーラが消え去った。", "The electrical aura disappeared."));
435         }
436         break;
437
438     case HEX_CURE_CRITICAL:
439         if (name)
440             return _("致命傷の治癒", "Cure critical wounds");
441         if (description)
442             return _("体力や傷を回復させる。", "Heals cuts and HP greatly.");
443         if (info)
444             return info_heal(4, 10, 0);
445         if (cast) {
446             msg_print(_("気分が良くなってくる。", "You feel much better."));
447         }
448         if (cast || continuation)
449             (void)cure_critical_wounds(player_ptr, damroll(4, 10));
450         break;
451
452     case HEX_RECHARGE:
453         if (name)
454             return _("呪力封入", "Recharging");
455         if (description)
456             return _("魔法の道具に魔力を再充填する。", "Recharges a magic device.");
457         power = player_ptr->lev * 2;
458         if (info)
459             return info_power(power);
460         if (cast) {
461             if (!recharge(player_ptr, power))
462                 return nullptr;
463             should_continue = false;
464         }
465         break;
466
467     case HEX_RAISE_DEAD:
468         if (name)
469             return _("死者復活", "Animate Dead");
470         if (description)
471             return _("死体を蘇らせてペットにする。", "Raises corpses and skeletons from dead.");
472         if (cast) {
473             msg_print(_("死者への呼びかけを始めた。", "You start to call the dead.!"));
474         }
475         if (cast || continuation) {
476             animate_dead(player_ptr, 0, player_ptr->y, player_ptr->x);
477         }
478         break;
479
480     case HEX_CURSE_ARMOUR:
481         if (name)
482             return _("防具呪縛", "Curse armor");
483         if (description)
484             return _("装備している防具に呪いをかける。", "Curse a piece of armour that you are wielding.");
485         if (cast) {
486             OBJECT_IDX item;
487             concptr q, s;
488             GAME_TEXT o_name[MAX_NLEN];
489             object_type *o_ptr;
490
491             q = _("どれを呪いますか?", "Which piece of armour do you curse?");
492             s = _("防具を装備していない。", "You're not wearing any armor.");
493
494             o_ptr = choose_object(player_ptr, &item, q, s, (USE_EQUIP), FuncItemTester(&object_type::is_armour));
495             if (!o_ptr)
496                 return "";
497
498             o_ptr = &player_ptr->inventory_list[item];
499             describe_flavor(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
500             auto f = object_flags(o_ptr);
501
502             if (!get_check(format(_("本当に %s を呪いますか?", "Do you curse %s, really?"), o_name)))
503                 return "";
504
505             if (!one_in_(3) && (o_ptr->is_artifact() || f.has(TR_BLESSED))) {
506                 msg_format(_("%s は呪いを跳ね返した。", "%s resists the effect."), o_name);
507                 if (one_in_(3)) {
508                     if (o_ptr->to_d > 0) {
509                         o_ptr->to_d -= randint1(3) % 2;
510                         if (o_ptr->to_d < 0)
511                             o_ptr->to_d = 0;
512                     }
513                     if (o_ptr->to_h > 0) {
514                         o_ptr->to_h -= randint1(3) % 2;
515                         if (o_ptr->to_h < 0)
516                             o_ptr->to_h = 0;
517                     }
518                     if (o_ptr->to_a > 0) {
519                         o_ptr->to_a -= randint1(3) % 2;
520                         if (o_ptr->to_a < 0)
521                             o_ptr->to_a = 0;
522                     }
523                     msg_format(_("%s は劣化してしまった。", "Your %s was disenchanted!"), o_name);
524                 }
525             } else {
526                 int curse_rank = 0;
527                 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
528                 o_ptr->curse_flags.set(TRC::CURSED);
529
530                 if (o_ptr->is_artifact() || o_ptr->is_ego()) {
531
532                     if (one_in_(3))
533                         o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
534                     if (one_in_(666)) {
535                         o_ptr->curse_flags.set(TRC::TY_CURSE);
536                         if (one_in_(666))
537                             o_ptr->curse_flags.set(TRC::PERMA_CURSE);
538
539                         o_ptr->art_flags.set(TR_AGGRAVATE);
540                         o_ptr->art_flags.set(TR_RES_POIS);
541                         o_ptr->art_flags.set(TR_RES_DARK);
542                         o_ptr->art_flags.set(TR_RES_NETHER);
543                         msg_print(_("血だ!血だ!血だ!", "Blood, Blood, Blood!"));
544                         curse_rank = 2;
545                     }
546                 }
547
548                 o_ptr->curse_flags.set(get_curse(curse_rank, o_ptr));
549             }
550
551             player_ptr->update |= (PU_BONUS);
552             should_continue = false;
553         }
554         break;
555
556     case HEX_SHADOW_CLOAK:
557         if (name)
558             return _("影のクローク", "Cloak of shadow");
559         if (description)
560             return _("影のオーラを身にまとい、敵に影のダメージを与える。", "Gives aura of shadow.");
561         if (cast) {
562             object_type *o_ptr = &player_ptr->inventory_list[INVEN_OUTER];
563
564             if (!o_ptr->k_idx) {
565                 msg_print(_("クロークを身につけていない!", "You are not wearing a cloak."));
566                 return nullptr;
567             } else if (!o_ptr->is_cursed()) {
568                 msg_print(_("クロークは呪われていない!", "Your cloak is not cursed."));
569                 return nullptr;
570             } else {
571                 msg_print(_("影のオーラを身にまとった。", "You are enveloped by a shadowy aura!"));
572             }
573         }
574         if (continuation) {
575             object_type *o_ptr = &player_ptr->inventory_list[INVEN_OUTER];
576
577             if ((!o_ptr->k_idx) || (!o_ptr->is_cursed())) {
578                 exe_spell(player_ptr, REALM_HEX, spell, SPELL_STOP);
579                 SpellHex spell_hex(player_ptr);
580                 spell_hex.reset_casting_flag(spell);
581                 if (!spell_hex.is_spelling_any())
582                     set_action(player_ptr, ACTION_NONE);
583             }
584         }
585         if (stop) {
586             msg_print(_("影のオーラが消え去った。", "The shadowy aura disappeared."));
587         }
588         break;
589
590     case HEX_PAIN_TO_MANA:
591         if (name)
592             return _("苦痛を魔力に", "Pain to mana");
593         if (description)
594             return _("視界内のモンスターに精神ダメージ与え、魔力を吸い取る。", "Deals psychic damage to all monsters in sight and drains some mana.");
595         power = player_ptr->lev * 3 / 2;
596         if (info)
597             return info_damage(1, power, 0);
598         if (cast || continuation) {
599             project_all_los(player_ptr, GF_PSI_DRAIN, randint1(power));
600         }
601         break;
602
603     case HEX_EYE_FOR_EYE:
604         if (name)
605             return _("目には目を", "Eye for an eye");
606         if (description)
607             return _("打撃や魔法で受けたダメージを、攻撃元のモンスターにも与える。", "Returns same damage which you got to the monster which damaged you.");
608         if (cast) {
609             msg_print(_("復讐したい欲望にかられた。", "You feel very vengeful."));
610         }
611         break;
612
613         /*** 4th book (24-31) ***/
614     case HEX_ANTI_MULTI:
615         if (name)
616             return _("反増殖結界", "Anti multiply barrier");
617         if (description)
618             return _("その階の増殖するモンスターの増殖を阻止する。", "Obstructs all multiplying by monsters on entire floor.");
619         if (cast) {
620             msg_print(_("増殖を阻止する呪いをかけた。", "You feel anyone can not multiply."));
621         }
622         break;
623
624     case HEX_RESTORE:
625         if (name)
626             return _("全復活", "Restoration");
627         if (description)
628             return _("経験値を徐々に復活し、減少した能力値を回復させる。", "Restores experience and status.");
629         if (cast) {
630             msg_print(_("体が元の活力を取り戻し始めた。", "You feel your lost status starting to return."));
631         }
632         if (cast || continuation) {
633             bool flag = false;
634             int d = (player_ptr->max_exp - player_ptr->exp);
635             int r = (player_ptr->exp / 20);
636             int i;
637
638             if (d > 0) {
639                 if (d < r)
640                     player_ptr->exp = player_ptr->max_exp;
641                 else
642                     player_ptr->exp += r;
643
644                 /* Check the experience */
645                 check_experience(player_ptr);
646
647                 flag = true;
648             }
649             for (i = A_STR; i < A_MAX; i++) {
650                 if (player_ptr->stat_cur[i] < player_ptr->stat_max[i]) {
651                     if (player_ptr->stat_cur[i] < 18)
652                         player_ptr->stat_cur[i]++;
653                     else
654                         player_ptr->stat_cur[i] += 10;
655
656                     if (player_ptr->stat_cur[i] > player_ptr->stat_max[i])
657                         player_ptr->stat_cur[i] = player_ptr->stat_max[i];
658                     player_ptr->update |= (PU_BONUS);
659
660                     flag = true;
661                 }
662             }
663
664             if (!flag) {
665                 msg_format(_("%sの呪文の詠唱をやめた。", "Finish casting '%^s'."), exe_spell(player_ptr, REALM_HEX, HEX_RESTORE, SPELL_NAME));
666                 SpellHex spell_hex(player_ptr);
667                 spell_hex.reset_casting_flag(HEX_RESTORE);
668                 if (spell_hex.get_casting_num() > 0) {
669                     player_ptr->action = ACTION_NONE;
670                 }
671
672                 player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
673                 player_ptr->redraw |= (PR_EXTRA);
674
675                 return "";
676             }
677         }
678         break;
679
680     case HEX_DRAIN_CURSE:
681         if (name)
682             return _("呪力吸収", "Drain curse power");
683         if (description)
684             return _("呪われた装備品の呪いを吸収して魔力を回復する。", "Drains curse on your equipment and heals SP a little.");
685         if (cast) {
686             OBJECT_IDX item;
687             concptr s, q;
688             object_type *o_ptr;
689
690             q = _("どの装備品から吸収しますか?", "Which cursed equipment do you drain mana from?");
691             s = _("呪われたアイテムを装備していない。", "You have no cursed equipment.");
692
693             o_ptr = choose_object(player_ptr, &item, q, s, (USE_EQUIP), FuncItemTester(&object_type::is_cursed));
694             if (!o_ptr)
695                 return "";
696
697             auto f = object_flags(o_ptr);
698
699             player_ptr->csp += (player_ptr->lev / 5) + randint1(player_ptr->lev / 5);
700             if (f.has(TR_TY_CURSE) || o_ptr->curse_flags.has(TRC::TY_CURSE))
701                 player_ptr->csp += randint1(5);
702             if (player_ptr->csp > player_ptr->msp)
703                 player_ptr->csp = player_ptr->msp;
704
705             if (o_ptr->curse_flags.has(TRC::PERMA_CURSE)) {
706                 /* Nothing */
707             } else if (o_ptr->curse_flags.has(TRC::HEAVY_CURSE)) {
708                 if (one_in_(7)) {
709                     msg_print(_("呪いを全て吸い取った。", "A heavy curse vanished."));
710                     o_ptr->curse_flags.clear();
711                 }
712             } else if (o_ptr->curse_flags.has(TRC::CURSED) && one_in_(3)) {
713                 msg_print(_("呪いを全て吸い取った。", "A curse vanished."));
714                 o_ptr->curse_flags.clear();
715             }
716
717             should_continue = false;
718         }
719         break;
720
721     case HEX_VAMP_BLADE:
722         if (name)
723             return _("吸血の刃", "Swords to vampires");
724         if (description)
725             return _("吸血属性で攻撃する。", "Gives vampiric ability to your weapon.");
726         if (cast) {
727 #ifdef JP
728             msg_print("あなたの武器が血を欲している。");
729 #else
730             if (!empty_hands(player_ptr, false))
731                 msg_print("Your weapons want more blood now.");
732             else
733                 msg_print("Your weapon wants more blood now.");
734 #endif
735         }
736         if (stop) {
737 #ifdef JP
738             msg_print("武器の渇望が消え去った。");
739 #else
740             msg_format("Your weapon%s less thirsty now.", (empty_hands(player_ptr, false)) ? " is" : "s are");
741 #endif
742         }
743         break;
744
745     case HEX_STUN_MONSTERS:
746         if (name)
747             return _("朦朧の言葉", "Word of stun");
748         if (description)
749             return _("視界内のモンスターを朦朧とさせる。", "Stuns all monsters in your sight.");
750         power = player_ptr->lev * 4;
751         if (info)
752             return info_power(power);
753         if (cast || continuation) {
754             stun_monsters(player_ptr, power);
755         }
756         break;
757
758     case HEX_SHADOW_MOVE:
759         if (name)
760             return _("影移動", "Moving into shadow");
761         if (description)
762             return _("モンスターの隣のマスに瞬間移動する。", "Teleports you close to a monster.");
763         if (cast) {
764             int i, dir;
765             POSITION y, x;
766             bool flag;
767
768             for (i = 0; i < 3; i++) {
769                 if (!tgt_pt(player_ptr, &x, &y))
770                     return "";
771
772                 flag = false;
773
774                 for (dir = 0; dir < 8; dir++) {
775                     int dy = y + ddy_ddd[dir];
776                     int dx = x + ddx_ddd[dir];
777                     if (dir == 5)
778                         continue;
779                     if (player_ptr->current_floor_ptr->grid_array[dy][dx].m_idx)
780                         flag = true;
781                 }
782
783                 if (!is_cave_empty_bold(player_ptr, y, x) || player_ptr->current_floor_ptr->grid_array[y][x].is_icky()
784                     || (distance(y, x, player_ptr->y, player_ptr->x) > player_ptr->lev + 2)) {
785                     msg_print(_("そこには移動できない。", "Can not teleport to there."));
786                     continue;
787                 }
788                 break;
789             }
790
791             if (flag && randint0(player_ptr->lev * player_ptr->lev / 2)) {
792                 teleport_player_to(player_ptr, y, x, TELEPORT_SPONTANEOUS);
793             } else {
794                 msg_print(_("おっと!", "Oops!"));
795                 teleport_player(player_ptr, 30, TELEPORT_SPONTANEOUS);
796             }
797
798             should_continue = false;
799         }
800         break;
801
802     case HEX_ANTI_MAGIC:
803         if (name)
804             return _("反魔法結界", "Anti magic barrier");
805         if (description)
806             return _("視界内のモンスターの魔法を阻害するバリアを張る。", "Obstructs all magic spells of monsters in your sight.");
807         power = player_ptr->lev * 3 / 2;
808         if (info)
809             return info_power(power);
810         if (cast) {
811             msg_print(_("魔法を防ぐ呪いをかけた。", "You feel anyone can not cast spells except you."));
812         }
813         break;
814
815     case HEX_REVENGE: {
816         if (name) {
817             return _("復讐の宣告", "Revenge sentence");
818         }
819
820         if (description) {
821             return _("数ターン後にそれまで受けたダメージに応じた威力の地獄の劫火の弾を放つ。", "Fires a ball of hell fire to try avenging damage from a few turns.");
822         }
823
824         SpellHex spell_hex(player_ptr);
825         power = spell_hex.get_revenge_power();
826         if (info) {
827             return info_damage(0, 0, power);
828         }
829
830         if (cast) {
831             byte r;
832             int a = 3 - (player_ptr->pspeed - 100) / 10;
833             r = 1 + randint1(2) + MAX(0, MIN(3, a));
834
835             if (spell_hex.get_revenge_turn() > 0) {
836                 msg_print(_("すでに復讐は宣告済みだ。", "You've already declared your revenge."));
837                 return nullptr;
838             }
839
840             spell_hex.set_revenge_type(SpellHexRevengeType::REVENGE);
841             spell_hex.set_revenge_turn(r, true);
842             msg_format(_("あなたは復讐を宣告した。あと %d ターン。", "You declare your revenge. %d turns left."), r);
843             should_continue = false;
844         }
845
846         if (continuation) {
847             spell_hex.set_revenge_turn(1, false);
848             if (spell_hex.get_revenge_turn() == 0) {
849                 DIRECTION dir;
850
851                 if (power) {
852                     command_dir = 0;
853
854                     do {
855                         msg_print(_("復讐の時だ!", "Time for revenge!"));
856                     } while (!get_aim_dir(player_ptr, &dir));
857
858                     fire_ball(player_ptr, GF_HELL_FIRE, dir, power, 1);
859
860                     if (allow_debug_options) {
861                         msg_format(_("%d点のダメージを返した。", "You return %d damage."), power);
862                     }
863                 } else {
864                     msg_print(_("復讐する気が失せた。", "You are not in the mood for revenge."));
865                 }
866
867                 spell_hex.set_revenge_power(0, true);
868             }
869         }
870
871         break;
872     }
873     case HEX_MAX:
874         break;
875     }
876
877     if (cast && should_continue) {
878         SpellHex spell_hex(player_ptr);
879         spell_hex.set_casting_flag(spell);
880         if (player_ptr->action != ACTION_SPELL) {
881             set_action(player_ptr, ACTION_SPELL);
882         }
883     }
884
885     if (!info) {
886         player_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
887         player_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
888     }
889
890     return "";
891 }