diff src/road_cmd.cpp @ 10289:5f3f0d0a6e07 draft

(svn r14528) -Codechange: cache the closest town for all road tiles instead of only roads owned by tiles. This replaces a O(n) search over all towns from the road's tileloop with a O(1) lookup (PhilSophus)
author rubidium <rubidium@openttd.org>
date Sat, 25 Oct 2008 13:51:47 +0000 (2008-10-25)
parents d23fed9a51e2
children e3f0f062c7c3
line wrap: on
line diff
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -4,6 +4,7 @@
 
 #include "stdafx.h"
 #include "openttd.h"
+#include "map_func.h"
 #include "bridge_map.h"
 #include "bridge.h"
 #include "cmd_helper.h"
@@ -317,6 +318,11 @@
 						/* Includes MarkTileDirtyByTile() */
 						DoClearSquare(tile);
 					} else {
+						if (rt == ROADTYPE_ROAD && IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) {
+							/* Promote ownership from tram or highway and invalidate town index */
+							SetRoadOwner(tile, ROADTYPE_ROAD, GetRoadOwner(tile, (HasBit(rts, ROADTYPE_TRAM) ? ROADTYPE_TRAM : ROADTYPE_HWAY)));
+							SetTownIndex(tile, (TownID)INVALID_TOWN);
+						}
 						SetRoadBits(tile, ROAD_NONE, rt);
 						SetRoadTypes(tile, rts);
 						MarkTileDirtyByTile(tile);
@@ -354,6 +360,7 @@
 					if (reserved) SetTrackReservation(tile, tracks);
 				} else {
 					SetRoadTypes(tile, rts);
+					/* If we ever get HWAY and it is possible without road then we will need to promote ownership and invalidate town index here, too */
 				}
 				MarkTileDirtyByTile(tile);
 				YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
@@ -479,6 +486,10 @@
 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 	 * if a non-company is building the road */
 	if ((IsValidCompanyID(_current_company) && p2 != 0) || (_current_company == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
+	if (_current_company != OWNER_TOWN) {
+		const Town *town = CalcClosestTownFromTile(tile, UINT_MAX);
+		p2 = (town != NULL) ? town->index : (TownID)INVALID_TOWN;
+	}
 
 	RoadBits pieces = Extract<RoadBits, 0>(p1);
 
@@ -654,7 +665,7 @@
 				if (existing == ROAD_NONE || rtt == ROAD_TILE_CROSSING) {
 					SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
 					SetRoadOwner(tile, rt, _current_company);
-					if (_current_company == OWNER_TOWN && rt == ROADTYPE_ROAD) SetTownIndex(tile, p2);
+					if (rt == ROADTYPE_ROAD) SetTownIndex(tile, p2);
 				}
 				if (rtt != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rt);
 			} break;
@@ -886,7 +897,7 @@
 		Depot *dep = new Depot(tile);
 		dep->town_index = ClosestTownFromTile(tile, UINT_MAX)->index;
 
-		MakeRoadDepot(tile, _current_company, dir, rt);
+		MakeRoadDepot(tile, _current_company, dir, rt, dep->town_index);
 		MarkTileDirtyByTile(tile);
 	}
 	return cost.AddCost(_price.build_road_depot);
@@ -1263,6 +1274,18 @@
 	}
 }
 
+void InvalidateTownForRoadTile()
+{
+	TileIndex map_size = MapSize();
+
+	for (TileIndex t = 0; t < map_size; t++) {
+		if (IsTileType(t, MP_ROAD) && GetRoadOwner(t, ROADTYPE_ROAD) != OWNER_TOWN) {
+			/* GetRoadOwner(t, ROADTYPE_ROAD) is valid for road tiles even when there is no road */
+			SetTownIndex(t, (TownID)INVALID_TOWN);
+		}
+	}
+}
+
 static uint GetSlopeZ_Road(TileIndex tile, uint x, uint y)
 {
 	uint z;