#include "AppHdr.h"
#include "coordit.h"
#include "coord.h"
#include "los.h"
rectangle_iterator::rectangle_iterator( const coord_def& corner1,
const coord_def& corner2 )
{
topleft.x = std::min(corner1.x, corner2.x);
topleft.y = std::min(corner1.y, corner2.y); bottomright.x = std::max(corner1.x, corner2.x);
bottomright.y = std::max(corner1.y, corner2.y);
current = topleft;
}
rectangle_iterator::rectangle_iterator( int x_border_dist, int y_border_dist )
{
if (y_border_dist < 0)
y_border_dist = x_border_dist;
topleft.set(x_border_dist, y_border_dist);
bottomright.set(GXM - x_border_dist - 1, GYM - y_border_dist - 1);
current = topleft;
}
rectangle_iterator::operator bool() const
{
return (current.y <= bottomright.y);
}
coord_def rectangle_iterator::operator *() const
{
return current;
}
const coord_def* rectangle_iterator::operator->() const
{
return ¤t;
}
rectangle_iterator& rectangle_iterator::operator ++()
{
if (current.x == bottomright.x)
{
current.x = topleft.x;
current.y++;
}
else
{
current.x++;
}
return *this;
}
rectangle_iterator rectangle_iterator::operator++( int dummy )
{
const rectangle_iterator copy = *this;
++(*this);
return (copy);
}
radius_iterator::radius_iterator(const coord_def& _center, int _radius,
bool _roguelike_metric, bool _require_los,
bool _exclude_center,
const env_show_grid* _losgrid)
: center(_center), radius(_radius), roguelike_metric(_roguelike_metric),
require_los(_require_los), exclude_center(_exclude_center),
losgrid(_losgrid), iter_done(false)
{
reset();
}
void radius_iterator::reset()
{
iter_done = false;
location.x = center.x - radius;
location.y = center.y - radius;
if ( !this->on_valid_square() )
++(*this);
}
bool radius_iterator::done() const
{
return iter_done;
}
coord_def radius_iterator::operator *() const
{
return location;
}
const coord_def* radius_iterator::operator->() const
{
return &location;
}
void radius_iterator::step()
{
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);
location.x++;
if (location.x > maxx)
{
location.x = minx;
location.y++;
if (location.y > maxy)
iter_done = true;
}
}
void radius_iterator::step_back()
{
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 miny = std::max(Y_BOUND_1+1, center.y - radius);
location.x--;
if (location.x < minx)
{
location.x = maxx;
location.y--;
if (location.y < miny)
iter_done = true;
}
}
bool radius_iterator::on_valid_square() const
{
if (!in_bounds(location))
return (false);
if (!roguelike_metric && (location - center).abs() > radius*radius)
return (false);
if (require_los)
{
if (!losgrid && !see_cell(location))
return (false);
if (losgrid && !see_cell(*losgrid, center, location))
return (false);
}
if (exclude_center && location == center)
return (false);
return (true);
}
const radius_iterator& radius_iterator::operator++()
{
do
this->step();
while (!this->done() && !this->on_valid_square());
return (*this);
}
const radius_iterator& radius_iterator::operator--()
{
do
this->step_back();
while (!this->done() && !this->on_valid_square());
return (*this);
}
radius_iterator radius_iterator::operator++(int dummy)
{
const radius_iterator copy = *this;
++(*this);
return (copy);
}
radius_iterator radius_iterator::operator--(int dummy)
{
const radius_iterator copy = *this;
--(*this);
return (copy);
}