OSDN Git Service

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