changeset 18567:1c2e5babf594 draft

(svn r23412) -Add: Company infrastructure counts for road.
author michi_cc <michi_cc@openttd.org>
date Sat, 03 Dec 2011 23:40:18 +0000
parents 9b9dc36d3eb2
children d2563220728e
files src/rail_cmd.cpp src/road_cmd.cpp src/saveload/company_sl.cpp src/station_cmd.cpp src/tunnelbridge_cmd.cpp
diffstat 5 files changed, 195 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -454,7 +454,15 @@
 					default: break;
 					case ROADTYPES_TRAM:
 						/* Tram crossings must always have road. */
-						if (flags & DC_EXEC) SetRoadOwner(tile, ROADTYPE_ROAD, _current_company);
+						if (flags & DC_EXEC) {
+							SetRoadOwner(tile, ROADTYPE_ROAD, _current_company);
+							Company *c = Company::GetIfValid(_current_company);
+							if (c != NULL) {
+								/* A full diagonal tile has two road bits. */
+								c->infrastructure.road[ROADTYPE_ROAD] += 2;
+								DirtyCompanyInfrastructureWindows(c->index);
+							}
+						}
 						roadtypes |= ROADTYPES_ROAD;
 						break;
 
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -35,6 +35,7 @@
 #include "newgrf_railtype.h"
 #include "date_func.h"
 #include "genworld.h"
+#include "company_gui.h"
 
 #include "table/strings.h"
 
@@ -218,8 +219,16 @@
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 			TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
 			/* Pay for *every* tile of the bridge or tunnel */
-			cost.AddCost((GetTunnelBridgeLength(other_end, tile) + 2) * _price[PR_CLEAR_ROAD]);
+			uint len = GetTunnelBridgeLength(other_end, tile) + 2;
+			cost.AddCost(len * _price[PR_CLEAR_ROAD]);
 			if (flags & DC_EXEC) {
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					/* A full diagonal road tile has two road bits. */
+					c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR;
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+
 				SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
 				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 
@@ -245,6 +254,12 @@
 			assert(IsDriveThroughStopTile(tile));
 			cost.AddCost(_price[PR_CLEAR_ROAD] * 2);
 			if (flags & DC_EXEC) {
+				Company *c = Company::GetIfValid(GetTileOwner(tile));
+				if (c != NULL) {
+					/* A full diagonal road tile has two road bits. */
+					c->infrastructure.road[rt] -= 2;
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
 				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 				MarkTileDirtyByTile(tile);
 			}
@@ -299,6 +314,13 @@
 						}
 					}
 				}
