diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-02 11:42:11 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-02 11:42:11 +0000 |
commit | b367d7d62fb29d7938f260999c634c5f11fa4cc8 (patch) | |
tree | 4cf67031f33d8e489c713d64d1c5ba76170290a1 /crawl-ref/source/beam.cc | |
parent | dbe9fa6e03ca3baa7f1d72be84d23c0c2338ad9e (diff) | |
download | crawl-ref-b367d7d62fb29d7938f260999c634c5f11fa4cc8.tar.gz crawl-ref-b367d7d62fb29d7938f260999c634c5f11fa4cc8.zip |
Fix explosions through walls (patch 1777426, zelgadis).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2040 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/beam.cc')
-rw-r--r-- | crawl-ref/source/beam.cc | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 3fdcc52fe9..cd1ae2acd2 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -4248,8 +4248,90 @@ static void explosion1(bolt &pbolt) // for each cell affected by the explosion, affect() is called. -void explosion( bolt &beam, bool hole_in_the_middle ) +void explosion( bolt &beam, bool hole_in_the_middle, + bool explode_in_wall, bool stop_at_statues, + bool stop_at_walls) { + if (in_bounds(beam.source_x, beam.source_y) + && !(beam.source_x == beam.target_x + && beam.source_y == beam.target_y) + && (!explode_in_wall || stop_at_statues || stop_at_walls)) + { + ray_def ray; + int max_dist = grid_distance(beam.source_x, beam.source_y, + beam.target_x, beam.target_y); + + ray.fullray_idx = -1; // to quiet valgrind + find_ray( beam.source_x, beam.source_y, beam.target_x, beam.target_y, + true, ray, 0, true ); + + // Can cast explosions out from statues or walls. + if (ray.x() == beam.source_x && ray.y() == beam.source_y) + { + max_dist--; + ray.advance(true); + } + + int dist = 0; + while (dist++ <= max_dist && !(ray.x() == beam.target_x + && ray.y() == beam.target_y)) + { + if (grid_is_solid(ray.x(), ray.y())) + { + bool is_wall = grid_is_wall(grd[ray.x()][ray.y()]); + if (!stop_at_statues && !is_wall) + { +#if DEBUG_DIAGNOSTICS + mpr("Explosion beam passing over a statue or other " + "non-wall solid feature.", MSGCH_DIAGNOSTICS); +#endif + continue; + } + else if (!stop_at_walls && is_wall) + { +#if DEBUG_DIAGNOSTICS + mpr("Explosion beam passing through a wall.", + MSGCH_DIAGNOSTICS); +#endif + continue; + } + +#if DEBUG_DIAGNOSTICS + if (!is_wall && stop_at_statues) + mpr("Explosion beam stopped by a statue or other " + "non-wall solid feature.", MSGCH_DIAGNOSTICS); + else if (is_wall && stop_at_walls) + mpr("Explosion beam stopped by a by wall.", + MSGCH_DIAGNOSTICS); + else + mpr("Explosion beam stopped by someting buggy.", + MSGCH_DIAGNOSTICS); +#endif + + break; + } + ray.advance(true); + } // while (dist++ <= max_dist) + + // Backup so we don't explode inside the wall. + if (!explode_in_wall && grid_is_wall(grd[ray.x()][ray.y()])) + { +#if DEBUG_DIAGNOSTICS + int old_x = ray.x(); + int old_y = ray.y(); +#endif + ray.regress(); +#if DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, + "Can't explode in a solid wall, backing up a step " + "along the beam path from (%d, %d) to (%d, %d)", + old_x, old_y, ray.x(), ray.y()); +#endif + } + beam.target_x = ray.x(); + beam.target_y = ray.y(); + } // if (!explode_in_wall) + int r = beam.ex_size; // beam is now an explosion; set in_explosion_phase |