OSDN Git Service

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