OSDN Git Service

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