+
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					c->infrastructure.road[rt] -= CountBits(pieces);
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+
 				if (present == ROAD_NONE) {
 					RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
 					if (rts == ROADTYPES_NONE) {
@@ -341,6 +363,13 @@
 			if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
 
 			if (flags & DC_EXEC) {
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					/* A full diagonal road tile has two road bits. */
+					c->infrastructure.road[rt] -= 2;
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+
 				Track railtrack = GetCrossingRailTrack(tile);
 				RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
 				if (rts == ROADTYPES_NONE) {
@@ -573,6 +602,13 @@
 			if (flags & DC_EXEC) {
 				Track railtrack = AxisToTrack(OtherAxis(roaddir));
 				YapfNotifyTrackLayoutChange(tile, railtrack);
+				/* Update company infrastructure counts. A level crossing has two road bits. */
+				Company *c = Company::GetIfValid(_current_company);
+				if (c != NULL) {
+					c->infrastructure.road[rt] += 2;
+					if (rt != ROADTYPE_ROAD) c->infrastructure.road[ROADTYPE_ROAD] += 2;
+					DirtyCompanyInfrastructureWindows(_current_company);
+				}
 				/* Always add road to the roadtypes (can't draw without it) */
 				bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack);
 				MakeRoadCrossing(tile, _current_company, _current_company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
@@ -708,6 +744,14 @@
 				break;
 		}
 
+		/* Update company infrastructure count. */
+		Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+		if (c != NULL) {
+			if (IsTileType(tile, MP_TUNNELBRIDGE)) num_pieces *= TUNNELBRIDGE_TRACKBIT_FACTOR;
+			c->infrastructure.road[rt] += num_pieces;
+			DirtyCompanyInfrastructureWindows(c->index);
+		}
+
 		if (rt != ROADTYPE_TRAM && IsNormalRoadTile(tile)) {
 			existing |= pieces;
 			SetDisallowedRoadDirections(tile, IsStraightRoad(existing) ?
@@ -928,6 +972,10 @@
 		Depot *dep = new Depot(tile);
 		dep->build_date = _date;
 
+		/* A road depot has two road bits. */
+		Company::Get(_current_company)->infrastructure.road[rt] += 2;
+		DirtyCompanyInfrastructureWindows(_current_company);
+
 		MakeRoadDepot(tile, _current_company, dep->index, dir, rt);
 		MarkTileDirtyByTile(tile);
 		MakeDefaultName(dep);
@@ -947,6 +995,13 @@
 	if (ret.Failed()) return ret;
 
 	if (flags & DC_EXEC) {
+		Company *c = Company::GetIfValid(GetTileOwner(tile));
+		if (c != NULL) {
+			/* A road depot has two road bits. */
+			c->infrastructure.road[FIND_FIRST_BIT(GetRoadTypes(tile))] -= 2;
+			DirtyCompanyInfrastructureWindows(c->index);
+		}
+
 		delete Depot::GetByTile(tile);
 		DoClearSquare(tile);
 	}
@@ -1653,6 +1708,11 @@
 			if (new_owner == INVALID_OWNER) {
 				DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
 			} else {
+				/* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */
+				RoadType rt = (RoadType)FIND_FIRST_BIT(GetRoadTypes(tile));
+				Company::Get(old_owner)->infrastructure.road[rt] -= 2;
+				Company::Get(new_owner)->infrastructure.road[rt] += 2;
+
 				SetTileOwner(tile, new_owner);
 			}
 		}
@@ -1662,6 +1722,13 @@
 	for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 		/* Update all roadtypes, no matter if they are present */
 		if (GetRoadOwner(tile, rt) == old_owner) {
+			if (HasTileRoadType(tile, rt)) {
+				/* A level crossing has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */
+				uint num_bits = IsLevelCrossing(tile) ? 2 : CountBits(GetRoadBits(tile, rt));
+				Company::Get(old_owner)->infrastructure.road[rt] -= num_bits;
+				if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_bits;
+			}
+
 			SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner);
 		}
 	}
--- a/src/saveload/company_sl.cpp
+++ b/src/saveload/company_sl.cpp
@@ -115,12 +115,21 @@
 				}
 				break;
 
-			case MP_ROAD:
+			case MP_ROAD: {
 				if (IsLevelCrossing(tile)) {
 					c = Company::GetIfValid(GetTileOwner(tile));
 					if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR;
 				}
+
+				/* Iterate all present road types as each can have a different owner. */
+				RoadType rt;
+				FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+					c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rt));
+					/* A level crossings and depots have two road bits. */
+					if (c != NULL) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rt)) : 2;
+				}
 				break;
+			}
 
 			case MP_STATION:
 				c = Company::GetIfValid(GetTileOwner(tile));
@@ -131,6 +140,17 @@
 						if (c != NULL && !IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]++;
 						break;
 
+					case STATION_BUS:
+					case STATION_TRUCK: {
+						/* Iterate all present road types as each can have a different owner. */
+						RoadType rt;
+						FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+							c = Company::GetIfValid(GetRoadOwner(tile, rt));
+							if (c != NULL) c->infrastructure.road[rt] += 2; // A road stop has two road bits.
+						}
+						break;
+					}
+
 					default:
 						break;
 				}
@@ -150,6 +170,16 @@
 							if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += len;
 							break;
 
+						case TRANSPORT_ROAD: {
+							/* Iterate all present road types as each can have a different owner. */
+							RoadType rt;
+							FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+								c = Company::GetIfValid(GetRoadOwner(tile, rt));
+								if (c != NULL) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits.
+							}
+							break;
+						}
+
 						default:
 							break;
 					}
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -1791,9 +1791,23 @@
 
 			RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS;
 			if (is_drive_through) {
+				/* Update company infrastructure counts. If the current tile is a normal
+				 * road tile, count only the new road bits needed to get a full diagonal road. */
+				RoadType rt;
+				FOR_EACH_SET_ROADTYPE(rt, cur_rts | rts) {
+					Company *c = Company::GetIfValid(IsNormalRoadTile(cur_tile) && HasBit(cur_rts, rt) ? GetRoadOwner(cur_tile, rt) : _current_company);
+					if (c != NULL) {
+						c->infrastructure.road[rt] += 2 - (IsNormalRoadTile(cur_tile) ? CountBits(GetRoadBits(cur_tile, rt)) : 0);
+						DirtyCompanyInfrastructureWindows(c->index);
+					}
+				}
+
 				MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts | cur_rts, DiagDirToAxis(ddir));
 				road_stop->MakeDriveThrough();
 			} else {
+				/* Non-drive-through stop never overbuild and always count as two road bits. */
+				Company::Get(st->owner)->infrastructure.road[FIND_FIRST_BIT(rts)] += 2;
+				DirtyCompanyInfrastructureWindows(st->owner);
 				MakeRoadStop(cur_tile, st->owner, st->index, rs_type, rts, ddir);
 			}
 
