OSDN Git Service

Merge pull request #1849 from dis-/feature/add-self-damage-equipment
[hengbandforosx/hengbandosx.git] / src / realm / realm-sorcery.cpp
1 #include "realm/realm-sorcery.h"
2 #include "avatar/avatar.h"
3 #include "cmd-action/cmd-spell.h"
4 #include "core/asking-player.h"
5 #include "player-info/self-info.h"
6 #include "spell-kind/magic-item-recharger.h"
7 #include "spell-kind/spells-charm.h"
8 #include "spell-kind/spells-detection.h"
9 #include "spell-kind/spells-fetcher.h"
10 #include "spell-kind/spells-floor.h"
11 #include "spell-kind/spells-grid.h"
12 #include "spell-kind/spells-launcher.h"
13 #include "spell-kind/spells-lite.h"
14 #include "spell-kind/spells-perception.h"
15 #include "spell-kind/spells-sight.h"
16 #include "spell-kind/spells-teleport.h"
17 #include "spell-kind/spells-world.h"
18 #include "spell-realm/spells-sorcery.h"
19 #include "spell/spell-types.h"
20 #include "spell/spells-status.h"
21 #include "status/body-improvement.h"
22 #include "status/buff-setter.h"
23 #include "status/sight-setter.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_sorcery_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 _("モンスター感知", "Detect Monsters");
49         if (desc)
50             return _("近くの全ての見えるモンスターを感知する。", "Detects all monsters in your vicinity unless invisible.");
51
52         {
53             POSITION rad = DETECT_RAD_DEFAULT;
54
55             if (info)
56                 return info_radius(rad);
57
58             if (cast) {
59                 detect_monsters_normal(player_ptr, rad);
60             }
61         }
62         break;
63
64     case 1:
65         if (name)
66             return _("ショート・テレポート", "Phase Door");
67         if (desc)
68             return _("近距離のテレポートをする。", "Teleports you a short distance.");
69
70         {
71             POSITION range = 10;
72
73             if (info)
74                 return info_range(range);
75
76             if (cast) {
77                 teleport_player(player_ptr, range, TELEPORT_SPONTANEOUS);
78             }
79         }
80         break;
81
82     case 2:
83         if (name)
84             return _("罠と扉感知", "Detect Doors and Traps");
85         if (desc)
86             return _("近くの全ての扉と罠を感知する。", "Detects traps, doors, and stairs in your vicinity.");
87
88         {
89             POSITION rad = DETECT_RAD_DEFAULT;
90
91             if (info)
92                 return info_radius(rad);
93
94             if (cast) {
95                 detect_traps(player_ptr, rad, true);
96                 detect_doors(player_ptr, rad);
97                 detect_stairs(player_ptr, rad);
98             }
99         }
100         break;
101
102     case 3:
103         if (name)
104             return _("ライト・エリア", "Light Area");
105         if (desc)
106             return _("光源が照らしている範囲か部屋全体を永久に明るくする。", "Lights up nearby area and the inside of a room permanently.");
107
108         {
109             DICE_NUMBER dice = 2;
110             DICE_SID sides = plev / 2;
111             POSITION rad = plev / 10 + 1;
112
113             if (info)
114                 return info_damage(dice, sides, 0);
115
116             if (cast) {
117                 lite_area(player_ptr, damroll(dice, sides), rad);
118             }
119         }
120         break;
121
122     case 4:
123         if (name)
124             return _("パニック・モンスター", "Confuse Monster");
125         if (desc)
126             return _("モンスター1体を混乱させる。抵抗されると無効。", "Attempts to confuse a monster.");
127
128         {
129             PLAYER_LEVEL power = (plev * 3) / 2;
130
131             if (info)
132                 return info_power(power);
133
134             if (cast) {
135                 if (!get_aim_dir(player_ptr, &dir))
136                     return nullptr;
137
138                 confuse_monster(player_ptr, dir, power);
139             }
140         }
141         break;
142
143     case 5:
144         if (name)
145             return _("テレポート", "Teleport");
146         if (desc)
147             return _("遠距離のテレポートをする。", "Teleports you a long distance.");
148
149         {
150             POSITION range = plev * 5;
151
152             if (info)
153                 return info_range(range);
154
155             if (cast) {
156                 teleport_player(player_ptr, range, TELEPORT_SPONTANEOUS);
157             }
158         }
159         break;
160
161     case 6:
162         if (name)
163             return _("スリープ・モンスター", "Sleep Monster");
164         if (desc)
165             return _("モンスター1体を眠らせる。抵抗されると無効。", "Attempts to put a monster to sleep.");
166
167         {
168             int power = plev;
169
170             if (info)
171                 return info_power(power);
172
173             if (cast) {
174                 if (!get_aim_dir(player_ptr, &dir))
175                     return nullptr;
176
177                 sleep_monster(player_ptr, dir, plev);
178             }
179         }
180         break;
181
182     case 7:
183         if (name)
184             return _("魔力充填", "Recharging");
185         if (desc)
186             return _("杖/魔法棒の充填回数を増やすか、充填中のロッドの充填時間を減らす。", "Recharges staffs, wands or rods.");
187
188         {
189             int power = plev * 4;
190
191             if (info)
192                 return info_power(power);
193
194             if (cast) {
195                 if (!recharge(player_ptr, power))
196                     return nullptr;
197             }
198         }
199         break;
200
201     case 8:
202         if (name)
203             return _("魔法の地図", "Magic Mapping");
204         if (desc)
205             return _("周辺の地形を感知する。", "Maps nearby area.");
206
207         {
208             POSITION rad = DETECT_RAD_MAP;
209
210             if (info)
211                 return info_radius(rad);
212
213             if (cast) {
214                 map_area(player_ptr, rad);
215             }
216         }
217         break;
218
219     case 9:
220         if (name)
221             return _("鑑定", "Identify");
222         if (desc)
223             return _("アイテムを識別する。", "Identifies an item.");
224
225         {
226             if (cast) {
227                 if (!ident_spell(player_ptr, false))
228                     return nullptr;
229             }
230         }
231         break;
232
233     case 10:
234         if (name)
235             return _("スロウ・モンスター", "Slow Monster");
236         if (desc)
237             return _("モンスター1体を減速させる。抵抗されると無効。", "Attempts to slow a monster.");
238
239         {
240             int power = plev;
241
242             if (info)
243                 return info_power(power);
244
245             if (cast) {
246                 if (!get_aim_dir(player_ptr, &dir))
247                     return nullptr;
248
249                 slow_monster(player_ptr, dir, plev);
250             }
251         }
252         break;
253
254     case 11:
255         if (name)
256             return _("周辺スリープ", "Mass Sleep");
257         if (desc)
258             return _("視界内の全てのモンスターを眠らせる。抵抗されると無効。", "Attempts to put all monsters in sight to sleep.");
259
260         {
261             int power = plev;
262
263             if (info)
264                 return info_power(power);
265
266             if (cast) {
267                 sleep_monsters(player_ptr, plev);
268             }
269         }
270         break;
271
272     case 12:
273         if (name)
274             return _("テレポート・モンスター", "Teleport Away");
275         if (desc)
276             return _("モンスターをテレポートさせるビームを放つ。抵抗されると無効。", "Teleports all monsters on the line away unless resisted.");
277
278         {
279             int power = plev;
280
281             if (info)
282                 return info_power(power);
283
284             if (cast) {
285                 if (!get_aim_dir(player_ptr, &dir))
286                     return nullptr;
287
288                 fire_beam(player_ptr, GF_AWAY_ALL, dir, power);
289             }
290         }
291         break;
292
293     case 13:
294         if (name)
295             return _("スピード", "Haste Self");
296         if (desc)
297             return _("一定時間、加速する。", "Hastes you for a while.");
298
299         {
300             int base = plev;
301             DICE_SID sides = 20 + plev;
302
303             if (info)
304                 return info_duration(base, sides);
305
306             if (cast) {
307                 set_fast(player_ptr, randint1(sides) + base, false);
308             }
309         }
310         break;
311
312     case 14:
313         if (name)
314             return _("真・感知", "Detection True");
315         if (desc)
316             return _("近くの全てのモンスター、罠、扉、階段、財宝、そしてアイテムを感知する。",
317                 "Detects all monsters, traps, doors, stairs, treasures and items in your vicinity.");
318
319         {
320             POSITION rad = DETECT_RAD_DEFAULT;
321
322             if (info)
323                 return info_radius(rad);
324
325             if (cast) {
326                 detect_all(player_ptr, rad);
327             }
328         }
329         break;
330
331     case 15:
332         if (name)
333             return _("真・鑑定", "Identify True");
334         if (desc)
335             return _("アイテムの持つ能力を完全に知る。", "*Identifies* an item.");
336
337         {
338             if (cast) {
339                 if (!identify_fully(player_ptr, false))
340                     return nullptr;
341             }
342         }
343         break;
344
345     case 16:
346         if (name)
347             return _("物体と財宝感知", "Detect items and Treasure");
348         if (desc)
349             return _("近くの全てのアイテムと財宝を感知する。", "Detects all treasures and items in your vicinity.");
350
351         {
352             POSITION rad = DETECT_RAD_DEFAULT;
353
354             if (info)
355                 return info_radius(rad);
356
357             if (cast) {
358                 detect_objects_normal(player_ptr, rad);
359                 detect_treasure(player_ptr, rad);
360                 detect_objects_gold(player_ptr, rad);
361             }
362         }
363         break;
364
365     case 17:
366         if (name)
367             return _("チャーム・モンスター", "Charm Monster");
368         if (desc)
369             return _("モンスター1体を魅了する。抵抗されると無効。", "Attempts to charm a monster.");
370
371         {
372             int power = plev;
373
374             if (info)
375                 return info_power(power);
376
377             if (cast) {
378                 if (!get_aim_dir(player_ptr, &dir))
379                     return nullptr;
380
381                 charm_monster(player_ptr, dir, plev);
382             }
383         }
384         break;
385
386     case 18:
387         if (name)
388             return _("精神感知", "Sense Minds");
389         if (desc)
390             return _("一定時間、テレパシー能力を得る。", "Gives telepathy for a while.");
391
392         {
393             int base = 25;
394             DICE_SID sides = 30;
395
396             if (info)
397                 return info_duration(base, sides);
398
399             if (cast) {
400                 set_tim_esp(player_ptr, randint1(sides) + base, false);
401             }
402         }
403         break;
404
405     case 19:
406         if (name)
407             return _("街移動", "Teleport to town");
408         if (desc)
409             return _("街へ移動する。地上にいるときしか使えない。", "Instantly teleports you to a town which you choose. Can only be used outdoors.");
410
411         {
412             if (cast) {
413                 if (!tele_town(player_ptr))
414                     return nullptr;
415             }
416         }
417         break;
418
419     case 20:
420         if (name)
421             return _("自己分析", "Self Knowledge");
422         if (desc)
423             return _("現在の自分の状態を完全に知る。",
424                 "Gives you useful info regarding your current resistances, the powers of your weapon and maximum limits of your stats.");
425
426         {
427             if (cast) {
428                 self_knowledge(player_ptr);
429             }
430         }
431         break;
432
433     case 21:
434         if (name)
435             return _("テレポート・レベル", "Teleport Level");
436         if (desc)
437             return _("瞬時に上か下の階にテレポートする。", "Instantly teleports you up or down a level.");
438
439         {
440             if (cast) {
441                 if (!get_check(_("本当に他の階にテレポートしますか?", "Are you sure? (Teleport Level)")))
442                     return nullptr;
443                 teleport_level(player_ptr, 0);
444             }
445         }
446         break;
447
448     case 22:
449         if (name)
450             return _("帰還の呪文", "Word of Recall");
451         if (desc)
452             return _("地上にいるときはダンジョンの最深階へ、ダンジョンにいるときは地上へと移動する。",
453                 "Recalls player from dungeon to town or from town to the deepest level of dungeon.");
454
455         {
456             int base = 15;
457             DICE_SID sides = 20;
458
459             if (info)
460                 return info_delay(base, sides);
461
462             if (cast) {
463                 if (!recall_player(player_ptr, randint0(21) + 15))
464                     return nullptr;
465             }
466         }
467         break;
468
469     case 23:
470         if (name)
471             return _("次元の扉", "Dimension Door");
472         if (desc)
473             return _("短距離内の指定した場所にテレポートする。", "Teleports you to a given location.");
474
475         {
476             POSITION range = plev / 2 + 10;
477
478             if (info)
479                 return info_range(range);
480
481             if (cast) {
482                 msg_print(_("次元の扉が開いた。目的地を選んで下さい。", "You open a dimensional gate. Choose a destination."));
483                 if (!dimension_door(player_ptr))
484                     return nullptr;
485             }
486         }
487         break;
488
489     case 24:
490         if (name)
491             return _("調査", "Probing");
492         if (desc)
493             return _("モンスターの属性、残り体力、最大体力、スピード、正体を知る。", "Probes all monsters' alignment, HP, speed and their true character.");
494
495         {
496             if (cast) {
497                 probing(player_ptr);
498             }
499         }
500         break;
501
502     case 25:
503         if (name)
504             return _("爆発のルーン", "Explosive Rune");
505         if (desc)
506             return _("自分のいる床の上に、モンスターが通ると爆発してダメージを与えるルーンを描く。",
507                 "Sets a rune under you. The rune will explode when a monster moves on it.");
508
509         {
510             DICE_NUMBER dice = 7;
511             DICE_SID sides = 7;
512             int base = plev;
513
514             if (info)
515                 return info_damage(dice, sides, base);
516
517             if (cast) {
518                 create_rune_explosion(player_ptr, player_ptr->y, player_ptr->x);
519             }
520         }
521         break;
522
523     case 26:
524         if (name)
525             return _("念動力", "Telekinesis");
526         if (desc)
527             return _("アイテムを自分の足元へ移動させる。", "Pulls a distant item close to you.");
528
529         {
530             WEIGHT weight = plev * 15;
531
532             if (info)
533                 return info_weight(weight);
534
535             if (cast) {
536                 if (!get_aim_dir(player_ptr, &dir))
537                     return nullptr;
538
539                 fetch_item(player_ptr, dir, weight, false);
540             }
541         }
542         break;
543
544     case 27:
545         if (name)
546             return _("千里眼", "Clairvoyance");
547         if (desc)
548             return _("その階全体を永久に照らし、ダンジョン内すべてのアイテムを感知する。さらに、一定時間テレパシー能力を得る。",
549                 "Maps and lights whole dungeon level. Knows all objects location. And gives telepathy for a while.");
550
551         {
552             int base = 25;
553             DICE_SID sides = 30;
554
555             if (info)
556                 return info_duration(base, sides);
557
558             if (cast) {
559                 chg_virtue(player_ptr, V_KNOWLEDGE, 1);
560                 chg_virtue(player_ptr, V_ENLIGHTEN, 1);
561
562                 wiz_lite(player_ptr, false);
563
564                 if (!player_ptr->telepathy) {
565                     set_tim_esp(player_ptr, randint1(sides) + base, false);
566                 }
567             }
568         }
569         break;
570
571     case 28:
572         if (name)
573             return _("魅了の視線", "Charm monsters");
574         if (desc)
575             return _("視界内の全てのモンスターを魅了する。抵抗されると無効。", "Attempts to charm all monsters in sight.");
576
577         {
578             int power = plev * 2;
579
580             if (info)
581                 return info_power(power);
582
583             if (cast) {
584                 charm_monsters(player_ptr, power);
585             }
586         }
587         break;
588
589     case 29:
590         if (name)
591             return _("錬金術", "Alchemy");
592         if (desc)
593             return _("アイテム1つをお金に変える。", "Turns an item into 1/3 of its value in gold.");
594
595         {
596             if (cast) {
597                 if (!alchemy(player_ptr))
598                     return nullptr;
599             }
600         }
601         break;
602
603     case 30:
604         if (name)
605             return _("怪物追放", "Banishment");
606         if (desc)
607             return _("視界内の全てのモンスターをテレポートさせる。抵抗されると無効。", "Teleports all monsters in sight away unless resisted.");
608
609         {
610             int power = plev * 4;
611
612             if (info)
613                 return info_power(power);
614
615             if (cast) {
616                 banish_monsters(player_ptr, power);
617             }
618         }
619         break;
620
621     case 31:
622         if (name)
623             return _("無傷の球", "Globe of Invulnerability");
624         if (desc)
625             return _("一定時間、ダメージを受けなくなるバリアを張る。切れた瞬間に少しターンを消費するので注意。",
626                 "Generates a barrier which completely protects you from almost all damage. Takes a few of your turns when the barrier breaks or duration time "
627                 "is exceeded.");
628
629         {
630             int base = 4;
631
632             if (info)
633                 return info_duration(base, base);
634
635             if (cast) {
636                 set_invuln(player_ptr, randint1(base) + base, false);
637             }
638         }
639         break;
640     }
641
642     return "";
643 }