OSDN Git Service

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