#define PROJECT_NO_HANGEKI 0x1000
#define PROJECT_PATH 0x2000
#define PROJECT_FAST 0x4000
+#define PROJECT_LOS 0x8000
/*
* Bit flags for the "enchant()" function
/* spells1.c */
extern bool in_disintegration_range(int y1, int x1, int y2, int x2);
-extern void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, bool disint_ball);
+extern void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, int typ);
extern int take_hit(int damage_type, int damage, cptr kb_str, int monspell);
extern u16b bolt_pict(int y, int x, int ny, int nx, int typ);
extern sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg);
char m_poss[80];
#endif
bool no_inate = FALSE;
- bool do_disi = FALSE;
+ bool do_br_lite = FALSE;
+ bool do_br_disi = FALSE;
int dam = 0;
u32b mode = 0L;
int s_num_6 = (easy_band ? 2 : 6);
/* Check path */
if (projectable(m_ptr->fy, m_ptr->fx, y, x))
{
- /* Breath disintegration to the glyph if possible */
- if (!have_flag(f_flags_bold(y, x), FF_PROJECT) && (f4 & RF4_BR_DISI) && one_in_(2)) do_disi = TRUE;
+ if (!have_flag(f_flags_bold(y, x), FF_PROJECT))
+ {
+ /* Breath lite to the transparent wall if possible */
+ if ((f4 & RF4_BR_LITE) && cave_los_bold(y, x) && one_in_(2)) do_br_lite = TRUE;
+
+ /* Breath disintegration to the wall if possible */
+ if ((f4 & RF4_BR_DISI) && have_flag(f_flags_bold(y, x), FF_HURT_DISI) && one_in_(2)) do_br_disi = TRUE;
+ }
}
/* Check path to next grid */
in_disintegration_range(m_ptr->fy, m_ptr->fx, y, x) &&
(one_in_(10) || (projectable(y, x, m_ptr->fy, m_ptr->fx) && one_in_(2))))
{
- do_disi = TRUE;
+ do_br_disi = TRUE;
+ success = TRUE;
+ }
+ else if ((f4 & RF4_BR_LITE) &&
+ (m_ptr->cdis < MAX_RANGE/2) &&
+ los(m_ptr->fy, m_ptr->fx, y, x) &&
+ (one_in_(10) || (projectable(y, x, m_ptr->fy, m_ptr->fx) && one_in_(2))))
+ {
+ do_br_lite = TRUE;
success = TRUE;
}
else
monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
#endif
- if (do_disi)
- thrown_spell = 96+31;
+ if (do_br_lite && do_br_disi)
+ {
+ if (one_in_(2)) thrown_spell = 96+14; /* RF4_BR_LITE */
+ else thrown_spell = 96+31; /* RF4_BR_DISI */
+ }
+ else if (do_br_lite)
+ {
+ thrown_spell = 96+14; /* RF4_BR_LITE */
+ }
+ else if (do_br_disi)
+ {
+ thrown_spell = 96+31; /* RF4_BR_DISI */
+ }
else
{
int attempt = 10;
return TRUE;
}
-static bool breath_direct(int y1, int x1, int y2, int x2, int rad, bool disint_ball, bool friend)
+static bool breath_direct(int y1, int x1, int y2, int x2, int rad, int typ, bool friend)
{
/* Must be the same as projectable() */
bool hit2 = FALSE;
bool hityou = FALSE;
+ int flg;
+
+ switch (typ)
+ {
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ flg = PROJECT_LOS;
+ break;
+ case GF_DISINTEGRATE:
+ flg = PROJECT_DISI;
+ break;
+ default:
+ flg = 0;
+ break;
+ }
+
/* Check the projection path */
- grid_n = project_path(grid_g, MAX_RANGE, y1, x1, y2, x2, disint_ball ? PROJECT_DISI : 0);
- breath_shape(grid_g, grid_n, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, y2, x2, disint_ball);
+ grid_n = project_path(grid_g, MAX_RANGE, y1, x1, y2, x2, flg);
+ breath_shape(grid_g, grid_n, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, y2, x2, typ);
for (i = 0; i < grids; i++)
{
/* Expected breath radius */
int rad = (r_ptr->flags2 & RF2_POWERFUL) ? 3 : 2;
- if (!breath_direct(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, FALSE, TRUE))
+ if (!breath_direct(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, 0, TRUE))
{
f4 &= ~(RF4_BREATH_MASK);
f5 &= ~(RF5_BREATH_MASK);
f6 &= ~(RF6_BREATH_MASK);
}
+ else if ((f4 & RF4_BR_LITE) &&
+ !breath_direct(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_LITE, TRUE))
+ {
+ f4 &= ~(RF4_BR_LITE);
+ }
else if ((f4 & RF4_BR_DISI) &&
- !breath_direct(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, TRUE, TRUE))
+ !breath_direct(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx, rad, GF_DISINTEGRATE, TRUE))
{
f4 &= ~(RF4_BR_DISI);
}
{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
{
if ((n > 0) && cave_stop_disintegration(y, x)) break;
}
+ else if (flg & (PROJECT_LOS))
+ {
+ if ((n > 0) && !cave_los_bold(y, x)) break;
+ }
else if (!(flg & (PROJECT_PATH)))
{
/* Always stop at non-initial wall grids */
/*
* breath shape
*/
-void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, bool disint_ball)
+void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, int typ)
{
int by = y1;
int bx = x1;
/* Enforce an arc */
if (distance(by, bx, y, x) != cdis) continue;
-
- if (disint_ball)
+ switch (typ)
{
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ /* Lights are stopped by opaque terrains */
+ if (!los(by, bx, y, x)) continue;
+ break;
+ case GF_DISINTEGRATE:
/* Disintegration are stopped only by perma-walls */
if (!in_disintegration_range(by, bx, y, x)) continue;
- }
- else
- {
- /* The blast is stopped by walls */
+ break;
+ default:
+ /* Ball explosions are stopped by walls */
if (!projectable(by, bx, y, x)) continue;
+ break;
}
/* Save this grid */
grids++;
}
- if (typ == GF_DISINTEGRATE)
+ switch (typ)
{
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_LOS);
+ break;
+ case GF_DISINTEGRATE:
flg |= (PROJECT_GRID);
if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_DISI);
+ break;
}
/* Calculate the projection path */
/* Hack -- Balls explode before reaching walls */
if (cave_stop_disintegration(ny, nx) && (rad > 0)) break;
}
+ else if (flg & PROJECT_LOS)
+ {
+ /* Hack -- Balls explode before reaching walls */
+ if (!cave_los_bold(ny, nx) && (rad > 0)) break;
+ }
else
{
/* Hack -- Balls explode before reaching walls */
{
flg &= ~(PROJECT_HIDE);
- breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, (bool)(typ == GF_DISINTEGRATE));
+ breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, typ);
}
else
{
/* Enforce a "circular" explosion */
if (distance(by, bx, y, x) != dist) continue;
- if (typ == GF_DISINTEGRATE)
+ switch (typ)
{
+ case GF_LITE:
+ case GF_LITE_WEAK:
+ /* Lights are stopped by opaque terrains */
+ if (!los(by, bx, y, x)) continue;
+ break;
+ case GF_DISINTEGRATE:
/* Disintegration are stopped only by perma-walls */
if (!in_disintegration_range(by, bx, y, x)) continue;
- }
- else
- {
+ break;
+ default:
/* Ball explosions are stopped by walls */
if (!projectable(by, bx, y, x)) continue;
+ break;
}
/* Save this grid */