Changeset - r11743:4941d7279e70
[Not reviewed]
master
0 3 0
rubidium - 15 years ago 2009-04-24 22:27:21
rubidium@openttd.org
(svn r16138) -Codechange: move GetClosestWaterDistance to map*
3 files changed with 62 insertions and 56 deletions:
0 comments (0 inline, 0 general)
src/map.cpp
Show inline comments
 
@@ -8,6 +8,7 @@
 
#include "core/alloc_func.hpp"
 
#include "core/math_func.hpp"
 
#include "map_func.h"
 
#include "tile_map.h"
 

	
 
#if defined(_MSC_VER)
 
/* Why the hell is that not in all MSVC headers?? */
 
@@ -327,3 +328,59 @@ bool CircularTileSearch(TileIndex *tile,
 
	*tile = INVALID_TILE;
 
	return false;
 
}
 

	
 
/*!
 
 * Finds the distance for the closest tile with water/land given a tile
 
 * @param tile  the tile to find the distance too
 
 * @param water whether to find water or land
 
 * @return distance to nearest water (max 0x7F) / land (max 0x1FF; 0x200 if there is no land)
 
 * @note FAILS when an industry should be seen as water
 
 */
 
uint GetClosestWaterDistance(TileIndex tile, bool water)
 
{
 
	if (IsTileType(tile, MP_WATER) == water) return 0;
 

	
 
	uint max_dist = water ? 0x7F : 0x200;
 

	
 
	int x = TileX(tile);
 
	int y = TileY(tile);
 

	
 
	uint max_x = MapMaxX();
 
	uint max_y = MapMaxY();
 
	uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
 

	
 
	/* go in a 'spiral' with increasing manhattan distance in each iteration */
 
	for (uint dist = 1; dist < max_dist; dist++) {
 
		/* next 'diameter' */
 
		y--;
 

	
 
		/* going counter-clockwise around this square */
 
		for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
 
			static const int8 ddx[DIAGDIR_END] = { -1,  1,  1, -1};
 
			static const int8 ddy[DIAGDIR_END] = {  1,  1, -1, -1};
 

	
 
			int dx = ddx[dir];
 
			int dy = ddy[dir];
 

	
 
			/* each side of this square has length 'dist' */
 
			for (uint a = 0; a < dist; a++) {
 
				/* MP_VOID tiles are not checked (interval is [min; max) for IsInsideMM())*/
 
				if (IsInsideMM(x, min_xy, max_x) && IsInsideMM(y, min_xy, max_y)) {
 
					TileIndex t = TileXY(x, y);
 
					if (IsTileType(t, MP_WATER) == water) return dist;
 
				}
 
				x += dx;
 
				y += dy;
 
			}
 
		}
 
	}
 

	
 
	if (!water) {
 
		/* no land found - is this a water-only map? */
 
		for (TileIndex t = 0; t < MapSize(); t++) {
 
			if (!IsTileType(t, MP_VOID) && !IsTileType(t, MP_WATER)) return 0x1FF;
 
		}
 
	}
 

	
 
	return max_dist;
 
}
src/map_func.h
Show inline comments
 
@@ -431,4 +431,9 @@ static inline TileIndex RandomTileSeed(u
 
 */
 
#define RandomTile() RandomTileSeed(Random())
 

	
 
/**
 
 * Finds the distance for the closest tile with water/land given a tile
 
 */
 
uint GetClosestWaterDistance(TileIndex tile, bool water);
 

	
 
#endif /* MAP_FUNC_H */
src/newgrf_industries.cpp
Show inline comments
 
@@ -38,62 +38,6 @@ IndustryType MapNewGRFIndustryType(Indus
 
	return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
 
}
 

	
 
/**
 
 * Finds the distance for the closest tile with water/land given a tile
 
 * @param tile  the tile to find the distance too
 
 * @param water whether to find water or land
 
 * @return distance to nearest water (max 0x7F) / land (max 0x1FF; 0x200 if there is no land)
 
 * @note FAILS when an industry should be seen as water
 
 */
 
static uint GetClosestWaterDistance(TileIndex tile, bool water)
 
{
 
	if (IsTileType(tile, MP_WATER) == water) return 0;
 

	
 
	uint max_dist = water ? 0x7F : 0x200;
 

	
 
	int x = TileX(tile);
 
	int y = TileY(tile);
 

	
 
	uint max_x = MapMaxX();
 
	uint max_y = MapMaxY();
 
	uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
 

	
 
	/* go in a 'spiral' with increasing manhattan distance in each iteration */
 
	for (uint dist = 1; dist < max_dist; dist++) {
 
		/* next 'diameter' */
 
		y--;
 

	
 
		/* going counter-clockwise around this square */
 
		for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
 
			static const int8 ddx[DIAGDIR_END] = { -1,  1,  1, -1};
 
			static const int8 ddy[DIAGDIR_END] = {  1,  1, -1, -1};
 

	
 
			int dx = ddx[dir];
 
			int dy = ddy[dir];
 

	
 
			/* each side of this square has length 'dist' */
 
			for (uint a = 0; a < dist; a++) {
 
				/* MP_VOID tiles are not checked (interval is [min; max) for IsInsideMM())*/
 
				if (IsInsideMM(x, min_xy, max_x) && IsInsideMM(y, min_xy, max_y)) {
 
					TileIndex t = TileXY(x, y);
 
					if (IsTileType(t, MP_WATER) == water) return dist;
 
				}
 
				x += dx;
 
				y += dy;
 
			}
 
		}
 
	}
 

	
 
	if (!water) {
 
		/* no land found - is this a water-only map? */
 
		for (TileIndex t = 0; t < MapSize(); t++) {
 
			if (!IsTileType(t, MP_VOID) && !IsTileType(t, MP_WATER)) return 0x1FF;
 
		}
 
	}
 

	
 
	return max_dist;
 
}
 

	
 
/** Make an analysis of a tile and check for its belonging to the same
 
 * industry, and/or the same grf file
 
 * @param tile TileIndex of the tile to query
0 comments (0 inline, 0 general)