OSDN Git Service

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