00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef MAP_FUNC_H
00013 #define MAP_FUNC_H
00014
00015 #include "core/math_func.hpp"
00016 #include "tile_type.h"
00017 #include "map_type.h"
00018 #include "direction_func.h"
00019
00020 extern uint _map_tile_mask;
00021
00028 #define TILE_MASK(x) ((x) & _map_tile_mask)
00029
00036 extern Tile *_m;
00037
00044 extern TileExtended *_me;
00045
00051 extern TileHeightData *_map_heightdata;
00052
00053 void AllocateMap(uint size_x, uint size_y, bool allocate_map_heightdata);
00054
00055 void CopyHeightlevelDataFromOldToExtended();
00056
00057 bool CopyHeightlevelDataFromExtendedToOld();
00058
00064 static inline uint MapLogX()
00065 {
00066 extern uint _map_log_x;
00067 return _map_log_x;
00068 }
00069
00075 static inline uint MapLogY()
00076 {
00077 extern uint _map_log_y;
00078 return _map_log_y;
00079 }
00080
00085 static inline uint MapSizeX()
00086 {
00087 extern uint _map_size_x;
00088 return _map_size_x;
00089 }
00090
00095 static inline uint MapSizeY()
00096 {
00097 extern uint _map_size_y;
00098 return _map_size_y;
00099 }
00100
00105 static inline uint MapSize()
00106 {
00107 extern uint _map_size;
00108 return _map_size;
00109 }
00110
00115 static inline uint MapMaxX()
00116 {
00117 return MapSizeX() - 1;
00118 }
00119
00124 static inline uint MapMaxY()
00125 {
00126 return MapSizeY() - 1;
00127 }
00128
00135 static inline uint ScaleByMapSize(uint n)
00136 {
00137
00138
00139 return CeilDiv(n << (MapLogX() + MapLogY() - 12), 1 << 4);
00140 }
00141
00142
00149 static inline uint ScaleByMapSize1D(uint n)
00150 {
00151
00152
00153
00154 return CeilDiv((n << MapLogX()) + (n << MapLogY()), 1 << 9);
00155 }
00156
00167 typedef int32 TileIndexDiff;
00168
00176 static inline TileIndex TileXY(uint x, uint y)
00177 {
00178 return (y << MapLogX()) + x;
00179 }
00180
00192 static inline TileIndexDiff TileDiffXY(int x, int y)
00193 {
00194
00195
00196
00197
00198 return (y * MapSizeX()) + x;
00199 }
00200
00207 static inline TileIndex TileVirtXY(uint x, uint y)
00208 {
00209 return (y >> 4 << MapLogX()) + (x >> 4);
00210 }
00211
00212
00218 static inline uint TileX(TileIndex tile)
00219 {
00220 return tile & MapMaxX();
00221 }
00222
00228 static inline uint TileY(TileIndex tile)
00229 {
00230 return tile >> MapLogX();
00231 }
00232
00243 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
00244 {
00245 return (tidc.y << MapLogX()) + tidc.x;
00246 }
00247
00248
00249 #ifndef _DEBUG
00250
00257 #define TILE_ADD(x, y) ((x) + (y))
00258 #else
00259 extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
00260 const char *exp, const char *file, int line);
00261 #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
00262 #endif
00263
00271 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
00272
00273 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
00274
00281 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
00282 {
00283 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00284
00285 assert(IsValidDiagDirection(dir));
00286 return _tileoffs_by_diagdir[dir];
00287 }
00288
00295 static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
00296 {
00297 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00298
00299 assert(IsValidDirection(dir));
00300 return _tileoffs_by_dir[dir];
00301 }
00302
00313 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
00314 {
00315 int x = TileX(tile) + diff.x;
00316 int y = TileY(tile) + diff.y;
00317
00318 if ((uint)x >= MapSizeX() || (uint)y >= MapSizeY()) return INVALID_TILE;
00319 return TileXY(x, y);
00320 }
00321
00329 static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
00330 {
00331 TileIndexDiffC difference;
00332
00333 difference.x = TileX(tile_a) - TileX(tile_b);
00334 difference.y = TileY(tile_a) - TileY(tile_b);
00335
00336 return difference;
00337 }
00338
00339
00340 uint DistanceManhattan(TileIndex, TileIndex);
00341 uint DistanceSquare(TileIndex, TileIndex);
00342 uint DistanceMax(TileIndex, TileIndex);
00343 uint DistanceMaxPlusManhattan(TileIndex, TileIndex);
00344 uint DistanceFromEdge(TileIndex);
00345 uint DistanceFromEdgeDir(TileIndex, DiagDirection);
00346
00354 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
00355 {
00356 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00357
00358 assert(IsValidDiagDirection(dir));
00359 return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
00360 }
00361
00368 static inline TileIndexDiff TileOffsByDir(Direction dir)
00369 {
00370 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00371
00372 assert(IsValidDirection(dir));
00373 return ToTileIndexDiff(_tileoffs_by_dir[dir]);
00374 }
00375
00383 static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
00384 {
00385 return TILE_ADD(tile, TileOffsByDiagDir(dir));
00386 }
00387
00395 static inline DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
00396 {
00397 int dx = (int)TileX(tile_to) - (int)TileX(tile_from);
00398 int dy = (int)TileY(tile_to) - (int)TileY(tile_from);
00399 if (dx == 0) {
00400 if (dy == 0) return INVALID_DIAGDIR;
00401 return (dy < 0 ? DIAGDIR_NW : DIAGDIR_SE);
00402 } else {
00403 if (dy != 0) return INVALID_DIAGDIR;
00404 return (dx < 0 ? DIAGDIR_NE : DIAGDIR_SW);
00405 }
00406 }
00407
00415 typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data);
00416
00417 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
00418 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data);
00419
00425 static inline TileIndex RandomTileSeed(uint32 r)
00426 {
00427 return TILE_MASK(r);
00428 }
00429
00436 #define RandomTile() RandomTileSeed(Random())
00437
00438 uint GetClosestWaterDistance(TileIndex tile, bool water);
00439
00440
00441
00452 #define TILE_LOOP(var, w, h, tile) \
00453 for (uint var = tile, cur_h = (h); cur_h > 0; --cur_h, var += TileDiffXY(0, 1) - (w)) \
00454 for (uint cur_w = (w); cur_w > 0; --cur_w, var++)
00455
00456 #endif