src/map.cpp
changeset 7036 9f23930e7ded
parent 6988 76eba6a9cc6f
child 7868 25b9aad39e4a
equal deleted inserted replaced
7035:b49ecaba95f5 7036:9f23930e7ded
    14 #if defined(_MSC_VER) && _MSC_VER >= 1400 /* VStudio 2005 is stupid! */
    14 #if defined(_MSC_VER) && _MSC_VER >= 1400 /* VStudio 2005 is stupid! */
    15 /* Why the hell is that not in all MSVC headers?? */
    15 /* Why the hell is that not in all MSVC headers?? */
    16 extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned);
    16 extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned);
    17 #endif
    17 #endif
    18 
    18 
    19 uint _map_log_x;
    19 uint _map_log_x;     ///< 2^_map_log_x == _map_size_x
    20 uint _map_size_x;
    20 uint _map_size_x;    ///< Size of the map along the X
    21 uint _map_size_y;
    21 uint _map_size_y;    ///< Size of the map along the Y
    22 uint _map_tile_mask;
    22 uint _map_size;      ///< The number of tiles on the map
    23 uint _map_size;
    23 uint _map_tile_mask; ///< _map_size - 1 (to mask the mapsize)
    24 
    24 
    25 Tile *_m = NULL;
    25 Tile *_m = NULL;          ///< Tiles of the map
    26 TileExtended *_me = NULL;
    26 TileExtended *_me = NULL; ///< Extended Tiles of the map
    27 
    27 
    28 
    28 
       
    29 /**
       
    30  * (Re)allocates a map with the given dimension
       
    31  * @param size_x the width of the map along the NE/SW edge
       
    32  * @param size_y the 'height' of the map along the SE/NW edge
       
    33  */
    29 void AllocateMap(uint size_x, uint size_y)
    34 void AllocateMap(uint size_x, uint size_y)
    30 {
    35 {
    31 	/* Make sure that the map size is within the limits and that
    36 	/* Make sure that the map size is within the limits and that
    32 	 * the x axis size is a power of 2. */
    37 	 * the x axis size is a power of 2. */
    33 	if (size_x < 64 || size_x > 2048 ||
    38 	if (size_x < 64 || size_x > 2048 ||
    34 			size_y < 64 || size_y > 2048 ||
    39 			size_y < 64 || size_y > 2048 ||
    35 			(size_x&(size_x-1)) != 0 ||
    40 			(size_x & (size_x - 1)) != 0 ||
    36 			(size_y&(size_y-1)) != 0)
    41 			(size_y & (size_y - 1)) != 0)
    37 		error("Invalid map size");
    42 		error("Invalid map size");
    38 
    43 
    39 	DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y);
    44 	DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y);
    40 
    45 
    41 	_map_log_x = FindFirstBit(size_x);
    46 	_map_log_x = FindFirstBit(size_x);
    90 
    95 
    91 	return TileXY(x, y);
    96 	return TileXY(x, y);
    92 }
    97 }
    93 #endif
    98 #endif
    94 
    99 
    95 
   100 /**
       
   101  * Scales the given value by the map size, where the given value is
       
   102  * for a 256 by 256 map
       
   103  * @param n the value to scale
       
   104  * @return the scaled size
       
   105  */
    96 uint ScaleByMapSize(uint n)
   106 uint ScaleByMapSize(uint n)
    97 {
   107 {
    98 	/* First shift by 12 to prevent integer overflow for large values of n.
   108 	/* First shift by 12 to prevent integer overflow for large values of n.
    99 	 * >>12 is safe since the min mapsize is 64x64
   109 	 * >>12 is safe since the min mapsize is 64x64
   100 	 * Add (1<<4)-1 to round upwards. */
   110 	 * Add (1<<4)-1 to round upwards. */
   101 	return (n * (MapSize() >> 12) + (1 << 4) - 1) >> 4;
   111 	return (n * (MapSize() >> 12) + (1 << 4) - 1) >> 4;
   102 }
   112 }
   103 
   113 
   104 
   114 
   105 /* Scale relative to the circumference of the map */
   115 /**
       
   116  * Scales the given value by the maps circumference, where the given
       
   117  * value is for a 256 by 256 map
       
   118  * @param n the value to scale
       
   119  * @return the scaled size
       
   120  */
   106 uint ScaleByMapSize1D(uint n)
   121 uint ScaleByMapSize1D(uint n)
   107 {
   122 {
   108 	/* Normal circumference for the X+Y is 256+256 = 1<<9
   123 	/* Normal circumference for the X+Y is 256+256 = 1<<9
   109 	 * Note, not actually taking the full circumference into account,
   124 	 * Note, not actually taking the full circumference into account,
   110 	 * just half of it.
   125 	 * just half of it.
   111 	 * (1<<9) - 1 is there to scale upwards. */
   126 	 * (1<<9) - 1 is there to scale upwards. */
   112 	return (n * (MapSizeX() + MapSizeY()) + (1 << 9) - 1) >> 9;
   127 	return (n * (MapSizeX() + MapSizeY()) + (1 << 9) - 1) >> 9;
   113 }
   128 }
   114 
   129 
   115 
   130 
   116 /* This function checks if we add addx/addy to tile, if we
   131 /**
       
   132  * This function checks if we add addx/addy to tile, if we
   117  *  do wrap around the edges. For example, tile = (10,2) and
   133  *  do wrap around the edges. For example, tile = (10,2) and
   118  *  addx = +3 and addy = -4. This function will now return
   134  *  addx = +3 and addy = -4. This function will now return
   119  *  INVALID_TILE, because the y is wrapped. This is needed in
   135  *  INVALID_TILE, because the y is wrapped. This is needed in
   120  *  for example, farmland. When the tile is not wrapped,
   136  *  for example, farmland. When the tile is not wrapped,
   121  *  the result will be tile + TileDiffXY(addx, addy) */
   137  *  the result will be tile + TileDiffXY(addx, addy)
       
   138  * @param tile the 'starting' point of the adding
       
   139  * @param addx the amount of tiles in the X direction to add
       
   140  * @param addy the amount of tiles in the Y direction to add
       
   141  * @return translated tile, or INVALID_TILE when it would've wrapped.
       
   142  */
   122 uint TileAddWrap(TileIndex tile, int addx, int addy)
   143 uint TileAddWrap(TileIndex tile, int addx, int addy)
   123 {
   144 {
   124 	uint x = TileX(tile) + addx;
   145 	uint x = TileX(tile) + addx;
   125 	uint y = TileY(tile) + addy;
   146 	uint y = TileY(tile) + addy;
   126 
   147 
   129 		return tile + TileDiffXY(addx, addy);
   150 		return tile + TileDiffXY(addx, addy);
   130 
   151 
   131 	return INVALID_TILE;
   152 	return INVALID_TILE;
   132 }
   153 }
   133 
   154 
       
   155 /** 'Lookup table' for tile offsets given a DiagDirection */
   134 extern const TileIndexDiffC _tileoffs_by_diagdir[] = {
   156 extern const TileIndexDiffC _tileoffs_by_diagdir[] = {
   135 	{-1,  0}, ///< DIAGDIR_NE
   157 	{-1,  0}, ///< DIAGDIR_NE
   136 	{ 0,  1}, ///< DIAGDIR_SE
   158 	{ 0,  1}, ///< DIAGDIR_SE
   137 	{ 1,  0}, ///< DIAGDIR_SW
   159 	{ 1,  0}, ///< DIAGDIR_SW
   138 	{ 0, -1}  ///< DIAGDIR_NW
   160 	{ 0, -1}  ///< DIAGDIR_NW
   139 };
   161 };
   140 
   162 
       
   163 /** 'Lookup table' for tile offsets given a Direction */
   141 extern const TileIndexDiffC _tileoffs_by_dir[] = {
   164 extern const TileIndexDiffC _tileoffs_by_dir[] = {
   142 	{-1, -1}, ///< DIR_N
   165 	{-1, -1}, ///< DIR_N
   143 	{-1,  0}, ///< DIR_NE
   166 	{-1,  0}, ///< DIR_NE
   144 	{-1,  1}, ///< DIR_E
   167 	{-1,  1}, ///< DIR_E
   145 	{ 0,  1}, ///< DIR_SE
   168 	{ 0,  1}, ///< DIR_SE
   147 	{ 1,  0}, ///< DIR_SW
   170 	{ 1,  0}, ///< DIR_SW
   148 	{ 1, -1}, ///< DIR_W
   171 	{ 1, -1}, ///< DIR_W
   149 	{ 0, -1}  ///< DIR_NW
   172 	{ 0, -1}  ///< DIR_NW
   150 };
   173 };
   151 
   174 
       
   175 /**
       
   176  * Gets the Manhattan distance between the two given tiles.
       
   177  * The Manhattan distance is the sum of the delta of both the
       
   178  * X and Y component.
       
   179  * Also known as L1-Norm
       
   180  * @param t0 the start tile
       
   181  * @param t1 the end tile
       
   182  * @return the distance
       
   183  */
   152 uint DistanceManhattan(TileIndex t0, TileIndex t1)
   184 uint DistanceManhattan(TileIndex t0, TileIndex t1)
   153 {
   185 {
   154 	const uint dx = delta(TileX(t0), TileX(t1));
   186 	const uint dx = delta(TileX(t0), TileX(t1));
   155 	const uint dy = delta(TileY(t0), TileY(t1));
   187 	const uint dy = delta(TileY(t0), TileY(t1));
   156 	return dx + dy;
   188 	return dx + dy;
   157 }
   189 }
   158 
   190 
   159 
   191 
       
   192 /**
       
   193  * Gets the 'Square' distance between the two given tiles.
       
   194  * The 'Square' distance is the square of the shortest (straight line)
       
   195  * distance between the two tiles.
       
   196  * Also known as euclidian- or L2-Norm squared.
       
   197  * @param t0 the start tile
       
   198  * @param t1 the end tile
       
   199  * @return the distance
       
   200  */
   160 uint DistanceSquare(TileIndex t0, TileIndex t1)
   201 uint DistanceSquare(TileIndex t0, TileIndex t1)
   161 {
   202 {
   162 	const int dx = TileX(t0) - TileX(t1);
   203 	const int dx = TileX(t0) - TileX(t1);
   163 	const int dy = TileY(t0) - TileY(t1);
   204 	const int dy = TileY(t0) - TileY(t1);
   164 	return dx * dx + dy * dy;
   205 	return dx * dx + dy * dy;
   165 }
   206 }
   166 
   207 
   167 
   208 
       
   209 /**
       
   210  * Gets the biggest distance component (x or y) between the two given tiles.
       
   211  * Also known as L-Infinity-Norm.
       
   212  * @param t0 the start tile
       
   213  * @param t1 the end tile
       
   214  * @return the distance
       
   215  */
   168 uint DistanceMax(TileIndex t0, TileIndex t1)
   216 uint DistanceMax(TileIndex t0, TileIndex t1)
   169 {
   217 {
   170 	const uint dx = delta(TileX(t0), TileX(t1));
   218 	const uint dx = delta(TileX(t0), TileX(t1));
   171 	const uint dy = delta(TileY(t0), TileY(t1));
   219 	const uint dy = delta(TileY(t0), TileY(t1));
   172 	return dx > dy ? dx : dy;
   220 	return dx > dy ? dx : dy;
   173 }
   221 }
   174 
   222 
   175 
   223 
       
   224 /**
       
   225  * Gets the biggest distance component (x or y) between the two given tiles
       
   226  * plus the Manhattan distance, i.e. two times the biggest distance component
       
   227  * and once the smallest component.
       
   228  * @param t0 the start tile
       
   229  * @param t1 the end tile
       
   230  * @return the distance
       
   231  */
   176 uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
   232 uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
   177 {
   233 {
   178 	const uint dx = delta(TileX(t0), TileX(t1));
   234 	const uint dx = delta(TileX(t0), TileX(t1));
   179 	const uint dy = delta(TileY(t0), TileY(t1));
   235 	const uint dy = delta(TileY(t0), TileY(t1));
   180 	return dx > dy ? 2 * dx + dy : 2 * dy + dx;
   236 	return dx > dy ? 2 * dx + dy : 2 * dy + dx;
   181 }
   237 }
   182 
   238 
       
   239 /**
       
   240  * Param the minimum distance to an edge
       
   241  * @param tile the tile to get the distance from
       
   242  * @return the distance from the edge in tiles
       
   243  */
   183 uint DistanceFromEdge(TileIndex tile)
   244 uint DistanceFromEdge(TileIndex tile)
   184 {
   245 {
   185 	const uint xl = TileX(tile);
   246 	const uint xl = TileX(tile);
   186 	const uint yl = TileY(tile);
   247 	const uint yl = TileY(tile);
   187 	const uint xh = MapSizeX() - 1 - xl;
   248 	const uint xh = MapSizeX() - 1 - xl;