OSDN Git Service

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