Changeset - r23200:d73d32853625
[Not reviewed]
master
0 3 0
Johannes E. Krause - 5 years ago 2019-01-13 19:56:10
j.k@eclipso.de
Codechange: Simplify marking tiles dirty when terraforming (Patch by adf88, #6583)
3 files changed with 23 insertions and 106 deletions:
0 comments (0 inline, 0 general)
src/terraform_cmd.cpp
Show inline comments
 
@@ -309,6 +309,14 @@ CommandCost CmdTerraformLand(TileIndex t
 
	}
 

	
 
	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 t
 
			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;
src/viewport.cpp
Show inline comments
 
@@ -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,
 
@@ -1792,22 +1793,6 @@ void MarkTileDirtyByTile(TileIndex tile,
 
}
 

	
 
/**
 
 * 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.
 
 *
 
 * This function marks the selected tiles as dirty for repaint
src/viewport_func.h
Show inline comments
 
@@ -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);
 

	
0 comments (0 inline, 0 general)