OSDN Git Service

[Refactor] #40634 Separated set_activation_target() from exe_activate()
[hengband/hengband.git] / src / action / mutation-execution.c
1 #include "action/mutation-execution.h"
2 #include "cmd-item/cmd-throw.h"
3 #include "core/asking-player.h"
4 #include "effect/spells-effect-util.h"
5 #include "game-option/play-record-options.h"
6 #include "grid/grid.h"
7 #include "inventory/inventory-slot-types.h"
8 #include "io/write-diary.h"
9 #include "mind/mind-mage.h"
10 #include "mind/mind-warrior.h"
11 #include "monster-floor/monster-remover.h"
12 #include "monster-floor/monster-summon.h"
13 #include "monster-floor/place-monster-types.h"
14 #include "monster-race/monster-race.h"
15 #include "monster-race/race-flags1.h"
16 #include "monster-race/race-flags3.h"
17 #include "monster/monster-describer.h"
18 #include "monster/monster-description-types.h"
19 #include "monster/monster-flag-types.h"
20 #include "monster/monster-info.h"
21 #include "mutation/mutation-flag-types.h"
22 #include "mutation/mutation-techniques.h"
23 #include "object-enchant/item-feeling.h"
24 #include "object-hook/hook-checker.h"
25 #include "player/player-damage.h"
26 #include "player/selfinfo.h"
27 #include "racial/racial-vampire.h"
28 #include "spell-kind/earthquake.h"
29 #include "spell-kind/spells-charm.h"
30 #include "spell-kind/spells-detection.h"
31 #include "spell-kind/spells-fetcher.h"
32 #include "spell-kind/spells-launcher.h"
33 #include "spell-kind/spells-lite.h"
34 #include "spell-kind/spells-sight.h"
35 #include "spell-kind/spells-teleport.h"
36 #include "spell-kind/spells-world.h"
37 #include "spell-realm/spells-sorcery.h"
38 #include "spell/spell-types.h"
39 #include "spell/spells-status.h"
40 #include "spell/spells-summon.h"
41 #include "status/element-resistance.h"
42 #include "status/shape-changer.h"
43 #include "system/floor-type-definition.h"
44 #include "system/object-type-definition.h"
45 #include "target/target-getter.h"
46 #include "view/display-messages.h"
47
48 /*!
49  * @brief 突然変異のレイシャル効果実装
50  * @param creature_ptr プレーヤーへの参照ポインタ
51  * @param power 発動させる突然変異レイシャルのID
52  * @return レイシャルを実行した場合TRUE、キャンセルした場合FALSEを返す
53  */
54 bool exe_mutation_power(player_type *creature_ptr, int power)
55 {
56     DIRECTION dir = 0;
57     PLAYER_LEVEL lvl = creature_ptr->lev;
58     switch (power) {
59     case MUT1_SPIT_ACID:
60         if (!get_aim_dir(creature_ptr, &dir))
61             return FALSE;
62
63         stop_mouth(creature_ptr);
64         msg_print(_("酸を吐きかけた...", "You spit acid..."));
65         fire_ball(creature_ptr, GF_ACID, dir, lvl, 1 + (lvl / 30));
66         return TRUE;
67     case MUT1_BR_FIRE:
68         if (!get_aim_dir(creature_ptr, &dir))
69             return FALSE;
70
71         stop_mouth(creature_ptr);
72         msg_print(_("あなたは火炎のブレスを吐いた...", "You breathe fire..."));
73         fire_breath(creature_ptr, GF_FIRE, dir, lvl * 2, 1 + (lvl / 20));
74         return TRUE;
75     case MUT1_HYPN_GAZE:
76         if (!get_aim_dir(creature_ptr, &dir))
77             return FALSE;
78
79         msg_print(_("あなたの目は幻惑的になった...", "Your eyes look mesmerizing..."));
80         (void)charm_monster(creature_ptr, dir, lvl);
81         return TRUE;
82     case MUT1_TELEKINES:
83         if (!get_aim_dir(creature_ptr, &dir))
84             return FALSE;
85
86         msg_print(_("集中している...", "You concentrate..."));
87         fetch_item(creature_ptr, dir, lvl * 10, TRUE);
88         return TRUE;
89     case MUT1_VTELEPORT:
90         msg_print(_("集中している...", "You concentrate..."));
91         teleport_player(creature_ptr, 10 + 4 * lvl, TELEPORT_SPONTANEOUS);
92         return TRUE;
93     case MUT1_MIND_BLST:
94         if (!get_aim_dir(creature_ptr, &dir))
95             return FALSE;
96
97         msg_print(_("集中している...", "You concentrate..."));
98         fire_bolt(creature_ptr, GF_PSI, dir, damroll(3 + ((lvl - 1) / 5), 3));
99         return TRUE;
100     case MUT1_RADIATION:
101         msg_print(_("体から放射能が発生した!", "Radiation flows from your body!"));
102         fire_ball(creature_ptr, GF_NUKE, 0, (lvl * 2), 3 + (lvl / 20));
103         return TRUE;
104     case MUT1_VAMPIRISM:
105         vampirism(creature_ptr);
106         return TRUE;
107     case MUT1_SMELL_MET:
108         stop_mouth(creature_ptr);
109         (void)detect_treasure(creature_ptr, DETECT_RAD_DEFAULT);
110         return TRUE;
111     case MUT1_SMELL_MON:
112         stop_mouth(creature_ptr);
113         (void)detect_monsters_normal(creature_ptr, DETECT_RAD_DEFAULT);
114         return TRUE;
115     case MUT1_BLINK:
116         teleport_player(creature_ptr, 10, TELEPORT_SPONTANEOUS);
117         return TRUE;
118     case MUT1_EAT_ROCK:
119         return eat_rock(creature_ptr);
120     case MUT1_SWAP_POS:
121         project_length = -1;
122         if (!get_aim_dir(creature_ptr, &dir)) {
123             project_length = 0;
124             return FALSE;
125         }
126
127         (void)teleport_swap(creature_ptr, dir);
128         project_length = 0;
129         return TRUE;
130     case MUT1_SHRIEK:
131         stop_mouth(creature_ptr);
132         (void)fire_ball(creature_ptr, GF_SOUND, 0, 2 * lvl, 8);
133         (void)aggravate_monsters(creature_ptr, 0);
134         return TRUE;
135     case MUT1_ILLUMINE:
136         (void)lite_area(creature_ptr, damroll(2, (lvl / 2)), (lvl / 10) + 1);
137         return TRUE;
138     case MUT1_DET_CURSE:
139         for (int i = 0; i < INVEN_TOTAL; i++) {
140             object_type *o_ptr = &creature_ptr->inventory_list[i];
141             if ((o_ptr->k_idx == 0) || !object_is_cursed(o_ptr))
142                 continue;
143
144             o_ptr->feeling = FEEL_CURSED;
145         }
146
147         return TRUE;
148     case MUT1_BERSERK:
149         (void)berserk(creature_ptr, randint1(25) + 25);
150         return TRUE;
151     case MUT1_POLYMORPH:
152         if (!get_check(_("変身します。よろしいですか?", "You will polymorph your self. Are you sure? ")))
153             return FALSE;
154
155         do_poly_self(creature_ptr);
156         return TRUE;
157     case MUT1_MIDAS_TCH:
158         return alchemy(creature_ptr);
159     case MUT1_GROW_MOLD:
160         for (DIRECTION i = 0; i < 8; i++)
161             summon_specific(creature_ptr, -1, creature_ptr->y, creature_ptr->x, lvl, SUMMON_MOLD, PM_FORCE_PET);
162
163         return TRUE;
164     case MUT1_RESIST: {
165         int num = lvl / 10;
166         TIME_EFFECT dur = randint1(20) + 20;
167         if (randint0(5) < num) {
168             (void)set_oppose_acid(creature_ptr, dur, FALSE);
169             num--;
170         }
171
172         if (randint0(4) < num) {
173             (void)set_oppose_elec(creature_ptr, dur, FALSE);
174             num--;
175         }
176
177         if (randint0(3) < num) {
178             (void)set_oppose_fire(creature_ptr, dur, FALSE);
179             num--;
180         }
181
182         if (randint0(2) < num) {
183             (void)set_oppose_cold(creature_ptr, dur, FALSE);
184             num--;
185         }
186
187         if (num != 0) {
188             (void)set_oppose_pois(creature_ptr, dur, FALSE);
189             num--;
190         }
191
192         return TRUE;
193     }
194     case MUT1_EARTHQUAKE:
195         (void)earthquake(creature_ptr, creature_ptr->y, creature_ptr->x, 10, 0);
196         return TRUE;
197     case MUT1_EAT_MAGIC:
198         return eat_magic(creature_ptr, creature_ptr->lev * 2);
199     case MUT1_WEIGH_MAG:
200         report_magics(creature_ptr);
201         return TRUE;
202     case MUT1_STERILITY:
203         msg_print(_("突然頭が痛くなった!", "You suddenly have a headache!"));
204         take_hit(creature_ptr, DAMAGE_LOSELIFE, randint1(17) + 17, _("禁欲を強いた疲労", "the strain of forcing abstinence"), -1);
205         creature_ptr->current_floor_ptr->num_repro += MAX_REPRO;
206         return TRUE;
207     case MUT1_HIT_AND_AWAY:
208         return hit_and_away(creature_ptr);
209     case MUT1_DAZZLE:
210         stun_monsters(creature_ptr, lvl * 4);
211         confuse_monsters(creature_ptr, lvl * 4);
212         turn_monsters(creature_ptr, lvl * 4);
213         return TRUE;
214     case MUT1_LASER_EYE:
215         if (!get_aim_dir(creature_ptr, &dir))
216             return FALSE;
217
218         fire_beam(creature_ptr, GF_LITE, dir, 2 * lvl);
219         return TRUE;
220     case MUT1_RECALL:
221         return recall_player(creature_ptr, randint0(21) + 15);
222     case MUT1_BANISH: {
223         if (!get_direction(creature_ptr, &dir, FALSE, FALSE))
224             return FALSE;
225
226         POSITION y = creature_ptr->y + ddy[dir];
227         POSITION x = creature_ptr->x + ddx[dir];
228         grid_type *g_ptr;
229         g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
230
231         if (!g_ptr->m_idx) {
232             msg_print(_("邪悪な存在を感じとれません!", "You sense no evil there!"));
233             return TRUE;
234         }
235
236         monster_type *m_ptr;
237         m_ptr = &creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
238         monster_race *r_ptr;
239         r_ptr = &r_info[m_ptr->r_idx];
240         if ((r_ptr->flags3 & RF3_EVIL) && !(r_ptr->flags1 & RF1_QUESTOR) && !(r_ptr->flags1 & RF1_UNIQUE) && !creature_ptr->current_floor_ptr->inside_arena
241             && !creature_ptr->current_floor_ptr->inside_quest && (r_ptr->level < randint1(creature_ptr->lev + 50)) && !(m_ptr->mflag2 & MFLAG2_NOGENO)) {
242             if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname) {
243                 GAME_TEXT m_name[MAX_NLEN];
244                 monster_desc(creature_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
245                 exe_write_diary(creature_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_GENOCIDE, m_name);
246             }
247
248             delete_monster_idx(creature_ptr, g_ptr->m_idx);
249             msg_print(_("その邪悪なモンスターは硫黄臭い煙とともに消え去った!", "The evil creature vanishes in a puff of sulfurous smoke!"));
250             return TRUE;
251         }
252
253         msg_print(_("祈りは効果がなかった!", "Your invocation is ineffectual!"));
254         if (one_in_(13))
255             m_ptr->mflag2 |= MFLAG2_NOGENO;
256
257         return TRUE;
258     }
259     case MUT1_COLD_TOUCH: {
260         if (!get_direction(creature_ptr, &dir, FALSE, FALSE))
261             return FALSE;
262
263         POSITION y = creature_ptr->y + ddy[dir];
264         POSITION x = creature_ptr->x + ddx[dir];
265         grid_type *g_ptr;
266         g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
267         if (!g_ptr->m_idx) {
268             msg_print(_("あなたは何もない場所で手を振った。", "You wave your hands in the air."));
269             return TRUE;
270         }
271
272         fire_bolt(creature_ptr, GF_COLD, dir, 2 * lvl);
273         return TRUE;
274     }
275     case 3:
276         return do_cmd_throw(creature_ptr, 2 + lvl / 40, FALSE, -1);
277     default:
278         free_turn(creature_ptr);
279         msg_format(_("能力 %s は実装されていません。", "Power %s not implemented. Oops."), power);
280         return TRUE;
281     }
282 }