OSDN Git Service

[Refactor] #2520 set_fast() をset_acceleration() に改名した
[hengbandforosx/hengbandosx.git] / src / realm / realm-life.cpp
1 #include "realm/realm-life.h"
2 #include "cmd-action/cmd-spell.h"
3 #include "effect/attribute-types.h"
4 #include "player/digestion-processor.h"
5 #include "spell-kind/spells-curse-removal.h"
6 #include "spell-kind/spells-detection.h"
7 #include "spell-kind/spells-floor.h"
8 #include "spell-kind/spells-genocide.h"
9 #include "spell-kind/spells-grid.h"
10 #include "spell-kind/spells-launcher.h"
11 #include "spell-kind/spells-lite.h"
12 #include "spell-kind/spells-neighbor.h"
13 #include "spell-kind/spells-perception.h"
14 #include "spell-kind/spells-sight.h"
15 #include "spell-kind/spells-world.h"
16 #include "spell/spells-status.h"
17 #include "status/bad-status-setter.h"
18 #include "status/buff-setter.h"
19 #include "status/element-resistance.h"
20 #include "status/experience.h"
21 #include "status/temporary-resistance.h"
22 #include "system/floor-type-definition.h"
23 #include "system/player-type-definition.h"
24 #include "target/target-getter.h"
25
26 /*!
27  * @brief 生命領域魔法の各処理を行う
28  * @param player_ptr プレイヤーへの参照ポインタ
29  * @param spell 魔法ID
30  * @param mode 処理内容 (SpellProcessType::NAME / SPELL_DESC / SpellProcessType::INFO / SpellProcessType::CAST)
31  * @return SpellProcessType::NAME / SPELL_DESC / SpellProcessType::INFO 時には文字列ポインタを返す。SpellProcessType::CAST時はnullptr文字列を返す。
32  */
33 concptr do_life_spell(PlayerType *player_ptr, SPELL_IDX spell, SpellProcessType mode)
34 {
35     bool name = mode == SpellProcessType::NAME;
36     bool desc = mode == SpellProcessType::DESCRIPTION;
37     bool info = mode == SpellProcessType::INFO;
38     bool cast = mode == SpellProcessType::CAST;
39
40     DIRECTION dir;
41     PLAYER_LEVEL plev = player_ptr->lev;
42
43     switch (spell) {
44     case 0:
45         if (name) {
46             return _("軽傷の治癒", "Cure Light Wounds");
47         }
48         if (desc) {
49             return _("怪我と体力を少し回復させる。", "Heals cuts and HP a little.");
50         }
51         {
52             DICE_NUMBER dice = 2;
53             DICE_SID sides = 10;
54             if (info) {
55                 return info_heal(dice, sides, 0);
56             }
57             if (cast) {
58                 (void)cure_light_wounds(player_ptr, dice, sides);
59             }
60         }
61         break;
62
63     case 1:
64         if (name) {
65             return _("祝福", "Bless");
66         }
67         if (desc) {
68             return _("一定時間、命中率とACにボーナスを得る。", "Gives a bonus to hit and AC for a few turns.");
69         }
70         {
71             int base = 12;
72
73             if (info) {
74                 return info_duration(base, base);
75             }
76
77             if (cast) {
78                 set_blessed(player_ptr, randint1(base) + base, false);
79             }
80         }
81         break;
82
83     case 2:
84         if (name) {
85             return _("軽傷", "Cause Light Wounds");
86         }
87         if (desc) {
88             return _("1体のモンスターに小ダメージを与える。抵抗されると無効。", "Wounds a monster a little unless resisted.");
89         }
90         {
91             DICE_NUMBER dice = 3 + (plev - 1) / 5;
92             DICE_SID sides = 4;
93
94             if (info) {
95                 return info_damage(dice, sides, 0);
96             }
97
98             if (cast) {
99                 if (!get_aim_dir(player_ptr, &dir)) {
100                     return nullptr;
101                 }
102                 fire_ball_hide(player_ptr, AttributeType::WOUNDS, dir, damroll(dice, sides), 0);
103             }
104         }
105         break;
106
107     case 3:
108         if (name) {
109             return _("光の召喚", "Call Light");
110         }
111         if (desc) {
112             return _("光源が照らしている範囲か部屋全体を永久に明るくする。", "Lights up nearby area and the inside of a room permanently.");
113         }
114         {
115             DICE_NUMBER dice = 2;
116             DICE_SID sides = plev / 2;
117             POSITION rad = plev / 10 + 1;
118
119             if (info) {
120                 return info_damage(dice, sides, 0);
121             }
122
123             if (cast) {
124                 lite_area(player_ptr, damroll(dice, sides), rad);
125             }
126         }
127         break;
128
129     case 4:
130         if (name) {
131             return _("罠 & 隠し扉感知", "Detect Doors & Traps");
132         }
133         if (desc) {
134             return _("近くの全ての罠と扉と階段を感知する。", "Detects traps, doors, and stairs in your vicinity.");
135         }
136         {
137             POSITION rad = DETECT_RAD_DEFAULT;
138
139             if (info) {
140                 return info_radius(rad);
141             }
142
143             if (cast) {
144                 detect_traps(player_ptr, rad, true);
145                 detect_doors(player_ptr, rad);
146                 detect_stairs(player_ptr, rad);
147             }
148         }
149         break;
150
151     case 5:
152         if (name) {
153             return _("重傷の治癒", "Cure Medium Wounds");
154         }
155         if (desc) {
156             return _("怪我と体力を中程度回復させる。", "Heals cuts and HP more.");
157         }
158         {
159             DICE_NUMBER dice = 4;
160             DICE_SID sides = 10;
161
162             if (info) {
163                 return info_heal(dice, sides, 0);
164             }
165             if (cast) {
166                 (void)cure_serious_wounds(player_ptr, dice, sides);
167             }
168         }
169         break;
170
171     case 6:
172         if (name) {
173             return _("解毒", "Cure Poison");
174         }
175
176         if (desc) {
177             return _("体内の毒を取り除く。", "Cures yourself of any poisons.");
178         }
179
180         if (cast) {
181             (void)BadStatusSetter(player_ptr).poison(0);
182         }
183
184         break;
185
186     case 7:
187         if (name) {
188             return _("空腹充足", "Satisfy Hunger");
189         }
190         if (desc) {
191             return _("満腹にする。", "Satisfies hunger.");
192         }
193         {
194             if (cast) {
195                 set_food(player_ptr, PY_FOOD_MAX - 1);
196             }
197         }
198         break;
199
200     case 8:
201         if (name) {
202             return _("解呪", "Remove Curse");
203         }
204         if (desc) {
205             return _("アイテムにかかった弱い呪いを解除する。", "Removes normal curses from equipped items.");
206         }
207         {
208             if (cast) {
209                 (void)remove_curse(player_ptr);
210             }
211         }
212         break;
213
214     case 9:
215         if (name) {
216             return _("重傷", "Cause Medium Wounds");
217         }
218         if (desc) {
219             return _("1体のモンスターに中ダメージを与える。抵抗されると無効。", "Wounds a monster unless resisted.");
220         }
221         {
222             DICE_SID sides = 8 + (plev - 5) / 4;
223             DICE_NUMBER dice = 8;
224
225             if (info) {
226                 return info_damage(dice, sides, 0);
227             }
228
229             if (cast) {
230                 if (!get_aim_dir(player_ptr, &dir)) {
231                     return nullptr;
232                 }
233                 fire_ball_hide(player_ptr, AttributeType::WOUNDS, dir, damroll(dice, sides), 0);
234             }
235         }
236         break;
237
238     case 10:
239         if (name) {
240             return _("致命傷の治癒", "Cure Critical Wounds");
241         }
242         if (desc) {
243             return _("体力を大幅に回復させ、負傷と朦朧状態も全快する。", "Heals HP greatly. Also cures cuts and being stunned.");
244         }
245         {
246             DICE_NUMBER dice = 8;
247             DICE_SID sides = 10;
248
249             if (info) {
250                 return info_heal(dice, sides, 0);
251             }
252             if (cast) {
253                 (void)cure_critical_wounds(player_ptr, damroll(dice, sides));
254             }
255         }
256         break;
257
258     case 11:
259         if (name) {
260             return _("耐熱耐寒", "Resist Heat and Cold");
261         }
262         if (desc) {
263             return _("一定時間、火炎と冷気に対する耐性を得る。装備による耐性に累積する。",
264                 "Gives resistance to fire and cold. These resistances can be added to those from equipment for more powerful resistances.");
265         }
266
267         {
268             int base = 20;
269
270             if (info) {
271                 return info_duration(base, base);
272             }
273
274             if (cast) {
275                 set_oppose_cold(player_ptr, randint1(base) + base, false);
276                 set_oppose_fire(player_ptr, randint1(base) + base, false);
277             }
278         }
279         break;
280
281     case 12:
282         if (name) {
283             return _("周辺感知", "Sense Surroundings");
284         }
285         if (desc) {
286             return _("周辺の地形を感知する。", "Maps nearby area.");
287         }
288
289         {
290             POSITION rad = DETECT_RAD_MAP;
291
292             if (info) {
293                 return info_radius(rad);
294             }
295
296             if (cast) {
297                 map_area(player_ptr, rad);
298             }
299         }
300         break;
301
302     case 13:
303         if (name) {
304             return _("パニック・アンデッド", "Turn Undead");
305         }
306         if (desc) {
307             return _("視界内のアンデッドを恐怖させる。抵抗されると無効。", "Attempts to scare undead monsters in sight.");
308         }
309
310         {
311             if (cast) {
312                 turn_undead(player_ptr);
313             }
314         }
315         break;
316
317     case 14:
318         if (name) {
319             return _("体力回復", "Healing");
320         }
321         if (desc) {
322             return _("極めて強力な回復呪文で、負傷と朦朧状態も全快する。", "Is very powerful healing magic. Also completely cures cuts and being stunned.");
323         }
324
325         {
326             int heal = 300;
327             if (info) {
328                 return info_heal(0, 0, heal);
329             }
330             if (cast) {
331                 (void)cure_critical_wounds(player_ptr, heal);
332             }
333         }
334         break;
335
336     case 15:
337         if (name) {
338             return _("結界の紋章", "Rune of Protection");
339         }
340         if (desc) {
341             return _("自分のいる床の上に、モンスターが通り抜けたり召喚されたりすることができなくなるルーンを描く。",
342                 "Sets a rune on the floor beneath you. If you are on a rune, monsters cannot attack you but can try to break the rune.");
343         }
344
345         {
346             if (cast) {
347                 create_rune_protection_one(player_ptr);
348             }
349         }
350         break;
351
352     case 16:
353         if (name) {
354             return _("*解呪*", "Dispel Curse");
355         }
356         if (desc) {
357             return _("アイテムにかかった強力な呪いを解除する。", "Removes normal and heavy curses from equipped items.");
358         }
359         {
360             if (cast) {
361                 (void)remove_all_curse(player_ptr);
362             }
363         }
364         break;
365
366     case 17:
367         if (name) {
368             return _("鑑識", "Perception");
369         }
370         if (desc) {
371             return _("アイテムを識別する。", "Identifies an item.");
372         }
373
374         {
375             if (cast) {
376                 if (!ident_spell(player_ptr, false)) {
377                     return nullptr;
378                 }
379             }
380         }
381         break;
382
383     case 18:
384         if (name) {
385             return _("アンデッド退散", "Dispel Undead");
386         }
387         if (desc) {
388             return _("視界内の全てのアンデッドにダメージを与える。", "Damages all undead monsters in sight.");
389         }
390
391         {
392             DICE_NUMBER dice = 1;
393             DICE_SID sides = plev * 5;
394
395             if (info) {
396                 return info_damage(dice, sides, 0);
397             }
398
399             if (cast) {
400                 dispel_undead(player_ptr, damroll(dice, sides));
401             }
402         }
403         break;
404
405     case 19:
406         if (name) {
407             return _("凪の刻", "Day of the Dove");
408         }
409         if (desc) {
410             return _("視界内の全てのモンスターを魅了する。抵抗されると無効。", "Attempts to charm all monsters in sight.");
411         }
412
413         {
414             int power = plev * 2;
415
416             if (info) {
417                 return info_power(power);
418             }
419
420             if (cast) {
421                 charm_monsters(player_ptr, power);
422             }
423         }
424         break;
425
426     case 20:
427         if (name) {
428             return _("致命傷", "Cause Critical Wounds");
429         }
430         if (desc) {
431             return _("1体のモンスターに大ダメージを与える。抵抗されると無効。", "Wounds a monster critically unless resisted.");
432         }
433
434         {
435             DICE_NUMBER dice = 5 + (plev - 5) / 3;
436             DICE_SID sides = 15;
437
438             if (info) {
439                 return info_damage(dice, sides, 0);
440             }
441
442             if (cast) {
443                 if (!get_aim_dir(player_ptr, &dir)) {
444                     return nullptr;
445                 }
446                 fire_ball_hide(player_ptr, AttributeType::WOUNDS, dir, damroll(dice, sides), 0);
447             }
448         }
449         break;
450
451     case 21:
452         if (name) {
453             return _("帰還の詔", "Word of Recall");
454         }
455         if (desc) {
456             return _("地上にいるときはダンジョンの最深階へ、ダンジョンにいるときは地上へと移動する。",
457                 "Recalls player from dungeon to town or from town to the deepest level of dungeon.");
458         }
459
460         {
461             int base = 15;
462             DICE_SID sides = 20;
463
464             if (info) {
465                 return info_delay(base, sides);
466             }
467
468             if (cast) {
469                 if (!recall_player(player_ptr, randint0(21) + 15)) {
470                     return nullptr;
471                 }
472             }
473         }
474         break;
475
476     case 22:
477         if (name) {
478             return _("真実の祭壇", "Alter Reality");
479         }
480         if (desc) {
481             return _("現在の階を再構成する。", "Recreates current dungeon level.");
482         }
483
484         {
485             int base = 15;
486             DICE_SID sides = 20;
487
488             if (info) {
489                 return info_delay(base, sides);
490             }
491
492             if (cast) {
493                 reserve_alter_reality(player_ptr, randint0(sides) + base);
494             }
495         }
496         break;
497
498     case 23:
499         if (name) {
500             return _("真・結界", "Warding True");
501         }
502         if (desc) {
503             return _("自分のいる床と周囲8マスの床の上に、モンスターが通り抜けたり召喚されたりすることができなくなるルーンを描く。",
504                 "Creates runes in all adjacent squares and under you.");
505         }
506
507         {
508             POSITION rad = 1;
509
510             if (info) {
511                 return info_radius(rad);
512             }
513
514             if (cast) {
515                 create_rune_protection_one(player_ptr);
516                 create_rune_protection_area(player_ptr, player_ptr->y, player_ptr->x);
517             }
518         }
519         break;
520
521     case 24:
522         if (name) {
523             return _("不毛化", "Sterilization");
524         }
525         if (desc) {
526             return _("この階の増殖するモンスターが増殖できなくなる。", "Prevents any breeders on current level from breeding.");
527         }
528
529         {
530             if (cast) {
531                 player_ptr->current_floor_ptr->num_repro += MAX_REPRO;
532             }
533         }
534         break;
535
536     case 25:
537         if (name) {
538             return _("全感知", "Detection");
539         }
540         if (desc) {
541             return _("近くの全てのモンスター、罠、扉、階段、財宝、そしてアイテムを感知する。",
542                 "Detects all monsters, traps, doors, stairs, treasures and items in your vicinity.");
543         }
544
545         {
546             POSITION rad = DETECT_RAD_DEFAULT;
547
548             if (info) {
549                 return info_radius(rad);
550             }
551
552             if (cast) {
553                 detect_all(player_ptr, rad);
554             }
555         }
556         break;
557
558     case 26:
559         if (name) {
560             return _("アンデッド消滅", "Annihilate Undead");
561         }
562         if (desc) {
563             return _("自分の周囲にいるアンデッドを現在の階から消し去る。抵抗されると無効。",
564                 "Eliminates all nearby undead monsters, exhausting you. Powerful or unique monsters may be able to resist.");
565         }
566
567         {
568             int power = plev + 50;
569
570             if (info) {
571                 return info_power(power);
572             }
573
574             if (cast) {
575                 mass_genocide_undead(player_ptr, power, true);
576             }
577         }
578         break;
579
580     case 27:
581         if (name) {
582             return _("千里眼", "Clairvoyance");
583         }
584         if (desc) {
585             return _("その階全体を永久に照らし、ダンジョン内すべてのアイテムを感知する。",
586                 "Maps and lights whole dungeon level. Knows all objects location. And gives telepathy for a while.");
587         }
588
589         {
590             if (cast) {
591                 wiz_lite(player_ptr, false);
592             }
593         }
594         break;
595
596     case 28:
597         if (name) {
598             return _("全復活", "Restoration");
599         }
600         if (desc) {
601             return _("すべてのステータスと経験値を回復する。", "Restores all stats and experience.");
602         }
603
604         {
605             if (cast) {
606                 (void)restore_all_status(player_ptr);
607                 restore_level(player_ptr);
608             }
609         }
610         break;
611
612     case 29:
613         if (name) {
614             return _("*体力回復*", "Healing True");
615         }
616         if (desc) {
617             return _("最強の治癒の魔法で、負傷と朦朧状態も全快する。", "Is the greatest healing magic. Heals all HP, cuts and being stunned.");
618         }
619
620         {
621             int heal = 2000;
622             if (info) {
623                 return info_heal(0, 0, heal);
624             }
625             if (cast) {
626                 (void)cure_critical_wounds(player_ptr, heal);
627             }
628         }
629         break;
630
631     case 30:
632         if (name) {
633             return _("聖なるビジョン", "Holy Vision");
634         }
635         if (desc) {
636             return _("アイテムの持つ能力を完全に知る。", "*Identifies* an item.");
637         }
638
639         {
640             if (cast) {
641                 if (!identify_fully(player_ptr, false)) {
642                     return nullptr;
643                 }
644             }
645         }
646         break;
647
648     case 31:
649         if (name) {
650             return _("究極の耐性", "Ultimate Resistance");
651         }
652         if (desc) {
653             return _("一定時間、あらゆる耐性を付け、ACと魔法防御能力を上昇させる。", "Gives ultimate resistance, bonus to AC and speed.");
654         }
655
656         {
657             TIME_EFFECT base = (TIME_EFFECT)plev / 2;
658
659             if (info) {
660                 return info_duration(base, base);
661             }
662
663             if (cast) {
664                 TIME_EFFECT v = randint1(base) + base;
665                 set_acceleration(player_ptr, v, false);
666                 set_oppose_acid(player_ptr, v, false);
667                 set_oppose_elec(player_ptr, v, false);
668                 set_oppose_fire(player_ptr, v, false);
669                 set_oppose_cold(player_ptr, v, false);
670                 set_oppose_pois(player_ptr, v, false);
671                 set_ultimate_res(player_ptr, v, false);
672             }
673         }
674         break;
675     }
676
677     return "";
678 }