diff options
author | Robert Vollmert <rvollmert@gmx.net> | 2009-11-03 13:31:42 +0100 |
---|---|---|
committer | Robert Vollmert <rvollmert@gmx.net> | 2009-11-03 15:27:27 +0100 |
commit | cf72e9d750a375f2d4fa3883946a9d3b0fb9bb5e (patch) | |
tree | 9d31891a5a45b71b7383128106c805049ab12e48 /crawl-ref/source/ray.cc | |
parent | e79394f321d455748113a360e76050019d41184f (diff) | |
download | crawl-ref-cf72e9d750a375f2d4fa3883946a9d3b0fb9bb5e.tar.gz crawl-ref-cf72e9d750a375f2d4fa3883946a9d3b0fb9bb5e.zip |
Fix a bug with corner rays.
Rays that reflected on corners could go too far.
Now passes the bounce test.
Diffstat (limited to 'crawl-ref/source/ray.cc')
-rw-r--r-- | crawl-ref/source/ray.cc | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/crawl-ref/source/ray.cc b/crawl-ref/source/ray.cc index fa3aa09ba8..e9187837f1 100644 --- a/crawl-ref/source/ray.cc +++ b/crawl-ref/source/ray.cc @@ -84,6 +84,16 @@ static bool in_non_diamond_int(const geom::vector &v) return (!in_diamond(v) && !on_line(v)); } +// Is r on a corner and heading into a non-diamond? +static bool bad_corner(const geom::ray &r) +{ + if (!is_corner(r.start)) + return (false); + geom::ray copy = r; + copy.to_grid(diamonds, true); + return (in_non_diamond_int(copy.start)); +} + static coord_def round_vec(const geom::vector &v) { int x = ifloor(v.x); @@ -334,13 +344,24 @@ void ray_def::bounce(const reflect_grid &rg) double t = intersect(rmirr, l); ASSERT(double_is_zero(t) || t >= 0); rmirr.advance(t); - rmirr.dir = reflect(rmirr.dir, l.f); - // Depending on the case, we're on some diamond edge - // or between diamonds. We'll just move safely into - // the next one. - rmirr.to_grid(diamonds, true); - if (!in_diamond(rmirr.start)) - on_corner = _advance_from_non_diamond(&rmirr); + rmirr.dir = geom::reflect(rmirr.dir, l.f); + if (bad_corner(rmirr)) + { + // Really want to stay and set on_corner. + // But then pos() might be a solid cell. + geom::vector v = _mirror_pt(rmirr.start, side); + v = _fudge_corner(v, rg); + rmirr.start = _mirror_pt(v, side); + } + else + { + // Depending on the case, we're on some diamond edge + // or between diamonds. We'll just move safely into + // the next one. + rmirr.to_grid(diamonds, true); + if (in_non_diamond_int(rmirr.start)) + on_corner = _advance_from_non_diamond(&rmirr); + } } // Mirror back. |