OSDN Git Service

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