summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2015-02-22 14:01:24 +0000
committerfrosch <frosch@openttd.org>2015-02-22 14:01:24 +0000
commite8e49e5ddabf6bdc6c6b6a77a1d2ead377c27444 (patch)
treea6cd6584172b1917357ac22feb2779fd3e18e6f4
parentff1f465191e9ea1651ad18070f53f8274c8c2f74 (diff)
downloadopenttd-e8e49e5ddabf6bdc6c6b6a77a1d2ead377c27444.tar.xz
(svn r27157) -Fix: Mark bridge middle tiles dirty when building/removing/changing bridges.
-rw-r--r--src/rail_cmd.cpp10
-rw-r--r--src/road_cmd.cpp18
-rw-r--r--src/tunnelbridge.h3
-rw-r--r--src/tunnelbridge_cmd.cpp34
-rw-r--r--src/viewport.cpp5
-rw-r--r--src/viewport_func.h2
6 files changed, 48 insertions, 24 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index d3093aa7b..ab383794b 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1688,13 +1688,11 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track);
- MarkTileDirtyByTile(tile);
- MarkTileDirtyByTile(endtile);
-
if (IsBridge(tile)) {
- TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
- TileIndex t = tile + delta;
- for (; t != endtile; t += delta) MarkTileDirtyByTile(t); // TODO encapsulate this into a function
+ MarkBridgeDirty(tile);
+ } else {
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(endtile);
}
}
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index e56633696..e7cfa2382 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -246,12 +246,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
}
/* Mark tiles dirty that have been repaved */
- MarkTileDirtyByTile(tile);
- MarkTileDirtyByTile(other_end);
if (IsBridge(tile)) {
- TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
-
- for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
+ MarkBridgeDirty(tile);
+ } else {
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(other_end);
}
}
} else {
@@ -747,12 +746,11 @@ do_clear:;
SetRoadOwner(tile, rt, company);
/* Mark tiles dirty that have been repaved */
- MarkTileDirtyByTile(other_end);
- MarkTileDirtyByTile(tile);
if (IsBridge(tile)) {
- TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
-
- for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
+ MarkBridgeDirty(tile);
+ } else {
+ MarkTileDirtyByTile(other_end);
+ MarkTileDirtyByTile(tile);
}
break;
}
diff --git a/src/tunnelbridge.h b/src/tunnelbridge.h
index ab8891f62..0a2c2293d 100644
--- a/src/tunnelbridge.h
+++ b/src/tunnelbridge.h
@@ -14,6 +14,9 @@
#include "map_func.h"
+void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height);
+void MarkBridgeDirty(TileIndex tile);
+
/**
* Calculates the length of a tunnel or a bridge (without end tiles)
* @param begin The begin of the tunnel or bridge.
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
index d4b794633..b3778a932 100644
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -52,6 +52,33 @@ TileIndex _build_tunnel_endtile; ///< The end of a tunnel; as hidden return from
/** Z position of the bridge sprites relative to bridge height (downwards) */
static const int BRIDGE_Z_START = 3;
+
+/**
+ * Mark bridge tiles dirty.
+ * Note: The bridge does not need to exist, everything is passed via parameters.
+ * @param begin Start tile.
+ * @param end End tile.
+ * @param direction Direction from \a begin to \a end.
+ * @param bridge_height Bridge height level.
+ */
+void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height)
+{
+ TileIndexDiff delta = TileOffsByDiagDir(direction);
+ for (TileIndex t = begin; t != end; t += delta) {
+ MarkTileDirtyByTile(t, bridge_height - TileHeight(t));
+ }
+ MarkTileDirtyByTile(end);
+}
+
+/**
+ * Mark bridge tiles dirty.
+ * @param tile Bridge head.
+ */
+void MarkBridgeDirty(TileIndex tile)
+{
+ MarkBridgeDirty(tile, GetOtherTunnelBridgeEnd(tile), GetTunnelBridgeDirection(tile), GetBridgeHeight(tile));
+}
+
/** Reset the data been eventually changed by the grf loaded. */
void ResetBridges()
{
@@ -506,10 +533,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
}
/* Mark all tiles dirty */
- TileIndexDiff delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
- for (TileIndex tile = tile_start; tile <= tile_end; tile += delta) {
- MarkTileDirtyByTile(tile);
- }
+ MarkBridgeDirty(tile_start, tile_end, AxisToDiagDir(direction), z_start);
DirtyCompanyInfrastructureWindows(owner);
}
@@ -926,7 +950,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags)
if (height < minz) SetRoadside(c, ROADSIDE_PAVED);
}
ClearBridgeMiddle(c);
- MarkTileDirtyByTile(c);
+ MarkTileDirtyByTile(c, height - TileHeight(c));
}
if (rail) {
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 301b5e799..796368114 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -2232,14 +2232,15 @@ 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.)
* @ingroup dirty
*/
-void MarkTileDirtyByTile(TileIndex tile)
+void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
{
Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, TilePixelHeight(tile));
MarkAllViewportsDirty(
pt.x - MAX_TILE_EXTENT_LEFT,
- pt.y - MAX_TILE_EXTENT_TOP,
+ pt.y - MAX_TILE_EXTENT_TOP - ZOOM_LVL_BASE * TILE_HEIGHT * bridge_level_offset,
pt.x + MAX_TILE_EXTENT_RIGHT,
pt.y + MAX_TILE_EXTENT_BOTTOM);
}
diff --git a/src/viewport_func.h b/src/viewport_func.h
index 3e05162d8..8dbbc5945 100644
--- a/src/viewport_func.h
+++ b/src/viewport_func.h
@@ -77,7 +77,7 @@ void UpdateAllVirtCoords();
extern Point _tile_fract_coords;
-void MarkTileDirtyByTile(TileIndex tile);
+void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = 0);
int GetRowAtTile(int viewport_y, Point tile, bool bridge_correct);
void MarkTileDirtyByTileOutsideMap(int x, int y);