OSDN Git Service

[Refactor] #40571 Renamed targeting.c/h to target-checker.c/h
[hengbandforosx/hengbandosx.git] / src / realm / realm-trump.c
1 #include "realm/realm-trump.h"
2 #include "cmd-action/cmd-spell.h"
3 #include "core/asking-player.h"
4 #include "effect/spells-effect-util.h"
5 #include "game-option/input-options.h"
6 #include "monster-floor/place-monster-types.h"
7 #include "mutation/mutation.h"
8 #include "player/player-class.h"
9 #include "spell-kind/spells-detection.h"
10 #include "spell-kind/spells-fetcher.h"
11 #include "spell-kind/spells-launcher.h"
12 #include "spell-kind/spells-perception.h"
13 #include "spell-kind/spells-sight.h"
14 #include "spell-kind/spells-teleport.h"
15 #include "spell-kind/spells-world.h"
16 #include "spell-realm/spells-chaos.h"
17 #include "spell-realm/spells-trump.h"
18 #include "spell/spell-types.h"
19 #include "spell/spells-object.h"
20 #include "spell/spells-status.h"
21 #include "spell/spells-summon.h"
22 #include "status/sight-setter.h"
23 #include "target/target-checker.h"
24 #include "target/target-getter.h"
25 #include "target/target-setter.h"
26 #include "target/target-types.h"
27 #include "view/display-messages.h"
28
29 /*!
30  * @brief トランプ領域魔法の各処理を行う
31  * @param caster_ptr プレーヤーへの参照ポインタ
32  * @param spell 魔法ID
33  * @param mode 処理内容 (SPELL_NAME / SPELL_DESC / SPELL_INFO / SPELL_CAST)
34  * @return SPELL_NAME / SPELL_DESC / SPELL_INFO 時には文字列ポインタを返す。SPELL_CAST時はNULL文字列を返す。
35  */
36 concptr do_trump_spell(player_type *caster_ptr, SPELL_IDX spell, spell_type mode)
37 {
38     bool name = (mode == SPELL_NAME) ? TRUE : FALSE;
39     bool desc = (mode == SPELL_DESC) ? TRUE : FALSE;
40     bool info = (mode == SPELL_INFO) ? TRUE : FALSE;
41     bool cast = (mode == SPELL_CAST) ? TRUE : FALSE;
42     bool fail = (mode == SPELL_FAIL) ? TRUE : FALSE;
43
44     DIRECTION dir;
45     PLAYER_LEVEL plev = caster_ptr->lev;
46
47     switch (spell) {
48     case 0:
49         if (name)
50             return _("ショート・テレポート", "Phase Door");
51         if (desc)
52             return _("近距離のテレポートをする。", "Teleports you a short distance.");
53
54         {
55             POSITION range = 10;
56
57             if (info)
58                 return info_range(range);
59
60             if (cast) {
61                 teleport_player(caster_ptr, range, TELEPORT_SPONTANEOUS);
62             }
63         }
64         break;
65
66     case 1:
67         if (name)
68             return _("蜘蛛のカード", "Trump Spiders");
69         if (desc)
70             return _("蜘蛛を召喚する。", "Summons spiders.");
71
72         {
73             if (cast || fail) {
74                 msg_print(_("あなたは蜘蛛のカードに集中する...", "You concentrate on the trump of an spider..."));
75                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_SPIDER, PM_ALLOW_GROUP)) {
76                     if (fail) {
77                         msg_print(_("召喚された蜘蛛は怒っている!", "The summoned spiders get angry!"));
78                     }
79                 }
80             }
81         }
82         break;
83
84     case 2:
85         if (name)
86             return _("シャッフル", "Shuffle");
87         if (desc)
88             return _("カードの占いをする。", "Causes random effects.");
89
90         {
91             if (info)
92                 return KWD_RANDOM;
93
94             if (cast) {
95                 cast_shuffle(caster_ptr);
96             }
97         }
98         break;
99
100     case 3:
101         if (name)
102             return _("フロア・リセット", "Reset Recall");
103         if (desc)
104             return _("最深階を変更する。", "Resets the 'deepest' level for recall spell.");
105
106         {
107             if (cast) {
108                 if (!reset_recall(caster_ptr))
109                     return NULL;
110             }
111         }
112         break;
113
114     case 4:
115         if (name)
116             return _("テレポート", "Teleport");
117         if (desc)
118             return _("遠距離のテレポートをする。", "Teleports you a long distance.");
119
120         {
121             POSITION range = plev * 4;
122
123             if (info)
124                 return info_range(range);
125
126             if (cast) {
127                 teleport_player(caster_ptr, range, TELEPORT_SPONTANEOUS);
128             }
129         }
130         break;
131
132     case 5:
133         if (name)
134             return _("感知のカード", "Trump Spying");
135         if (desc)
136             return _("一定時間、テレパシー能力を得る。", "Gives telepathy for a while.");
137
138         {
139             int base = 25;
140             DICE_SID sides = 30;
141
142             if (info)
143                 return info_duration(base, sides);
144
145             if (cast) {
146                 set_tim_esp(caster_ptr, randint1(sides) + base, FALSE);
147             }
148         }
149         break;
150
151     case 6:
152         if (name)
153             return _("テレポート・モンスター", "Teleport Away");
154         if (desc)
155             return _("モンスターをテレポートさせるビームを放つ。抵抗されると無効。", "Teleports all monsters on the line away unless resisted.");
156
157         {
158             int power = plev;
159
160             if (info)
161                 return info_power(power);
162
163             if (cast) {
164                 if (!get_aim_dir(caster_ptr, &dir))
165                     return NULL;
166
167                 fire_beam(caster_ptr, GF_AWAY_ALL, dir, power);
168             }
169         }
170         break;
171
172     case 7:
173         if (name)
174             return _("動物のカード", "Trump Animals");
175         if (desc)
176             return _("1体の動物を召喚する。", "Summons an animal.");
177
178         {
179             if (cast || fail) {
180                 int type = (!fail ? SUMMON_ANIMAL_RANGER : SUMMON_ANIMAL);
181                 msg_print(_("あなたは動物のカードに集中する...", "You concentrate on the trump of an animal..."));
182                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, type, 0L)) {
183                     if (fail) {
184                         msg_print(_("召喚された動物は怒っている!", "The summoned animal gets angry!"));
185                     }
186                 }
187             }
188         }
189         break;
190
191     case 8:
192         if (name)
193             return _("移動のカード", "Trump Reach");
194         if (desc)
195             return _("アイテムを自分の足元へ移動させる。", "Pulls a distant item close to you.");
196
197         {
198             WEIGHT weight = plev * 15;
199
200             if (info)
201                 return info_weight(weight);
202
203             if (cast) {
204                 if (!get_aim_dir(caster_ptr, &dir))
205                     return NULL;
206
207                 fetch_item(caster_ptr, dir, weight, FALSE);
208             }
209         }
210         break;
211
212     case 9:
213         if (name)
214             return _("カミカゼのカード", "Trump Kamikaze");
215         if (desc)
216             return _("複数の爆発するモンスターを召喚する。", "Summons monsters which explode by itself.");
217
218         {
219             if (cast || fail) {
220                 POSITION x, y;
221                 int type;
222
223                 if (cast) {
224                     if (!target_set(caster_ptr, TARGET_KILL))
225                         return NULL;
226                     x = target_col;
227                     y = target_row;
228                 } else {
229                     /* Summons near player when failed */
230                     x = caster_ptr->x;
231                     y = caster_ptr->y;
232                 }
233
234                 if (caster_ptr->pclass == CLASS_BEASTMASTER)
235                     type = SUMMON_KAMIKAZE_LIVING;
236                 else
237                     type = SUMMON_KAMIKAZE;
238
239                 msg_print(_("あなたはカミカゼのカードに集中する...", "You concentrate on several trumps at once..."));
240                 if (trump_summoning(caster_ptr, 2 + randint0(plev / 7), !fail, y, x, 0, type, 0L)) {
241                     if (fail) {
242                         msg_print(_("召喚されたモンスターは怒っている!", "The summoned creatures get angry!"));
243                     }
244                 }
245             }
246         }
247         break;
248
249     case 10:
250         if (name)
251             return _("幻霊召喚", "Phantasmal Servant");
252         if (desc)
253             return _("1体の幽霊を召喚する。", "Summons a ghost.");
254
255         {
256             /* Phantasmal Servant is not summoned as enemy when failed */
257             if (cast) {
258                 int summon_lev = plev * 2 / 3 + randint1(plev / 2);
259
260                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, (summon_lev * 3 / 2), SUMMON_PHANTOM, 0L)) {
261                     msg_print(_("御用でございますか、御主人様?", "'Your wish, master?'"));
262                 }
263             }
264         }
265         break;
266
267     case 11:
268         if (name)
269             return _("スピード・モンスター", "Haste Monster");
270         if (desc)
271             return _("モンスター1体を加速させる。", "Hastes a monster.");
272
273         {
274             if (cast) {
275                 bool result;
276
277                 /* Temporary enable target_pet option */
278                 bool old_target_pet = target_pet;
279                 target_pet = TRUE;
280
281                 result = get_aim_dir(caster_ptr, &dir);
282
283                 /* Restore target_pet option */
284                 target_pet = old_target_pet;
285
286                 if (!result)
287                     return NULL;
288
289                 speed_monster(caster_ptr, dir, plev);
290             }
291         }
292         break;
293
294     case 12:
295         if (name)
296             return _("テレポート・レベル", "Teleport Level");
297         if (desc)
298             return _("瞬時に上か下の階にテレポートする。", "Instantly teleports you up or down a level.");
299
300         {
301             if (cast) {
302                 if (!get_check(_("本当に他の階にテレポートしますか?", "Are you sure? (Teleport Level)")))
303                     return NULL;
304                 teleport_level(caster_ptr, 0);
305             }
306         }
307         break;
308
309     case 13:
310         if (name)
311             return _("次元の扉", "Dimension Door");
312         if (desc)
313             return _("短距離内の指定した場所にテレポートする。", "Teleports you to a given location.");
314
315         {
316             POSITION range = plev / 2 + 10;
317
318             if (info)
319                 return info_range(range);
320
321             if (cast) {
322                 msg_print(_("次元の扉が開いた。目的地を選んで下さい。", "You open a dimensional gate. Choose a destination."));
323                 if (!dimension_door(caster_ptr))
324                     return NULL;
325             }
326         }
327         break;
328
329     case 14:
330         if (name)
331             return _("帰還の呪文", "Word of Recall");
332         if (desc)
333             return _("地上にいるときはダンジョンの最深階へ、ダンジョンにいるときは地上へと移動する。",
334                 "Recalls player from dungeon to town or from town to the deepest level of dungeon.");
335
336         {
337             int base = 15;
338             DICE_SID sides = 20;
339
340             if (info)
341                 return info_delay(base, sides);
342
343             if (cast) {
344                 if (!recall_player(caster_ptr, randint0(21) + 15))
345                     return NULL;
346             }
347         }
348         break;
349
350     case 15:
351         if (name)
352             return _("怪物追放", "Banish");
353         if (desc)
354             return _("視界内の全てのモンスターをテレポートさせる。抵抗されると無効。", "Teleports all monsters in sight away unless resisted.");
355
356         {
357             int power = plev * 4;
358
359             if (info)
360                 return info_power(power);
361
362             if (cast) {
363                 banish_monsters(caster_ptr, power);
364             }
365         }
366         break;
367
368     case 16:
369         if (name)
370             return _("位置交換のカード", "Swap Position");
371         if (desc)
372             return _("1体のモンスターと位置を交換する。", "Swap positions of you and a monster.");
373
374         {
375             if (cast) {
376                 bool result;
377
378                 /* HACK -- No range limit */
379                 project_length = -1;
380
381                 result = get_aim_dir(caster_ptr, &dir);
382
383                 /* Restore range to default */
384                 project_length = 0;
385
386                 if (!result)
387                     return NULL;
388
389                 teleport_swap(caster_ptr, dir);
390             }
391         }
392         break;
393
394     case 17:
395         if (name)
396             return _("アンデッドのカード", "Trump Undead");
397         if (desc)
398             return _("1体のアンデッドを召喚する。", "Summons an undead monster.");
399
400         {
401             if (cast || fail) {
402                 msg_print(_("あなたはアンデッドのカードに集中する...", "You concentrate on the trump of an undead creature..."));
403                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_UNDEAD, 0L)) {
404                     if (fail) {
405                         msg_print(_("召喚されたアンデッドは怒っている!", "The summoned undead creature gets angry!"));
406                     }
407                 }
408             }
409         }
410         break;
411
412     case 18:
413         if (name)
414             return _("爬虫類のカード", "Trump Reptile");
415         if (desc)
416             return _("1体のヒドラを召喚する。", "Summons a hydra.");
417
418         {
419             if (cast || fail) {
420                 msg_print(_("あなたは爬虫類のカードに集中する...", "You concentrate on the trump of a reptile..."));
421                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_HYDRA, 0L)) {
422                     if (fail) {
423                         msg_print(_("召喚された爬虫類は怒っている!", "The summoned reptile gets angry!"));
424                     }
425                 }
426             }
427         }
428         break;
429
430     case 19:
431         if (name)
432             return _("モンスターのカード", "Trump Monsters");
433         if (desc)
434             return _("複数のモンスターを召喚する。", "Summons some monsters.");
435
436         {
437             if (cast || fail) {
438                 int type;
439                 msg_print(_("あなたはモンスターのカードに集中する...", "You concentrate on several trumps at once..."));
440                 if (caster_ptr->pclass == CLASS_BEASTMASTER)
441                     type = SUMMON_LIVING;
442                 else
443                     type = 0;
444
445                 if (trump_summoning(caster_ptr, (1 + (plev - 15) / 10), !fail, caster_ptr->y, caster_ptr->x, 0, type, 0L)) {
446                     if (fail) {
447                         msg_print(_("召喚されたモンスターは怒っている!", "The summoned creatures get angry!"));
448                     }
449                 }
450             }
451         }
452         break;
453
454     case 20:
455         if (name)
456             return _("ハウンドのカード", "Trump Hounds");
457         if (desc)
458             return _("1グループのハウンドを召喚する。", "Summons a group of hounds.");
459
460         {
461             if (cast || fail) {
462                 msg_print(_("あなたはハウンドのカードに集中する...", "You concentrate on the trump of a hound..."));
463                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_HOUND, PM_ALLOW_GROUP)) {
464                     if (fail) {
465                         msg_print(_("召喚されたハウンドは怒っている!", "The summoned hounds get angry!"));
466                     }
467                 }
468             }
469         }
470         break;
471
472     case 21:
473         if (name)
474             return _("トランプの刃", "Trump Branding");
475         if (desc)
476             return _("武器にトランプの属性をつける。", "Makes current weapon a Trump weapon.");
477
478         {
479             if (cast) {
480                 brand_weapon(caster_ptr, 5);
481             }
482         }
483         break;
484
485     case 22:
486         if (name)
487             return _("人間トランプ", "Living Trump");
488         if (desc)
489             return _("ランダムにテレポートする突然変異か、自分の意思でテレポートする突然変異が身につく。",
490                 "Gives mutation which makes you teleport randomly or makes you able to teleport at will.");
491         if (cast)
492             become_living_trump(caster_ptr);
493         break;
494
495     case 23:
496         if (name)
497             return _("サイバーデーモンのカード", "Trump Cyberdemon");
498         if (desc)
499             return _("1体のサイバーデーモンを召喚する。", "Summons a cyber demon.");
500
501         {
502             if (cast || fail) {
503                 msg_print(_("あなたはサイバーデーモンのカードに集中する...", "You concentrate on the trump of a Cyberdemon..."));
504                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_CYBER, 0L)) {
505                     if (fail) {
506                         msg_print(_("召喚されたサイバーデーモンは怒っている!", "The summoned Cyberdemon gets angry!"));
507                     }
508                 }
509             }
510         }
511         break;
512
513     case 24:
514         if (name)
515             return _("予見のカード", "Trump Divination");
516         if (desc)
517             return _("近くの全てのモンスター、罠、扉、階段、財宝、そしてアイテムを感知する。",
518                 "Detects all monsters, traps, doors, stairs, treasures and items in your vicinity.");
519
520         {
521             POSITION rad = DETECT_RAD_DEFAULT;
522
523             if (info)
524                 return info_radius(rad);
525
526             if (cast) {
527                 detect_all(caster_ptr, rad);
528             }
529         }
530         break;
531
532     case 25:
533         if (name)
534             return _("知識のカード", "Trump Lore");
535         if (desc)
536             return _("アイテムの持つ能力を完全に知る。", "*Identifies* an item.");
537
538         {
539             if (cast) {
540                 if (!identify_fully(caster_ptr, FALSE, 0))
541                     return NULL;
542             }
543         }
544         break;
545
546     case 26:
547         if (name)
548             return _("回復モンスター", "Heal Monster");
549         if (desc)
550             return _("モンスター1体の体力を回復させる。", "Heals a monster.");
551
552         {
553             int heal = plev * 10 + 200;
554
555             if (info)
556                 return info_heal(0, 0, heal);
557
558             if (cast) {
559                 bool result;
560
561                 /* Temporary enable target_pet option */
562                 bool old_target_pet = target_pet;
563                 target_pet = TRUE;
564
565                 result = get_aim_dir(caster_ptr, &dir);
566
567                 /* Restore target_pet option */
568                 target_pet = old_target_pet;
569
570                 if (!result)
571                     return NULL;
572
573                 heal_monster(caster_ptr, dir, heal);
574             }
575         }
576         break;
577
578     case 27:
579         if (name)
580             return _("ドラゴンのカード", "Trump Dragon");
581         if (desc)
582             return _("1体のドラゴンを召喚する。", "Summons a dragon.");
583
584         {
585             if (cast || fail) {
586                 msg_print(_("あなたはドラゴンのカードに集中する...", "You concentrate on the trump of a dragon..."));
587                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_DRAGON, 0L)) {
588                     if (fail) {
589                         msg_print(_("召喚されたドラゴンは怒っている!", "The summoned dragon gets angry!"));
590                     }
591                 }
592             }
593         }
594         break;
595
596     case 28:
597         if (name)
598             return _("隕石のカード", "Trump Meteor");
599         if (desc)
600             return _("自分の周辺に隕石を落とす。", "Causes meteorites to fall down on nearby random locations.");
601
602         {
603             HIT_POINT dam = plev * 2;
604             POSITION rad = 2;
605
606             if (info)
607                 return info_multi_damage(dam);
608
609             if (cast) {
610                 cast_meteor(caster_ptr, dam, rad);
611             }
612         }
613         break;
614
615     case 29:
616         if (name)
617             return _("デーモンのカード", "Trump Demon");
618         if (desc)
619             return _("1体の悪魔を召喚する。", "Summons a demon.");
620
621         {
622             if (cast || fail) {
623                 msg_print(_("あなたはデーモンのカードに集中する...", "You concentrate on the trump of a demon..."));
624                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_DEMON, 0L)) {
625                     if (fail) {
626                         msg_print(_("召喚されたデーモンは怒っている!", "The summoned demon gets angry!"));
627                     }
628                 }
629             }
630         }
631         break;
632
633     case 30:
634         if (name)
635             return _("地獄のカード", "Trump Greater Undead");
636         if (desc)
637             return _("1体の上級アンデッドを召喚する。", "Summons a greater undead.");
638
639         {
640             if (cast || fail) {
641                 msg_print(_("あなたは強力なアンデッドのカードに集中する...", "You concentrate on the trump of a greater undead being..."));
642                 /* May allow unique depend on level and dice roll */
643                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, SUMMON_HI_UNDEAD, PM_ALLOW_UNIQUE)) {
644                     if (fail) {
645                         msg_print(_("召喚された上級アンデッドは怒っている!", "The summoned greater undead creature gets angry!"));
646                     }
647                 }
648             }
649         }
650         break;
651
652     case 31:
653         if (name)
654             return _("古代ドラゴンのカード", "Trump Ancient Dragon");
655         if (desc)
656             return _("1体の古代ドラゴンを召喚する。", "Summons an ancient dragon.");
657
658         {
659             if (cast) {
660                 int type;
661
662                 if (caster_ptr->pclass == CLASS_BEASTMASTER)
663                     type = SUMMON_HI_DRAGON_LIVING;
664                 else
665                     type = SUMMON_HI_DRAGON;
666
667                 msg_print(_("あなたは古代ドラゴンのカードに集中する...", "You concentrate on the trump of an ancient dragon..."));
668                 /* May allow unique depend on level and dice roll */
669                 if (trump_summoning(caster_ptr, 1, !fail, caster_ptr->y, caster_ptr->x, 0, type, PM_ALLOW_UNIQUE)) {
670                     if (fail) {
671                         msg_print(_("召喚された古代ドラゴンは怒っている!", "The summoned ancient dragon gets angry!"));
672                     }
673                 }
674             }
675         }
676         break;
677     }
678
679     return "";
680 }