OSDN Git Service

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