diff options
author | Neil Moore <neil@s-z.org> | 2013-09-06 23:39:35 -0400 |
---|---|---|
committer | Neil Moore <neil@s-z.org> | 2013-09-06 23:41:56 -0400 |
commit | d5d8a818bb7867862396b3f76bcd511b574ef457 (patch) | |
tree | 39e7498f602137410606c969d37463e0e69110bf /crawl-ref/source/ray.cc | |
parent | d60a8dff6c7b2c4ff34715fb0f15f1e556779101 (diff) | |
download | crawl-ref-d5d8a818bb7867862396b3f76bcd511b574ef457.tar.gz crawl-ref-d5d8a818bb7867862396b3f76bcd511b574ef457.zip |
Fix a chaos bounce crash (#5892).
It wasn't safe to change the angle of a ray that was on a corner of
the 45-degree diamond grid: if the new angle pointed inside the cell,
we would violate the _valid() checks. Have set_degrees (only called
for chaos bouncing currently) nudge the ray inside the diamond to
avoid this problem.
Diffstat (limited to 'crawl-ref/source/ray.cc')
-rw-r--r-- | crawl-ref/source/ray.cc | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/crawl-ref/source/ray.cc b/crawl-ref/source/ray.cc index c14204e2ce..0066bce38a 100644 --- a/crawl-ref/source/ray.cc +++ b/crawl-ref/source/ray.cc @@ -468,6 +468,17 @@ static geom::ray _bounce_corner(const geom::ray &rorig, const coord_def &side, return r; } +// Nudge an on-corner ray to be inside the diamond. +void ray_def::nudge_inside() +{ + ASSERT(on_corner); + geom::vector centre(pos().x + 0.5, pos().y + 0.5); + // Move a little bit towards cell center. + r.start = 0.9 * r.start + 0.1 * centre; + on_corner = false; + ASSERT(in_diamond_int(r.start)); +} + void ray_def::bounce(const reflect_grid &rg) { ASSERT(_valid()); @@ -476,20 +487,16 @@ void ray_def::bounce(const reflect_grid &rg) const coord_def old_pos = pos(); #endif + // If we're exactly on a corner, adjust to slightly inside the diamond. + if (on_corner) + nudge_inside(); + // Translate to cell (0,0). geom::vector p(pos().x, pos().y); geom::ray rtrans; rtrans.start = r.start - p; rtrans.dir = r.dir; - if (on_corner) - { - // Move a little bit towards cell center (0.5, 0.5). - rtrans.start = 0.9 * rtrans.start + 0.1 * geom::vector(0.5, 0.5); - on_corner = false; - ASSERT(in_diamond_int(rtrans.start)); - } - // Move to the diamond edge to determine the side. coord_def side; bool corner = _to_grid(&rtrans, false); @@ -531,5 +538,10 @@ double ray_def::get_degrees() const void ray_def::set_degrees(double d) { + // Changing the angle while on a diamond corner causes problems when the + // new direction points inside a diamond (#5892). Move the ray slightly + // inside the diamond first correct for this. + if (on_corner) + nudge_inside(); r.dir = geom::degree_to_vector(d); } |