From dfb566331390a87f01d048f57ed6d51b2f329d65 Mon Sep 17 00:00:00 2001 From: zuu Date: Sat, 12 Oct 2013 22:07:58 +0000 Subject: (svn r25849) -Codechange: Introduce IsTileFlat to not compute full slope information for situations when we only want to know if a tile is flat or not (cirdan, LordAro) --- src/clear_cmd.cpp | 3 +-- src/industry_cmd.cpp | 2 +- src/landscape.cpp | 9 ++++----- src/object_cmd.cpp | 6 +++--- src/saveload/afterload.cpp | 8 ++++---- src/station_cmd.cpp | 6 +++--- src/tile_map.cpp | 24 ++++++++++++++++++++++++ src/tile_map.h | 2 ++ src/town_cmd.cpp | 6 +++--- src/water_cmd.cpp | 10 +++++----- src/waypoint_cmd.cpp | 2 +- 11 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index 46598866f..858197c91 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -249,8 +249,7 @@ static void TileLoop_Clear(TileIndex tile) /* If the tile is at any edge flood it to prevent maps without water. */ if (_settings_game.construction.freeform_edges && DistanceFromEdge(tile) == 1) { int z; - Slope slope = GetTileSlope(tile, &z); - if (z == 0 && slope == SLOPE_FLAT) { + if (IsTileFlat(tile, &z) && z == 0) { DoFloodTile(tile); MarkTileDirtyByTile(tile); return; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index c29a00820..7841ce84c 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1386,7 +1386,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil if (gfx == GFX_WATERTILE_SPECIALCHECK) { if (!IsTileType(cur_tile, MP_WATER) || - GetTileSlope(cur_tile) != SLOPE_FLAT) { + !IsTileFlat(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } } else { diff --git a/src/landscape.cpp b/src/landscape.cpp index 2e3e3d52e..d69275dd3 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -937,8 +937,7 @@ static void CreateDesertOrRainForest() static bool FindSpring(TileIndex tile, void *user_data) { int referenceHeight; - Slope s = GetTileSlope(tile, &referenceHeight); - if (s != SLOPE_FLAT || IsWaterTile(tile)) return false; + if (!IsTileFlat(tile, &referenceHeight) || IsWaterTile(tile)) return false; /* In the tropics rivers start in the rainforest. */ if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) != TROPICZONE_RAINFOREST) return false; @@ -974,7 +973,7 @@ static bool FindSpring(TileIndex tile, void *user_data) static bool MakeLake(TileIndex tile, void *user_data) { uint height = *(uint*)user_data; - if (!IsValidTile(tile) || TileHeight(tile) != height || GetTileSlope(tile) != SLOPE_FLAT) return false; + if (!IsValidTile(tile) || TileHeight(tile) != height || !IsTileFlat(tile)) return false; if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) == TROPICZONE_DESERT) return false; for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { @@ -1123,7 +1122,7 @@ static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin) queue.pop_front(); uint height2 = TileHeight(end); - if (GetTileSlope(end) == SLOPE_FLAT && (height2 < height || (height2 == height && IsWaterTile(end)))) { + if (IsTileFlat(end) && (height2 < height || (height2 == height && IsWaterTile(end)))) { found = true; break; } @@ -1150,7 +1149,7 @@ static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin) if (IsValidTile(lakeCenter) && /* A river, or lake, can only be built on flat slopes. */ - GetTileSlope(lakeCenter) == SLOPE_FLAT && + IsTileFlat(lakeCenter) && /* We want the lake to be built at the height of the river. */ TileHeight(begin) == TileHeight(lakeCenter) && /* We don't want the lake at the entry of the valley. */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 59fc3f5c4..20a392ca6 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -303,7 +303,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 switch (type) { case OBJECT_TRANSMITTER: case OBJECT_LIGHTHOUSE: - if (GetTileSlope(tile) != SLOPE_FLAT) return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); + if (!IsTileFlat(tile)) return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); break; case OBJECT_OWNED_LAND: @@ -673,7 +673,7 @@ void GenerateObjects() TileIndex tile = RandomTile(); int h; - if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h >= 4 && !IsBridgeAbove(tile)) { + if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h >= 4 && !IsBridgeAbove(tile)) { TileIndex t = tile; if (CircularTileSearch(&t, 9, HasTransmitter, NULL)) continue; @@ -710,7 +710,7 @@ void GenerateObjects() for (int j = 0; j < 19; j++) { int h; - if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h <= 2 && !IsBridgeAbove(tile)) { + if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h <= 2 && !IsBridgeAbove(tile)) { BuildObject(OBJECT_LIGHTHOUSE, tile); IncreaseGeneratingWorldProgress(GWP_OBJECT); lighthouses_to_build--; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 96b568b82..67b2f8975 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -74,7 +74,7 @@ void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_wate { /* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores. * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */ - if (GetTileSlope(t) != SLOPE_FLAT) { + if (!IsTileFlat(t)) { if (include_invalid_water_class) { SetWaterClass(t, WATER_CLASS_INVALID); return; @@ -1106,7 +1106,7 @@ bool AfterLoadGame() if (GB(_m[t].m5, 3, 2) == 0) { MakeClear(t, CLEAR_GRASS, 3); } else { - if (GetTileSlope(t) != SLOPE_FLAT) { + if (!IsTileFlat(t)) { MakeShore(t); } else { if (GetTileOwner(t) == OWNER_WATER) { @@ -1712,7 +1712,7 @@ bool AfterLoadGame() * on its neighbouring tiles. Done after river and canal updates to * ensure neighbours are correct. */ for (TileIndex t = 0; t < map_size; t++) { - if (GetTileSlope(t) != SLOPE_FLAT) continue; + if (!IsTileFlat(t)) continue; if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false); if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false); @@ -2390,7 +2390,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(149)) { for (TileIndex t = 0; t < map_size; t++) { if (!IsTileType(t, MP_STATION)) continue; - if (!IsBuoy(t) && !IsOilRig(t) && !(IsDock(t) && GetTileSlope(t) == SLOPE_FLAT)) { + if (!IsBuoy(t) && !IsOilRig(t) && !(IsDock(t) && IsTileFlat(t))) { SetWaterClass(t, WATER_CLASS_INVALID); } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index c57e4382d..19f7b3e64 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2471,7 +2471,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 TileIndex tile_cur = tile + TileOffsByDiagDir(direction); - if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur) != SLOPE_FLAT) { + if (!IsTileType(tile_cur, MP_WATER) || !IsTileFlat(tile_cur)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -2484,7 +2484,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (ret.Failed()) return ret; tile_cur += TileOffsByDiagDir(direction); - if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur) != SLOPE_FLAT) { + if (!IsTileType(tile_cur, MP_WATER) || !IsTileFlat(tile_cur)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -3069,7 +3069,7 @@ static void TileLoop_Station(TileIndex tile) break; case STATION_DOCK: - if (GetTileSlope(tile) != SLOPE_FLAT) break; // only handle water part + if (!IsTileFlat(tile)) break; // only handle water part /* FALL THROUGH */ case STATION_OILRIG: //(station part) case STATION_BUOY: diff --git a/src/tile_map.cpp b/src/tile_map.cpp index 86670c88a..1e30ba0d9 100644 --- a/src/tile_map.cpp +++ b/src/tile_map.cpp @@ -58,6 +58,30 @@ Slope GetTileSlope(TileIndex tile, int *h) return (Slope)r; } +/** + * Check if a given tile is flat + * @param tile Tile to check + * @param h If not \c NULL, pointer to storage of z height (only if tile is flat) + * @return Whether the tile is flat + */ +bool IsTileFlat(TileIndex tile, int *h) +{ + assert(tile < MapSize()); + + if (!IsInnerTile(tile)) { + if (h != NULL) *h = TileHeight(tile); + return true; + } + + uint z = TileHeight(tile); + if (TileHeight(tile + TileDiffXY(1, 0)) != z) return false; + if (TileHeight(tile + TileDiffXY(0, 1)) != z) return false; + if (TileHeight(tile + TileDiffXY(1, 1)) != z) return false; + + if (h != NULL) *h = z; + return true; +} + /** * Get bottom height of the tile * @param tile Tile to compute height of diff --git a/src/tile_map.h b/src/tile_map.h index f9c7a2ac9..98863eb59 100644 --- a/src/tile_map.h +++ b/src/tile_map.h @@ -247,6 +247,8 @@ Slope GetTileSlope(TileIndex tile, int *h = NULL); int GetTileZ(TileIndex tile); int GetTileMaxZ(TileIndex tile); +bool IsTileFlat(TileIndex tile, int *h = NULL); + /** * Return the slope of a given tile * @param tile Tile to compute slope of diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 6d469ba06..7ab9dcdad 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1411,7 +1411,7 @@ static bool GrowTown(Town *t) tile = t->xy; for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ - if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile) == SLOPE_FLAT) { + if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) { DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); cur_company.Restore(); @@ -1574,7 +1574,7 @@ static CommandCost TownCanBePlacedHere(TileIndex tile) } /* Can only build on clear flat areas, possibly with trees. */ - if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile) != SLOPE_FLAT) { + if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -1775,7 +1775,7 @@ static bool FindFurthestFromWater(TileIndex tile, void *user_data) uint dist = GetClosestWaterDistance(tile, true); if (IsTileType(tile, MP_CLEAR) && - GetTileSlope(tile) == SLOPE_FLAT && + IsTileFlat(tile) && IsTileAlignedToGrid(tile, sp->layout) && dist > sp->max_dist) { sp->tile = tile; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index b99741cfe..263731937 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -110,7 +110,7 @@ CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if ((MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) || (MayHaveBridgeAbove(tile2) && IsBridgeAbove(tile2))) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); - if (GetTileSlope(tile) != SLOPE_FLAT || GetTileSlope(tile2) != SLOPE_FLAT) { + if (!IsTileFlat(tile) || !IsTileFlat(tile2)) { /* Prevent depots on rapids */ return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -270,7 +270,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); } - if (GetTileSlope(tile - delta) != SLOPE_FLAT) { + if (!IsTileFlat(tile - delta)) { return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); } @@ -283,7 +283,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); } - if (GetTileSlope(tile + delta) != SLOPE_FLAT) { + if (!IsTileFlat(tile + delta)) { return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); } @@ -590,7 +590,7 @@ bool IsWateredTile(TileIndex tile, Direction from) return IsTileOnWater(tile); } - return (IsDock(tile) && GetTileSlope(tile) == SLOPE_FLAT) || IsBuoy(tile); + return (IsDock(tile) && IsTileFlat(tile)) || IsBuoy(tile); case MP_INDUSTRY: { /* Do not draw waterborders inside of industries. @@ -1240,7 +1240,7 @@ static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, if (mode != TRANSPORT_WATER) return 0; switch (GetWaterTileType(tile)) { - case WATER_TILE_CLEAR: ts = (GetTileSlope(tile) == SLOPE_FLAT) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break; + case WATER_TILE_CLEAR: ts = IsTileFlat(tile) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break; case WATER_TILE_COAST: ts = (TrackBits)coast_tracks[GetTileSlope(tile) & 0xF]; break; case WATER_TILE_LOCK: ts = DiagDirToDiagTrackBits(GetLockDirection(tile)); break; case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break; diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 35d7745c7..1a3d6e6e9 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -289,7 +289,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (tile == 0 || !HasTileWaterGround(tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); - if (GetTileSlope(tile) != SLOPE_FLAT) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); + if (!IsTileFlat(tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */ Waypoint *wp = FindDeletedWaypointCloseTo(tile, STR_SV_STNAME_BUOY, OWNER_NONE); -- cgit v1.2.3-54-g00ecf