@@ -1883,6 +1897,16 @@
 			pred->next = cur_stop->next;
 		}
 
+		/* Update company infrastructure counts. */
+		RoadType rt;
+		FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+			Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+			if (c != NULL) {
+				c->infrastructure.road[rt] -= 2;
+				DirtyCompanyInfrastructureWindows(c->index);
+			}
+		}
+
 		if (IsDriveThroughStopTile(tile)) {
 			/* Clears the tile for us */
 			cur_stop->ClearDriveThrough();
@@ -1967,6 +1991,16 @@
 		if ((flags & DC_EXEC) && is_drive_through) {
 			MakeRoadNormal(cur_tile, road_bits, rts, ClosestTownFromTile(cur_tile, UINT_MAX)->index,
 					road_owner, tram_owner);
+
+			/* Update company infrastructure counts. */
+			RoadType rt;
+			FOR_EACH_SET_ROADTYPE(rt, rts) {
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					c->infrastructure.road[rt] += CountBits(road_bits);
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+			}
 		}
 	}
 
@@ -3504,6 +3538,11 @@
 		for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 			/* Update all roadtypes, no matter if they are present */
 			if (GetRoadOwner(tile, rt) == old_owner) {
+				if (HasTileRoadType(tile, rt)) {
+					/* A drive-through road-stop has always two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */
+					Company::Get(old_owner)->infrastructure.road[rt] -= 2;
+					if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += 2;
+				}
 				SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner);
 			}
 		}
@@ -3523,6 +3562,13 @@
 			old_company->infrastructure.rail[GetRailType(tile)]--;
 			new_company->infrastructure.rail[GetRailType(tile)]++;
 		}
+		if (IsRoadStop(tile) && !IsDriveThroughStopTile(tile)) {
+			RoadType rt;
+			FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+				old_company->infrastructure.road[rt] -= 2;
+				new_company->infrastructure.road[rt] += 2;
+			}
+		}
 
 		/* for buoys, owner of tile is owner of water, st->owner == OWNER_NONE */
 		SetTileOwner(tile, new_owner);
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -443,6 +443,14 @@
 				break;
 
 			case TRANSPORT_ROAD:
+				if (c != NULL) {
+					/* Add all new road types to the company infrastructure counter. */
+					RoadType new_rt;
+					FOR_EACH_SET_ROADTYPE(new_rt, roadtypes ^ (IsBridgeTile(tile_start) ? GetRoadTypes(tile_start) : ROADTYPES_NONE)) {
+						/* A full diagonal road tile has two road bits. */
+						Company::Get(owner)->infrastructure.road[new_rt] += (bridge_len + 2) * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR;
+					}
+				}
 				MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir,                 roadtypes);
 				MakeRoadBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir), roadtypes);
 				break;
@@ -640,6 +648,12 @@
 			AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_company);
 			YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction));
 		} else {
+			if (c != NULL) {
+				RoadType rt;
+				FOR_EACH_SET_ROADTYPE(rt, rts ^ (IsTunnelTile(start_tile) ? GetRoadTypes(start_tile) : ROADTYPES_NONE)) {
+					c->infrastructure.road[rt] += num_pieces * 2; // A full diagonal road has two road bits.
+				}
+			}
 			MakeRoadTunnel(start_tile, _current_company, direction,                 rts);
 			MakeRoadTunnel(end_tile,   _current_company, ReverseDiagDir(direction), rts);
 		}
@@ -761,6 +775,16 @@
 
 			if (v != NULL) TryPathReserve(v);
 		} else {
+			RoadType rt;
+			FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+				/* A full diagonal road tile has two road bits. */
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR;
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+			}
+
 			DoClearSquare(tile);
 			DoClearSquare(endtile);
 		}
@@ -822,6 +846,16 @@
 		/* Update company infrastructure counts. */
 		if (rail) {
 			if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR;
+		} else if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) {
+			RoadType rt;
+			FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
+				Company *c = Company::GetIfValid(GetRoadOwner(tile, rt));
+				if (c != NULL) {
+					/* A full diagonal road tile has two road bits. */
+					c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR;
+					DirtyCompanyInfrastructureWindows(c->index);
+				}
+			}
 		}
 		DirtyCompanyInfrastructureWindows(owner);
 
@@ -1520,6 +1554,13 @@
 	for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 		/* Update all roadtypes, no matter if they are present */
 		if (GetRoadOwner(tile, rt) == old_owner) {
+			if (HasBit(GetRoadTypes(tile), rt)) {
+				/* Update company infrastructure counts. A full diagonal road tile has two road bits.
+				 * No need to dirty windows here, we'll redraw the whole screen anyway. */
+				Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2;
+				if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_pieces * 2;
+			}
+
 			SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner);
 		}
 	}