OSDN Git Service

[Refactor] #40414 Moved wall_breaker() from spells2.c/h to spells-neighbor.c/h
[hengband/hengband.git] / src / spell / spells-launcher.c
1 #include "spell/spells-launcher.h"
2 #include "effect/effect-characteristics.h"
3 #include "io/targeting.h"
4 #include "spell/process-effect.h"
5 #include "spell/spells-type.h"
6
7 /*!
8  * @brief ボール系スペルの発動 / Cast a ball spell
9  * @param caster_ptr プレーヤーへの参照ポインタ
10  * @param typ 効果属性
11  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
12  * @param dam 威力
13  * @param rad 半径
14  * @return 作用が実際にあった場合TRUEを返す
15  * @details
16  * <pre>
17  * Stop if we hit a monster, act as a "ball"
18  * Allow "target" mode to pass over monsters
19  * Affect grids, objects, and monsters
20  * </pre>
21  */
22 bool fire_ball(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
23 {
24     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
25     if (typ == GF_CHARM_LIVING)
26         flg |= PROJECT_HIDE;
27
28     POSITION tx = caster_ptr->x + 99 * ddx[dir];
29     POSITION ty = caster_ptr->y + 99 * ddy[dir];
30
31     if ((dir == 5) && target_okay(caster_ptr)) {
32         flg &= ~(PROJECT_STOP);
33         tx = target_col;
34         ty = target_row;
35     }
36
37     return project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1);
38 }
39
40 /*!
41  * @brief ブレス系スペルの発動 / Cast a breath spell
42  * @param caster_ptr プレーヤーへの参照ポインタ
43  * @param typ 効果属性
44  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
45  * @param dam 威力
46  * @param rad 半径
47  * @return 作用が実際にあった場合TRUEを返す
48  * @details
49  * <pre>
50  * Stop if we hit a monster, act as a "ball"
51  * Allow "target" mode to pass over monsters
52  * Affect grids, objects, and monsters
53  * </pre>
54  */
55 bool fire_breath(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad) { return fire_ball(caster_ptr, typ, dir, dam, -rad); }
56
57 /*!
58  * @brief ロケット系スペルの発動(詳細な差は確認中) / Cast a ball spell
59  * @param caster_ptr プレーヤーへの参照ポインタ
60  * @param typ 効果属性
61  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
62  * @param dam 威力
63  * @param rad 半径
64  * @return 作用が実際にあった場合TRUEを返す
65  * @details
66  * <pre>
67  * Stop if we hit a monster, act as a "ball"
68  * Allow "target" mode to pass over monsters
69  * Affect grids, objects, and monsters
70  * </pre>
71  */
72 bool fire_rocket(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
73 {
74     POSITION tx = caster_ptr->x + 99 * ddx[dir];
75     POSITION ty = caster_ptr->y + 99 * ddy[dir];
76     if ((dir == 5) && target_okay(caster_ptr)) {
77         tx = target_col;
78         ty = target_row;
79     }
80
81     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
82     return (project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1));
83 }
84
85 /*!
86  * @brief ボール(ハイド)系スペルの発動 / Cast a ball spell
87  * @param caster_ptr プレーヤーへの参照ポインタ
88  * @param typ 効果属性
89  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
90  * @param dam 威力
91  * @param rad 半径
92  * @return 作用が実際にあった場合TRUEを返す
93  * @details
94  * <pre>
95  * Stop if we hit a monster, act as a "ball"
96  * Allow "target" mode to pass over monsters
97  * Affect grids, objects, and monsters
98  * </pre>
99  */
100 bool fire_ball_hide(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
101 {
102     POSITION tx = caster_ptr->x + 99 * ddx[dir];
103     POSITION ty = caster_ptr->y + 99 * ddy[dir];
104     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE;
105     if ((dir == 5) && target_okay(caster_ptr)) {
106         flg &= ~(PROJECT_STOP);
107         tx = target_col;
108         ty = target_row;
109     }
110
111     return (project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1));
112 }
113
114 /*!
115  * @brief メテオ系スペルの発動 / Cast a meteor spell
116  * @param caster_ptr プレーヤーへの参照ポインタ
117  * @param who スぺル詠唱者のモンスターID(0=プレイヤー)
118  * @param typ 効果属性
119  * @param dam 威力
120  * @param rad 半径
121  * @param y 中心点Y座標
122  * @param x 中心点X座標
123  * @return 作用が実際にあった場合TRUEを返す
124  * @details
125  * <pre>
126  * Cast a meteor spell, defined as a ball spell cast by an arbitary monster,
127  * player, or outside source, that starts out at an arbitrary location, and
128  * leaving no trail from the "caster" to the target.  This function is
129  * especially useful for bombardments and similar. -LM-
130  * Option to hurt the player.
131  * </pre>
132  */
133 bool fire_meteor(player_type *caster_ptr, MONSTER_IDX who, EFFECT_ID typ, POSITION y, POSITION x, HIT_POINT dam, POSITION rad)
134 {
135     BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
136     return (project(caster_ptr, who, rad, y, x, dam, typ, flg, -1));
137 }
138
139 /*!
140  * @brief ブラスト系スペルの発動 / Cast a blast spell
141  * @param caster_ptr プレーヤーへの参照ポインタ
142  * @param typ 効果属性
143  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
144  * @param dd 威力ダイス数
145  * @param ds 威力ダイス目
146  * @param num 基本回数
147  * @param dev 回数分散
148  * @return 作用が実際にあった場合TRUEを返す
149  */
150 bool fire_blast(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, DICE_NUMBER dd, DICE_SID ds, int num, int dev)
151 {
152     POSITION ty, tx, y, x;
153     POSITION ly, lx;
154     if (dir == 5) {
155         tx = target_col;
156         ty = target_row;
157
158         lx = 20 * (tx - caster_ptr->x) + caster_ptr->x;
159         ly = 20 * (ty - caster_ptr->y) + caster_ptr->y;
160     } else {
161         ly = ty = caster_ptr->y + 20 * ddy[dir];
162         lx = tx = caster_ptr->x + 20 * ddx[dir];
163     }
164
165     int ld = distance(caster_ptr->y, caster_ptr->x, ly, lx);
166     BIT_FLAGS flg = PROJECT_FAST | PROJECT_THRU | PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE | PROJECT_GRID;
167     bool result = TRUE;
168     for (int i = 0; i < num; i++) {
169         while (TRUE) {
170             /* Get targets for some bolts */
171             y = rand_spread(ly, ld * dev / 20);
172             x = rand_spread(lx, ld * dev / 20);
173
174             if (distance(ly, lx, y, x) <= ld * dev / 20)
175                 break;
176         }
177
178         /* Analyze the "dir" and the "target". */
179         if (!project(caster_ptr, 0, 0, y, x, damroll(dd, ds), typ, flg, -1)) {
180             result = FALSE;
181         }
182     }
183
184     return result;
185 }
186
187 /*!
188  * @brief ボルト系スペルの発動 / Cast a bolt spell.
189  * @param caster_ptr プレーヤーへの参照ポインタ
190  * @param typ 効果属性
191  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
192  * @param dam 威力
193  * @return 作用が実際にあった場合TRUEを返す
194  * @details
195  * <pre>
196  * Stop if we hit a monster, as a "bolt".
197  * Affect monsters and grids (not objects).
198  * </pre>
199  */
200 bool fire_bolt(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
201 {
202     BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_GRID;
203     if (typ != GF_ARROW)
204         flg |= PROJECT_REFLECTABLE;
205     return (project_hook(caster_ptr, typ, dir, dam, flg));
206 }
207
208 /*!
209  * @brief ビーム系スペルの発動 / Cast a beam spell.
210  * @param caster_ptr プレーヤーへの参照ポインタ
211  * @param typ 効果属性
212  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
213  * @param dam 威力
214  * @return 作用が実際にあった場合TRUEを返す
215  * @details
216  * <pre>
217  * Pass through monsters, as a "beam".
218  * Affect monsters, grids and objects.
219  * </pre>
220  */
221 bool fire_beam(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
222 {
223     BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM;
224     return (project_hook(caster_ptr, typ, dir, dam, flg));
225 }
226
227 /*!
228  * @brief 確率に応じたボルト系/ビーム系スペルの発動 / Cast a bolt spell, or rarely, a beam spell.
229  * @param caster_ptr プレーヤーへの参照ポインタ
230  * @param prob ビーム化する確率(%)
231  * @param typ 効果属性
232  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
233  * @param dam 威力
234  * @return 作用が実際にあった場合TRUEを返す
235  * @details
236  * <pre>
237  * Pass through monsters, as a "beam".
238  * Affect monsters, grids and objects.
239  * </pre>
240  */
241 bool fire_bolt_or_beam(player_type *caster_ptr, PERCENTAGE prob, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
242 {
243     if (randint0(100) < prob) {
244         return (fire_beam(caster_ptr, typ, dir, dam));
245     }
246
247     return (fire_bolt(caster_ptr, typ, dir, dam));
248 }
249
250 /*!
251  * @brief 指定方向に飛び道具を飛ばす (フラグ任意指定) / Apply a "project()" in a direction (or at the target)
252  * @param caster_ptr プレーヤーへの参照ポインタ
253  * @param typ 効果属性
254  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
255  * @param dam 威力
256  * @param flg フラグ
257  * @return 作用が実際にあった場合TRUEを返す
258  */
259 bool project_hook(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, BIT_FLAGS flg)
260 {
261     flg |= (PROJECT_THRU);
262     POSITION tx = caster_ptr->x + ddx[dir];
263     POSITION ty = caster_ptr->y + ddy[dir];
264     if ((dir == 5) && target_okay(caster_ptr)) {
265         tx = target_col;
266         ty = target_row;
267     }
268
269     return (project(caster_ptr, 0, 0, ty, tx, dam, typ, flg, -1));
270 }