OSDN Git Service

[Refactor] #40014 Separated place-monster-types.h from monster.h
[hengband/hengband.git] / src / mutation / mutation-processor.c
1 #include "mutation/mutation-processor.h"
2 #include "io/targeting.h"
3 #include "monster/monster-status.h"
4 #include "monster/place-monster-types.h"
5 #include "mutation/mutation.h"
6 #include "object/lite-processor.h"
7 #include "object/object-hook.h"
8 #include "player/player-damage.h"
9 #include "player/player-effects.h"
10 #include "player/player-move.h"
11 #include "spell-kind/spells-floor.h"
12 #include "spell-realm/spells-hex.h"
13 #include "spell-kind/spells-launcher.h"
14 #include "spell-kind/spells-lite.h"
15 #include "spell-kind/spells-sight.h"
16 #include "spell/spells-summon.h"
17 #include "spell-kind/spells-teleport.h"
18 #include "spell/spells-type.h"
19 #include "spell/spells3.h"
20 #include "store/store-owners.h"
21 #include "store/store-util.h"
22 #include "store/store.h"
23
24 /*!
25  * @brief 10ゲームターンが進行するごとに突然変異の発動判定を行う処理
26  * / Handle mutation effects once every 10 game turns
27  * @return なし
28  */
29 void process_world_aux_mutation(player_type* creature_ptr)
30 {
31     if (!creature_ptr->muta2)
32         return;
33     if (creature_ptr->phase_out)
34         return;
35     if (creature_ptr->wild_mode)
36         return;
37
38     if ((creature_ptr->muta2 & MUT2_BERS_RAGE) && one_in_(3000)) {
39         disturb(creature_ptr, FALSE, TRUE);
40         msg_print(_("ウガァァア!", "RAAAAGHH!"));
41         msg_print(_("激怒の発作に襲われた!", "You feel a fit of rage coming over you!"));
42         (void)set_shero(creature_ptr, 10 + randint1(creature_ptr->lev), FALSE);
43         (void)set_afraid(creature_ptr, 0);
44     }
45
46     if ((creature_ptr->muta2 & MUT2_COWARDICE) && (randint1(3000) == 13)) {
47         if (!creature_ptr->resist_fear) {
48             disturb(creature_ptr, FALSE, TRUE);
49             msg_print(_("とても暗い... とても恐い!", "It's so dark... so scary!"));
50             set_afraid(creature_ptr, creature_ptr->afraid + 13 + randint1(26));
51         }
52     }
53
54     if ((creature_ptr->muta2 & MUT2_RTELEPORT) && (randint1(5000) == 88)) {
55         if (!creature_ptr->resist_nexus && !(creature_ptr->muta1 & MUT1_VTELEPORT) && !creature_ptr->anti_tele) {
56             disturb(creature_ptr, FALSE, TRUE);
57             msg_print(_("あなたの位置は突然ひじょうに不確定になった...", "Your position suddenly seems very uncertain..."));
58             msg_print(NULL);
59             teleport_player(creature_ptr, 40, TELEPORT_PASSIVE);
60         }
61     }
62
63     if ((creature_ptr->muta2 & MUT2_ALCOHOL) && (randint1(6400) == 321)) {
64         if (!creature_ptr->resist_conf && !creature_ptr->resist_chaos) {
65             disturb(creature_ptr, FALSE, TRUE);
66             creature_ptr->redraw |= PR_EXTRA;
67             msg_print(_("いひきがもーろーとひてきたきがふる...ヒック!", "You feel a SSSCHtupor cOmINg over yOu... *HIC*!"));
68         }
69
70         if (!creature_ptr->resist_conf) {
71             (void)set_confused(creature_ptr, creature_ptr->confused + randint0(20) + 15);
72         }
73
74         if (!creature_ptr->resist_chaos) {
75             if (one_in_(20)) {
76                 msg_print(NULL);
77                 if (one_in_(3))
78                     lose_all_info(creature_ptr);
79                 else
80                     wiz_dark(creature_ptr);
81                 (void)teleport_player_aux(creature_ptr, 100, FALSE, TELEPORT_NONMAGICAL | TELEPORT_PASSIVE);
82                 wiz_dark(creature_ptr);
83                 msg_print(_("あなたは見知らぬ場所で目が醒めた...頭が痛い。", "You wake up somewhere with a sore head..."));
84                 msg_print(_("何も覚えていない。どうやってここに来たかも分からない!", "You can't remember a thing or how you got here!"));
85             } else {
86                 if (one_in_(3)) {
87                     msg_print(_("き~れいなちょおちょらとんれいる~", "Thishcischs GooDSChtuff!"));
88                     (void)set_image(creature_ptr, creature_ptr->image + randint0(150) + 150);
89                 }
90             }
91         }
92     }
93
94     if ((creature_ptr->muta2 & MUT2_HALLU) && (randint1(6400) == 42)) {
95         if (!creature_ptr->resist_chaos) {
96             disturb(creature_ptr, FALSE, TRUE);
97             creature_ptr->redraw |= PR_EXTRA;
98             (void)set_image(creature_ptr, creature_ptr->image + randint0(50) + 20);
99         }
100     }
101
102     if ((creature_ptr->muta2 & MUT2_FLATULENT) && (randint1(3000) == 13)) {
103         disturb(creature_ptr, FALSE, TRUE);
104         msg_print(_("ブゥーーッ!おっと。", "BRRAAAP! Oops."));
105         msg_print(NULL);
106         fire_ball(creature_ptr, GF_POIS, 0, creature_ptr->lev, 3);
107     }
108
109     if ((creature_ptr->muta2 & MUT2_PROD_MANA) && !creature_ptr->anti_magic && one_in_(9000)) {
110         int dire = 0;
111         disturb(creature_ptr, FALSE, TRUE);
112         msg_print(_("魔法のエネルギーが突然あなたの中に流れ込んできた!エネルギーを解放しなければならない!",
113             "Magical energy flows through you! You must release it!"));
114
115         flush();
116         msg_print(NULL);
117         (void)get_hack_dir(creature_ptr, &dire);
118         fire_ball(creature_ptr, GF_MANA, dire, creature_ptr->lev * 2, 3);
119     }
120
121     if ((creature_ptr->muta2 & MUT2_ATT_DEMON) && !creature_ptr->anti_magic && (randint1(6666) == 666)) {
122         bool pet = one_in_(6);
123         BIT_FLAGS mode = PM_ALLOW_GROUP;
124
125         if (pet)
126             mode |= PM_FORCE_PET;
127         else
128             mode |= (PM_ALLOW_UNIQUE | PM_NO_PET);
129
130         if (summon_specific(creature_ptr, (pet ? -1 : 0), creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_DEMON, mode)) {
131             msg_print(_("あなたはデーモンを引き寄せた!", "You have attracted a demon!"));
132             disturb(creature_ptr, FALSE, TRUE);
133         }
134     }
135
136     if ((creature_ptr->muta2 & MUT2_SPEED_FLUX) && one_in_(6000)) {
137         disturb(creature_ptr, FALSE, TRUE);
138         if (one_in_(2)) {
139             msg_print(_("精力的でなくなった気がする。", "You feel less energetic."));
140
141             if (creature_ptr->fast > 0) {
142                 set_fast(creature_ptr, 0, TRUE);
143             } else {
144                 set_slow(creature_ptr, randint1(30) + 10, FALSE);
145             }
146         } else {
147             msg_print(_("精力的になった気がする。", "You feel more energetic."));
148
149             if (creature_ptr->slow > 0) {
150                 set_slow(creature_ptr, 0, TRUE);
151             } else {
152                 set_fast(creature_ptr, randint1(30) + 10, FALSE);
153             }
154         }
155         msg_print(NULL);
156     }
157     if ((creature_ptr->muta2 & MUT2_BANISH_ALL) && one_in_(9000)) {
158         disturb(creature_ptr, FALSE, TRUE);
159         msg_print(_("突然ほとんど孤独になった気がする。", "You suddenly feel almost lonely."));
160
161         banish_monsters(creature_ptr, 100);
162         if (!creature_ptr->current_floor_ptr->dun_level && creature_ptr->town_num) {
163             int n;
164             do {
165                 n = randint0(MAX_STORES);
166             } while ((n == STORE_HOME) || (n == STORE_MUSEUM));
167
168             msg_print(_("店の主人が丘に向かって走っている!", "You see one of the shopkeepers running for the hills!"));
169             store_shuffle(creature_ptr, n);
170         }
171         msg_print(NULL);
172     }
173
174     if ((creature_ptr->muta2 & MUT2_EAT_LIGHT) && one_in_(3000)) {
175         object_type* o_ptr;
176
177         msg_print(_("影につつまれた。", "A shadow passes over you."));
178         msg_print(NULL);
179
180         if ((creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) {
181             hp_player(creature_ptr, 10);
182         }
183
184         o_ptr = &creature_ptr->inventory_list[INVEN_LITE];
185
186         if (o_ptr->tval == TV_LITE) {
187             if (!object_is_fixed_artifact(o_ptr) && (o_ptr->xtra4 > 0)) {
188                 hp_player(creature_ptr, o_ptr->xtra4 / 20);
189                 o_ptr->xtra4 /= 2;
190                 msg_print(_("光源からエネルギーを吸収した!", "You absorb energy from your light!"));
191                 notice_lite_change(creature_ptr, o_ptr);
192             }
193         }
194
195         /*
196                  * Unlite the area (radius 10) around player and
197                  * do 50 points damage to every affected monster
198                  */
199         unlite_area(creature_ptr, 50, 10);
200     }
201
202     if ((creature_ptr->muta2 & MUT2_ATT_ANIMAL) && !creature_ptr->anti_magic && one_in_(7000)) {
203         bool pet = one_in_(3);
204         BIT_FLAGS mode = PM_ALLOW_GROUP;
205
206         if (pet)
207             mode |= PM_FORCE_PET;
208         else
209             mode |= (PM_ALLOW_UNIQUE | PM_NO_PET);
210
211         if (summon_specific(creature_ptr, (pet ? -1 : 0), creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_ANIMAL, mode)) {
212             msg_print(_("動物を引き寄せた!", "You have attracted an animal!"));
213             disturb(creature_ptr, FALSE, TRUE);
214         }
215     }
216
217     if ((creature_ptr->muta2 & MUT2_RAW_CHAOS) && !creature_ptr->anti_magic && one_in_(8000)) {
218         disturb(creature_ptr, FALSE, TRUE);
219         msg_print(_("周りの空間が歪んでいる気がする!", "You feel the world warping around you!"));
220
221         msg_print(NULL);
222         fire_ball(creature_ptr, GF_CHAOS, 0, creature_ptr->lev, 8);
223     }
224
225     if ((creature_ptr->muta2 & MUT2_NORMALITY) && one_in_(5000)) {
226         if (!lose_mutation(creature_ptr, 0))
227             msg_print(_("奇妙なくらい普通になった気がする。", "You feel oddly normal."));
228     }
229
230     if ((creature_ptr->muta2 & MUT2_WRAITH) && !creature_ptr->anti_magic && one_in_(3000)) {
231         disturb(creature_ptr, FALSE, TRUE);
232         msg_print(_("非物質化した!", "You feel insubstantial!"));
233
234         msg_print(NULL);
235         set_wraith_form(creature_ptr, randint1(creature_ptr->lev / 2) + (creature_ptr->lev / 2), FALSE);
236     }
237
238     if ((creature_ptr->muta2 & MUT2_POLY_WOUND) && one_in_(3000)) {
239         do_poly_wounds(creature_ptr);
240     }
241
242     if ((creature_ptr->muta2 & MUT2_WASTING) && one_in_(3000)) {
243         int which_stat = randint0(A_MAX);
244         int sustained = FALSE;
245
246         switch (which_stat) {
247         case A_STR:
248             if (creature_ptr->sustain_str)
249                 sustained = TRUE;
250             break;
251         case A_INT:
252             if (creature_ptr->sustain_int)
253                 sustained = TRUE;
254             break;
255         case A_WIS:
256             if (creature_ptr->sustain_wis)
257                 sustained = TRUE;
258             break;
259         case A_DEX:
260             if (creature_ptr->sustain_dex)
261                 sustained = TRUE;
262             break;
263         case A_CON:
264             if (creature_ptr->sustain_con)
265                 sustained = TRUE;
266             break;
267         case A_CHR:
268             if (creature_ptr->sustain_chr)
269                 sustained = TRUE;
270             break;
271         default:
272             msg_print(_("不正な状態!", "Invalid stat chosen!"));
273             sustained = TRUE;
274         }
275
276         if (!sustained) {
277             disturb(creature_ptr, FALSE, TRUE);
278             msg_print(_("自分が衰弱していくのが分かる!", "You can feel yourself wasting away!"));
279             msg_print(NULL);
280             (void)dec_stat(creature_ptr, which_stat, randint1(6) + 6, one_in_(3));
281         }
282     }
283
284     if ((creature_ptr->muta2 & MUT2_ATT_DRAGON) && !creature_ptr->anti_magic && one_in_(3000)) {
285         bool pet = one_in_(5);
286         BIT_FLAGS mode = PM_ALLOW_GROUP;
287
288         if (pet)
289             mode |= PM_FORCE_PET;
290         else
291             mode |= (PM_ALLOW_UNIQUE | PM_NO_PET);
292
293         if (summon_specific(creature_ptr, (pet ? -1 : 0), creature_ptr->y, creature_ptr->x, creature_ptr->current_floor_ptr->dun_level, SUMMON_DRAGON, mode)) {
294             msg_print(_("ドラゴンを引き寄せた!", "You have attracted a dragon!"));
295             disturb(creature_ptr, FALSE, TRUE);
296         }
297     }
298
299     if ((creature_ptr->muta2 & MUT2_WEIRD_MIND) && !creature_ptr->anti_magic && one_in_(3000)) {
300         if (creature_ptr->tim_esp > 0) {
301             msg_print(_("精神にもやがかかった!", "Your mind feels cloudy!"));
302             set_tim_esp(creature_ptr, 0, TRUE);
303         } else {
304             msg_print(_("精神が広がった!", "Your mind expands!"));
305             set_tim_esp(creature_ptr, creature_ptr->lev, FALSE);
306         }
307     }
308
309     if ((creature_ptr->muta2 & MUT2_NAUSEA) && !creature_ptr->slow_digest && one_in_(9000)) {
310         disturb(creature_ptr, FALSE, TRUE);
311         msg_print(_("胃が痙攣し、食事を失った!", "Your stomach roils, and you lose your lunch!"));
312         msg_print(NULL);
313         set_food(creature_ptr, PY_FOOD_WEAK);
314         if (music_singing_any(creature_ptr))
315             stop_singing(creature_ptr);
316         if (hex_spelling_any(creature_ptr))
317             stop_hex_spell_all(creature_ptr);
318     }
319
320     if ((creature_ptr->muta2 & MUT2_WALK_SHAD) && !creature_ptr->anti_magic && one_in_(12000) && !creature_ptr->current_floor_ptr->inside_arena) {
321         reserve_alter_reality(creature_ptr);
322     }
323
324     if ((creature_ptr->muta2 & MUT2_WARNING) && one_in_(1000)) {
325         int danger_amount = 0;
326         for (MONSTER_IDX monster = 0; monster < creature_ptr->current_floor_ptr->m_max; monster++) {
327             monster_type* m_ptr = &creature_ptr->current_floor_ptr->m_list[monster];
328             monster_race* r_ptr = &r_info[m_ptr->r_idx];
329             if (!monster_is_valid(m_ptr))
330                 continue;
331
332             if (r_ptr->level >= creature_ptr->lev) {
333                 danger_amount += r_ptr->level - creature_ptr->lev + 1;
334             }
335         }
336
337         if (danger_amount > 100)
338             msg_print(_("非常に恐ろしい気がする!", "You feel utterly terrified!"));
339         else if (danger_amount > 50)
340             msg_print(_("恐ろしい気がする!", "You feel terrified!"));
341         else if (danger_amount > 20)
342             msg_print(_("非常に心配な気がする!", "You feel very worried!"));
343         else if (danger_amount > 10)
344             msg_print(_("心配な気がする!", "You feel paranoid!"));
345         else if (danger_amount > 5)
346             msg_print(_("ほとんど安全な気がする。", "You feel almost safe."));
347         else
348             msg_print(_("寂しい気がする。", "You feel lonely."));
349     }
350
351     if ((creature_ptr->muta2 & MUT2_INVULN) && !creature_ptr->anti_magic && one_in_(5000)) {
352         disturb(creature_ptr, FALSE, TRUE);
353         msg_print(_("無敵な気がする!", "You feel invincible!"));
354         msg_print(NULL);
355         (void)set_invuln(creature_ptr, randint1(8) + 8, FALSE);
356     }
357
358     if ((creature_ptr->muta2 & MUT2_SP_TO_HP) && one_in_(2000)) {
359         MANA_POINT wounds = (MANA_POINT)(creature_ptr->mhp - creature_ptr->chp);
360
361         if (wounds > 0) {
362             HIT_POINT healing = creature_ptr->csp;
363             if (healing > wounds)
364                 healing = wounds;
365
366             hp_player(creature_ptr, healing);
367             creature_ptr->csp -= healing;
368             creature_ptr->redraw |= (PR_HP | PR_MANA);
369         }
370     }
371
372     if ((creature_ptr->muta2 & MUT2_HP_TO_SP) && !creature_ptr->anti_magic && one_in_(4000)) {
373         HIT_POINT wounds = (HIT_POINT)(creature_ptr->msp - creature_ptr->csp);
374
375         if (wounds > 0) {
376             HIT_POINT healing = creature_ptr->chp;
377             if (healing > wounds)
378                 healing = wounds;
379
380             creature_ptr->csp += healing;
381             creature_ptr->redraw |= (PR_HP | PR_MANA);
382             take_hit(creature_ptr, DAMAGE_LOSELIFE, healing, _("頭に昇った血", "blood rushing to the head"), -1);
383         }
384     }
385
386     if ((creature_ptr->muta2 & MUT2_DISARM) && one_in_(10000)) {
387         disturb(creature_ptr, FALSE, TRUE);
388         msg_print(_("足がもつれて転んだ!", "You trip over your own feet!"));
389         take_hit(creature_ptr, DAMAGE_NOESCAPE, randint1(creature_ptr->wt / 6), _("転倒", "tripping"), -1);
390         drop_weapons(creature_ptr);
391     }
392 }