OSDN Git Service

[Refactor] #39970 Separated output-updater.c/h from core.c/h
[hengband/hengband.git] / src / realm / realm-hex.c
1 /*!
2  * @file hex.c
3  * @brief 呪術の処理実装 / Hex code
4  * @date 2014/01/14
5  * @author
6  * 2014 Deskull rearranged comment for Doxygen.\n
7  * @details
8  * magic_num1\n
9  * 0: Flag bits of spelling spells\n
10  * 1: Flag bits of despelled spells\n
11  * 2: Revange damage\n
12  * magic_num2\n
13  * 0: Number of spelling spells\n
14  * 1: Type of revenge\n
15  * 2: Turn count for revenge\n
16  */
17
18 #include "angband.h"
19 #include "util.h"
20
21 #include "effect/effect-characteristics.h"
22 #include "cmd-spell.h"
23 #include "cmd-quaff.h"
24 #include "object-flavor.h"
25 #include "object-hook.h"
26 #include "object-curse.h"
27 #include "spells-status.h"
28 #include "spell/technic-info-table.h"
29 #include "player-status.h"
30 #include "player-effects.h"
31 #include "player-skill.h"
32 #include "player-inventory.h"
33 #include "realm/realm-hex.h"
34 #include "grid.h"
35 #include "monsterrace.h"
36 #include "targeting.h"
37 #include "realm/realm-song.h"
38 #include "view/display-main-window.h"
39 #include "world.h"
40 #include "realm/realm-hex.h"
41 #include "spell/spells-execution.h"
42 #include "spell/spells-type.h"
43 #include "spell/process-effect.h"
44 #include "spell/spells2.h"
45 #include "spell/spells3.h"
46
47 #define MAX_KEEP 4 /*!<呪術の最大詠唱数 */
48
49 /*!
50  * @brief プレイヤーが詠唱中の全呪術を停止する
51  * @return なし
52  */
53 bool stop_hex_spell_all(player_type *caster_ptr)
54 {
55         SPELL_IDX i;
56
57         for (i = 0; i < 32; i++)
58         {
59                 if (hex_spelling(caster_ptr, i)) exe_spell(caster_ptr, REALM_HEX, i, SPELL_STOP);
60         }
61
62         CASTING_HEX_FLAGS(caster_ptr) = 0;
63         CASTING_HEX_NUM(caster_ptr) = 0;
64
65         if (caster_ptr->action == ACTION_SPELL) set_action(caster_ptr, ACTION_NONE);
66
67         caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
68         caster_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
69
70         return TRUE;
71 }
72
73 /*!
74  * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する
75  * @return なし
76  */
77 bool stop_hex_spell(player_type *caster_ptr)
78 {
79         int spell;
80         char choice = 0;
81         char out_val[160];
82         bool flag = FALSE;
83         TERM_LEN y = 1;
84         TERM_LEN x = 20;
85         int sp[MAX_KEEP];
86
87         if (!hex_spelling_any(caster_ptr))
88         {
89                 msg_print(_("呪文を詠唱していません。", "You are casting no spell."));
90                 return FALSE;
91         }
92
93         /* Stop all spells */
94         else if ((CASTING_HEX_NUM(caster_ptr) == 1) || (caster_ptr->lev < 35))
95         {
96                 return stop_hex_spell_all(caster_ptr);
97         }
98         else
99         {
100                 strnfmt(out_val, 78, _("どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)", "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)"),
101                         I2A(0), I2A(CASTING_HEX_NUM(caster_ptr) - 1));
102
103                 screen_save();
104
105                 while (!flag)
106                 {
107                         int n = 0;
108                         Term_erase(x, y, 255);
109                         prt(_("     名前", "     Name"), y, x + 5);
110                         for (spell = 0; spell < 32; spell++)
111                         {
112                                 if (hex_spelling(caster_ptr, spell))
113                                 {
114                                         Term_erase(x, y + n + 1, 255);
115                                         put_str(format("%c)  %s", I2A(n), exe_spell(caster_ptr, REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2);
116                                         sp[n++] = spell;
117                                 }
118                         }
119
120                         if (!get_com(out_val, &choice, TRUE)) break;
121                         if (isupper(choice)) choice = (char)tolower(choice);
122
123                         if (choice == 'l')      /* All */
124                         {
125                                 screen_load();
126                                 return stop_hex_spell_all(caster_ptr);
127                         }
128                         if ((choice < I2A(0)) || (choice > I2A(CASTING_HEX_NUM(caster_ptr) - 1))) continue;
129                         flag = TRUE;
130                 }
131         }
132
133         screen_load();
134
135         if (flag)
136         {
137                 int n = sp[A2I(choice)];
138
139                 exe_spell(caster_ptr, REALM_HEX, n, SPELL_STOP);
140                 CASTING_HEX_FLAGS(caster_ptr) &= ~(1L << n);
141                 CASTING_HEX_NUM(caster_ptr)--;
142         }
143
144         caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
145         caster_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
146
147         return flag;
148 }
149
150
151 /*!
152  * @brief 一定時間毎に呪術で消費するMPを処理する /
153  * Upkeeping hex spells Called from dungeon.c
154  * @return なし
155  */
156 void check_hex(player_type *caster_ptr)
157 {
158         int spell;
159         MANA_POINT need_mana;
160         u32b need_mana_frac;
161         bool res = FALSE;
162
163         /* Spells spelled by player */
164         if (caster_ptr->realm1 != REALM_HEX) return;
165         if (!CASTING_HEX_FLAGS(caster_ptr) && !caster_ptr->magic_num1[1]) return;
166
167         if (caster_ptr->magic_num1[1])
168         {
169                 caster_ptr->magic_num1[0] = caster_ptr->magic_num1[1];
170                 caster_ptr->magic_num1[1] = 0;
171                 res = TRUE;
172         }
173
174         /* Stop all spells when anti-magic ability is given */
175         if (caster_ptr->anti_magic)
176         {
177                 stop_hex_spell_all(caster_ptr);
178                 return;
179         }
180
181         need_mana = 0;
182         for (spell = 0; spell < 32; spell++)
183         {
184                 if (hex_spelling(caster_ptr, spell))
185                 {
186                         const magic_type *s_ptr;
187                         s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
188                         need_mana += mod_need_mana(caster_ptr, s_ptr->smana, spell, REALM_HEX);
189                 }
190         }
191
192         /* Culcurates final mana cost */
193         need_mana_frac = 0;
194         s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */
195         need_mana += (CASTING_HEX_NUM(caster_ptr) - 1);
196
197         /* Not enough mana */
198         if (s64b_cmp(caster_ptr->csp, caster_ptr->csp_frac, need_mana, need_mana_frac) < 0)
199         {
200                 stop_hex_spell_all(caster_ptr);
201                 return;
202         }
203
204         /* Enough mana */
205         else
206         {
207                 s64b_sub(&(caster_ptr->csp), &(caster_ptr->csp_frac), need_mana, need_mana_frac);
208
209                 caster_ptr->redraw |= PR_MANA;
210                 if (res)
211                 {
212                         msg_print(_("詠唱を再開した。", "You restart casting."));
213
214                         caster_ptr->action = ACTION_SPELL;
215
216                         caster_ptr->update |= (PU_BONUS | PU_HP);
217                         caster_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
218                         caster_ptr->update |= (PU_MONSTERS);
219                         caster_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
220                 }
221         }
222
223         /* Gain experiences of spelling spells */
224         for (spell = 0; spell < 32; spell++)
225         {
226                 const magic_type *s_ptr;
227
228                 if (!hex_spelling(caster_ptr, spell)) continue;
229
230                 s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell];
231
232                 if (caster_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
233                         caster_ptr->spell_exp[spell] += 5;
234                 else if(caster_ptr->spell_exp[spell] < SPELL_EXP_SKILLED)
235                 { if (one_in_(2) && (caster_ptr->current_floor_ptr->dun_level > 4) && ((caster_ptr->current_floor_ptr->dun_level + 10) > caster_ptr->lev)) caster_ptr->spell_exp[spell] += 1; }
236                 else if(caster_ptr->spell_exp[spell] < SPELL_EXP_EXPERT)
237                 { if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev) && ((caster_ptr->current_floor_ptr->dun_level + 5) > s_ptr->slevel)) caster_ptr->spell_exp[spell] += 1; }
238                 else if(caster_ptr->spell_exp[spell] < SPELL_EXP_MASTER)
239                 { if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev) && (caster_ptr->current_floor_ptr->dun_level > s_ptr->slevel)) caster_ptr->spell_exp[spell] += 1; }
240         }
241
242         /* Do any effects of continual spells */
243         for (spell = 0; spell < 32; spell++)
244         {
245                 if (hex_spelling(caster_ptr, spell))
246                 {
247                         exe_spell(caster_ptr, REALM_HEX, spell, SPELL_CONT);
248                 }
249         }
250 }
251
252 /*!
253  * @brief プレイヤーの呪術詠唱枠がすでに最大かどうかを返す
254  * @return すでに全枠を利用しているならTRUEを返す
255  */
256 bool hex_spell_fully(player_type *caster_ptr)
257 {
258         int k_max = 0;
259         k_max = (caster_ptr->lev / 15) + 1;
260         k_max = MIN(k_max, MAX_KEEP);
261         if (CASTING_HEX_NUM(caster_ptr) < k_max) return FALSE;
262         return TRUE;
263 }
264
265 /*!
266  * @brief 一定ゲームターン毎に復讐処理の残り期間の判定を行う
267  * @return なし
268  */
269 void revenge_spell(player_type *caster_ptr)
270 {
271         if (caster_ptr->realm1 != REALM_HEX) return;
272         if (HEX_REVENGE_TURN(caster_ptr) <= 0) return;
273
274         switch(HEX_REVENGE_TYPE(caster_ptr))
275         {
276                 case 1: exe_spell(caster_ptr, REALM_HEX, HEX_PATIENCE, SPELL_CONT); break;
277                 case 2: exe_spell(caster_ptr, REALM_HEX, HEX_REVENGE, SPELL_CONT); break;
278         }
279 }
280
281 /*!
282  * @brief 復讐ダメージの追加を行う
283  * @param dam 蓄積されるダメージ量
284  * @return なし
285  */
286 void revenge_store(player_type *caster_ptr, HIT_POINT dam)
287 {
288         if (caster_ptr->realm1 != REALM_HEX) return;
289         if (HEX_REVENGE_TURN(caster_ptr) <= 0) return;
290
291         HEX_REVENGE_POWER(caster_ptr) += dam;
292 }
293
294 /*!
295  * @brief 反テレポート結界の判定
296  * @param m_idx 判定の対象となるモンスターID
297  * @return 反テレポートの効果が適用されるならTRUEを返す
298  */
299 bool teleport_barrier(player_type *caster_ptr, MONSTER_IDX m_idx)
300 {
301         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
302         monster_race *r_ptr = &r_info[m_ptr->r_idx];
303
304         if (!hex_spelling(caster_ptr, HEX_ANTI_TELE)) return FALSE;
305         if ((caster_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
306
307         return TRUE;
308 }
309
310 /*!
311  * @brief 反魔法結界の判定
312  * @param m_idx 判定の対象となるモンスターID
313  * @return 反魔法の効果が適用されるならTRUEを返す
314  */
315 bool magic_barrier(player_type *target_ptr, MONSTER_IDX m_idx)
316 {
317         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
318         monster_race *r_ptr = &r_info[m_ptr->r_idx];
319
320         if (!hex_spelling(target_ptr, HEX_ANTI_MAGIC)) return FALSE;
321         if ((target_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
322
323         return TRUE;
324 }
325
326 /*!
327  * @brief 反増殖結界の判定
328  * @param m_idx 判定の対象となるモンスターID
329  * @return 反増殖の効果が適用されるならTRUEを返す
330  */
331 bool multiply_barrier(player_type *caster_ptr, MONSTER_IDX m_idx)
332 {
333         monster_type *m_ptr = &caster_ptr->current_floor_ptr->m_list[m_idx];
334         monster_race *r_ptr = &r_info[m_ptr->r_idx];
335
336         if (!hex_spelling(caster_ptr, HEX_ANTI_MULTI)) return FALSE;
337         if ((caster_ptr->lev * 3 / 2) < randint1(r_ptr->level)) return FALSE;
338
339         return TRUE;
340 }
341
342 /*!
343 * @brief 呪術領域魔法の各処理を行う
344 * @param spell 魔法ID
345 * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_INFO / SPELL_CAST / SPELL_CONT / SPELL_STOP)
346 * @return SPELL_NAME / SPELL_DESC / SPELL_INFO 時には文字列ポインタを返す。SPELL_CAST / SPELL_CONT / SPELL_STOP 時はNULL文字列を返す。
347 */
348 concptr do_hex_spell(player_type *caster_ptr, SPELL_IDX spell, spell_type mode)
349 {
350         bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
351         bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
352         bool info = (mode == SPELL_INFO) ? TRUE : FALSE;
353         bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
354         bool cont = (mode == SPELL_CONT) ? TRUE : FALSE;
355         bool stop = (mode == SPELL_STOP) ? TRUE : FALSE;
356
357         bool add = TRUE;
358
359         PLAYER_LEVEL plev = caster_ptr->lev;
360         HIT_POINT power;
361
362         switch (spell)
363         {
364                 /*** 1st book (0-7) ***/
365         case 0:
366                 if (name) return _("邪なる祝福", "Evily blessing");
367                 if (desc) return _("祝福により攻撃精度と防御力が上がる。", "Attempts to increase +to_hit of a weapon and AC");
368                 if (cast)
369                 {
370                         if (!caster_ptr->blessed)
371                         {
372                                 msg_print(_("高潔な気分になった!", "You feel righteous!"));
373                         }
374                 }
375                 if (stop)
376                 {
377                         if (!caster_ptr->blessed)
378                         {
379                                 msg_print(_("高潔な気分が消え失せた。", "The prayer has expired."));
380                         }
381                 }
382                 break;
383
384         case 1:
385                 if (name) return _("軽傷の治癒", "Cure light wounds");
386                 if (desc) return _("HPや傷を少し回復させる。", "Heals cuts and HP a little.");
387                 if (info) return info_heal(1, 10, 0);
388                 if (cast)
389                 {
390                         msg_print(_("気分が良くなってくる。", "You feel a little better."));
391                 }
392                 if (cast || cont) (void)cure_light_wounds(caster_ptr, 1, 10);
393                 break;
394
395         case 2:
396                 if (name) return _("悪魔のオーラ", "Demonic aura");
397                 if (desc) return _("炎のオーラを身にまとい、回復速度が速くなる。", "Gives fire aura and regeneration.");
398                 if (cast)
399                 {
400                         msg_print(_("体が炎のオーラで覆われた。", "You are enveloped by a fiery aura!"));
401                 }
402                 if (stop)
403                 {
404                         msg_print(_("炎のオーラが消え去った。", "The fiery aura disappeared."));
405                 }
406                 break;
407
408         case 3:
409                 if (name) return _("悪臭霧", "Stinking mist");
410                 if (desc) return _("視界内のモンスターに微弱量の毒のダメージを与える。", "Deals a little poison damage to all monsters in your sight.");
411                 power = plev / 2 + 5;
412                 if (info) return info_damage(1, power, 0);
413                 if (cast || cont)
414                 {
415                         project_all_los(caster_ptr, GF_POIS, randint1(power));
416                 }
417                 break;
418
419         case 4:
420                 if (name) return _("腕力強化", "Extra might");
421                 if (desc) return _("術者の腕力を上昇させる。", "Attempts to increase your strength.");
422                 if (cast)
423                 {
424                         msg_print(_("何だか力が湧いて来る。", "You feel stronger."));
425                 }
426                 break;
427
428         case 5:
429                 if (name) return _("武器呪縛", "Curse weapon");
430                 if (desc) return _("装備している武器を呪う。", "Curses your weapon.");
431                 if (cast)
432                 {
433                         OBJECT_IDX item;
434                         concptr q, s;
435                         GAME_TEXT o_name[MAX_NLEN];
436                         object_type *o_ptr;
437                         u32b f[TR_FLAG_SIZE];
438
439                         item_tester_hook = item_tester_hook_weapon_except_bow;
440                         q = _("どれを呪いますか?", "Which weapon do you curse?");
441                         s = _("武器を装備していない。", "You're not wielding a weapon.");
442
443                         o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP), 0);
444                         if (!o_ptr) return FALSE;
445
446                         object_desc(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
447                         object_flags(o_ptr, f);
448
449                         if (!get_check(format(_("本当に %s を呪いますか?", "Do you curse %s, really?"), o_name))) return FALSE;
450
451                         if (!one_in_(3) &&
452                                 (object_is_artifact(o_ptr) || have_flag(f, TR_BLESSED)))
453                         {
454                                 msg_format(_("%s は呪いを跳ね返した。", "%s resists the effect."), o_name);
455                                 if (one_in_(3))
456                                 {
457                                         if (o_ptr->to_d > 0)
458                                         {
459                                                 o_ptr->to_d -= randint1(3) % 2;
460                                                 if (o_ptr->to_d < 0) o_ptr->to_d = 0;
461                                         }
462                                         if (o_ptr->to_h > 0)
463                                         {
464                                                 o_ptr->to_h -= randint1(3) % 2;
465                                                 if (o_ptr->to_h < 0) o_ptr->to_h = 0;
466                                         }
467                                         if (o_ptr->to_a > 0)
468                                         {
469                                                 o_ptr->to_a -= randint1(3) % 2;
470                                                 if (o_ptr->to_a < 0) o_ptr->to_a = 0;
471                                         }
472                                         msg_format(_("%s は劣化してしまった。", "Your %s was disenchanted!"), o_name);
473                                 }
474                         }
475                         else
476                         {
477                                 int curse_rank = 0;
478                                 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
479                                 o_ptr->curse_flags |= (TRC_CURSED);
480
481                                 if (object_is_artifact(o_ptr) || object_is_ego(o_ptr))
482                                 {
483
484                                         if (one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
485                                         if (one_in_(666))
486                                         {
487                                                 o_ptr->curse_flags |= (TRC_TY_CURSE);
488                                                 if (one_in_(666)) o_ptr->curse_flags |= (TRC_PERMA_CURSE);
489
490                                                 add_flag(o_ptr->art_flags, TR_AGGRAVATE);
491                                                 add_flag(o_ptr->art_flags, TR_VORPAL);
492                                                 add_flag(o_ptr->art_flags, TR_VAMPIRIC);
493                                                 msg_print(_("血だ!血だ!血だ!", "Blood, Blood, Blood!"));
494                                                 curse_rank = 2;
495                                         }
496                                 }
497
498                                 o_ptr->curse_flags |= get_curse(curse_rank, o_ptr);
499                         }
500
501                         caster_ptr->update |= (PU_BONUS);
502                         add = FALSE;
503                 }
504                 break;
505
506         case 6:
507                 if (name) return _("邪悪感知", "Evil detection");
508                 if (desc) return _("周囲の邪悪なモンスターを感知する。", "Detects evil monsters.");
509                 if (info) return info_range(MAX_SIGHT);
510                 if (cast)
511                 {
512                         msg_print(_("邪悪な生物の存在を感じ取ろうとした。", "You sense the presence of evil creatures."));
513                 }
514                 break;
515
516         case 7:
517                 if (name) return _("我慢", "Patience");
518                 if (desc) return _("数ターン攻撃を耐えた後、受けたダメージを地獄の業火として周囲に放出する。",
519                 "Bursts hell fire strongly after enduring damage for a few turns.");
520                 power = MIN(200, (HEX_REVENGE_POWER(caster_ptr) * 2));
521                 if (info) return info_damage(0, 0, power);
522                 if (cast)
523                 {
524                         int a = 3 - (caster_ptr->pspeed - 100) / 10;
525                         MAGIC_NUM2 r = 3 + randint1(3) + MAX(0, MIN(3, a));
526
527                         if (HEX_REVENGE_TURN(caster_ptr) > 0)
528                         {
529                                 msg_print(_("すでに我慢をしている。", "You are already biding your time for vengeance."));
530                                 return NULL;
531                         }
532
533                         HEX_REVENGE_TYPE(caster_ptr) = 1;
534                         HEX_REVENGE_TURN(caster_ptr) = r;
535                         HEX_REVENGE_POWER(caster_ptr) = 0;
536                         msg_print(_("じっと耐えることにした。", "You decide to endure damage for future retribution."));
537                         add = FALSE;
538                 }
539                 if (cont)
540                 {
541                         POSITION rad = 2 + (power / 50);
542
543                         HEX_REVENGE_TURN(caster_ptr)--;
544
545                         if ((HEX_REVENGE_TURN(caster_ptr) <= 0) || (power >= 200))
546                         {
547                                 msg_print(_("我慢が解かれた!", "My patience is at an end!"));
548                                 if (power)
549                                 {
550                                         project(caster_ptr, 0, rad, caster_ptr->y, caster_ptr->x, power, GF_HELL_FIRE,
551                                                 (PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL), -1);
552                                 }
553                                 if (current_world_ptr->wizard)
554                                 {
555                                         msg_format(_("%d点のダメージを返した。", "You return %d damage."), power);
556                                 }
557
558                                 /* Reset */
559                                 HEX_REVENGE_TYPE(caster_ptr) = 0;
560                                 HEX_REVENGE_TURN(caster_ptr) = 0;
561                                 HEX_REVENGE_POWER(caster_ptr) = 0;
562                         }
563                 }
564                 break;
565
566                 /*** 2nd book (8-15) ***/
567         case 8:
568                 if (name) return _("氷の鎧", "Armor of ice");
569                 if (desc) return _("氷のオーラを身にまとい、防御力が上昇する。", "Surrounds you with an icy aura and gives a bonus to AC.");
570                 if (cast)
571                 {
572                         msg_print(_("体が氷の鎧で覆われた。", "You are enveloped by icy armor!"));
573                 }
574                 if (stop)
575                 {
576                         msg_print(_("氷の鎧が消え去った。", "The icy armor disappeared."));
577                 }
578                 break;
579
580         case 9:
581                 if (name) return _("重傷の治癒", "Cure serious wounds");
582                 if (desc) return _("体力や傷を多少回復させる。", "Heals cuts and HP.");
583                 if (info) return info_heal(2, 10, 0);
584                 if (cast)
585                 {
586                         msg_print(_("気分が良くなってくる。", "You feel better."));
587                 }
588                 if (cast || cont) (void)cure_serious_wounds(caster_ptr, 2, 10);
589                 break;
590
591         case 10:
592                 if (name) return _("薬品吸入", "Inhale potion");
593                 if (desc) return _("呪文詠唱を中止することなく、薬の効果を得ることができる。", "Quaffs a potion without canceling spell casting.");
594                 if (cast)
595                 {
596                         CASTING_HEX_FLAGS(caster_ptr) |= (1L << HEX_INHAIL);
597                         do_cmd_quaff_potion(caster_ptr);
598                         CASTING_HEX_FLAGS(caster_ptr) &= ~(1L << HEX_INHAIL);
599                         add = FALSE;
600                 }
601                 break;
602
603         case 11:
604                 if (name) return _("衰弱の霧", "Hypodynamic mist");
605                 if (desc) return _("視界内のモンスターに微弱量の衰弱属性のダメージを与える。",
606                         "Deals a little life-draining damage to all monsters in your sight.");
607                 power = (plev / 2) + 5;
608                 if (info) return info_damage(1, power, 0);
609                 if (cast || cont)
610                 {
611                         project_all_los(caster_ptr, GF_HYPODYNAMIA, randint1(power));
612                 }
613                 break;
614
615         case 12:
616                 if (name) return _("魔剣化", "Swords to runeswords");
617                 if (desc) return _("武器の攻撃力を上げる。切れ味を得、呪いに応じて与えるダメージが上昇し、善良なモンスターに対するダメージが2倍になる。",
618                         "Gives vorpal ability to your weapon. Increases damage from your weapon acccording to curse of your weapon.");
619                 if (cast)
620                 {
621 #ifdef JP
622                         msg_print("あなたの武器が黒く輝いた。");
623 #else
624                         if (!empty_hands(caster_ptr, FALSE))
625                                 msg_print("Your weapons glow bright black.");
626                         else
627                                 msg_print("Your weapon glows bright black.");
628 #endif
629                 }
630                 if (stop)
631                 {
632 #ifdef JP
633                         msg_print("武器の輝きが消え去った。");
634 #else
635                         msg_format("Your weapon%s.", (empty_hands(caster_ptr, FALSE)) ? " no longer glows" : "s no longer glow");
636 #endif
637                 }
638                 break;
639
640         case 13:
641                 if (name) return _("混乱の手", "Touch of confusion");
642                 if (desc) return _("攻撃した際モンスターを混乱させる。", "Confuses a monster when you attack.");
643                 if (cast)
644                 {
645                         msg_print(_("あなたの手が赤く輝き始めた。", "Your hands glow bright red."));
646                 }
647                 if (stop)
648                 {
649                         msg_print(_("手の輝きがなくなった。", "Your hands no longer glow."));
650                 }
651                 break;
652
653         case 14:
654                 if (name) return _("肉体強化", "Building up");
655                 if (desc) return _("術者の腕力、器用さ、耐久力を上昇させる。攻撃回数の上限を 1 増加させる。",
656                         "Attempts to increases your strength, dexterity and constitusion.");
657                 if (cast)
658                 {
659                         msg_print(_("身体が強くなった気がした。", "You feel your body is more developed now."));
660                 }
661                 break;
662
663         case 15:
664                 if (name) return _("反テレポート結界", "Anti teleport barrier");
665                 if (desc) return _("視界内のモンスターのテレポートを阻害するバリアを張る。", "Obstructs all teleportations by monsters in your sight.");
666                 power = plev * 3 / 2;
667                 if (info) return info_power(power);
668                 if (cast)
669                 {
670                         msg_print(_("テレポートを防ぐ呪いをかけた。", "You feel anyone can not teleport except you."));
671                 }
672                 break;
673
674                 /*** 3rd book (16-23) ***/
675         case 16:
676                 if (name) return _("衝撃のクローク", "Cloak of shock");
677                 if (desc) return _("電気のオーラを身にまとい、動きが速くなる。", "Gives lightning aura and a bonus to speed.");
678                 if (cast)
679                 {
680                         msg_print(_("体が稲妻のオーラで覆われた。", "You are enveloped by an electrical aura!"));
681                 }
682                 if (stop)
683                 {
684                         msg_print(_("稲妻のオーラが消え去った。", "The electrical aura disappeared."));
685                 }
686                 break;
687
688         case 17:
689                 if (name) return _("致命傷の治癒", "Cure critical wounds");
690                 if (desc) return _("体力や傷を回復させる。", "Heals cuts and HP greatly.");
691                 if (info) return info_heal(4, 10, 0);
692                 if (cast)
693                 {
694                         msg_print(_("気分が良くなってくる。", "You feel much better."));
695                 }
696                 if (cast || cont) (void)cure_critical_wounds(caster_ptr, damroll(4, 10));
697                 break;
698
699         case 18:
700                 if (name) return _("呪力封入", "Recharging");
701                 if (desc) return _("魔法の道具に魔力を再充填する。", "Recharges a magic device.");
702                 power = plev * 2;
703                 if (info) return info_power(power);
704                 if (cast)
705                 {
706                         if (!recharge(caster_ptr, power)) return NULL;
707                         add = FALSE;
708                 }
709                 break;
710
711         case 19:
712                 if (name) return _("死者復活", "Animate Dead");
713                 if (desc) return _("死体を蘇らせてペットにする。", "Raises corpses and skeletons from dead.");
714                 if (cast)
715                 {
716                         msg_print(_("死者への呼びかけを始めた。", "You start to call the dead.!"));
717                 }
718                 if (cast || cont)
719                 {
720                         animate_dead(caster_ptr, 0, caster_ptr->y, caster_ptr->x);
721                 }
722                 break;
723
724         case 20:
725                 if (name) return _("防具呪縛", "Curse armor");
726                 if (desc) return _("装備している防具に呪いをかける。", "Curse a piece of armour that you wielding.");
727                 if (cast)
728                 {
729                         OBJECT_IDX item;
730                         concptr q, s;
731                         GAME_TEXT o_name[MAX_NLEN];
732                         object_type *o_ptr;
733                         u32b f[TR_FLAG_SIZE];
734
735                         item_tester_hook = object_is_armour;
736                         q = _("どれを呪いますか?", "Which piece of armour do you curse?");
737                         s = _("防具を装備していない。", "You're not wearing any armor.");
738
739                         o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP), 0);
740                         if (!o_ptr) return FALSE;
741
742                         o_ptr = &caster_ptr->inventory_list[item];
743                         object_desc(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
744                         object_flags(o_ptr, f);
745
746                         if (!get_check(format(_("本当に %s を呪いますか?", "Do you curse %s, really?"), o_name))) return FALSE;
747
748                         if (!one_in_(3) &&
749                                 (object_is_artifact(o_ptr) || have_flag(f, TR_BLESSED)))
750                         {
751                                 msg_format(_("%s は呪いを跳ね返した。", "%s resists the effect."), o_name);
752                                 if (one_in_(3))
753                                 {
754                                         if (o_ptr->to_d > 0)
755                                         {
756                                                 o_ptr->to_d -= randint1(3) % 2;
757                                                 if (o_ptr->to_d < 0) o_ptr->to_d = 0;
758                                         }
759                                         if (o_ptr->to_h > 0)
760                                         {
761                                                 o_ptr->to_h -= randint1(3) % 2;
762                                                 if (o_ptr->to_h < 0) o_ptr->to_h = 0;
763                                         }
764                                         if (o_ptr->to_a > 0)
765                                         {
766                                                 o_ptr->to_a -= randint1(3) % 2;
767                                                 if (o_ptr->to_a < 0) o_ptr->to_a = 0;
768                                         }
769                                         msg_format(_("%s は劣化してしまった。", "Your %s was disenchanted!"), o_name);
770                                 }
771                         }
772                         else
773                         {
774                                 int curse_rank = 0;
775                                 msg_format(_("恐怖の暗黒オーラがあなたの%sを包み込んだ!", "A terrible black aura blasts your %s!"), o_name);
776                                 o_ptr->curse_flags |= (TRC_CURSED);
777
778                                 if (object_is_artifact(o_ptr) || object_is_ego(o_ptr))
779                                 {
780
781                                         if (one_in_(3)) o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
782                                         if (one_in_(666))
783                                         {
784                                                 o_ptr->curse_flags |= (TRC_TY_CURSE);
785                                                 if (one_in_(666)) o_ptr->curse_flags |= (TRC_PERMA_CURSE);
786
787                                                 add_flag(o_ptr->art_flags, TR_AGGRAVATE);
788                                                 add_flag(o_ptr->art_flags, TR_RES_POIS);
789                                                 add_flag(o_ptr->art_flags, TR_RES_DARK);
790                                                 add_flag(o_ptr->art_flags, TR_RES_NETHER);
791                                                 msg_print(_("血だ!血だ!血だ!", "Blood, Blood, Blood!"));
792                                                 curse_rank = 2;
793                                         }
794                                 }
795
796                                 o_ptr->curse_flags |= get_curse(curse_rank, o_ptr);
797                         }
798
799                         caster_ptr->update |= (PU_BONUS);
800                         add = FALSE;
801                 }
802                 break;
803
804         case 21:
805                 if (name) return _("影のクローク", "Cloak of shadow");
806                 if (desc) return _("影のオーラを身にまとい、敵に影のダメージを与える。", "Gives aura of shadow.");
807                 if (cast)
808                 {
809                         object_type *o_ptr = &caster_ptr->inventory_list[INVEN_OUTER];
810
811                         if (!o_ptr->k_idx)
812                         {
813                                 msg_print(_("クロークを身につけていない!", "You are not wearing a cloak."));
814                                 return NULL;
815                         }
816                         else if (!object_is_cursed(o_ptr))
817                         {
818                                 msg_print(_("クロークは呪われていない!", "Your cloak is not cursed."));
819                                 return NULL;
820                         }
821                         else
822                         {
823                                 msg_print(_("影のオーラを身にまとった。", "You are enveloped by a shadowy aura!"));
824                         }
825                 }
826                 if (cont)
827                 {
828                         object_type *o_ptr = &caster_ptr->inventory_list[INVEN_OUTER];
829
830                         if ((!o_ptr->k_idx) || (!object_is_cursed(o_ptr)))
831                         {
832                                 exe_spell(caster_ptr, REALM_HEX, spell, SPELL_STOP);
833                                 CASTING_HEX_FLAGS(caster_ptr) &= ~(1L << spell);
834                                 CASTING_HEX_NUM(caster_ptr)--;
835                                 if (!SINGING_SONG_ID(caster_ptr)) set_action(caster_ptr, ACTION_NONE);
836                         }
837                 }
838                 if (stop)
839                 {
840                         msg_print(_("影のオーラが消え去った。", "The shadowy aura disappeared."));
841                 }
842                 break;
843
844         case 22:
845                 if (name) return _("苦痛を魔力に", "Pain to mana");
846                 if (desc) return _("視界内のモンスターに精神ダメージ与え、魔力を吸い取る。", "Deals psychic damage to all monsters in sight and drains some mana.");
847                 power = plev * 3 / 2;
848                 if (info) return info_damage(1, power, 0);
849                 if (cast || cont)
850                 {
851                         project_all_los(caster_ptr, GF_PSI_DRAIN, randint1(power));
852                 }
853                 break;
854
855         case 23:
856                 if (name) return _("目には目を", "Eye for an eye");
857                 if (desc) return _("打撃や魔法で受けたダメージを、攻撃元のモンスターにも与える。", "Returns same damage which you got to the monster which damaged you.");
858                 if (cast)
859                 {
860                         msg_print(_("復讐したい欲望にかられた。", "You feel very vengeful."));
861                 }
862                 break;
863
864                 /*** 4th book (24-31) ***/
865         case 24:
866                 if (name) return _("反増殖結界", "Anti multiply barrier");
867                 if (desc) return _("その階の増殖するモンスターの増殖を阻止する。", "Obstructs all multiplying by monsters in entire floor.");
868                 if (cast)
869                 {
870                         msg_print(_("増殖を阻止する呪いをかけた。", "You feel anyone can not already multiply."));
871                 }
872                 break;
873
874         case 25:
875                 if (name) return _("全復活", "Restoration");
876                 if (desc) return _("経験値を徐々に復活し、減少した能力値を回復させる。", "Restores experience and status.");
877                 if (cast)
878                 {
879                         msg_print(_("体が元の活力を取り戻し始めた。", "You feel your lost status starting to return."));
880                 }
881                 if (cast || cont)
882                 {
883                         bool flag = FALSE;
884                         int d = (caster_ptr->max_exp - caster_ptr->exp);
885                         int r = (caster_ptr->exp / 20);
886                         int i;
887
888                         if (d > 0)
889                         {
890                                 if (d < r)
891                                         caster_ptr->exp = caster_ptr->max_exp;
892                                 else
893                                         caster_ptr->exp += r;
894
895                                 /* Check the experience */
896                                 check_experience(caster_ptr);
897
898                                 flag = TRUE;
899                         }
900                         for (i = A_STR; i < A_MAX; i++)
901                         {
902                                 if (caster_ptr->stat_cur[i] < caster_ptr->stat_max[i])
903                                 {
904                                         if (caster_ptr->stat_cur[i] < 18)
905                                                 caster_ptr->stat_cur[i]++;
906                                         else
907                                                 caster_ptr->stat_cur[i] += 10;
908
909                                         if (caster_ptr->stat_cur[i] > caster_ptr->stat_max[i])
910                                                 caster_ptr->stat_cur[i] = caster_ptr->stat_max[i];
911                                         caster_ptr->update |= (PU_BONUS);
912
913                                         flag = TRUE;
914                                 }
915                         }
916
917                         if (!flag)
918                         {
919                                 msg_format(_("%sの呪文の詠唱をやめた。", "Finish casting '%^s'."), exe_spell(caster_ptr, REALM_HEX, HEX_RESTORE, SPELL_NAME));
920                                 CASTING_HEX_FLAGS(caster_ptr) &= ~(1L << HEX_RESTORE);
921                                 if (cont) CASTING_HEX_NUM(caster_ptr)--;
922                                 if (CASTING_HEX_NUM(caster_ptr)) caster_ptr->action = ACTION_NONE;
923
924                                 caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
925                                 caster_ptr->redraw |= (PR_EXTRA);
926
927                                 return "";
928                         }
929                 }
930                 break;
931
932         case 26:
933                 if (name) return _("呪力吸収", "Drain curse power");
934                 if (desc) return _("呪われた武器の呪いを吸収して魔力を回復する。", "Drains curse on your weapon and heals SP a little.");
935                 if (cast)
936                 {
937                         OBJECT_IDX item;
938                         concptr s, q;
939                         u32b f[TR_FLAG_SIZE];
940                         object_type *o_ptr;
941
942                         item_tester_hook = item_tester_hook_cursed;
943                         q = _("どの装備品から吸収しますか?", "Which cursed equipment do you drain mana from?");
944                         s = _("呪われたアイテムを装備していない。", "You have no cursed equipment.");
945
946                         o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP), 0);
947                         if (!o_ptr) return FALSE;
948
949                         object_flags(o_ptr, f);
950
951                         caster_ptr->csp += (caster_ptr->lev / 5) + randint1(caster_ptr->lev / 5);
952                         if (have_flag(f, TR_TY_CURSE) || (o_ptr->curse_flags & TRC_TY_CURSE)) caster_ptr->csp += randint1(5);
953                         if (caster_ptr->csp > caster_ptr->msp) caster_ptr->csp = caster_ptr->msp;
954
955                         if (o_ptr->curse_flags & TRC_PERMA_CURSE)
956                         {
957                                 /* Nothing */
958                         }
959                         else if (o_ptr->curse_flags & TRC_HEAVY_CURSE)
960                         {
961                                 if (one_in_(7))
962                                 {
963                                         msg_print(_("呪いを全て吸い取った。", "A heavy curse vanished."));
964                                         o_ptr->curse_flags = 0L;
965                                 }
966                         }
967                         else if ((o_ptr->curse_flags & (TRC_CURSED)) && one_in_(3))
968                         {
969                                 msg_print(_("呪いを全て吸い取った。", "A curse vanished."));
970                                 o_ptr->curse_flags = 0L;
971                         }
972
973                         add = FALSE;
974                 }
975                 break;
976
977         case 27:
978                 if (name) return _("吸血の刃", "Swords to vampires");
979                 if (desc) return _("吸血属性で攻撃する。", "Gives vampiric ability to your weapon.");
980                 if (cast)
981                 {
982 #ifdef JP
983                         msg_print("あなたの武器が血を欲している。");
984 #else
985                         if (!empty_hands(caster_ptr, FALSE))
986                                 msg_print("Your weapons want more blood now.");
987                         else
988                                 msg_print("Your weapon wants more blood now.");
989 #endif
990                 }
991                 if (stop)
992                 {
993 #ifdef JP
994                         msg_print("武器の渇望が消え去った。");
995 #else
996                         msg_format("Your weapon%s less thirsty now.", (empty_hands(caster_ptr, FALSE)) ? " is" : "s are");
997 #endif
998                 }
999                 break;
1000
1001         case 28:
1002                 if (name) return _("朦朧の言葉", "Word of stun");
1003                 if (desc) return _("視界内のモンスターを朦朧とさせる。", "Stuns all monsters in your sight.");
1004                 power = plev * 4;
1005                 if (info) return info_power(power);
1006                 if (cast || cont)
1007                 {
1008                         stun_monsters(caster_ptr, power);
1009                 }
1010                 break;
1011
1012         case 29:
1013                 if (name) return _("影移動", "Moving into shadow");
1014                 if (desc) return _("モンスターの隣のマスに瞬間移動する。", "Teleports you close to a monster.");
1015                 if (cast)
1016                 {
1017                         int i, dir;
1018                         POSITION y, x;
1019                         bool flag;
1020
1021                         for (i = 0; i < 3; i++)
1022                         {
1023                                 if (!tgt_pt(caster_ptr, &x, &y)) return FALSE;
1024
1025                                 flag = FALSE;
1026
1027                                 for (dir = 0; dir < 8; dir++)
1028                                 {
1029                                         int dy = y + ddy_ddd[dir];
1030                                         int dx = x + ddx_ddd[dir];
1031                                         if (dir == 5) continue;
1032                                         if (caster_ptr->current_floor_ptr->grid_array[dy][dx].m_idx) flag = TRUE;
1033                                 }
1034
1035                                 if (!is_cave_empty_bold(caster_ptr, y, x) || (caster_ptr->current_floor_ptr->grid_array[y][x].info & CAVE_ICKY) ||
1036                                         (distance(y, x, caster_ptr->y, caster_ptr->x) > plev + 2))
1037                                 {
1038                                         msg_print(_("そこには移動できない。", "Can not teleport to there."));
1039                                         continue;
1040                                 }
1041                                 break;
1042                         }
1043
1044                         if (flag && randint0(plev * plev / 2))
1045                         {
1046                                 teleport_player_to(caster_ptr, y, x, TELEPORT_SPONTANEOUS);
1047                         }
1048                         else
1049                         {
1050                                 msg_print(_("おっと!", "Oops!"));
1051                                 teleport_player(caster_ptr, 30, TELEPORT_SPONTANEOUS);
1052                         }
1053
1054                         add = FALSE;
1055                 }
1056                 break;
1057
1058         case 30:
1059                 if (name) return _("反魔法結界", "Anti magic barrier");
1060                 if (desc) return _("視界内のモンスターの魔法を阻害するバリアを張る。", "Obstructs all magic spells of monsters in your sight.");
1061                 power = plev * 3 / 2;
1062                 if (info) return info_power(power);
1063                 if (cast)
1064                 {
1065                         msg_print(_("魔法を防ぐ呪いをかけた。", "You feel anyone can not cast spells except you."));
1066                 }
1067                 break;
1068
1069         case 31:
1070                 if (name) return _("復讐の宣告", "Revenge sentence");
1071                 if (desc) return _("数ターン後にそれまで受けたダメージに応じた威力の地獄の劫火の弾を放つ。",
1072                         "Fires a ball of hell fire to try avenging damage from a few turns.");
1073                 power = HEX_REVENGE_POWER(caster_ptr);
1074                 if (info) return info_damage(0, 0, power);
1075                 if (cast)
1076                 {
1077                         MAGIC_NUM2 r;
1078                         int a = 3 - (caster_ptr->pspeed - 100) / 10;
1079                         r = 1 + randint1(2) + MAX(0, MIN(3, a));
1080
1081                         if (HEX_REVENGE_TURN(caster_ptr) > 0)
1082                         {
1083                                 msg_print(_("すでに復讐は宣告済みだ。", "You've already declared your revenge."));
1084                                 return NULL;
1085                         }
1086
1087                         HEX_REVENGE_TYPE(caster_ptr) = 2;
1088                         HEX_REVENGE_TURN(caster_ptr) = r;
1089                         msg_format(_("あなたは復讐を宣告した。あと %d ターン。", "You declare your revenge. %d turns left."), r);
1090                         add = FALSE;
1091                 }
1092                 if (cont)
1093                 {
1094                         HEX_REVENGE_TURN(caster_ptr)--;
1095
1096                         if (HEX_REVENGE_TURN(caster_ptr) <= 0)
1097                         {
1098                                 DIRECTION dir;
1099
1100                                 if (power)
1101                                 {
1102                                         command_dir = 0;
1103
1104                                         do
1105                                         {
1106                                                 msg_print(_("復讐の時だ!", "Time for revenge!"));
1107                                         } while (!get_aim_dir(caster_ptr, &dir));
1108
1109                                         fire_ball(caster_ptr, GF_HELL_FIRE, dir, power, 1);
1110
1111                                         if (current_world_ptr->wizard)
1112                                         {
1113                                                 msg_format(_("%d点のダメージを返した。", "You return %d damage."), power);
1114                                         }
1115                                 }
1116                                 else
1117                                 {
1118                                         msg_print(_("復讐する気が失せた。", "You are not in the mood for revenge."));
1119                                 }
1120                                 HEX_REVENGE_POWER(caster_ptr) = 0;
1121                         }
1122                 }
1123                 break;
1124         }
1125
1126         /* start casting */
1127         if ((cast) && (add))
1128         {
1129                 /* add spell */
1130                 CASTING_HEX_FLAGS(caster_ptr) |= 1L << (spell);
1131                 CASTING_HEX_NUM(caster_ptr)++;
1132
1133                 if (caster_ptr->action != ACTION_SPELL) set_action(caster_ptr, ACTION_SPELL);
1134         }
1135
1136         if (!info)
1137         {
1138                 caster_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
1139                 caster_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA);
1140         }
1141
1142         return "";
1143 }
1144
1145 bool hex_spelling(player_type *caster_ptr, int hex)
1146 {
1147         return (caster_ptr->realm1 == REALM_HEX) && (caster_ptr->magic_num1[0] & (1L << (hex)));
1148 }