OSDN Git Service

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