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 #include "settings_type.h"
00020
00021 extern uint _map_tile_mask;
00022
00029 #define TILE_MASK(x) ((x) & _map_tile_mask)
00030
00037 extern Tile *_m;
00038
00045 extern TileExtended *_me;
00046
00047 void AllocateMap(uint size_x, uint size_y);
00048
00054 static inline uint MapLogX()
00055 {
00056 extern uint _map_log_x;
00057 return _map_log_x;
00058 }
00059
00065 static inline uint MapLogY()
00066 {
00067 extern uint _map_log_y;
00068 return _map_log_y;
00069 }
00070
00075 static inline uint MapSizeX()
00076 {
00077 extern uint _map_size_x;
00078 return _map_size_x;
00079 }
00080
00085 static inline uint MapSizeY()
00086 {
00087 extern uint _map_size_y;
00088 return _map_size_y;
00089 }
00090
00095 static inline uint MapSize()
00096 {
00097 extern uint _map_size;
00098 return _map_size;
00099 }
00100
00105 static inline uint MapMaxX()
00106 {
00107 return MapSizeX() - 1;
00108 }
00109
00114 static inline uint MapMaxY()
00115 {
00116 return MapSizeY() - 1;
00117 }
00118
00119 extern uint8 _head_to_head;
00120 static inline uint AreaMinY()
00121 {
00122 assert(_head_to_head > 0);
00123 uint offset = MapSizeY() / _settings_game.game_creation.head_to_head_areas;
00124 return offset * (_head_to_head - 1);
00125 }
00126
00127 static inline uint AreaMaxY()
00128 {
00129 assert(_head_to_head > 0);
00130 uint offset = MapSizeY() / _settings_game.game_creation.head_to_head_areas;
00131 return offset * (_head_to_head);
00132 }
00133
00134 static inline uint AreaMinX()
00135 {
00136 return 0;
00137 }
00138
00139 static inline uint AreaMaxX()
00140 {
00141 return MapSizeX();
00142 }
00143
00150 static inline uint ScaleByMapSize(uint n)
00151 {
00152
00153
00154 return CeilDiv(n << (MapLogX() + MapLogY() - 12), 1 << 4);
00155 }
00156
00157
00164 static inline uint ScaleByMapSize1D(uint n)
00165 {
00166
00167
00168
00169 return CeilDiv((n << MapLogX()) + (n << MapLogY()), 1 << 9);
00170 }
00171
00182 typedef int32 TileIndexDiff;
00183
00191 static inline TileIndex TileXY(uint x, uint y)
00192 {
00193 return (y << MapLogX()) + x;
00194 }
00195
00207 static inline TileIndexDiff TileDiffXY(int x, int y)
00208 {
00209
00210
00211
00212
00213 return (y * MapSizeX()) + x;
00214 }
00215
00222 static inline TileIndex TileVirtXY(uint x, uint y)
00223 {
00224 return (y >> 4 << MapLogX()) + (x >> 4);
00225 }
00226
00227
00233 static inline uint TileX(TileIndex tile)
00234 {
00235 return tile & MapMaxX();
00236 }
00237
00243 static inline uint TileY(TileIndex tile)
00244 {
00245 return tile >> MapLogX();
00246 }
00247
00248 static inline uint GetAreaByTile(TileIndex tile)
00249 {
00250 assert(tile < MapSize());
00251 return 1 + (TileY(tile) / (MapSizeY() / _settings_game.game_creation.head_to_head_areas));
00252 }
00253
00264 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
00265 {
00266 return (tidc.y << MapLogX()) + tidc.x;
00267 }
00268
00269
00270 #ifndef _DEBUG
00271
00278 #define TILE_ADD(x, y) ((x) + (y))
00279 #else
00280 extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
00281 const char *exp, const char *file, int line);
00282 #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
00283 #endif
00284
00292 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
00293
00294 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
00295 TileIndex TileAddAreaWrap(TileIndex tile, int addx, int addy);
00296
00303 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
00304 {
00305 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00306
00307 assert(IsValidDiagDirection(dir));
00308 return _tileoffs_by_diagdir[dir];
00309 }
00310
00317 static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
00318 {
00319 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00320
00321 assert(IsValidDirection(dir));
00322 return _tileoffs_by_dir[dir];
00323 }
00324
00335 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
00336 {
00337 int x = TileX(tile) + diff.x;
00338 int y = TileY(tile) + diff.y;
00339
00340 if ((uint)x >= MapSizeX() || (uint)y >= MapSizeY()) return INVALID_TILE;
00341 return TileXY(x, y);
00342 }
00343
00351 static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
00352 {
00353 TileIndexDiffC difference;
00354
00355 difference.x = TileX(tile_a) - TileX(tile_b);
00356 difference.y = TileY(tile_a) - TileY(tile_b);
00357
00358 return difference;
00359 }
00360
00361
00362 uint DistanceManhattan(TileIndex, TileIndex);
00363 uint DistanceSquare(TileIndex, TileIndex);
00364 uint DistanceMax(TileIndex, TileIndex);
00365 uint DistanceMaxPlusManhattan(TileIndex, TileIndex);
00366 uint DistanceFromEdge(TileIndex);
00367 uint DistanceFromEdgeDir(TileIndex, DiagDirection);
00368
00376 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
00377 {
00378 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00379
00380 assert(IsValidDiagDirection(dir));
00381 return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
00382 }
00383
00390 static inline TileIndexDiff TileOffsByDir(Direction dir)
00391 {
00392 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00393
00394 assert(IsValidDirection(dir));
00395 return ToTileIndexDiff(_tileoffs_by_dir[dir]);
00396 }
00397
00405 static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
00406 {
00407 return TILE_ADD(tile, TileOffsByDiagDir(dir));
00408 }
00409
00417 static inline DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
00418 {
00419 int dx = (int)TileX(tile_to) - (int)TileX(tile_from);
00420 int dy = (int)TileY(tile_to) - (int)TileY(tile_from);
00421 if (dx == 0) {
00422 if (dy == 0) return INVALID_DIAGDIR;
00423 return (dy < 0 ? DIAGDIR_NW : DIAGDIR_SE);
00424 } else {
00425 if (dy != 0) return INVALID_DIAGDIR;
00426 return (dx < 0 ? DIAGDIR_NE : DIAGDIR_SW);
00427 }
00428 }
00429
00437 typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data);
00438
00439 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
00440 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data);
00441
00447 static inline TileIndex RandomTileSeed(uint32 r)
00448 {
00449 return TILE_MASK(r);
00450 }
00451
00458 #define RandomTile() RandomTileSeed(Random())
00459
00463 uint GetClosestWaterDistance(TileIndex tile, bool water);
00464
00465 TileIndex RandomTileInArea(uint area);
00466
00467 #endif