OSDN Git Service

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