# tile_map.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef TILE_MAP_H
    00013 #define TILE_MAP_H
    00014
    00015 #include "slope_type.h"
    00016 #include "map_func.h"
    00017 #include "core/bitmath_func.hpp"
    00018 #include "core/math_func.hpp"
    00019 #include "settings_type.h"
    00020
    00031 static inline bool AllowMoreHeightlevels()
    00032 {
    00033   return _settings_game.construction.allow_more_heightlevels;
    00034 }
    00035
    00042 static inline uint GetMaxTileHeight()
    00043 {
    00044   if (AllowMoreHeightlevels()) {
    00045     return MAX_TILE_HEIGHT_EXTENDED;
    00046   } else {
    00047     return MAX_TILE_HEIGHT_OLD;
    00048   }
    00049 }
    00050
    00057 static inline uint GetMaxSnowlineHeight()
    00058 {
    00059   if (AllowMoreHeightlevels()) {
    00060     return MAX_SNOWLINE_HEIGHT_EXTENDED;
    00061   } else {
    00062     return MAX_SNOWLINE_HEIGHT_OLD;
    00063   }
    00064 }
    00065
    00072 static inline uint GetMaxTreelineHeight()
    00073 {
    00074   if (AllowMoreHeightlevels()) {
    00075     return MAX_TREELINE_HEIGHT_EXTENDED;
    00076   } else {
    00077     return MAX_TREELINE_HEIGHT_OLD;
    00078   }
    00079 }
    00080
    00090 static inline uint TileHeight(TileIndex tile)
    00091 {
    00092   assert(tile < MapSize());
    00093
    00094   if (AllowMoreHeightlevels()) {
    00095     return _map_heightdata[tile].heightlevel;
    00096   } else {
    00097     return GB(_m[tile].type_height, 0, 4);
    00098   }
    00099 }
    00100
    00105 static inline uint TileHeightOutsideMap(int x, int y)
    00106 {
    00107   /* In all cases: Descend to heightlevel 0 as fast as possible.
    00108    * So: If we are at the 0-side of the map (x<0 or y<0), we must
    00109    * subtract the distance to coordinate 0 from the heightlevel.
    00110    * In other words: Subtract e.g. -x. If we are at the MapMax
    00111    * side of the map, we also need to subtract the distance to
    00112    * the edge of map, e.g. MapMaxX - x.
    00113    *
    00114    * NOTE: Assuming constant heightlevel outside map would be
    00115    * simpler here. However, then we run into painting problems,
    00116    * since whenever a heightlevel change at the map border occurs,
    00117    * we would need to repaint anything outside map.
    00118    * In contrast, by doing it this way, we can localize this change,
    00119    * which means we may assume constant heightlevel for all tiles
    00120    * at more than <heightlevel at map border> distance from the
    00121    * map border. */
    00122   if (x < 0) {
    00123     if (y < 0) {
    00124       return max((int)TileHeight(TileXY(0, 0)) - (-x) - (-y), 0);
    00125     } else if (y < (int)MapMaxY()) {
    00126       return max((int)TileHeight(TileXY(0, y)) - (-x), 0);
    00127     } else {
    00128       return max((int)TileHeight(TileXY(0, (int)MapMaxY())) - (-x) - (y - (int)MapMaxY()), 0);
    00129     }
    00130   } else if (x < (int)MapMaxX()) {
    00131     if (y < 0) {
    00132       return max((int)TileHeight(TileXY(x, 0)) - (-y), 0);
    00133     } else if (y < (int)MapMaxY()) {
    00134       return TileHeight(TileXY(x, y));
    00135     } else {
    00136       return max((int)TileHeight(TileXY(x, (int)MapMaxY())) - (y - (int)MapMaxY()), 0);
    00137     }
    00138   } else {
    00139     if (y < 0) {
    00140       return max((int)TileHeight(TileXY((int)MapMaxX(), 0)) - (x - (int)MapMaxX()) - (-y), 0);
    00141     } else if (y < (int)MapMaxY()) {
    00142       return max((int)TileHeight(TileXY((int)MapMaxX(), y)) - (x - (int)MapMaxX()), 0);
    00143     } else {
    00144       return max((int)TileHeight(TileXY((int)MapMaxX(), (int)MapMaxY())) - (x - (int)MapMaxX()) - (y - (int)MapMaxY()), 0);
    00145     }
    00146   }
    00147 }
    00148
    00157 static inline void SetTileHeight(TileIndex tile, uint height)
    00158 {
    00159   assert(tile < MapSize());
    00160
    00161   if (height > GetMaxTileHeight()) {
    00162     /* Make sure height is within allowed range. */
    00163     height = GetMaxTileHeight();
    00164   }
    00165
    00166   if (AllowMoreHeightlevels()) {
    00167     _map_heightdata[tile].heightlevel = height;
    00168   } else {
    00169     SB(_m[tile].type_height, 0, 4, height);
    00170   }
    00171 }
    00172
    00181 static inline uint TilePixelHeight(TileIndex tile)
    00182 {
    00183   return TileHeight(tile) * TILE_HEIGHT;
    00184 }
    00185
    00193 static inline TileType GetTileType(TileIndex tile)
    00194 {
    00195   assert(tile < MapSize());
    00196   return (TileType)GB(_m[tile].type_height, 4, 4);
    00197 }
    00198
    00211 static inline void SetTileType(TileIndex tile, TileType type)
    00212 {
    00213   assert(tile < MapSize());
    00214   /* VOID tiles (and no others) are exactly allowed at the lower left and right
    00215    * edges of the map. If _settings_game.construction.freeform_edges is true,
    00216    * the upper edges of the map are also VOID tiles. */
    00217   assert((TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY() || (_settings_game.construction.freeform_edges && (TileX(tile) == 0 || TileY(tile) == 0))) == (type == MP_VOID));
    00218   SB(_m[tile].type_height, 4, 4, type);
    00219 }
    00220
    00230 static inline bool IsTileType(TileIndex tile, TileType type)
    00231 {
    00232   return GetTileType(tile) == type;
    00233 }
    00234
    00241 static inline bool IsValidTile(TileIndex tile)
    00242 {
    00243   return tile < MapSize() && !IsTileType(tile, MP_VOID);
    00244 }
    00245
    00258 static inline Owner GetTileOwner(TileIndex tile)
    00259 {
    00260   assert(IsValidTile(tile));
    00261   assert(!IsTileType(tile, MP_HOUSE));
    00262   assert(!IsTileType(tile, MP_INDUSTRY));
    00263
    00264   return (Owner)GB(_m[tile].m1, 0, 5);
    00265 }
    00266
    00278 static inline void SetTileOwner(TileIndex tile, Owner owner)
    00279 {
    00280   assert(IsValidTile(tile));
    00281   assert(!IsTileType(tile, MP_HOUSE));
    00282   assert(!IsTileType(tile, MP_INDUSTRY));
    00283
    00284   SB(_m[tile].m1, 0, 5, owner);
    00285 }
    00286
    00294 static inline bool IsTileOwner(TileIndex tile, Owner owner)
    00295 {
    00296   return GetTileOwner(tile) == owner;
    00297 }
    00298
    00305 static inline void SetTropicZone(TileIndex tile, TropicZone type)
    00306 {
    00307   assert(tile < MapSize());
    00308   assert(!IsTileType(tile, MP_VOID) || type == TROPICZONE_NORMAL);
    00309   SB(_m[tile].m6, 0, 2, type);
    00310 }
    00311
    00318 static inline TropicZone GetTropicZone(TileIndex tile)
    00319 {
    00320   assert(tile < MapSize());
    00321   return (TropicZone)GB(_m[tile].m6, 0, 2);
    00322 }
    00323
    00330 static inline byte GetAnimationFrame(TileIndex t)
    00331 {
    00332   assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION));
    00333   return _me[t].m7;
    00334 }
    00335
    00342 static inline void SetAnimationFrame(TileIndex t, byte frame)
    00343 {
    00344   assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION));
    00345   _me[t].m7 = frame;
    00346 }
    00347
    00348 Slope GetTileSlope(TileIndex tile, uint *h);
    00349 Slope GetTileSlopeOutsideMap(int x, int y, uint *h);
    00350 uint GetTileZ(TileIndex tile);
    00351 uint GetTileZOutsideMap(int x, int y);
    00352 uint GetTileMaxZ(TileIndex tile);
    00353
    00382 uint GetTileMaxZOutsideMap(int x, int y);
    00383
    00391 static inline uint TileHash(uint x, uint y)
    00392 {
    00393   uint hash = x >> 4;
    00394   hash ^= x >> 6;
    00395   hash ^= y >> 4;
    00396   hash -= y >> 6;
    00397   return hash;
    00398 }
    00399
    00409 static inline uint TileHash2Bit(uint x, uint y)
    00410 {
    00411   return GB(TileHash(x, y), 0, 2);
    00412 }
    00413
    00414 #endif /* TILE_MAP_H */