OSDN Git Service

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