OSDN Git Service

d1a2a5b4a422d2ee22a4febbe29cc88df4185ce1
[hengband/hengband.git] / src / realm-crusade.c
1 #include "angband.h"
2 #include "util.h"
3
4 #include "world.h"
5 #include "cmd-spell.h"
6 #include "floor.h"
7 #include "spells.h"
8 #include "spells-object.h"
9 #include "spells-summon.h"
10 #include "spells-status.h"
11 #include "spells-floor.h"
12 #include "player-class.h"
13 #include "player-effects.h"
14 #include "targeting.h"
15
16
17
18 /*!
19 * @brief 破邪領域魔法の各処理を行う
20 * @param caster_ptr プレーヤーへの参照ポインタ
21 * @param spell 魔法ID
22 * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_INFO / SPELL_CAST)
23 * @return SPELL_NAME / SPELL_DESC / SPELL_INFO 時には文字列ポインタを返す。SPELL_CAST時はNULL文字列を返す。
24 */
25 concptr do_crusade_spell(player_type *caster_ptr, SPELL_IDX spell, BIT_FLAGS mode)
26 {
27         bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
28         bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
29         bool info = (mode == SPELL_INFO) ? TRUE : FALSE;
30         bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
31
32         DIRECTION dir;
33         PLAYER_LEVEL plev = caster_ptr->lev;
34
35         switch (spell)
36         {
37         case 0:
38                 if (name) return _("懲罰", "Punishment");
39                 if (desc) return _("電撃のボルトもしくはビームを放つ。", "Fires a bolt or beam of lightning.");
40                 {
41                         DICE_NUMBER dice = 3 + (plev - 1) / 5;
42                         DICE_SID sides = 4;
43                         if (info) return info_damage(dice, sides, 0);
44                         if (cast)
45                         {
46                                 if (!get_aim_dir(&dir)) return NULL;
47                                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_ELEC, dir, damroll(dice, sides));
48                         }
49                 }
50                 break;
51
52         case 1:
53                 if (name) return _("邪悪存在感知", "Detect Evil");
54                 if (desc) return _("近くの邪悪なモンスターを感知する。", "Detects all evil monsters in your vicinity.");
55                 {
56                         POSITION rad = DETECT_RAD_DEFAULT;
57                         if (info) return info_radius(rad);
58                         if (cast)
59                         {
60                                 detect_monsters_evil(caster_ptr, rad);
61                         }
62                 }
63                 break;
64
65         case 2:
66                 if (name) return _("恐怖除去", "Remove Fear");
67                 if (desc) return _("恐怖を取り除く。", "Removes fear.");
68                 {
69                         if (cast) set_afraid(caster_ptr, 0);
70                 }
71                 break;
72
73         case 3:
74                 if (name) return _("威圧", "Scare Monster");
75                 if (desc) return _("モンスター1体を恐怖させる。抵抗されると無効。", "Attempts to scare a monster.");
76
77                 {
78                         PLAYER_LEVEL power = plev;
79                         if (info) return info_power(power);
80                         if (cast)
81                         {
82                                 if (!get_aim_dir(&dir)) return NULL;
83                                 fear_monster(dir, power);
84                         }
85                 }
86                 break;
87
88         case 4:
89                 if (name) return _("聖域", "Sanctuary");
90                 if (desc) return _("隣接した全てのモンスターを眠らせる。抵抗されると無効。", "Attempts to sleep monsters in the adjacent squares.");
91                 {
92                         PLAYER_LEVEL power = plev;
93                         if (info) return info_power(power);
94                         if (cast) sleep_monsters_touch();
95                 }
96                 break;
97
98         case 5:
99                 if (name) return _("入口", "Portal");
100                 if (desc) return _("中距離のテレポートをする。", "Teleport medium distance.");
101
102                 {
103                         POSITION range = 25 + plev / 2;
104                         if (info) return info_range(range);
105                         if (cast) teleport_player(caster_ptr, range, 0L);
106                 }
107                 break;
108
109         case 6:
110                 if (name) return _("スターダスト", "Star Dust");
111                 if (desc) return _("ターゲット付近に閃光のボルトを連射する。", "Fires many bolts of light near the target.");
112
113                 {
114                         DICE_NUMBER dice = 3 + (plev - 1) / 9;
115                         DICE_SID sides = 2;
116                         if (info) return info_multi_damage_dice(dice, sides);
117                         if (cast)
118                         {
119                                 if (!get_aim_dir(&dir)) return NULL;
120                                 fire_blast(caster_ptr, GF_LITE, dir, dice, sides, 10, 3);
121                         }
122                 }
123                 break;
124
125         case 7:
126                 if (name) return _("身体浄化", "Purify");
127                 if (desc) return _("傷、毒、朦朧から全快する。", "Heals all cut, stun and poison status.");
128                 {
129                         if (cast)
130                         {
131                                 set_cut(caster_ptr,0);
132                                 set_poisoned(caster_ptr, 0);
133                                 set_stun(caster_ptr, 0);
134                         }
135                 }
136                 break;
137
138         case 8:
139                 if (name) return _("邪悪飛ばし", "Scatter Evil");
140                 if (desc) return _("邪悪なモンスター1体をテレポートさせる。抵抗されると無効。", "Attempts to teleport an evil monster away.");
141
142                 {
143                         int power = MAX_SIGHT * 5;
144                         if (info) return info_power(power);
145                         if (cast)
146                         {
147                                 if (!get_aim_dir(&dir)) return NULL;
148                                 fire_ball(caster_ptr, GF_AWAY_EVIL, dir, power, 0);
149                         }
150                 }
151                 break;
152
153         case 9:
154                 if (name) return _("聖なる光球", "Holy Orb");
155                 if (desc) return _("聖なる力をもつ宝珠を放つ。邪悪なモンスターに対して大きなダメージを与えるが、善良なモンスターには効果がない。",
156                         "Fires a ball with holy power. Hurts evil monsters greatly, but don't effect good monsters.");
157
158                 {
159                         DICE_NUMBER dice = 3;
160                         DICE_SID sides = 6;
161                         POSITION rad = (plev < 30) ? 2 : 3;
162                         int base;
163                         if (caster_ptr->pclass == CLASS_PRIEST ||
164                                 caster_ptr->pclass == CLASS_HIGH_MAGE ||
165                                 caster_ptr->pclass == CLASS_SORCERER)
166                                 base = plev + plev / 2;
167                         else
168                                 base = plev + plev / 4;
169
170
171                         if (info) return info_damage(dice, sides, base);
172
173                         if (cast)
174                         {
175                                 if (!get_aim_dir(&dir)) return NULL;
176
177                                 fire_ball(caster_ptr, GF_HOLY_FIRE, dir, damroll(dice, sides) + base, rad);
178                         }
179                 }
180                 break;
181
182         case 10:
183                 if (name) return _("悪魔払い", "Exorcism");
184                 if (desc) return _("視界内の全てのアンデッド及び悪魔にダメージを与え、邪悪なモンスターを恐怖させる。",
185                         "Damages all undead and demons in sight, and scares all evil monsters in sight.");
186                 {
187                         DICE_SID sides = plev;
188                         int power = plev;
189                         if (info) return info_damage(1, sides, 0);
190                         if (cast)
191                         {
192                                 dispel_undead(caster_ptr, randint1(sides));
193                                 dispel_demons(caster_ptr, randint1(sides));
194                                 turn_evil(power);
195                         }
196                 }
197                 break;
198
199         case 11:
200                 if (name) return _("解呪", "Remove Curse");
201                 if (desc) return _("アイテムにかかった弱い呪いを解除する。", "Removes normal curses from equipped items.");
202                 {
203                         if (cast) (void)remove_curse(caster_ptr);
204                 }
205                 break;
206
207         case 12:
208                 if (name) return _("透明視認", "Sense Unseen");
209                 if (desc) return _("一定時間、透明なものが見えるようになる。", "Gives see invisible for a while.");
210
211                 {
212                         int base = 24;
213
214                         if (info) return info_duration(base, base);
215
216                         if (cast)
217                         {
218                                 set_tim_invis(caster_ptr, randint1(base) + base, FALSE);
219                         }
220                 }
221                 break;
222
223         case 13:
224                 if (name) return _("対邪悪結界", "Protection from Evil");
225                 if (desc) return _("邪悪なモンスターの攻撃を防ぐバリアを張る。", "Gives aura which protect you from evil monster's physical attack.");
226
227                 {
228                         int base = 25;
229                         DICE_SID sides = 3 * plev;
230
231                         if (info) return info_duration(base, sides);
232
233                         if (cast)
234                         {
235                                 set_protevil(caster_ptr, randint1(sides) + base, FALSE);
236                         }
237                 }
238                 break;
239
240         case 14:
241                 if (name) return _("裁きの雷", "Judgment Thunder");
242                 if (desc) return _("強力な電撃のボルトを放つ。", "Fires a powerful bolt of lightning.");
243
244                 {
245                         HIT_POINT dam = plev * 5;
246
247                         if (info) return info_damage(0, 0, dam);
248
249                         if (cast)
250                         {
251                                 if (!get_aim_dir(&dir)) return NULL;
252                                 fire_bolt(caster_ptr, GF_ELEC, dir, dam);
253                         }
254                 }
255                 break;
256
257         case 15:
258                 if (name) return _("聖なる御言葉", "Holy Word");
259                 if (desc) return _("視界内の邪悪な存在に大きなダメージを与え、体力を回復し、毒、恐怖、朦朧状態、負傷から全快する。",
260                         "Damages all evil monsters in sight, heals HP somewhat, and completely heals poison, fear, stun and cut status.");
261
262                 {
263                         int dam_sides = plev * 6;
264                         int heal = 100;
265
266                         if (info) return format(_("損:1d%d/回%d", "dam:d%d/h%d"), dam_sides, heal);
267                         if (cast)
268                         {
269                                 dispel_evil(caster_ptr, randint1(dam_sides));
270                                 hp_player(caster_ptr, heal);
271                                 set_afraid(caster_ptr, 0);
272                                 set_poisoned(caster_ptr, 0);
273                                 set_stun(caster_ptr, 0);
274                                 set_cut(caster_ptr,0);
275                         }
276                 }
277                 break;
278
279         case 16:
280                 if (name) return _("開かれた道", "Unbarring Ways");
281                 if (desc) return _("一直線上の全ての罠と扉を破壊する。", "Fires a beam which destroy traps and doors.");
282
283                 {
284                         if (cast)
285                         {
286                                 if (!get_aim_dir(&dir)) return NULL;
287
288                                 destroy_door(dir);
289                         }
290                 }
291                 break;
292
293         case 17:
294                 if (name) return _("封魔", "Arrest");
295                 if (desc) return _("邪悪なモンスターの動きを止める。", "Attempts to paralyze an evil monster.");
296
297                 {
298                         int power = plev * 2;
299
300                         if (info) return info_power(power);
301
302                         if (cast)
303                         {
304                                 if (!get_aim_dir(&dir)) return NULL;
305                                 stasis_evil(dir);
306                         }
307                 }
308                 break;
309
310         case 18:
311                 if (name) return _("聖なるオーラ", "Holy Aura");
312                 if (desc) return _("一定時間、邪悪なモンスターを傷つける聖なるオーラを得る。",
313                         "Gives aura of holy power which injures evil monsters which attacked you for a while.");
314
315                 {
316                         int base = 20;
317
318                         if (info) return info_duration(base, base);
319
320                         if (cast)
321                         {
322                                 set_tim_sh_holy(caster_ptr, randint1(base) + base, FALSE);
323                         }
324                 }
325                 break;
326
327         case 19:
328                 if (name) return _("アンデッド&悪魔退散", "Dispel Undead & Demons");
329                 if (desc) return _("視界内の全てのアンデッド及び悪魔にダメージを与える。", "Damages all undead and demons in sight.");
330
331                 {
332                         DICE_SID sides = plev * 4;
333
334                         if (info) return info_damage(1, sides, 0);
335
336                         if (cast)
337                         {
338                                 dispel_undead(caster_ptr, randint1(sides));
339                                 dispel_demons(caster_ptr, randint1(sides));
340                         }
341                 }
342                 break;
343
344         case 20:
345                 if (name) return _("邪悪退散", "Dispel Evil");
346                 if (desc) return _("視界内の全ての邪悪なモンスターにダメージを与える。", "Damages all evil monsters in sight.");
347
348                 {
349                         DICE_SID sides = plev * 4;
350
351                         if (info) return info_damage(1, sides, 0);
352
353                         if (cast)
354                         {
355                                 dispel_evil(caster_ptr, randint1(sides));
356                         }
357                 }
358                 break;
359
360         case 21:
361                 if (name) return _("聖なる刃", "Holy Blade");
362                 if (desc) return _("通常の武器に滅邪の属性をつける。", "Makes current weapon especially deadly against evil monsters.");
363
364                 {
365                         if (cast)
366                         {
367                                 brand_weapon(caster_ptr, 13);
368                         }
369                 }
370                 break;
371
372         case 22:
373                 if (name) return _("スターバースト", "Star Burst");
374                 if (desc) return _("巨大な閃光の球を放つ。", "Fires a huge ball of powerful light.");
375
376                 {
377                         HIT_POINT dam = 100 + plev * 2;
378                         POSITION rad = 4;
379
380                         if (info) return info_damage(0, 0, dam);
381
382                         if (cast)
383                         {
384                                 if (!get_aim_dir(&dir)) return NULL;
385
386                                 fire_ball(caster_ptr, GF_LITE, dir, dam, rad);
387                         }
388                 }
389                 break;
390
391         case 23:
392                 if (name) return _("天使召喚", "Summon Angel");
393                 if (desc) return _("天使を1体召喚する。", "Summons an angel.");
394
395                 {
396                         if (cast)
397                         {
398                                 bool pet = !one_in_(3);
399                                 u32b flg = 0L;
400
401                                 if (pet) flg |= PM_FORCE_PET;
402                                 else flg |= PM_NO_PET;
403                                 if (!(pet && (plev < 50))) flg |= PM_ALLOW_GROUP;
404
405                                 if (summon_specific((pet ? -1 : 0), caster_ptr->y, caster_ptr->x, (plev * 3) / 2, SUMMON_ANGEL, flg))
406                                 {
407                                         if (pet)
408                                         {
409                                                 msg_print(_("「ご用でございますか、ご主人様」", "'What is thy bidding... Master?'"));
410                                         }
411                                         else
412                                         {
413                                                 msg_print(_("「我は汝の下僕にあらず! 悪行者よ、悔い改めよ!」", "Mortal! Repent of thy impiousness."));
414                                         }
415                                 }
416                         }
417                 }
418                 break;
419
420         case 24:
421                 if (name) return _("士気高揚", "Heroism");
422                 if (desc) return _("一定時間、ヒーロー気分になる。", "Removes fear, and gives bonus to hit and 10 more HP for a while.");
423
424                 {
425                         int base = 25;
426
427                         if (info) return info_duration(base, base);
428
429                         if (cast)
430                         {
431                                 (void)heroism(caster_ptr, base);
432                         }
433                 }
434                 break;
435
436         case 25:
437                 if (name) return _("呪い退散", "Dispel Curse");
438                 if (desc) return _("アイテムにかかった強力な呪いを解除する。", "Removes normal and heavy curse from equipped items.");
439
440                 {
441                         if (cast) (void)remove_all_curse(caster_ptr);
442                 }
443                 break;
444
445         case 26:
446                 if (name) return _("邪悪追放", "Banish Evil");
447                 if (desc) return _("視界内の全ての邪悪なモンスターをテレポートさせる。抵抗されると無効。",
448                         "Teleports all evil monsters in sight away unless resisted.");
449
450                 {
451                         int power = 100;
452
453                         if (info) return info_power(power);
454
455                         if (cast)
456                         {
457                                 if (banish_evil(caster_ptr, power))
458                                 {
459                                         msg_print(_("神聖な力が邪悪を打ち払った!", "The holy power banishes evil!"));
460                                 }
461                         }
462                 }
463                 break;
464
465         case 27:
466                 if (name) return _("ハルマゲドン", "Armageddon");
467                 if (desc) return _("周辺のアイテム、モンスター、地形を破壊する。", "Destroy everything in nearby area.");
468
469                 {
470                         int base = 12;
471                         DICE_SID sides = 4;
472
473                         if (cast)
474                         {
475                                 destroy_area(caster_ptr->current_floor_ptr, caster_ptr->y, caster_ptr->x, base + randint1(sides), FALSE);
476                         }
477                 }
478                 break;
479
480         case 28:
481                 if (name) return _("目には目を", "An Eye for an Eye");
482                 if (desc) return _("一定時間、自分がダメージを受けたときに攻撃を行ったモンスターに対して同等のダメージを与える。",
483                         "Gives special aura for a while. When you are attacked by a monster, the monster are injured with same amount of damage as you take.");
484
485                 {
486                         int base = 10;
487
488                         if (info) return info_duration(base, base);
489
490                         if (cast)
491                         {
492                                 set_tim_eyeeye(caster_ptr, randint1(base) + base, FALSE);
493                         }
494                 }
495                 break;
496
497         case 29:
498                 if (name) return _("神の怒り", "Wrath of the God");
499                 if (desc) return _("ターゲットの周囲に分解の球を多数落とす。", "Drops many balls of disintegration near the target.");
500
501                 {
502                         HIT_POINT dam = plev * 3 + 25;
503                         POSITION rad = 2;
504
505                         if (info) return info_multi_damage(dam);
506
507                         if (cast)
508                         {
509                                 if (!cast_wrath_of_the_god(caster_ptr, dam, rad)) return NULL;
510                         }
511                 }
512                 break;
513
514         case 30:
515                 if (name) return _("神威", "Divine Intervention");
516                 if (desc) return _("隣接するモンスターに聖なるダメージを与え、視界内のモンスターにダメージ、減速、朦朧、混乱、恐怖、眠りを与える。さらに体力を回復する。",
517                         "Damages all adjacent monsters with holy power. Damages and attempt to slow, stun, confuse, scare and freeze all monsters in sight. And heals HP.");
518
519                 {
520                         int b_dam = plev * 11;
521                         int d_dam = plev * 4;
522                         int heal = 100;
523                         int power = plev * 4;
524
525                         if (info) return format(_("回%d/損%d+%d", "h%d/dm%d+%d"), heal, d_dam, b_dam / 2);
526                         if (cast)
527                         {
528                                 project(caster_ptr, 0, 1, caster_ptr->y, caster_ptr->x, b_dam, GF_HOLY_FIRE, PROJECT_KILL, -1);
529                                 dispel_monsters(caster_ptr, d_dam);
530                                 slow_monsters(caster_ptr, plev);
531                                 stun_monsters(power);
532                                 confuse_monsters(power);
533                                 turn_monsters(power);
534                                 stasis_monsters(power);
535                                 hp_player(caster_ptr, heal);
536                         }
537                 }
538                 break;
539
540         case 31:
541                 if (name) return _("聖戦", "Crusade");
542                 if (desc) return _("視界内の善良なモンスターをペットにしようとし、ならなかった場合及び善良でないモンスターを恐怖させる。さらに多数の加速された騎士を召喚し、ヒーロー、祝福、加速、対邪悪結界を得る。",
543                         "Attempts to charm all good monsters in sight, and scare all non-charmed monsters, and summons great number of knights, and gives heroism, bless, speed and protection from evil.");
544
545                 {
546                         if (cast)
547                         {
548                                 int base = 25;
549                                 int sp_sides = 20 + plev;
550                                 int sp_base = plev;
551
552                                 int i;
553                                 crusade(caster_ptr);
554                                 for (i = 0; i < 12; i++)
555                                 {
556                                         int attempt = 10;
557                                         POSITION my = 0, mx = 0;
558
559                                         while (attempt--)
560                                         {
561                                                 scatter(&my, &mx, caster_ptr->y, caster_ptr->x, 4, 0);
562
563                                                 /* Require empty grids */
564                                                 if (cave_empty_bold2(caster_ptr->current_floor_ptr, my, mx)) break;
565                                         }
566                                         if (attempt < 0) continue;
567                                         summon_specific(-1, my, mx, plev, SUMMON_KNIGHTS, (PM_ALLOW_GROUP | PM_FORCE_PET | PM_HASTE));
568                                 }
569                                 set_hero(caster_ptr, randint1(base) + base, FALSE);
570                                 set_blessed(caster_ptr, randint1(base) + base, FALSE);
571                                 set_fast(caster_ptr, randint1(sp_sides) + sp_base, FALSE);
572                                 set_protevil(caster_ptr, randint1(base) + base, FALSE);
573                                 set_afraid(caster_ptr, 0);
574                         }
575                 }
576                 break;
577         }
578
579         return "";
580 }
581