diff options
-rw-r--r-- | crawl-ref/source/coord-circle.cc | 39 | ||||
-rw-r--r-- | crawl-ref/source/coord-circle.h | 19 | ||||
-rw-r--r-- | crawl-ref/source/coordit.cc | 127 | ||||
-rw-r--r-- | crawl-ref/source/coordit.h | 40 | ||||
-rw-r--r-- | crawl-ref/source/halo.cc | 1 |
5 files changed, 121 insertions, 105 deletions
diff --git a/crawl-ref/source/coord-circle.cc b/crawl-ref/source/coord-circle.cc index 9072c6fa3e..8580313e01 100644 --- a/crawl-ref/source/coord-circle.cc +++ b/crawl-ref/source/coord-circle.cc @@ -63,6 +63,16 @@ const rect_def& circle_def::get_bbox() const return (bbox); } +const coord_def& circle_def::get_center() const +{ + return (origin); +} + +circle_iterator circle_def::iter() const +{ + return (circle_iterator(*this)); +} + bool circle_def::contains(const coord_def &p) const { switch (shape) @@ -75,32 +85,3 @@ bool circle_def::contains(const coord_def &p) const return (false); } } - -circle_iterator::circle_iterator(const circle_def &circle_) - : circle(circle_), iter(circle_.get_bbox().iter()) -{ - while (iter && !circle.contains(*iter)) - ++iter; -} - -circle_iterator::operator bool() const -{ - return ((bool)iter); -} - -coord_def circle_iterator::operator*() const -{ - return (*iter); -} - -void circle_iterator::operator++() -{ - do - ++iter; - while (iter && !circle.contains(*iter)); -} - -void circle_iterator::operator++(int) -{ - ++(*this); -} diff --git a/crawl-ref/source/coord-circle.h b/crawl-ref/source/coord-circle.h index 172e2600b6..9cf52acbe8 100644 --- a/crawl-ref/source/coord-circle.h +++ b/crawl-ref/source/coord-circle.h @@ -1,8 +1,6 @@ #ifndef COORD_CIRCLE_H #define COORD_CIRCLE_H -#include "coordit.h" - enum shape_type { SH_SQUARE, // square around an origin @@ -17,6 +15,7 @@ enum circle_type C_ROUND }; +class rectangle_iterator; class rect_def { coord_def min; @@ -51,6 +50,7 @@ public: bool contains(const coord_def &p) const; const rect_def& get_bbox() const; + const coord_def& get_center() const; circle_iterator iter() const; @@ -58,19 +58,4 @@ private: void init(int param, circle_type ctype); }; -class circle_iterator -{ - const circle_def &circle; - rectangle_iterator iter; - -public: - circle_iterator(const circle_def &circle_); - - operator bool() const; - coord_def operator*() const; - - void operator++(); - void operator++(int); -}; - #endif 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); } diff --git a/crawl-ref/source/coordit.h b/crawl-ref/source/coordit.h index 60fbf1a669..da17c67a7b 100644 --- a/crawl-ref/source/coordit.h +++ b/crawl-ref/source/coordit.h @@ -1,6 +1,8 @@ #ifndef COORDIT_H #define COORDIT_H +#include "coord-circle.h" + class rectangle_iterator : public std::iterator<std::forward_iterator_tag, coord_def> { @@ -17,33 +19,53 @@ private: coord_def current, topleft, bottomright; }; +class circle_iterator +{ + const circle_def &circle; + rectangle_iterator iter; + +public: + circle_iterator(const circle_def &circle_); + + operator bool() const; + coord_def operator*() const; + + void operator++(); + void operator++(int); +}; + class los_def; class radius_iterator : public std::iterator<std::forward_iterator_tag, coord_def> { public: + radius_iterator(const coord_def& center, int param, + circle_type ctype, + const los_def* los = NULL, + bool exclude_center = false); radius_iterator(const coord_def& center, int radius, bool roguelike_metric = true, bool require_los = true, bool exclude_center = false, const los_def* los = NULL); - bool done() const; - void reset(); - operator bool() const { return !done(); } + radius_iterator(const los_def* los, + bool exclude_center = false); + operator bool() const; coord_def operator *() const; const coord_def* operator->() const; const radius_iterator& operator ++ (); radius_iterator operator ++ (int); + private: - void step(); - bool on_valid_square() const; + void advance(bool may_stay); + bool is_valid_square(const coord_def& p) const; - coord_def location, center; - int radius; - bool roguelike_metric, require_los, exclude_center; + circle_def circle; + circle_iterator iter; + bool exclude_center; const los_def* los; - bool iter_done; + coord_def current; }; class adjacent_iterator : public radius_iterator diff --git a/crawl-ref/source/halo.cc b/crawl-ref/source/halo.cc index f37bbf8cf9..a71447ac2b 100644 --- a/crawl-ref/source/halo.cc +++ b/crawl-ref/source/halo.cc @@ -3,6 +3,7 @@ #include "halo.h" #include "actor.h" +#include "coordit.h" #include "player.h" #include "monster.h" #include "religion.h" |