2 * @brief ダイス目により様々な効果を及ぼす魔法の処理
7 #include "spell-kind/spells-random.h"
8 #include "avatar/avatar.h"
9 #include "effect/attribute-types.h"
10 #include "effect/effect-characteristics.h"
11 #include "effect/effect-processor.h"
12 #include "hpmp/hp-mp-processor.h"
13 #include "monster-floor/monster-summon.h"
14 #include "monster-floor/place-monster-types.h"
15 #include "mutation/mutation-investor-remover.h"
16 #include "player-base/player-class.h"
17 #include "player/player-damage.h"
18 #include "spell-kind/earthquake.h"
19 #include "spell-kind/spells-equipment.h"
20 #include "spell-kind/spells-floor.h"
21 #include "spell-kind/spells-genocide.h"
22 #include "spell-kind/spells-launcher.h"
23 #include "spell-kind/spells-lite.h"
24 #include "spell-kind/spells-neighbor.h"
25 #include "spell-kind/spells-sight.h"
26 #include "spell-kind/spells-specific-bolt.h"
27 #include "spell-kind/spells-teleport.h"
28 #include "spell/spells-diceroll.h"
29 #include "spell/spells-status.h"
30 #include "spell/spells-summon.h"
31 #include "spell/summon-types.h"
32 #include "status/bad-status-setter.h"
33 #include "status/base-status.h"
34 #include "status/experience.h"
35 #include "system/floor-type-definition.h"
36 #include "system/player-type-definition.h"
37 #include "target/target-getter.h"
38 #include "view/display-messages.h"
42 * @return 作用が実際にあった場合TRUEを返す
44 void call_chaos(PlayerType *player_ptr)
46 AttributeType hurt_types[32] = { AttributeType::ELEC, AttributeType::POIS, AttributeType::ACID, AttributeType::COLD, AttributeType::FIRE,
47 AttributeType::MISSILE, AttributeType::PLASMA, AttributeType::HOLY_FIRE, AttributeType::WATER, AttributeType::LITE,
48 AttributeType::DARK, AttributeType::FORCE, AttributeType::INERTIAL, AttributeType::MANA, AttributeType::METEOR, AttributeType::ICE,
49 AttributeType::CHAOS, AttributeType::NETHER, AttributeType::DISENCHANT, AttributeType::SHARDS, AttributeType::SOUND, AttributeType::NEXUS,
50 AttributeType::CONFUSION, AttributeType::TIME, AttributeType::GRAVITY, AttributeType::ROCKET, AttributeType::NUKE, AttributeType::HELL_FIRE,
51 AttributeType::DISINTEGRATE, AttributeType::PSY_SPEAR, AttributeType::VOID_MAGIC, AttributeType::ABYSS };
53 AttributeType chaos_type = hurt_types[randint0(32)];
54 bool line_chaos = false;
60 for (int dummy = 1; dummy < 10; dummy++) {
63 fire_beam(player_ptr, chaos_type, dummy, 150);
65 fire_ball(player_ptr, chaos_type, dummy, 150, 2);
73 fire_ball(player_ptr, chaos_type, 0, 500, 8);
77 if (!get_aim_dir(player_ptr, &dir))
80 fire_beam(player_ptr, chaos_type, dir, 250);
82 fire_ball(player_ptr, chaos_type, dir, 250, 3 + (player_ptr->lev / 35));
86 * @brief TY_CURSE処理発動 / Activate the evil Topi Ylinen curse
87 * @param player_ptr プレイヤーへの参照ポインタ
88 * @param stop_ty 再帰処理停止フラグ
90 * @return 作用が実際にあった場合TRUEを返す
93 * rr9: Stop the nasty things when a Cyberdemon is summoned
94 * or the player gets paralyzed.
97 bool activate_ty_curse(PlayerType *player_ptr, bool stop_ty, int *count)
99 BIT_FLAGS flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
100 bool is_first_curse = true;
101 auto *floor_ptr = player_ptr->current_floor_ptr;
102 while (is_first_curse || (one_in_(3) && !stop_ty)) {
103 is_first_curse = false;
104 switch (randint1(34)) {
108 msg_print(_("地面が揺れた...", "The ground trembles..."));
109 earthquake(player_ptr, player_ptr->y, player_ptr->x, 5 + randint0(10), 0);
117 HIT_POINT dam = damroll(10, 10);
118 msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
119 project(player_ptr, 0, 8, player_ptr->y, player_ptr->x, dam, AttributeType::MANA, flg);
120 take_hit(player_ptr, DAMAGE_NOESCAPE, dam, _("純粋な魔力の解放", "released pure mana"));
128 msg_print(_("周囲の空間が歪んだ!", "Space warps about you!"));
129 teleport_player(player_ptr, damroll(10, 10), TELEPORT_PASSIVE);
131 (*count) += activate_hi_summon(player_ptr, player_ptr->y, player_ptr->x, false);
137 msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
138 wall_breaker(player_ptr);
140 project(player_ptr, 0, 7, player_ptr->y, player_ptr->x, 50, AttributeType::KILL_WALL, flg);
141 take_hit(player_ptr, DAMAGE_NOESCAPE, 50, _("エネルギーのうねり", "surge of energy"));
152 aggravate_monsters(player_ptr, 0);
159 (*count) += activate_hi_summon(player_ptr, player_ptr->y, player_ptr->x, false);
167 (*count) += summon_specific(
168 player_ptr, 0, player_ptr->y, player_ptr->x, floor_ptr->dun_level, SUMMON_NONE, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));
175 msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
176 lose_exp(player_ptr, player_ptr->exp / 16);
185 auto is_statue = stop_ty;
186 is_statue |= player_ptr->free_act && (randint1(125) < player_ptr->skill_sav);
187 is_statue |= PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER);
189 msg_print(_("彫像になった気分だ!", "You feel like a statue!"));
190 TIME_EFFECT turns = player_ptr->free_act ? randint1(3) : randint1(13);
191 (void)BadStatusSetter(player_ptr).mod_paralysis(turns);
203 (void)do_dec_stat(player_ptr, randint0(6));
208 msg_print(_("ほえ?私は誰?ここで何してる?", "Huh? Who am I? What am I doing here?"));
209 lose_all_info(player_ptr);
214 if ((floor_ptr->dun_level > 65) && !stop_ty) {
215 (*count) += summon_cyber(player_ptr, -1, player_ptr->y, player_ptr->x);
224 for (int i = 0; i < A_MAX; i++) {
226 (void)do_dec_stat(player_ptr, i);
227 } while (one_in_(2));
236 * @brief 運命の輪、並びにカオス的な効果の発動
237 * @param player_ptr プレイヤーへの参照ポインタ
238 * @param spell ランダムな効果を選択するための基準ID
240 void wild_magic(PlayerType *player_ptr, int spell)
242 int type = SUMMON_MOLD + randint0(6);
243 if (type < SUMMON_MOLD)
245 else if (type > SUMMON_MIMIC)
248 auto *floor_ptr = player_ptr->current_floor_ptr;
249 switch (randint1(spell) + randint1(8) + 1) {
253 teleport_player(player_ptr, 10, TELEPORT_PASSIVE);
258 teleport_player(player_ptr, 100, TELEPORT_PASSIVE);
262 teleport_player(player_ptr, 200, TELEPORT_PASSIVE);
267 unlite_area(player_ptr, 10, 3);
272 lite_area(player_ptr, damroll(2, 3), 2);
275 destroy_doors_touch(player_ptr);
279 wall_breaker(player_ptr);
282 sleep_monsters_touch(player_ptr);
286 trap_creation(player_ptr, player_ptr->y, player_ptr->x);
290 door_creation(player_ptr, player_ptr->y, player_ptr->x);
295 aggravate_monsters(player_ptr, 0);
298 earthquake(player_ptr, player_ptr->y, player_ptr->x, 5, 0);
302 (void)gain_mutation(player_ptr, 0);
306 apply_disenchant(player_ptr, 1);
309 lose_all_info(player_ptr);
312 fire_ball(player_ptr, AttributeType::CHAOS, 0, spell + 5, 1 + (spell / 10));
315 wall_stone(player_ptr);
319 for (int counter = 0; counter < 8; counter++) {
320 (void)summon_specific(
321 player_ptr, 0, player_ptr->y, player_ptr->x, (floor_ptr->dun_level * 3) / 2, i2enum<summon_type>(type), (PM_ALLOW_GROUP | PM_NO_PET));
327 activate_hi_summon(player_ptr, player_ptr->y, player_ptr->x, false);
330 (void)summon_cyber(player_ptr, -1, player_ptr->y, player_ptr->x);
334 (void)activate_ty_curse(player_ptr, false, &count);
341 * @brief 「ワンダー」のランダムな効果を決定して処理する。
342 * @param player_ptr プレイヤーへの参照ポインタ
345 * This spell should become more useful (more controlled) as the\n
346 * player gains experience levels. Thus, add 1/5 of the player's\n
347 * level to the die roll. This eliminates the worst effects later on,\n
348 * while keeping the results quite random. It also allows some potent\n
349 * effects only at high level.
351 void cast_wonder(PlayerType *player_ptr, DIRECTION dir)
353 PLAYER_LEVEL plev = player_ptr->lev;
354 int die = randint1(100) + plev / 5;
355 int vir = virtue_number(player_ptr, V_CHANCE);
357 if (player_ptr->virtues[vir - 1] > 0) {
358 while (randint1(400) < player_ptr->virtues[vir - 1])
361 while (randint1(400) < (0 - player_ptr->virtues[vir - 1]))
367 chg_virtue(player_ptr, V_CHANCE, 1);
371 msg_print(_("あなたは力がみなぎるのを感じた!", "You feel a surge of power!"));
375 clone_monster(player_ptr, dir);
380 speed_monster(player_ptr, dir, plev);
385 heal_monster(player_ptr, dir, damroll(4, 6));
390 poly_monster(player_ptr, dir, plev);
395 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr) - 10, AttributeType::MISSILE, dir, damroll(3 + ((plev - 1) / 5), 4));
400 confuse_monster(player_ptr, dir, plev);
405 fire_ball(player_ptr, AttributeType::POIS, dir, 20 + (plev / 2), 3);
410 (void)lite_line(player_ptr, dir, damroll(6, 8));
415 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr) - 10, AttributeType::ELEC, dir, damroll(3 + ((plev - 5) / 4), 8));
420 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr) - 10, AttributeType::COLD, dir, damroll(5 + ((plev - 5) / 4), 8));
425 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr), AttributeType::ACID, dir, damroll(6 + ((plev - 5) / 4), 8));
430 fire_bolt_or_beam(player_ptr, beam_chance(player_ptr), AttributeType::FIRE, dir, damroll(8 + ((plev - 5) / 4), 8));
435 hypodynamic_bolt(player_ptr, dir, 75);
440 fire_ball(player_ptr, AttributeType::ELEC, dir, 30 + plev / 2, 2);
445 fire_ball(player_ptr, AttributeType::ACID, dir, 40 + plev, 2);
450 fire_ball(player_ptr, AttributeType::ICE, dir, 70 + plev, 3);
455 fire_ball(player_ptr, AttributeType::FIRE, dir, 80 + plev, 3);
460 hypodynamic_bolt(player_ptr, dir, 100 + plev);
465 earthquake(player_ptr, player_ptr->y, player_ptr->x, 12, 0);
470 (void)destroy_area(player_ptr, player_ptr->y, player_ptr->x, 13 + randint0(5), false);
475 symbol_genocide(player_ptr, plev + 50, true);
480 dispel_monsters(player_ptr, 120);
484 dispel_monsters(player_ptr, 150);
485 slow_monsters(player_ptr, plev);
486 sleep_monsters(player_ptr, plev);
487 hp_player(player_ptr, 300);