mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-13 07:10:57 +00:00
Codechange: Simplify marking tiles dirty when terraforming (Patch by adf88, #6583)
This commit is contained in:
parent
f744dea0ff
commit
05da5a177c
@ -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;
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user