summaryrefslogtreecommitdiffstats
path: root/crawl-ref
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
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')
-rw-r--r--crawl-ref/source/beam.cc84
-rw-r--r--crawl-ref/source/beam.h6
-rw-r--r--crawl-ref/source/dat/descript/spells.txt4
-rw-r--r--crawl-ref/source/spells4.cc6
4 files changed, 95 insertions, 5 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
diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h
index 2db36672fe..e9ac9efa84 100644
--- a/crawl-ref/source/beam.h
+++ b/crawl-ref/source/beam.h
@@ -39,8 +39,10 @@ bool nasty_beam( struct monsters *mon, struct bolt &beam );
* called from: ability - it_use3 - item_use - mstuff2 - religion -
* spells - spells4
* *********************************************************************** */
-void explosion( struct bolt &pbolt, bool hole_in_the_middle = false );
-
+void explosion( struct bolt &pbolt, bool hole_in_the_middle = false,
+ bool explode_in_wall = false,
+ bool stop_at_statues = true,
+ bool stop_at_walls = true);
// last updated 22jan2001 {gdl}
/* ***********************************************************************
diff --git a/crawl-ref/source/dat/descript/spells.txt b/crawl-ref/source/dat/descript/spells.txt
index 8c687d7310..fcc109002e 100644
--- a/crawl-ref/source/dat/descript/spells.txt
+++ b/crawl-ref/source/dat/descript/spells.txt
@@ -363,6 +363,10 @@ Iskenderun's Mystic Blast
This spell throws a crackling sphere of destructive energy.
%%%%
+Lee's Rapid Deconstruction
+
+This spells fragments a wall into an explosion of deadly shrapnel. It can also be used directly on monsters made of wall-like substances.
+%%%%
Lehudib's Crystal Spear
This spell hurls a lethally sharp bolt of crystal.
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 7773c3efda..082d435ed7 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -2346,7 +2346,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
bool hole = true;
const char *what = NULL;
- mpr("Fragment what (e.g. a wall)?", MSGCH_PROMPT);
+ mpr("Fragment what (e.g. a wall or monster)?", MSGCH_PROMPT);
direction( beam, DIR_TARGET, TARG_ENEMY );
if (!beam.isValid)
@@ -2363,6 +2363,8 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
blast.type = '#';
blast.colour = 0;
blast.set_target(beam);
+ blast.source_x = you.x_pos;
+ blast.source_y = you.y_pos;
blast.is_tracer = false;
blast.flavour = BEAM_FRAG;
blast.hit = AUTOMATIC_HIT;
@@ -2680,7 +2682,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
if (what != NULL)
mprf("The %s explodes!", what);
- explosion( blast, hole );
+ explosion( blast, hole, true );
}
else if (blast.damage.num == 0)
{