OSDN Git Service

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