OSDN Git Service

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