OSDN Git Service

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