177 const uint yh = MapSizeY() - 1 - yl; |
178 const uint yh = MapSizeY() - 1 - yl; |
178 const uint minl = xl < yl ? xl : yl; |
179 const uint minl = xl < yl ? xl : yl; |
179 const uint minh = xh < yh ? xh : yh; |
180 const uint minh = xh < yh ? xh : yh; |
180 return minl < minh ? minl : minh; |
181 return minl < minh ? minl : minh; |
181 } |
182 } |
|
183 |
|
184 /** |
|
185 * Function performing a search around a center tile and going outward, thus in circle. |
|
186 * Although it really is a square search... |
|
187 * Every tile will be tested by means of the callback function proc, |
|
188 * which will determine if yes or no the given tile meets criteria of search. |
|
189 * @param tile to start the search from |
|
190 * @param size: number of tiles per side of the desired search area |
|
191 * @param proc: callback testing function pointer. |
|
192 * @param data to be passed to the callback function. Depends on the implementation |
|
193 * @result of the search |
|
194 * @pre proc != NULL |
|
195 * @pre size > 0 |
|
196 */ |
|
197 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data) |
|
198 { |
|
199 uint n, x, y; |
|
200 DiagDirection dir; |
|
201 |
|
202 assert(proc != NULL); |
|
203 assert(size > 0); |
|
204 |
|
205 x = TileX(tile); |
|
206 y = TileY(tile); |
|
207 |
|
208 if (size % 2 == 1) { |
|
209 /* If the length of the side is uneven, the center has to be checked |
|
210 * separately, as the pattern of uneven sides requires to go around the center */ |
|
211 n = 2; |
|
212 if (proc(TileXY(x, y), data)) return true; |
|
213 |
|
214 /* If tile test is not successfull, get one tile down and left, |
|
215 * ready for a test in first circle around center tile */ |
|
216 x += _tileoffs_by_dir[DIR_W].x; |
|
217 y += _tileoffs_by_dir[DIR_W].y; |
|
218 } else { |
|
219 n = 1; |
|
220 /* To use _tileoffs_by_diagdir's order, we must relocate to |
|
221 * another tile, as we now first go 'up', 'right', 'down', 'left' |
|
222 * instead of 'right', 'down', 'left', 'up', which the calling |
|
223 * function assume. */ |
|
224 x++; |
|
225 } |
|
226 |
|
227 for (; n < size; n += 2) { |
|
228 for (dir = DIAGDIR_NE; dir < DIAGDIR_END; dir++) { |
|
229 uint j; |
|
230 for (j = n; j != 0; j--) { |
|
231 if (x <= MapMaxX() && y <= MapMaxY() && ///< Is the tile within the map? |
|
232 proc(TileXY(x, y), data)) { ///< Is the callback successfulll? |
|
233 return true; ///< then stop the search |
|
234 } |
|
235 |
|
236 /* Step to the next 'neighbour' in the circular line */ |
|
237 x += _tileoffs_by_diagdir[dir].x; |
|
238 y += _tileoffs_by_diagdir[dir].y; |
|
239 } |
|
240 } |
|
241 /* Jump to next circle to test */ |
|
242 x += _tileoffs_by_dir[DIR_W].x; |
|
243 y += _tileoffs_by_dir[DIR_W].y; |
|
244 } |
|
245 return false; |
|
246 } |