OSDN Git Service

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