From 05da5a177c7e976d5da0da541a842482ab23017d Mon Sep 17 00:00:00 2001 From: "Johannes E. Krause" Date: Sun, 13 Jan 2019 20:56:10 +0100 Subject: [PATCH] Codechange: Simplify marking tiles dirty when terraforming (Patch by adf88, #6583) --- src/terraform_cmd.cpp | 93 ++++--------------------------------------- src/viewport.cpp | 21 ++-------- src/viewport_func.h | 15 +++++-- 3 files changed, 23 insertions(+), 106 deletions(-) diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index aad9822822..5b476da18e 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -309,6 +309,14 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } if (flags & DC_EXEC) { + /* Mark affected areas dirty. */ + for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) { + MarkTileDirtyByTile(*it); + TileIndexToHeightMap::const_iterator new_height = ts.tile_to_new_height.find(tile); + if (new_height != ts.tile_to_new_height.end()) continue; + MarkTileDirtyByTile(*it, 0, new_height->second); + } + /* change the height */ for (TileIndexToHeightMap::const_iterator it = ts.tile_to_new_height.begin(); it != ts.tile_to_new_height.end(); it++) { @@ -318,91 +326,6 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin SetTileHeight(tile, (uint)height); } - /* Finally mark the dirty tiles dirty */ - for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) { - MarkTileDirtyByTile(*it); - - int height = TerraformGetHeightOfTile(&ts, *it); - - /* Now, if we alter the height of the map edge, we need to take care - * about repainting the affected areas outside map as well. - * Remember: - * Outside map, we assume that our landscape descends to - * height zero as fast as possible. - * Those simulated tiles (they don't exist as datastructure, - * only as concept in code) need to be repainted properly, - * otherwise we will get ugly glitches. - * - * Furthermore, note that we have to take care about the possibility, - * that landscape was higher before the change, - * so also tiles a bit outside need to be repainted. - */ - int x = TileX(*it); - int y = TileY(*it); - if (x == 0) { - if (y == 0) { - /* Height of the northern corner is altered. */ - for (int cx = 0; cx >= -height - 1; cx--) { - for (int cy = 0; cy >= -height - 1; cy--) { - /* This means, tiles in the sector north of that - * corner need to be repainted. - */ - if (cx + cy >= -height - 2) { - /* But only tiles that actually might have changed. */ - MarkTileDirtyByTileOutsideMap(cx, cy); - } - } - } - } else if (y < (int)MapMaxY()) { - for (int cx = 0; cx >= -height - 1; cx--) { - MarkTileDirtyByTileOutsideMap(cx, y); - } - } else { - for (int cx = 0; cx >= -height - 1; cx--) { - for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) { - if (cx + ((int)MapMaxY() - cy) >= -height - 2) { - MarkTileDirtyByTileOutsideMap(cx, cy); - } - } - } - } - } else if (x < (int)MapMaxX()) { - if (y == 0) { - for (int cy = 0; cy >= -height - 1; cy--) { - MarkTileDirtyByTileOutsideMap(x, cy); - } - } else if (y < (int)MapMaxY()) { - /* Nothing to be done here, we are inside the map. */ - } else { - for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) { - MarkTileDirtyByTileOutsideMap(x, cy); - } - } - } else { - if (y == 0) { - for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) { - for (int cy = 0; cy >= -height - 1; cy--) { - if (((int)MapMaxX() - cx) + cy >= -height - 2) { - MarkTileDirtyByTileOutsideMap(cx, cy); - } - } - } - } else if (y < (int)MapMaxY()) { - for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) { - MarkTileDirtyByTileOutsideMap(cx, y); - } - } else { - for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) { - for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) { - if (((int)MapMaxX() - cx) + ((int)MapMaxY() - cy) >= -height - 2) { - MarkTileDirtyByTileOutsideMap(cx, cy); - } - } - } - } - } - } - if (c != NULL) c->terraform_limit -= (uint32)ts.tile_to_new_height.size() << 16; } return total_cost; diff --git a/src/viewport.cpp b/src/viewport.cpp index 7fe280a203..11a1587126 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1779,11 +1779,12 @@ void ConstrainAllViewportsZoom() * Mark a tile given by its index dirty for repaint. * @param tile The tile to mark dirty. * @param bridge_level_offset Height of bridge on tile to also mark dirty. (Height level relative to north corner.) + * @param tile_height_override Height of the tile (#TileHeight). * @ingroup dirty */ -void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset) +void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override) { - Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, TilePixelHeight(tile)); + Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, tile_height_override * TILE_HEIGHT); MarkAllViewportsDirty( pt.x - MAX_TILE_EXTENT_LEFT, pt.y - MAX_TILE_EXTENT_TOP - ZOOM_LVL_BASE * TILE_HEIGHT * bridge_level_offset, @@ -1791,22 +1792,6 @@ void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset) pt.y + MAX_TILE_EXTENT_BOTTOM); } -/** - * Mark a (virtual) tile outside the map dirty for repaint. - * @param x Tile X position. - * @param y Tile Y position. - * @ingroup dirty - */ -void MarkTileDirtyByTileOutsideMap(int x, int y) -{ - Point pt = RemapCoords(x * TILE_SIZE, y * TILE_SIZE, TilePixelHeightOutsideMap(x, y)); - MarkAllViewportsDirty( - pt.x - MAX_TILE_EXTENT_LEFT, - pt.y, // no buildings outside of map - pt.x + MAX_TILE_EXTENT_RIGHT, - pt.y + MAX_TILE_EXTENT_BOTTOM); -} - /** * Marks the selected tiles as dirty. * diff --git a/src/viewport_func.h b/src/viewport_func.h index cbdcc5019a..319d4efd60 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -15,7 +15,7 @@ #include "gfx_type.h" #include "viewport_type.h" #include "window_type.h" -#include "tile_type.h" +#include "tile_map.h" #include "station_type.h" static const int TILE_HEIGHT_STEP = 50; ///< One Z unit tile height difference is displayed as 50m. @@ -78,9 +78,18 @@ void UpdateAllVirtCoords(); extern Point _tile_fract_coords; -void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = 0); +void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override); -void MarkTileDirtyByTileOutsideMap(int x, int y); +/** + * Mark a tile given by its index dirty for repaint. + * @param tile The tile to mark dirty. + * @param bridge_level_offset Height of bridge on tile to also mark dirty. (Height level relative to north corner.) + * @ingroup dirty + */ +static inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = 0) +{ + MarkTileDirtyByTile(tile, bridge_level_offset, TileHeight(tile)); +} Point GetViewportStationMiddle(const ViewPort *vp, const Station *st);