From b0d21459b7ec552fe6f9690d3d172bf6412551a9 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Fri, 13 Nov 2009 22:09:35 +0100 Subject: Reimplement radius_iterator on the basis of circle_def. --- crawl-ref/source/coordit.cc | 127 +++++++++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 50 deletions(-) (limited to 'crawl-ref/source/coordit.cc') diff --git a/crawl-ref/source/coordit.cc b/crawl-ref/source/coordit.cc index 3a759c2a61..e4cf878f37 100644 --- a/crawl-ref/source/coordit.cc +++ b/crawl-ref/source/coordit.cc @@ -8,6 +8,7 @@ #include "coordit.h" #include "coord.h" +#include "coord-circle.h" #include "player.h" rectangle_iterator::rectangle_iterator( const coord_def& corner1, @@ -59,6 +60,7 @@ rectangle_iterator& rectangle_iterator::operator ++() return *this; } + rectangle_iterator rectangle_iterator::operator++( int dummy ) { const rectangle_iterator copy = *this; @@ -66,85 +68,110 @@ rectangle_iterator rectangle_iterator::operator++( int dummy ) return (copy); } -radius_iterator::radius_iterator(const coord_def& _center, int _radius, - bool _roguelike_metric, bool _require_los, - bool _exclude_center, - const los_def* _los) - : center(_center), radius(_radius), roguelike_metric(_roguelike_metric), - require_los(_require_los), exclude_center(_exclude_center), - los(_los), iter_done(false) +/* + * circle iterator + */ + +circle_iterator::circle_iterator(const circle_def &circle_) + : circle(circle_), iter(circle_.get_bbox().iter()) { - reset(); + while (iter && !circle.contains(*iter)) + ++iter; } -void radius_iterator::reset() +circle_iterator::operator bool() const { - iter_done = false; + return ((bool)iter); +} - location.x = center.x - radius; - location.y = center.y - radius; +coord_def circle_iterator::operator*() const +{ + return (*iter); +} - if ( !this->on_valid_square() ) - ++(*this); +void circle_iterator::operator++() +{ + do + ++iter; + while (iter && !circle.contains(*iter)); } -bool radius_iterator::done() const +void circle_iterator::operator++(int) { - return iter_done; + ++(*this); } -coord_def radius_iterator::operator *() const + +radius_iterator::radius_iterator(const coord_def& center, int param, + circle_type ctype, + const los_def* _los, + bool _exclude_center) + : circle(center, param, ctype), + iter(circle.iter()), + exclude_center(_exclude_center), + los(_los) { - return location; + advance(true); } -const coord_def* radius_iterator::operator->() const +radius_iterator::radius_iterator(const coord_def& _center, int _radius, + bool roguelike, bool _require_los, + bool _exclude_center, + const los_def* _los) + : circle(_center, _radius, roguelike ? C_SQUARE : C_POINTY), + iter(circle.iter()), + exclude_center(_exclude_center), + los(_require_los ? (_los ? _los : &you.get_los()) : NULL) { - return &location; + advance(true); } -void radius_iterator::step() +radius_iterator::radius_iterator(const los_def* los_, + bool _exclude_center) + : circle(los_->get_bounds()), + iter(circle.iter()), + exclude_center(_exclude_center), + los(los_) { - const int minx = std::max(X_BOUND_1+1, center.x - radius); - const int maxx = std::min(X_BOUND_2-1, center.x + radius); - const int maxy = std::min(Y_BOUND_2-1, center.y + radius); + advance(true); +} - // Sweep L-R, U-D - location.x++; - if (location.x > maxx) - { - location.x = minx; - location.y++; - if (location.y > maxy) - iter_done = true; - } +void radius_iterator::advance(bool may_stay) +{ + if (!may_stay) + ++iter; + while (iter && !is_valid_square(*iter)) + ++iter; + current = *iter; } -bool radius_iterator::on_valid_square() const +radius_iterator::operator bool() const { - if (!in_bounds(location)) - return (false); - if (!roguelike_metric && (location - center).abs() > radius*radius) + return (iter); +} + +coord_def radius_iterator::operator *() const +{ + return (current); +} + +const coord_def* radius_iterator::operator->() const +{ + return ¤t; +} + +bool radius_iterator::is_valid_square(const coord_def &p) const +{ + if (exclude_center && p == circle.get_center()) return (false); - if (require_los) - { - if (!los && !you.see_cell(location)) - return (false); - if (los && !los->see_cell(location)) - return (false); - } - if (exclude_center && location == center) + if (los && !los->see_cell(p)) return (false); - return (true); } const radius_iterator& radius_iterator::operator++() { - do - this->step(); - while (!this->done() && !this->on_valid_square()); - + advance(false); return (*this); } -- cgit v1.2.3-54-g00ecf