summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/beam.cc
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-02 11:42:11 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-02 11:42:11 +0000
commitb367d7d62fb29d7938f260999c634c5f11fa4cc8 (patch)
tree4cf67031f33d8e489c713d64d1c5ba76170290a1 /crawl-ref/source/beam.cc
parentdbe9fa6e03ca3baa7f1d72be84d23c0c2338ad9e (diff)
downloadcrawl-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.cc84
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