OSDN Git Service

[Refactor] #37353 IS_WIZARD_CLASS() を player-class.h へ移動.
[hengband/hengband.git] / src / realm-death.c
1 #include "angband.h"
2 #include "cmd-spell.h"
3 #include "spells.h"
4 #include "spells-summon.h"
5 #include "spells-status.h"
6 #include "avatar.h"
7 #include "player-status.h"
8 #include "player-effects.h"
9 #include "targeting.h"
10 #include "player-class.h"
11
12 /*!
13 * @brief 暗黒領域魔法の各処理を行う
14 * @param spell 魔法ID
15 * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_INFO / SPELL_CAST)
16 * @return SPELL_NAME / SPELL_DESC / SPELL_INFO 時には文字列ポインタを返す。SPELL_CAST時はNULL文字列を返す。
17 */
18 concptr do_death_spell(SPELL_IDX spell, BIT_FLAGS mode)
19 {
20         bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
21         bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
22         bool info = (mode == SPELL_INFO) ? TRUE : FALSE;
23         bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
24
25         DIRECTION dir;
26         PLAYER_LEVEL plev = p_ptr->lev;
27
28         switch (spell)
29         {
30         case 0:
31                 if (name) return _("無生命感知", "Detect Unlife");
32                 if (desc) return _("近くの生命のないモンスターを感知する。", "Detects all nonliving monsters in your vicinity.");
33
34                 {
35                         POSITION rad = DETECT_RAD_DEFAULT;
36
37                         if (info) return info_radius(rad);
38
39                         if (cast)
40                         {
41                                 detect_monsters_nonliving(rad);
42                         }
43                 }
44                 break;
45
46         case 1:
47                 if (name) return _("呪殺弾", "Malediction");
48                 if (desc) return _("ごく小さな邪悪な力を持つボールを放つ。善良なモンスターには大きなダメージを与える。",
49                         "Fires a tiny ball of evil power which hurts good monsters greatly.");
50
51                 {
52                         DICE_NUMBER dice = 3 + (plev - 1) / 5;
53                         DICE_SID sides = 4;
54                         POSITION rad = 0;
55
56                         if (info) return info_damage(dice, sides, 0);
57
58                         if (cast)
59                         {
60                                 if (!get_aim_dir(&dir)) return NULL;
61
62                                 /*
63                                 * A radius-0 ball may (1) be aimed at
64                                 * objects etc., and will affect them;
65                                 * (2) may be aimed at ANY visible
66                                 * monster, unlike a 'bolt' which must
67                                 * travel to the monster.
68                                 */
69
70                                 fire_ball(GF_HELL_FIRE, dir, damroll(dice, sides), rad);
71
72                                 if (one_in_(5))
73                                 {
74                                         /* Special effect first */
75                                         int effect = randint1(1000);
76
77                                         if (effect == 666)
78                                                 fire_ball_hide(GF_DEATH_RAY, dir, plev * 200, 0);
79                                         else if (effect < 500)
80                                                 fire_ball_hide(GF_TURN_ALL, dir, plev, 0);
81                                         else if (effect < 800)
82                                                 fire_ball_hide(GF_OLD_CONF, dir, plev, 0);
83                                         else
84                                                 fire_ball_hide(GF_STUN, dir, plev, 0);
85                                 }
86                         }
87                 }
88                 break;
89
90         case 2:
91                 if (name) return _("邪悪感知", "Detect Evil");
92                 if (desc) return _("近くの邪悪なモンスターを感知する。", "Detects all evil monsters in your vicinity.");
93
94                 {
95                         POSITION rad = DETECT_RAD_DEFAULT;
96
97                         if (info) return info_radius(rad);
98
99                         if (cast)
100                         {
101                                 detect_monsters_evil(rad);
102                         }
103                 }
104                 break;
105
106         case 3:
107                 if (name) return _("悪臭雲", "Stinking Cloud");
108                 if (desc) return _("毒の球を放つ。", "Fires a ball of poison.");
109
110                 {
111                         HIT_POINT dam = 10 + plev / 2;
112                         POSITION rad = 2;
113
114                         if (info) return info_damage(0, 0, dam);
115
116                         if (cast)
117                         {
118                                 if (!get_aim_dir(&dir)) return NULL;
119
120                                 fire_ball(GF_POIS, dir, dam, rad);
121                         }
122                 }
123                 break;
124
125         case 4:
126                 if (name) return _("黒い眠り", "Black Sleep");
127                 if (desc) return _("1体のモンスターを眠らせる。抵抗されると無効。", "Attempts to sleep a monster.");
128
129                 {
130                         int power = plev;
131
132                         if (info) return info_power(power);
133
134                         if (cast)
135                         {
136                                 if (!get_aim_dir(&dir)) return NULL;
137
138                                 sleep_monster(dir, plev);
139                         }
140                 }
141                 break;
142
143         case 5:
144                 if (name) return _("耐毒", "Resist Poison");
145                 if (desc) return _("一定時間、毒への耐性を得る。装備による耐性に累積する。",
146                         "Gives resistance to poison. This resistance can be added to which from equipment for more powerful resistance.");
147
148                 {
149                         int base = 20;
150
151                         if (info) return info_duration(base, base);
152
153                         if (cast)
154                         {
155                                 set_oppose_pois(randint1(base) + base, FALSE);
156                         }
157                 }
158                 break;
159
160         case 6:
161                 if (name) return _("恐慌", "Horrify");
162                 if (desc) return _("モンスター1体を恐怖させ、朦朧させる。抵抗されると無効。", "Attempts to scare and stun a monster.");
163
164                 {
165                         int power = plev;
166
167                         if (info) return info_power(power);
168
169                         if (cast)
170                         {
171                                 if (!get_aim_dir(&dir)) return NULL;
172
173                                 fear_monster(dir, plev);
174                                 stun_monster(dir, plev);
175                         }
176                 }
177                 break;
178
179         case 7:
180                 if (name) return _("アンデッド従属", "Enslave Undead");
181                 if (desc) return _("アンデッド1体を魅了する。抵抗されると無効。", "Attempts to charm an undead monster.");
182
183                 {
184                         int power = plev;
185
186                         if (info) return info_power(power);
187
188                         if (cast)
189                         {
190                                 if (!get_aim_dir(&dir)) return NULL;
191
192                                 control_one_undead(dir, plev);
193                         }
194                 }
195                 break;
196
197         case 8:
198                 if (name) return _("エントロピーの球", "Orb of Entropy");
199                 if (desc) return _("生命のある者のHPと最大HP双方にダメージを与える効果のある球を放つ。", "Fires a ball which damages to both HP and MaxHP of living monsters.");
200
201                 {
202                         DICE_NUMBER dice = 3;
203                         DICE_SID sides = 6;
204                         POSITION rad = (plev < 30) ? 2 : 3;
205                         int base;
206
207                         if (IS_WIZARD_CLASS())
208                                 base = plev + plev / 2;
209                         else
210                                 base = plev + plev / 4;
211
212
213                         if (info) return info_damage(dice, sides, base);
214
215                         if (cast)
216                         {
217                                 if (!get_aim_dir(&dir)) return NULL;
218
219                                 fire_ball(GF_HYPODYNAMIA, dir, damroll(dice, sides) + base, rad);
220                         }
221                 }
222                 break;
223
224         case 9:
225                 if (name) return _("地獄の矢", "Nether Bolt");
226                 if (desc) return _("地獄のボルトもしくはビームを放つ。", "Fires a bolt or beam of nether.");
227
228                 {
229                         DICE_NUMBER dice = 8 + (plev - 5) / 4;
230                         DICE_SID sides = 8;
231
232                         if (info) return info_damage(dice, sides, 0);
233
234                         if (cast)
235                         {
236                                 if (!get_aim_dir(&dir)) return NULL;
237
238                                 fire_bolt_or_beam(beam_chance(), GF_NETHER, dir, damroll(dice, sides));
239                         }
240                 }
241                 break;
242
243         case 10:
244                 if (name) return _("殺戮雲", "Cloud kill");
245                 if (desc) return _("自分を中心とした毒の球を発生させる。", "Generate a ball of poison centered on you.");
246
247                 {
248                         HIT_POINT dam = (30 + plev) * 2;
249                         POSITION rad = plev / 10 + 2;
250
251                         if (info) return info_damage(0, 0, dam / 2);
252
253                         if (cast)
254                         {
255                                 project(0, rad, p_ptr->y, p_ptr->x, dam, GF_POIS, PROJECT_KILL | PROJECT_ITEM, -1);
256                         }
257                 }
258                 break;
259
260         case 11:
261                 if (name) return _("モンスター消滅", "Genocide One");
262                 if (desc) return _("モンスター1体を消し去る。経験値やアイテムは手に入らない。抵抗されると無効。", "Attempts to vanish a monster.");
263
264                 {
265                         int power = plev + 50;
266
267                         if (info) return info_power(power);
268
269                         if (cast)
270                         {
271                                 if (!get_aim_dir(&dir)) return NULL;
272
273                                 fire_ball_hide(GF_GENOCIDE, dir, power, 0);
274                         }
275                 }
276                 break;
277
278         case 12:
279                 if (name) return _("毒の刃", "Poison Branding");
280                 if (desc) return _("武器に毒の属性をつける。", "Makes current weapon poison branded.");
281
282                 {
283                         if (cast)
284                         {
285                                 brand_weapon(3);
286                         }
287                 }
288                 break;
289
290         case 13:
291                 if (name) return _("吸血の矢", "Vampiric Bolt");
292                 if (desc) return _("ボルトによりモンスター1体から生命力を吸いとる。吸いとった生命力によって満腹度が上がる。",
293                         "Absorbs some HP from a monster and gives them to you by bolt. You will also gain nutritional sustenance from this.");
294
295                 {
296                         DICE_NUMBER dice = 1;
297                         DICE_SID sides = plev * 2;
298                         int base = plev * 2;
299
300                         if (info) return info_damage(dice, sides, base);
301
302                         if (cast)
303                         {
304                                 HIT_POINT dam = base + damroll(dice, sides);
305
306                                 if (!get_aim_dir(&dir)) return NULL;
307
308                                 if (hypodynamic_bolt(dir, dam))
309                                 {
310                                         chg_virtue(V_SACRIFICE, -1);
311                                         chg_virtue(V_VITALITY, -1);
312
313                                         hp_player(dam);
314
315                                         /*
316                                         * Gain nutritional sustenance:
317                                         * 150/hp drained
318                                         *
319                                         * A Food ration gives 5000
320                                         * food points (by contrast)
321                                         * Don't ever get more than
322                                         * "Full" this way But if we
323                                         * ARE Gorged, it won't cure
324                                         * us
325                                         */
326                                         dam = p_ptr->food + MIN(5000, 100 * dam);
327
328                                         /* Not gorged already */
329                                         if (p_ptr->food < PY_FOOD_MAX)
330                                                 set_food(dam >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dam);
331                                 }
332                         }
333                 }
334                 break;
335
336         case 14:
337                 if (name) return _("反魂の術", "Animate dead");
338                 if (desc) return _("周囲の死体や骨を生き返す。", "Resurrects nearby corpse and skeletons. And makes these your pets.");
339
340                 {
341                         if (cast)
342                         {
343                                 animate_dead(0, p_ptr->y, p_ptr->x);
344                         }
345                 }
346                 break;
347
348         case 15:
349                 if (name) return _("抹殺", "Genocide");
350                 if (desc) return _("指定した文字のモンスターを現在の階から消し去る。抵抗されると無効。",
351                         "Eliminates an entire class of monster, exhausting you.  Powerful or unique monsters may resist.");
352
353                 {
354                         int power = plev + 50;
355
356                         if (info) return info_power(power);
357
358                         if (cast)
359                         {
360                                 symbol_genocide(power, TRUE);
361                         }
362                 }
363                 break;
364
365         case 16:
366                 if (name) return _("狂戦士化", "Berserk");
367                 if (desc) return _("狂戦士化し、恐怖を除去する。", "Gives bonus to hit and HP, immunity to fear for a while. But decreases AC.");
368
369                 {
370                         int base = 25;
371
372                         if (info) return info_duration(base, base);
373
374                         if (cast)
375                         {
376                                 (void)berserk(base + randint1(base));
377                         }
378                 }
379                 break;
380
381         case 17:
382                 if (name) return _("悪霊召喚", "Invoke Spirits");
383                 if (desc) return _("ランダムで様々な効果が起こる。", "Causes random effects.");
384
385                 {
386                         if (info) return KWD_RANDOM;
387
388                         if (cast)
389                         {
390                                 if (!get_aim_dir(&dir)) return NULL;
391
392                                 cast_invoke_spirits(dir);
393                         }
394                 }
395                 break;
396
397         case 18:
398                 if (name) return _("暗黒の矢", "Dark Bolt");
399                 if (desc) return _("暗黒のボルトもしくはビームを放つ。", "Fires a bolt or beam of darkness.");
400
401                 {
402                         DICE_NUMBER dice = 4 + (plev - 5) / 4;
403                         DICE_SID sides = 8;
404
405                         if (info) return info_damage(dice, sides, 0);
406
407                         if (cast)
408                         {
409                                 if (!get_aim_dir(&dir)) return NULL;
410
411                                 fire_bolt_or_beam(beam_chance(), GF_DARK, dir, damroll(dice, sides));
412                         }
413                 }
414                 break;
415
416         case 19:
417                 if (name) return _("狂乱戦士", "Battle Frenzy");
418                 if (desc) return _("狂戦士化し、恐怖を除去し、加速する。",
419                         "Gives another bonus to hit and HP, immunity to fear for a while. Hastes you. But decreases AC.");
420
421                 {
422                         int b_base = 25;
423                         int sp_base = plev / 2;
424                         int sp_sides = 20 + plev / 2;
425
426                         if (info) return info_duration(b_base, b_base);
427
428                         if (cast)
429                         {
430                                 (void)berserk(b_base + randint1(b_base));
431                                 set_fast(randint1(sp_sides) + sp_base, FALSE);
432                         }
433                 }
434                 break;
435
436         case 20:
437                 if (name) return _("吸血の刃", "Vampiric Branding");
438                 if (desc) return _("武器に吸血の属性をつける。", "Makes current weapon Vampiric.");
439
440                 {
441                         if (cast)
442                         {
443                                 brand_weapon(4);
444                         }
445                 }
446                 break;
447
448         case 21:
449                 if (name) return _("吸血の連矢", "Vampiric Bolts");
450                 if (desc) return _("3連射のボルトによりモンスター1体から生命力を吸いとる。吸いとった生命力によって体力が回復する。",
451                         "Fires 3 bolts. Each of the bolts absorbs some HP from a monster and gives them to you.");
452                 {
453                         HIT_POINT dam = 100;
454
455                         if (info) return format("%s3*%d", KWD_DAM, dam);
456
457                         if (cast)
458                         {
459                                 int i;
460
461                                 if (!get_aim_dir(&dir)) return NULL;
462
463                                 chg_virtue(V_SACRIFICE, -1);
464                                 chg_virtue(V_VITALITY, -1);
465
466                                 for (i = 0; i < 3; i++)
467                                 {
468                                         if (hypodynamic_bolt(dir, dam))
469                                                 hp_player(dam);
470                                 }
471                         }
472                 }
473                 break;
474
475         case 22:
476                 if (name) return _("死の言魂", "Nether Wave");
477                 if (desc) return _("視界内の生命のあるモンスターにダメージを与える。", "Damages all living monsters in sight.");
478
479                 {
480                         DICE_SID sides = plev * 3;
481
482                         if (info) return info_damage(1, sides, 0);
483
484                         if (cast)
485                         {
486                                 dispel_living(randint1(sides));
487                         }
488                 }
489                 break;
490
491         case 23:
492                 if (name) return _("暗黒の嵐", "Darkness Storm");
493                 if (desc) return _("巨大な暗黒の球を放つ。", "Fires a huge ball of darkness.");
494
495                 {
496                         HIT_POINT dam = 100 + plev * 2;
497                         POSITION rad = 4;
498
499                         if (info) return info_damage(0, 0, dam);
500
501                         if (cast)
502                         {
503                                 if (!get_aim_dir(&dir)) return NULL;
504
505                                 fire_ball(GF_DARK, dir, dam, rad);
506                         }
507                 }
508                 break;
509
510         case 24:
511                 if (name) return _("死の光線", "Death Ray");
512                 if (desc) return _("死の光線を放つ。", "Fires a beam of death.");
513
514                 {
515                         if (cast)
516                         {
517                                 if (!get_aim_dir(&dir)) return NULL;
518
519                                 death_ray(dir, plev);
520                         }
521                 }
522                 break;
523
524         case 25:
525                 if (name) return _("死者召喚", "Raise the Dead");
526                 if (desc) return _("1体のアンデッドを召喚する。", "Summons an undead monster.");
527                 if (cast) cast_summon_undead(p_ptr, (plev * 3) / 2);
528                 break;
529
530         case 26:
531                 if (name) return _("死者の秘伝", "Esoteria");
532                 if (desc) return _("アイテムを1つ識別する。レベルが高いとアイテムの能力を完全に知ることができる。",
533                         "Identifies an item. Or *identifies* an item at higher level.");
534
535                 {
536                         if (cast)
537                         {
538                                 if (randint1(50) > plev)
539                                 {
540                                         if (!ident_spell(FALSE)) return NULL;
541                                 }
542                                 else
543                                 {
544                                         if (!identify_fully(FALSE)) return NULL;
545                                 }
546                         }
547                 }
548                 break;
549
550         case 27:
551                 if (name) return _("吸血鬼変化", "Polymorph Vampire");
552                 if (desc) return _("一定時間、吸血鬼に変化する。変化している間は本来の種族の能力を失い、代わりに吸血鬼としての能力を得る。",
553                         "Mimic a vampire for a while. Loses abilities of original race and gets abilities as a vampire.");
554
555                 {
556                         int base = 10 + plev / 2;
557
558                         if (info) return info_duration(base, base);
559
560                         if (cast)
561                         {
562                                 set_mimic(base + randint1(base), MIMIC_VAMPIRE, FALSE);
563                         }
564                 }
565                 break;
566
567         case 28:
568                 if (name) return _("経験値復活", "Restore Life");
569                 if (desc) return _("失った経験値を回復する。", "Restore lost experience.");
570
571                 {
572                         if (cast)
573                         {
574                                 restore_level();
575                         }
576                 }
577                 break;
578
579         case 29:
580                 if (name) return _("周辺抹殺", "Mass Genocide");
581                 if (desc) return _("自分の周囲にいるモンスターを現在の階から消し去る。抵抗されると無効。",
582                         "Eliminates all nearby monsters, exhausting you.  Powerful or unique monsters may be able to resist.");
583
584                 {
585                         int power = plev + 50;
586
587                         if (info) return info_power(power);
588
589                         if (cast)
590                         {
591                                 mass_genocide(power, TRUE);
592                         }
593                 }
594                 break;
595
596         case 30:
597                 if (name) return _("地獄の劫火", "Hellfire");
598                 if (desc) return _("邪悪な力を持つ宝珠を放つ。善良なモンスターには大きなダメージを与える。",
599                         "Fires a powerful ball of evil power. Hurts good monsters greatly.");
600
601                 {
602                         HIT_POINT dam = 666;
603                         POSITION rad = 3;
604
605                         if (info) return info_damage(0, 0, dam);
606
607                         if (cast)
608                         {
609                                 if (!get_aim_dir(&dir)) return NULL;
610
611                                 fire_ball(GF_HELL_FIRE, dir, dam, rad);
612                                 take_hit(DAMAGE_USELIFE, 20 + randint1(30), _("地獄の劫火の呪文を唱えた疲労", "the strain of casting Hellfire"), -1);
613                         }
614                 }
615                 break;
616
617         case 31:
618                 if (name) return _("幽体化", "Wraithform");
619                 if (desc) return _("一定時間、壁を通り抜けることができ受けるダメージが軽減される幽体の状態に変身する。",
620                         "Becomes wraith form which gives ability to pass walls and makes all damages half.");
621
622                 {
623                         int base = plev / 2;
624
625                         if (info) return info_duration(base, base);
626
627                         if (cast)
628                         {
629                                 set_wraith_form(randint1(base) + base, FALSE);
630                         }
631                 }
632                 break;
633         }
634
635         return "";
636 }