OSDN Git Service

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