changeset 18568:d2563220728e draft

(svn r23413) -Add: Company infrastructure counts for canals.
author michi_cc <michi_cc@openttd.org>
date Sat, 03 Dec 2011 23:40:23 +0000
parents 1c2e5babf594
children 42709d5de004
files src/economy_type.h src/object_cmd.cpp src/saveload/company_sl.cpp src/station_cmd.cpp src/tunnelbridge_cmd.cpp src/water_cmd.cpp
diffstat 6 files changed, 116 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/economy_type.h
+++ b/src/economy_type.h
@@ -205,6 +205,8 @@
 static const uint TUNNELBRIDGE_TRACKBIT_FACTOR = 4;
 /** Multiplier for how many regular track bits a level crossing counts. */
 static const uint LEVELCROSSING_TRACKBIT_FACTOR = 2;
+/** Multiplier for how many regular tiles a lock counts. */
+static const uint LOCK_DEPOT_TILE_FACTOR = 2;
 
 struct CargoPayment;
 typedef uint32 CargoPaymentID;
--- a/src/object_cmd.cpp
+++ b/src/object_cmd.cpp
@@ -103,6 +103,11 @@
 
 	TILE_AREA_LOOP(t, ta) {
 		WaterClass wc = (IsWaterTile(t) ? GetWaterClass(t) : WATER_CLASS_INVALID);
+		/* Update company infrastructure counts for objects build on canals owned by nobody. */
+		if (wc == WATER_CLASS_CANAL && owner != OWNER_NONE && (IsTileOwner(tile, OWNER_NONE) || IsTileOwner(tile, OWNER_WATER))) {
+			Company::Get(owner)->infrastructure.water++;
+			DirtyCompanyInfrastructureWindows(owner);
+		}
 		MakeObject(t, type, owner, o->index, wc, Random());
 		MarkTileDirtyByTile(t);
 	}
--- a/src/saveload/company_sl.cpp
+++ b/src/saveload/company_sl.cpp
@@ -151,11 +151,32 @@
 						break;
 					}
 
+					case STATION_DOCK:
+					case STATION_BUOY:
+						if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
+							if (c != NULL) c->infrastructure.water++;
+						}
+						break;
+
 					default:
 						break;
 				}
 				break;
 
+			case MP_WATER:
+				if (IsShipDepot(tile) || IsLock(tile)) {
+					c = Company::GetIfValid(GetTileOwner(tile));
+					if (c != NULL) c->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
+				}
+				/* FALL THROUGH */
+
+			case MP_OBJECT:
+				if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
+					c = Company::GetIfValid(GetTileOwner(tile));
+					if (c != NULL) c->infrastructure.water++;
+				}
+				break;
+
 			case MP_TUNNELBRIDGE: {
 				/* Only count the tunnel/bridge if we're on the northern end tile. */
 				TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
@@ -180,6 +201,11 @@
 							break;
 						}
 
+						case TRANSPORT_WATER:
+							c = Company::GetIfValid(GetTileOwner(tile));
+							if (c != NULL) c->infrastructure.water += len;
+							break;
+
 						default:
 							break;
 					}
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2482,6 +2482,13 @@
 				tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 				_dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY);
 
+		/* If the water part of the dock is on a canal, update infrastructure counts.
+		 * This is needed as we've unconditionally cleared that tile before. */
+		if (wc == WATER_CLASS_CANAL) {
+			Company::Get(st->owner)->infrastructure.water++;
+			DirtyCompanyInfrastructureWindows(st->owner);
+		}
+
 		MakeDock(tile, st->owner, st->index, direction, wc);
 
 		st->UpdateVirtCoord();
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -456,6 +456,7 @@
 				break;
 
 			case TRANSPORT_WATER:
+				if (!IsBridgeTile(tile_start) && c != NULL) c->infrastructure.water += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR;
 				MakeAqueductBridgeRamp(tile_start, owner, dir);
 				MakeAqueductBridgeRamp(tile_end,   owner, ReverseDiagDir(dir));
 				break;
@@ -856,6 +857,8 @@
 					DirtyCompanyInfrastructureWindows(c->index);
 				}
 			}
+		} else { // Aqueduct
+			if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.water -= len * TUNNELBRIDGE_TRACKBIT_FACTOR;
 		}
 		DirtyCompanyInfrastructureWindows(owner);
 
