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"
9 * @brief ボール系スペルの発動 / Cast a ball spell
10 * @param caster_ptr プレーヤーへの参照ポインタ
12 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
15 * @return 作用が実際にあった場合TRUEを返す
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
23 bool fire_ball(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
25 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
26 if (typ == GF_CHARM_LIVING)
29 POSITION tx = caster_ptr->x + 99 * ddx[dir];
30 POSITION ty = caster_ptr->y + 99 * ddy[dir];
32 if ((dir == 5) && target_okay(caster_ptr)) {
33 flg &= ~(PROJECT_STOP);
38 return project(caster_ptr, 0, rad, ty, tx, dam, typ, flg).notice;
42 * @brief ブレス系スペルの発動 / Cast a breath spell
43 * @param caster_ptr プレーヤーへの参照ポインタ
45 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
48 * @return 作用が実際にあった場合TRUEを返す
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
56 bool fire_breath(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
58 return fire_ball(caster_ptr, typ, dir, dam, -rad);
62 * @brief ロケット系スペルの発動(詳細な差は確認中) / Cast a ball spell
63 * @param caster_ptr プレーヤーへの参照ポインタ
65 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
68 * @return 作用が実際にあった場合TRUEを返す
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
76 bool fire_rocket(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
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)) {
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;
90 * @brief ボール(ハイド)系スペルの発動 / Cast a ball spell
91 * @param caster_ptr プレーヤーへの参照ポインタ
93 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
96 * @return 作用が実際にあった場合TRUEを返す
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
104 bool fire_ball_hide(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
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);
115 return project(caster_ptr, 0, rad, ty, tx, dam, typ, flg).notice;
119 * @brief メテオ系スペルの発動 / Cast a meteor spell
120 * @param caster_ptr プレーヤーへの参照ポインタ
121 * @param who スぺル詠唱者のモンスターID(0=プレイヤー)
127 * @return 作用が実際にあった場合TRUEを返す
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.
137 bool fire_meteor(player_type *caster_ptr, MONSTER_IDX who, EFFECT_ID typ, POSITION y, POSITION x, HIT_POINT dam, POSITION rad)
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;
144 * @brief ブラスト系スペルの発動 / Cast a blast spell
145 * @param caster_ptr プレーヤーへの参照ポインタ
147 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
152 * @return 作用が実際にあった場合TRUEを返す
154 bool fire_blast(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, DICE_NUMBER dd, DICE_SID ds, int num, int dev)
156 POSITION ty, tx, y, x;
162 lx = 20 * (tx - caster_ptr->x) + caster_ptr->x;
163 ly = 20 * (ty - caster_ptr->y) + caster_ptr->y;
165 ly = ty = caster_ptr->y + 20 * ddy[dir];
166 lx = tx = caster_ptr->x + 20 * ddx[dir];
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;
172 for (int i = 0; i < num; i++) {
174 /* Get targets for some bolts */
175 y = rand_spread(ly, ld * dev / 20);
176 x = rand_spread(lx, ld * dev / 20);
178 if (distance(ly, lx, y, x) <= ld * dev / 20)
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)
192 * @brief ボルト系スペルの発動 / Cast a bolt spell.
193 * @param caster_ptr プレーヤーへの参照ポインタ
195 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
197 * @return 作用が実際にあった場合TRUEを返す
200 * Stop if we hit a monster, as a "bolt".
201 * Affect monsters and grids (not objects).
204 bool fire_bolt(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
206 BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_GRID;
208 flg |= PROJECT_REFLECTABLE;
209 return (project_hook(caster_ptr, typ, dir, dam, flg));
213 * @brief ビーム系スペルの発動 / Cast a beam spell.
214 * @param caster_ptr プレーヤーへの参照ポインタ
216 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
218 * @return 作用が実際にあった場合TRUEを返す
221 * Pass through monsters, as a "beam".
222 * Affect monsters, grids and objects.
225 bool fire_beam(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
227 BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM;
228 return (project_hook(caster_ptr, typ, dir, dam, flg));
232 * @brief 確率に応じたボルト系/ビーム系スペルの発動 / Cast a bolt spell, or rarely, a beam spell.
233 * @param caster_ptr プレーヤーへの参照ポインタ
234 * @param prob ビーム化する確率(%)
236 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
238 * @return 作用が実際にあった場合TRUEを返す
241 * Pass through monsters, as a "beam".
242 * Affect monsters, grids and objects.
245 bool fire_bolt_or_beam(player_type *caster_ptr, PERCENTAGE prob, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
247 if (randint0(100) < prob) {
248 return (fire_beam(caster_ptr, typ, dir, dam));
251 return (fire_bolt(caster_ptr, typ, dir, dam));
255 * @brief 指定方向に飛び道具を飛ばす (フラグ任意指定) / Apply a "project()" in a direction (or at the target)
256 * @param caster_ptr プレーヤーへの参照ポインタ
258 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
261 * @return 作用が実際にあった場合TRUEを返す
263 bool project_hook(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, BIT_FLAGS flg)
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)) {
273 return project(caster_ptr, 0, 0, ty, tx, dam, typ, flg).notice;