OSDN Git Service

[Refactor] enum spells-typeをenum class AttributeTypeに置換
[hengbandforosx/hengbandosx.git] / src / realm / realm-chaos.cpp
1 #include "realm/realm-chaos.h"
2 #include "cmd-action/cmd-spell.h"
3 #include "core/asking-player.h"
4 #include "core/player-redraw-types.h"
5 #include "effect/effect-characteristics.h"
6 #include "effect/effect-processor.h"
7 #include "player-base/player-class.h"
8 #include "player/attack-defense-types.h"
9 #include "spell-kind/magic-item-recharger.h"
10 #include "spell-kind/spells-floor.h"
11 #include "spell-kind/spells-launcher.h"
12 #include "spell-kind/spells-lite.h"
13 #include "spell-kind/spells-neighbor.h"
14 #include "spell-kind/spells-random.h"
15 #include "spell-kind/spells-teleport.h"
16 #include "spell-kind/spells-world.h"
17 #include "spell-realm/spells-chaos.h"
18 #include "effect/attribute-types.h"
19 #include "spell/spells-diceroll.h"
20 #include "spell/spells-object.h"
21 #include "spell/spells-status.h"
22 #include "spell/spells-summon.h"
23 #include "status/shape-changer.h"
24 #include "system/player-type-definition.h"
25 #include "target/target-getter.h"
26 #include "view/display-messages.h"
27
28 /*!
29  * @brief カオス領域魔法の各処理を行う
30  * @param player_ptr プレイヤーへの参照ポインタ
31  * @param spell 魔法ID
32  * @param mode 処理内容 (SpellProcessType::NAME / SPELL_DESC / SpellProcessType::INFO / SpellProcessType::CAST)
33  * @return SpellProcessType::NAME / SPELL_DESC / SpellProcessType::INFO 時には文字列ポインタを返す。SpellProcessType::CAST時はnullptr文字列を返す。
34  */
35 concptr do_chaos_spell(player_type *player_ptr, SPELL_IDX spell, SpellProcessType mode)
36 {
37     bool name = mode == SpellProcessType::NAME;
38     bool desc = mode == SpellProcessType::DESCRIPTION;
39     bool info = mode == SpellProcessType::INFO;
40     bool cast = mode == SpellProcessType::CAST;
41
42     DIRECTION dir;
43     PLAYER_LEVEL plev = player_ptr->lev;
44
45     switch (spell) {
46     case 0:
47         if (name)
48             return _("マジック・ミサイル", "Magic Missile");
49         if (desc)
50             return _("弱い魔法の矢を放つ。", "Fires a weak bolt of magic.");
51
52         {
53             DICE_NUMBER dice = 3 + ((plev - 1) / 5);
54             DICE_SID sides = 4;
55
56             if (info)
57                 return info_damage(dice, sides, 0);
58
59             if (cast) {
60                 if (!get_aim_dir(player_ptr, &dir))
61                     return nullptr;
62
63                 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr) - 10, AttributeType::MISSILE, dir, damroll(dice, sides));
64             }
65         }
66         break;
67
68     case 1:
69         if (name)
70             return _("トラップ/ドア破壊", "Trap / Door Destruction");
71         if (desc)
72             return _("隣接する罠と扉を破壊する。", "Destroys all doors and traps in adjacent squares.");
73
74         {
75             POSITION rad = 1;
76
77             if (info)
78                 return info_radius(rad);
79
80             if (cast) {
81                 destroy_doors_touch(player_ptr);
82             }
83         }
84         break;
85
86     case 2:
87         if (name)
88             return _("閃光", "Flash of Light");
89         if (desc)
90             return _("光源が照らしている範囲か部屋全体を永久に明るくする。", "Lights up nearby area and the inside of a room permanently.");
91
92         {
93             DICE_NUMBER dice = 2;
94             DICE_SID sides = plev / 2;
95             POSITION rad = (plev / 10) + 1;
96
97             if (info)
98                 return info_damage(dice, sides, 0);
99
100             if (cast) {
101                 lite_area(player_ptr, damroll(dice, sides), rad);
102             }
103         }
104         break;
105
106     case 3:
107         if (name)
108             return _("混乱の手", "Touch of Confusion");
109         if (desc)
110             return _("相手を混乱させる攻撃をできるようにする。", "Attempts to confuse the next monster that you hit.");
111
112         {
113             if (cast) {
114                 if (!(player_ptr->special_attack & ATTACK_CONFUSE)) {
115                     msg_print(_("あなたの手は光り始めた。", "Your hands start glowing."));
116                     player_ptr->special_attack |= ATTACK_CONFUSE;
117                     player_ptr->redraw |= (PR_STATUS);
118                 }
119             }
120         }
121         break;
122
123     case 4:
124         if (name)
125             return _("魔力炸裂", "Mana Burst");
126         if (desc)
127             return _("魔法の球を放つ。", "Fires a ball of magic.");
128
129         {
130             DICE_NUMBER dice = 3;
131             DICE_SID sides = 5;
132             POSITION rad = (plev < 30) ? 2 : 3;
133             int base;
134
135             if (PlayerClass(player_ptr).is_wizard())
136                 base = plev + plev / 2;
137             else
138                 base = plev + plev / 4;
139
140             if (info)
141                 return info_damage(dice, sides, base);
142
143             if (cast) {
144                 if (!get_aim_dir(player_ptr, &dir))
145                     return nullptr;
146
147                 fire_ball(player_ptr, AttributeType::MISSILE, dir, damroll(dice, sides) + base, rad);
148
149                 /*
150                  * Shouldn't actually use MANA, as
151                  * it will destroy all items on the
152                  * floor
153                  */
154             }
155         }
156         break;
157
158     case 5:
159         if (name)
160             return _("ファイア・ボルト", "Fire Bolt");
161         if (desc)
162             return _("炎のボルトもしくはビームを放つ。", "Fires a bolt or beam of fire.");
163
164         {
165             DICE_NUMBER dice = 8 + (plev - 5) / 4;
166             DICE_SID sides = 8;
167
168             if (info)
169                 return info_damage(dice, sides, 0);
170
171             if (cast) {
172                 if (!get_aim_dir(player_ptr, &dir))
173                     return nullptr;
174
175                 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr), AttributeType::FIRE, dir, damroll(dice, sides));
176             }
177         }
178         break;
179
180     case 6:
181         if (name)
182             return _("力の拳", "Fist of Force");
183         if (desc)
184             return _("ごく小さな分解の球を放つ。", "Fires a tiny ball of disintegration.");
185
186         {
187             DICE_NUMBER dice = 8 + ((plev - 5) / 4);
188             DICE_SID sides = 8;
189
190             if (info)
191                 return info_damage(dice, sides, 0);
192
193             if (cast) {
194                 if (!get_aim_dir(player_ptr, &dir))
195                     return nullptr;
196
197                 fire_ball(player_ptr, AttributeType::DISINTEGRATE, dir, damroll(dice, sides), 0);
198             }
199         }
200         break;
201
202     case 7:
203         if (name)
204             return _("テレポート", "Teleport Self");
205         if (desc)
206             return _("遠距離のテレポートをする。", "Teleports you a long distance.");
207
208         {
209             POSITION range = plev * 5;
210
211             if (info)
212                 return info_range(range);
213
214             if (cast) {
215                 teleport_player(player_ptr, range, TELEPORT_SPONTANEOUS);
216             }
217         }
218         break;
219
220     case 8:
221         if (name)
222             return _("ワンダー", "Wonder");
223         if (desc)
224             return _("モンスターにランダムな効果を与える。", "Fires something with random effects.");
225
226         {
227             if (info)
228                 return KWD_RANDOM;
229
230             if (cast) {
231
232                 if (!get_aim_dir(player_ptr, &dir))
233                     return nullptr;
234
235                 cast_wonder(player_ptr, dir);
236             }
237         }
238         break;
239
240     case 9:
241         if (name)
242             return _("カオス・ボルト", "Chaos Bolt");
243         if (desc)
244             return _("カオスのボルトもしくはビームを放つ。", "Fires a bolt or ball of chaos.");
245
246         {
247             DICE_NUMBER dice = 10 + (plev - 5) / 4;
248             DICE_SID sides = 8;
249
250             if (info)
251                 return info_damage(dice, sides, 0);
252
253             if (cast) {
254                 if (!get_aim_dir(player_ptr, &dir))
255                     return nullptr;
256
257                 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr), AttributeType::CHAOS, dir, damroll(dice, sides));
258             }
259         }
260         break;
261
262     case 10:
263         if (name)
264             return _("ソニック・ブーム", "Sonic Boom");
265         if (desc)
266             return _("自分を中心とした轟音の球を発生させる。", "Generates a ball of sound centered on you.");
267
268         {
269             HIT_POINT dam = 60 + plev;
270             POSITION rad = plev / 10 + 2;
271
272             if (info)
273                 return info_damage(0, 0, dam / 2);
274
275             if (cast) {
276                 msg_print(_("ドーン!部屋が揺れた!", "BOOM! Shake the room!"));
277                 project(player_ptr, 0, rad, player_ptr->y, player_ptr->x, dam, AttributeType::SOUND, PROJECT_KILL | PROJECT_ITEM);
278             }
279         }
280         break;
281
282     case 11:
283         if (name)
284             return _("破滅の矢", "Doom Bolt");
285         if (desc)
286             return _("純粋な魔力のビームを放つ。", "Fires a beam of pure mana.");
287
288         {
289             DICE_NUMBER dice = 11 + (plev - 5) / 4;
290             DICE_SID sides = 8;
291
292             if (info)
293                 return info_damage(dice, sides, 0);
294
295             if (cast) {
296                 if (!get_aim_dir(player_ptr, &dir))
297                     return nullptr;
298
299                 fire_beam(player_ptr, AttributeType::MANA, dir, damroll(dice, sides));
300             }
301         }
302         break;
303
304     case 12:
305         if (name)
306             return _("ファイア・ボール", "Fire Ball");
307         if (desc)
308             return _("炎の球を放つ。", "Fires a ball of fire.");
309
310         {
311             HIT_POINT dam = plev + 55;
312             POSITION rad = 2;
313
314             if (info)
315                 return info_damage(0, 0, dam);
316
317             if (cast) {
318                 if (!get_aim_dir(player_ptr, &dir))
319                     return nullptr;
320
321                 fire_ball(player_ptr, AttributeType::FIRE, dir, dam, rad);
322             }
323         }
324         break;
325
326     case 13:
327         if (name)
328             return _("テレポート・アウェイ", "Teleport Other");
329         if (desc)
330             return _("モンスターをテレポートさせるビームを放つ。抵抗されると無効。", "Teleports all monsters on the line away unless resisted.");
331
332         {
333             int power = plev;
334
335             if (info)
336                 return info_power(power);
337
338             if (cast) {
339                 if (!get_aim_dir(player_ptr, &dir))
340                     return nullptr;
341
342                 fire_beam(player_ptr, AttributeType::AWAY_ALL, dir, power);
343             }
344         }
345         break;
346
347     case 14:
348         if (name)
349             return _("破壊の言葉", "Word of Destruction");
350         if (desc)
351             return _("周辺のアイテム、モンスター、地形を破壊する。", "Destroys everything in nearby area.");
352
353         {
354             int base = 12;
355             DICE_SID sides = 4;
356
357             if (cast) {
358                 destroy_area(player_ptr, player_ptr->y, player_ptr->x, base + randint1(sides), false);
359             }
360         }
361         break;
362
363     case 15:
364         if (name)
365             return _("ログルス発動", "Invoke Logrus");
366         if (desc)
367             return _("巨大なカオスの球を放つ。", "Fires a huge ball of chaos.");
368
369         {
370             HIT_POINT dam = plev * 2 + 99;
371             POSITION rad = plev / 5;
372
373             if (info)
374                 return info_damage(0, 0, dam);
375
376             if (cast) {
377                 if (!get_aim_dir(player_ptr, &dir))
378                     return nullptr;
379
380                 fire_ball(player_ptr, AttributeType::CHAOS, dir, dam, rad);
381             }
382         }
383         break;
384
385     case 16:
386         if (name)
387             return _("他者変容", "Polymorph Other");
388         if (desc)
389             return _("モンスター1体を変身させる。抵抗されると無効。", "Attempts to polymorph a monster.");
390
391         {
392             int power = plev;
393
394             if (info)
395                 return info_power(power);
396
397             if (cast) {
398                 if (!get_aim_dir(player_ptr, &dir))
399                     return nullptr;
400
401                 poly_monster(player_ptr, dir, plev);
402             }
403         }
404         break;
405
406     case 17:
407         if (name)
408             return _("連鎖稲妻", "Chain Lightning");
409         if (desc)
410             return _("全方向に対して電撃のビームを放つ。", "Fires lightning beams in all directions.");
411
412         {
413             DICE_NUMBER dice = 5 + plev / 10;
414             DICE_SID sides = 8;
415
416             if (info)
417                 return info_damage(dice, sides, 0);
418
419             if (cast) {
420                 for (dir = 0; dir <= 9; dir++)
421                     fire_beam(player_ptr, AttributeType::ELEC, dir, damroll(dice, sides));
422             }
423         }
424         break;
425
426     case 18:
427         if (name)
428             return _("魔力封入", "Arcane Binding");
429         if (desc)
430             return _("杖/魔法棒の充填回数を増やすか、充填中のロッドの充填時間を減らす。", "Recharges staffs, wands or rods.");
431
432         {
433             int power = 90;
434
435             if (info)
436                 return info_power(power);
437             if (cast) {
438                 if (!recharge(player_ptr, power))
439                     return nullptr;
440             }
441         }
442         break;
443
444     case 19:
445         if (name)
446             return _("原子分解", "Disintegrate");
447         if (desc)
448             return _("巨大な分解の球を放つ。", "Fires a huge ball of disintegration.");
449
450         {
451             HIT_POINT dam = plev + 70;
452             POSITION rad = 3 + plev / 40;
453
454             if (info)
455                 return info_damage(0, 0, dam);
456
457             if (cast) {
458                 if (!get_aim_dir(player_ptr, &dir))
459                     return nullptr;
460
461                 fire_ball(player_ptr, AttributeType::DISINTEGRATE, dir, dam, rad);
462             }
463         }
464         break;
465
466     case 20:
467         if (name)
468             return _("現実変容", "Alter Reality");
469         if (desc)
470             return _("現在の階を再構成する。", "Recreates current dungeon level.");
471
472         {
473             int base = 15;
474             DICE_SID sides = 20;
475
476             if (info)
477                 return info_delay(base, sides);
478
479             if (cast) {
480                 reserve_alter_reality(player_ptr, randint0(sides) + base);
481             }
482         }
483         break;
484
485     case 21:
486         if (name)
487             return _("マジック・ロケット", "Magic Rocket");
488         if (desc)
489             return _("ロケットを発射する。", "Fires a magic rocket.");
490
491         {
492             HIT_POINT dam = 120 + plev * 2;
493             POSITION rad = 2;
494
495             if (info)
496                 return info_damage(0, 0, dam);
497
498             if (cast) {
499                 if (!get_aim_dir(player_ptr, &dir))
500                     return nullptr;
501
502                 msg_print(_("ロケット発射!", "You launch a rocket!"));
503                 fire_rocket(player_ptr, AttributeType::ROCKET, dir, dam, rad);
504             }
505         }
506         break;
507
508     case 22:
509         if (name)
510             return _("混沌の刃", "Chaos Branding");
511         if (desc)
512             return _("武器にカオスの属性をつける。", "Makes current weapon a Chaotic weapon.");
513
514         {
515             if (cast) {
516                 brand_weapon(player_ptr, 2);
517             }
518         }
519         break;
520
521     case 23:
522         if (name)
523             return _("悪魔召喚", "Summon Demon");
524         if (desc)
525             return _("悪魔を1体召喚する。", "Summons a demon.");
526
527         {
528             if (cast) {
529                 cast_summon_demon(player_ptr, (plev * 3) / 2);
530             }
531         }
532         break;
533
534     case 24:
535         if (name)
536             return _("重力光線", "Beam of Gravity");
537         if (desc)
538             return _("重力のビームを放つ。", "Fires a beam of gravity.");
539
540         {
541             DICE_NUMBER dice = 9 + (plev - 5) / 4;
542             DICE_SID sides = 8;
543
544             if (info)
545                 return info_damage(dice, sides, 0);
546
547             if (cast) {
548                 if (!get_aim_dir(player_ptr, &dir))
549                     return nullptr;
550                 fire_beam(player_ptr, AttributeType::GRAVITY, dir, damroll(dice, sides));
551             }
552         }
553         break;
554
555     case 25:
556         if (name)
557             return _("流星群", "Meteor Swarm");
558         if (desc)
559             return _("自分の周辺に隕石を落とす。", "Causes meteorites to fall down on nearby random locations.");
560
561         {
562             HIT_POINT dam = plev * 2;
563             POSITION rad = 2;
564
565             if (info)
566                 return info_multi_damage(dam);
567
568             if (cast) {
569                 cast_meteor(player_ptr, dam, rad);
570             }
571         }
572         break;
573
574     case 26:
575         if (name)
576             return _("焔の一撃", "Flame Strike");
577         if (desc)
578             return _("自分を中心とした超巨大な炎の球を発生させる。", "Generates a huge ball of fire centered on you.");
579
580         {
581             HIT_POINT dam = 300 + 3 * plev;
582             POSITION rad = 8;
583
584             if (info)
585                 return info_damage(0, 0, dam / 2);
586
587             if (cast) {
588                 fire_ball(player_ptr, AttributeType::FIRE, 0, dam, rad);
589             }
590         }
591         break;
592
593     case 27:
594         if (name)
595             return _("混沌召来", "Call Chaos");
596         if (desc)
597             return _("ランダムな属性の球やビームを発生させる。", "Generates random kinds of balls or beams.");
598
599         {
600             if (info)
601                 return format("%s150 / 250", KWD_DAM);
602
603             if (cast) {
604                 call_chaos(player_ptr);
605             }
606         }
607         break;
608
609     case 28:
610         if (name)
611             return _("自己変容", "Polymorph Self");
612         if (desc)
613             return _("自分を変身させようとする。", "Polymorphs yourself.");
614
615         {
616             if (cast) {
617                 if (!get_check(_("変身します。よろしいですか?", "You will polymorph yourself. Are you sure? ")))
618                     return nullptr;
619                 do_poly_self(player_ptr);
620             }
621         }
622         break;
623
624     case 29:
625         if (name)
626             return _("魔力の嵐", "Mana Storm");
627         if (desc)
628             return _("非常に強力で巨大な純粋な魔力の球を放つ。", "Fires an extremely powerful huge ball of pure mana.");
629
630         {
631             HIT_POINT dam = 300 + plev * 4;
632             POSITION rad = 4;
633
634             if (info)
635                 return info_damage(0, 0, dam);
636
637             if (cast) {
638                 if (!get_aim_dir(player_ptr, &dir))
639                     return nullptr;
640                 fire_ball(player_ptr, AttributeType::MANA, dir, dam, rad);
641             }
642         }
643         break;
644
645     case 30:
646         if (name)
647             return _("ログルスのブレス", "Breathe Logrus");
648         if (desc)
649             return _("非常に強力なカオスの球を放つ。", "Fires an extremely powerful ball of chaos.");
650
651         {
652             HIT_POINT dam = player_ptr->chp;
653             POSITION rad = 2;
654
655             if (info)
656                 return info_damage(0, 0, dam);
657
658             if (cast) {
659                 if (!get_aim_dir(player_ptr, &dir))
660                     return nullptr;
661
662                 fire_ball(player_ptr, AttributeType::CHAOS, dir, dam, rad);
663             }
664         }
665         break;
666
667     case 31:
668         if (name)
669             return _("虚無召来", "Call the Void");
670         if (desc)
671             return _("自分の周囲に向かって、ロケット、純粋な魔力の球、放射性廃棄物の球を放つ。ただし、壁に隣接して使用すると広範囲を破壊する。",
672                 "Fires rockets, mana balls and nuclear waste balls in all directions if you are not adjacent to any walls. Otherwise *destroys* huge area.");
673         {
674             if (info)
675                 return format("%s3 * 175", KWD_DAM);
676
677             if (cast) {
678                 call_the_void(player_ptr);
679             }
680         }
681         break;
682     }
683
684     return "";
685 }