OSDN Git Service

[Refactor] enum spells-typeをenum class AttributeTypeに置換
[hengbandforosx/hengbandosx.git] / src / spell-kind / blood-curse.cpp
1 #include "spell-kind/blood-curse.h"
2 #include "effect/effect-characteristics.h"
3 #include "effect/effect-processor.h"
4 #include "monster-floor/monster-summon.h"
5 #include "monster-floor/place-monster-types.h"
6 #include "spell-kind/earthquake.h"
7 #include "spell-kind/spells-sight.h"
8 #include "spell-kind/spells-teleport.h"
9 #include "effect/attribute-types.h"
10 #include "spell/spells-summon.h"
11 #include "spell/summon-types.h"
12 #include "status/base-status.h"
13 #include "status/experience.h"
14 #include "system/floor-type-definition.h"
15 #include "system/grid-type-definition.h"
16 #include "system/monster-type-definition.h"
17 #include "system/player-type-definition.h"
18 #include "view/display-messages.h"
19
20 void blood_curse_to_enemy(player_type *player_ptr, MONSTER_IDX m_idx)
21 {
22     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
23     grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
24     BIT_FLAGS curse_flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
25     int count = 0;
26     bool is_first_loop = true;
27     while (is_first_loop || one_in_(5)) {
28         is_first_loop = false;
29         switch (randint1(28)) {
30         case 1:
31         case 2:
32             if (!count) {
33                 msg_print(_("地面が揺れた...", "The ground trembles..."));
34                 earthquake(player_ptr, m_ptr->fy, m_ptr->fx, 4 + randint0(4), 0);
35                 if (!one_in_(6))
36                     break;
37             }
38             /* Fall through */
39         case 3:
40         case 4:
41         case 5:
42         case 6:
43             if (!count) {
44                 int extra_dam = damroll(10, 10);
45                 msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
46                 project(player_ptr, 0, 8, m_ptr->fy, m_ptr->fx, extra_dam, AttributeType::MANA, curse_flg);
47                 if (!one_in_(6))
48                     break;
49             }
50             /* Fall through */
51         case 7:
52         case 8:
53             if (!count) {
54                 msg_print(_("空間が歪んだ!", "Space warps about you!"));
55                 if (m_ptr->r_idx)
56                     teleport_away(player_ptr, g_ptr->m_idx, damroll(10, 10), TELEPORT_PASSIVE);
57                 if (one_in_(13))
58                     count += activate_hi_summon(player_ptr, m_ptr->fy, m_ptr->fx, true);
59                 if (!one_in_(6))
60                     break;
61             }
62             /* Fall through */
63         case 9:
64         case 10:
65         case 11:
66             msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
67             project(player_ptr, 0, 7, m_ptr->fy, m_ptr->fx, 50, AttributeType::DISINTEGRATE, curse_flg);
68             if (!one_in_(6))
69                 break;
70             /* Fall through */
71         case 12:
72         case 13:
73         case 14:
74         case 15:
75         case 16:
76             aggravate_monsters(player_ptr, 0);
77             if (!one_in_(6))
78                 break;
79             /* Fall through */
80         case 17:
81         case 18:
82             count += activate_hi_summon(player_ptr, m_ptr->fy, m_ptr->fx, true);
83             if (!one_in_(6))
84                 break;
85             /* Fall through */
86         case 19:
87         case 20:
88         case 21:
89         case 22: {
90             bool pet = !one_in_(3);
91             BIT_FLAGS mode = PM_ALLOW_GROUP;
92
93             if (pet)
94                 mode |= PM_FORCE_PET;
95             else
96                 mode |= (PM_NO_PET | PM_FORCE_FRIENDLY);
97
98             count += summon_specific(player_ptr, (pet ? -1 : 0), player_ptr->y, player_ptr->x,
99                 (pet ? player_ptr->lev * 2 / 3 + randint1(player_ptr->lev / 2) : player_ptr->current_floor_ptr->dun_level), SUMMON_NONE, mode);
100             if (!one_in_(6))
101                 break;
102         }
103             /* Fall through */
104         case 23:
105         case 24:
106         case 25:
107             if (player_ptr->hold_exp && (randint0(100) < 75))
108                 break;
109
110             msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
111             if (player_ptr->hold_exp)
112                 lose_exp(player_ptr, player_ptr->exp / 160);
113             else
114                 lose_exp(player_ptr, player_ptr->exp / 16);
115             if (!one_in_(6))
116                 break;
117             /* Fall through */
118         case 26:
119         case 27:
120         case 28:
121         default: {
122             if (one_in_(13)) {
123                 for (int i = 0; i < A_MAX; i++) {
124                     do {
125                         (void)do_dec_stat(player_ptr, i);
126                     } while(one_in_(2));
127                 }
128             } else {
129                 (void)do_dec_stat(player_ptr, randint0(6));
130             }
131
132             break;
133         }
134         }
135     }
136 }