@@ -1574,6 +1577,9 @@
 	if (tt == TRANSPORT_RAIL) {
 		old->infrastructure.rail[GetRailType(tile)] -= num_pieces;
 		if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.rail[GetRailType(tile)] += num_pieces;
+	} else if (tt == TRANSPORT_WATER) {
+		old->infrastructure.water -= num_pieces;
+		if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.water += num_pieces;
 	}
 
 	if (new_owner != INVALID_OWNER) {
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -35,6 +35,8 @@
 #include "core/random_func.hpp"
 #include "core/backup_type.hpp"
 #include "date_func.h"
+#include "company_base.h"
+#include "company_gui.h"
 
 #include "table/strings.h"
 
@@ -134,6 +136,13 @@
 		Depot *depot = new Depot(tile);
 		depot->build_date = _date;
 
+		if (wc1 == WATER_CLASS_CANAL || wc2 == WATER_CLASS_CANAL) {
+			/* Update infrastructure counts after the unconditional clear earlier. */
+			Company::Get(_current_company)->infrastructure.water += wc1 == WATER_CLASS_CANAL && wc2 == WATER_CLASS_CANAL ? 2 : 1;
+		}
+		Company::Get(_current_company)->infrastructure.water += 2 * LOCK_DEPOT_TILE_FACTOR;
+		DirtyCompanyInfrastructureWindows(_current_company);
+
 		MakeShipDepot(tile,  _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1);
 		MakeShipDepot(tile2, _current_company, depot->index, DEPOT_PART_SOUTH, axis, wc2);
 		MarkTileDirtyByTile(tile);
@@ -150,9 +159,28 @@
 
 	/* Autoslope might turn an originally canal or river tile into land */
 	int z;
-	if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID;
+	if (GetTileSlope(tile, &z) != SLOPE_FLAT) {
+		if (wc == WATER_CLASS_CANAL) {
+			/* If we clear the canal, we have to remove it from the infrastructure count as well. */
+			Company *c = Company::GetIfValid(o);
+			if (c != NULL) {
+				c->infrastructure.water--;
+				DirtyCompanyInfrastructureWindows(c->index);
+			}
+		}
+		wc = WATER_CLASS_INVALID;
+	}
 
-	if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL;
+	if (wc == WATER_CLASS_SEA && z > 0) {
+		/* Update company infrastructure count. */
+		Company *c = Company::GetIfValid(o);
+		if (c != NULL) {
+			c->infrastructure.water++;
+			DirtyCompanyInfrastructureWindows(c->index);
+		}
+
+		wc = WATER_CLASS_CANAL;
+	}
 
 	/* Zero map array and terminate animation */
 	DoClearSquare(tile);
@@ -187,6 +215,12 @@
 	if (flags & DC_EXEC) {
 		delete Depot::GetByTile(tile);
 
+		Company *c = Company::GetIfValid(GetTileOwner(tile));
+		if (c != NULL) {
+			c->infrastructure.water -= 2 * LOCK_DEPOT_TILE_FACTOR;
+			DirtyCompanyInfrastructureWindows(c->index);
+		}
+
 		MakeWaterKeepingClass(tile,  GetTileOwner(tile));
 		MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
 	}
@@ -249,6 +283,16 @@
 	}
 
 	if (flags & DC_EXEC) {
+		/* Update company infrastructure counts. */
+		Company *c = Company::Get(_current_company);
+		/* Counts for the water. */
+		c->infrastructure.water++;
+		if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
+		if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
+		/* Count for the lock itself. */
+		c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
+		DirtyCompanyInfrastructureWindows(_current_company);
+
 		MakeLock(tile, _current_company, dir, wc_lower, wc_upper);
 		MarkTileDirtyByTile(tile);
 		MarkTileDirtyByTile(tile - delta);
@@ -283,6 +327,13 @@
 	if (ret.Failed()) return ret;
 
 	if (flags & DC_EXEC) {
+		/* Remove middle part from company infrastructure count. */
+		Company *c = Company::GetIfValid(GetTileOwner(tile));
+		if (c != NULL) {
+			c->infrastructure.water -= 1 + 3 * LOCK_DEPOT_TILE_FACTOR; // Middle tile + three parts of the lock.
+			DirtyCompanyInfrastructureWindows(c->index);
+		}
+
 		DoClearSquare(tile);
 		MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
 		MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
@@ -377,6 +428,10 @@
 
 				default:
 					MakeCanal(tile, _current_company, Random());
+					if (Company::IsValidID(_current_company)) {
+						Company::Get(_current_company)->infrastructure.water++;
+						DirtyCompanyInfrastructureWindows(_current_company);
+					}
 					break;
 			}
 			MarkTileDirtyByTile(tile);
@@ -410,12 +465,17 @@
 			CommandCost ret = EnsureNoVehicleOnGround(tile);
 			if (ret.Failed()) return ret;
 
-			if (GetTileOwner(tile) != OWNER_WATER && GetTileOwner(tile) != OWNER_NONE) {
+			Owner owner = GetTileOwner(tile);
+			if (owner != OWNER_WATER && owner != OWNER_NONE) {
 				CommandCost ret = CheckTileOwnership(tile);
 				if (ret.Failed()) return ret;
 			}
 
 			if (flags & DC_EXEC) {
+				if (IsCanal(tile) && Company::IsValidID(owner)) {
+					Company::Get(owner)->infrastructure.water--;
+					DirtyCompanyInfrastructureWindows(owner);
+				}
 				DoClearSquare(tile);
 				MarkCanalsAndRiversAroundDirty(tile);
 			}
@@ -1191,7 +1251,10 @@
 {
 	if (!IsTileOwner(tile, old_owner)) return;
 
+	/* No need to dirty company windows here, we'll redraw the whole screen anyway. */
+	if (IsCanal(tile)) Company::Get(old_owner)->infrastructure.water--;
 	if (new_owner != INVALID_OWNER) {
+		if (IsCanal(tile)) Company::Get(new_owner)->infrastructure.water++;
 		SetTileOwner(tile, new_owner);
 		return;
 	}
@@ -1201,7 +1264,10 @@
 
 	/* Set owner of canals and locks ... and also canal under dock there was before.
 	 * Check if the new owner after removing depot isn't OWNER_WATER. */
-	if (IsTileOwner(tile, old_owner)) SetTileOwner(tile, OWNER_NONE);
+	if (IsTileOwner(tile, old_owner)) {
+		if (IsCanal(tile)) Company::Get(old_owner)->infrastructure.water--;
+		SetTileOwner(tile, OWNER_NONE);
+	}
 }
 
 static VehicleEnterTileStatus VehicleEnter_Water(Vehicle *v, TileIndex tile, int x, int y)