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 "system/player-type-definition.h"
6 #include "target/target-checker.h"
7 #include "util/bit-flags-calculator.h"
10 * @brief ボール系スペルの発動 / Cast a ball spell
11 * @param player_ptr プレイヤーへの参照ポインタ
13 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
16 * @return 作用が実際にあった場合TRUEを返す
19 * Stop if we hit a monster, act as a "ball"
20 * Allow "target" mode to pass over monsters
21 * Affect grids, objects, and monsters
24 bool fire_ball(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam, POSITION rad, std::optional<CapturedMonsterType *> cap_mon_ptr)
26 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
27 if (typ == AttributeType::CHARM_LIVING) {
31 POSITION tx = player_ptr->x + 99 * ddx[dir];
32 POSITION ty = player_ptr->y + 99 * ddy[dir];
34 if ((dir == 5) && target_okay(player_ptr)) {
35 flg &= ~(PROJECT_STOP);
40 return project(player_ptr, 0, rad, ty, tx, dam, typ, flg, cap_mon_ptr).notice;
44 * @brief ブレス系スペルの発動 / Cast a breath spell
45 * @param player_ptr プレイヤーへの参照ポインタ
47 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
50 * @return 作用が実際にあった場合TRUEを返す
53 * Stop if we hit a monster, act as a "ball"
54 * Allow "target" mode to pass over monsters
55 * Affect grids, objects, and monsters
58 bool fire_breath(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam, POSITION rad)
60 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_BREATH;
62 auto tx = player_ptr->x + 99 * ddx[dir];
63 auto ty = player_ptr->y + 99 * ddy[dir];
65 if ((dir == 5) && target_okay(player_ptr)) {
66 reset_bits(flg, PROJECT_STOP);
71 return project(player_ptr, 0, rad, ty, tx, dam, typ, flg).notice;
75 * @brief ロケット系スペルの発動(詳細な差は確認中) / Cast a ball spell
76 * @param player_ptr プレイヤーへの参照ポインタ
78 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
81 * @return 作用が実際にあった場合TRUEを返す
84 * Stop if we hit a monster, act as a "ball"
85 * Allow "target" mode to pass over monsters
86 * Affect grids, objects, and monsters
89 bool fire_rocket(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam, POSITION rad)
91 POSITION tx = player_ptr->x + 99 * ddx[dir];
92 POSITION ty = player_ptr->y + 99 * ddy[dir];
93 if ((dir == 5) && target_okay(player_ptr)) {
98 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
99 return project(player_ptr, 0, rad, ty, tx, dam, typ, flg).notice;
103 * @brief ボール(ハイド)系スペルの発動 / Cast a ball spell
104 * @param player_ptr プレイヤーへの参照ポインタ
106 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
109 * @return 作用が実際にあった場合TRUEを返す
112 * Stop if we hit a monster, act as a "ball"
113 * Allow "target" mode to pass over monsters
114 * Affect grids, objects, and monsters
117 bool fire_ball_hide(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam, POSITION rad)
119 POSITION tx = player_ptr->x + 99 * ddx[dir];
120 POSITION ty = player_ptr->y + 99 * ddy[dir];
121 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE;
122 if ((dir == 5) && target_okay(player_ptr)) {
123 flg &= ~(PROJECT_STOP);
128 return project(player_ptr, 0, rad, ty, tx, dam, typ, flg).notice;
132 * @brief メテオ系スペルの発動 / Cast a meteor spell
133 * @param player_ptr プレイヤーへの参照ポインタ
134 * @param src_idx スぺル詠唱者のモンスターID(0=プレイヤー)
140 * @return 作用が実際にあった場合TRUEを返す
143 * Cast a meteor spell, defined as a ball spell cast by an arbitary monster,
144 * player, or outside source, that starts out at an arbitrary location, and
145 * leaving no trail from the "caster" to the target. This function is
146 * especially useful for bombardments and similar. -LM-
147 * Option to hurt the player.
150 bool fire_meteor(PlayerType *player_ptr, MONSTER_IDX src_idx, AttributeType typ, POSITION y, POSITION x, int dam, POSITION rad)
152 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
153 return project(player_ptr, src_idx, rad, y, x, dam, typ, flg).notice;
157 * @brief ブラスト系スペルの発動 / Cast a blast spell
158 * @param player_ptr プレイヤーへの参照ポインタ
160 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
165 * @return 作用が実際にあった場合TRUEを返す
167 bool fire_blast(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, DICE_NUMBER dd, DICE_SID ds, int num, int dev)
169 POSITION ty, tx, y, x;
175 lx = 20 * (tx - player_ptr->x) + player_ptr->x;
176 ly = 20 * (ty - player_ptr->y) + player_ptr->y;
178 ly = ty = player_ptr->y + 20 * ddy[dir];
179 lx = tx = player_ptr->x + 20 * ddx[dir];
182 int ld = distance(player_ptr->y, player_ptr->x, ly, lx);
183 BIT_FLAGS flg = PROJECT_FAST | PROJECT_THRU | PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE | PROJECT_GRID;
185 for (int i = 0; i < num; i++) {
187 /* Get targets for some bolts */
188 y = rand_spread(ly, ld * dev / 20);
189 x = rand_spread(lx, ld * dev / 20);
191 if (distance(ly, lx, y, x) <= ld * dev / 20) {
196 /* Analyze the "dir" and the "target". */
197 const auto proj_res = project(player_ptr, 0, 0, y, x, damroll(dd, ds), typ, flg);
198 if (!proj_res.notice) {
207 * @brief ボルト系スペルの発動 / Cast a bolt spell.
208 * @param player_ptr プレイヤーへの参照ポインタ
210 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
212 * @return 作用が実際にあった場合TRUEを返す
215 * Stop if we hit a monster, as a "bolt".
216 * Affect monsters and grids (not objects).
219 bool fire_bolt(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam)
221 BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_GRID;
222 if (typ != AttributeType::MONSTER_SHOOT) {
223 flg |= PROJECT_REFLECTABLE;
225 return project_hook(player_ptr, typ, dir, dam, flg);
229 * @brief ビーム系スペルの発動 / Cast a beam spell.
230 * @param player_ptr プレイヤーへの参照ポインタ
232 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
234 * @return 作用が実際にあった場合TRUEを返す
237 * Pass through monsters, as a "beam".
238 * Affect monsters, grids and objects.
241 bool fire_beam(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam)
243 BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM;
244 return project_hook(player_ptr, typ, dir, dam, flg);
248 * @brief 確率に応じたボルト系/ビーム系スペルの発動 / Cast a bolt spell, or rarely, a beam spell.
249 * @param player_ptr プレイヤーへの参照ポインタ
250 * @param prob ビーム化する確率(%)
252 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
254 * @return 作用が実際にあった場合TRUEを返す
257 * Pass through monsters, as a "beam".
258 * Affect monsters, grids and objects.
261 bool fire_bolt_or_beam(PlayerType *player_ptr, PERCENTAGE prob, AttributeType typ, DIRECTION dir, int dam)
263 if (randint0(100) < prob) {
264 return (fire_beam(player_ptr, typ, dir, dam));
267 return (fire_bolt(player_ptr, typ, dir, dam));
271 * @brief 指定方向に飛び道具を飛ばす (フラグ任意指定) / Apply a "project()" in a direction (or at the target)
272 * @param player_ptr プレイヤーへの参照ポインタ
274 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
277 * @return 作用が実際にあった場合TRUEを返す
279 bool project_hook(PlayerType *player_ptr, AttributeType typ, DIRECTION dir, int dam, BIT_FLAGS flg)
281 flg |= (PROJECT_THRU);
282 POSITION tx = player_ptr->x + ddx[dir];
283 POSITION ty = player_ptr->y + ddy[dir];
284 if ((dir == 5) && target_okay(player_ptr)) {
289 return project(player_ptr, 0, 0, ty, tx, dam, typ, flg).notice;