Rename TileArea to OrthogonalTileArea
[openttd/fttd.git] / src / map / tilearea.h
blob924d9354280b45480852119a7c28f70c96f45d09
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /** @file map/tilearea.h Handling of tile areas. */
10 #ifndef MAP_TILEAREA_H
11 #define MAP_TILEAREA_H
13 #include "coord.h"
15 /** Represents the covered area of e.g. a rail station */
16 struct OrthogonalTileArea {
17 TileIndex tile; ///< The base tile of the area
18 uint16 w; ///< The width of the area
19 uint16 h; ///< The height of the area
21 /** Just construct this tile area */
22 OrthogonalTileArea() : tile(INVALID_TILE), w(0), h(0) {}
24 /**
25 * Construct this tile area with some set values
26 * @param tile the base tile
27 * @param w the width
28 * @param h the height
30 OrthogonalTileArea(TileIndex tile, uint8 w, uint8 h) : tile(tile), w(w), h(h) {}
32 OrthogonalTileArea(TileIndex start, TileIndex end);
34 void Set(uint x0, uint y0, uint x1, uint y1);
36 void Add(TileIndex to_add);
38 void Add(const OrthogonalTileArea &to_add);
40 /**
41 * Clears the 'tile area', i.e. make the tile invalid.
43 void Clear()
45 this->tile = INVALID_TILE;
46 this->w = 0;
47 this->h = 0;
50 bool Intersects(const OrthogonalTileArea &ta) const;
52 bool Contains(TileIndex tile) const;
54 void ClampToMap();
56 /**
57 * Get the center tile.
58 * @return The tile at the center, or just north of it.
60 TileIndex GetCenterTile() const
62 return TILE_ADDXY(this->tile, this->w / 2, this->h / 2);
65 /**
66 * Get the tile in the area closest to a given tile.
67 * @param t The reference tile.
68 * @return The closest tile, or INVALID_TILE if the area is empty.
70 TileIndex get_closest_tile(TileIndex t) const
72 if (this->tile == INVALID_TILE) return INVALID_TILE;
74 /* clamp x coordinate */
75 uint x = TileX(this->tile);
76 x = ClampU(TileX(t), x, x + this->w - 1);
78 /* clamp y coordinate */
79 uint y = TileY(this->tile);
80 y = ClampU(TileY(t), y, y + this->h - 1);
82 /* return the tile of our target coordinates */
83 return TileXY(x, y);
87 /** Shorthand for the much more common orthogonal tile area. */
88 typedef OrthogonalTileArea TileArea;
91 /** Base class for tile iterators. */
92 class TileIterator {
93 protected:
94 TileIndex tile; ///< The current tile we are at.
96 /**
97 * Initialise the iterator starting at this tile.
98 * @param tile The tile we start iterating from.
100 TileIterator(TileIndex tile) : tile(tile)
105 * Compute the next tile.
107 virtual void Next() = 0;
109 public:
110 /** Some compilers really like this. */
111 virtual ~TileIterator()
116 * Get the tile we are currently at.
117 * @return The tile we are at, or INVALID_TILE when we're done.
119 inline operator TileIndex () const
121 return this->tile;
125 * Move ourselves to the next tile in the rectangle on the map.
127 TileIterator& operator ++()
129 assert(this->tile != INVALID_TILE);
130 this->Next();
131 return *this;
135 * Allocate a new iterator that is a copy of this one.
137 virtual TileIterator *Clone() const = 0;
140 /** Iterator to iterate over a tile area (rectangle) of the map. */
141 class OrthogonalTileIterator : public TileIterator {
142 private:
143 const uint w; ///< The width of the iterated area.
144 const uint rowdiff; ///< The amount to add when switching rows
145 uint x; ///< The current 'x' position in the rectangle.
146 uint y; ///< The current 'y' position in the rectangle.
148 protected:
150 * Move ourselves to the next tile in the rectangle on the map.
152 inline void Next() OVERRIDE
154 assert(this->tile != INVALID_TILE);
156 if (--this->x > 0) {
157 this->tile++;
158 } else if (--this->y > 0) {
159 this->x = this->w;
160 this->tile += this->rowdiff;
161 } else {
162 this->tile = INVALID_TILE;
166 public:
168 * Construct the iterator.
169 * @param ta Area, i.e. begin point and width/height of to-be-iterated area.
171 OrthogonalTileIterator(const OrthogonalTileArea &ta)
172 : TileIterator(ta.w == 0 || ta.h == 0 ? INVALID_TILE : ta.tile),
173 w(ta.w), rowdiff(TileDiffXY(1, 1) - ta.w), x(ta.w), y(ta.h)
177 OrthogonalTileIterator *Clone() const OVERRIDE
179 return new OrthogonalTileIterator(*this);
183 /** Iterator to iterate over a diagonal area of the map. */
184 class DiagonalTileIterator : public TileIterator {
185 private:
186 uint x; ///< x coordinate of the current tile
187 uint y; ///< y coordinate of the current tile
188 bool odd; ///< Whether this is an "odd" area
189 int8 s1; ///< Advancing a tile adds (s1,s1)
190 int s2x; ///< Advancing a row adds (s2x,s2y)
191 int s2y; ///< Advancing a row adds (s2x,s2y)
192 uint w; ///< The width of the main rectangle side
193 uint n; ///< The number of tiles left on the current row
194 uint m; ///< The number of rows left
196 protected:
197 void Next() OVERRIDE;
199 public:
200 DiagonalTileIterator(TileIndex begin, TileIndex end);
202 DiagonalTileIterator *Clone() const OVERRIDE
204 return new DiagonalTileIterator(*this);
209 * A loop which iterates over the tiles of a TileArea.
210 * @param var The name of the variable which contains the current tile.
211 * This variable will be allocated in this \c for of this loop.
212 * @param ta The tile area to search over.
214 #define TILE_AREA_LOOP(var, ta) for (OrthogonalTileIterator var(ta); var != INVALID_TILE; ++var)
216 #endif /* MAP_TILEAREA_H */