src/tunnelbridge_cmd.cpp
branchgamebalance
changeset 9912 1ac8aac92385
parent 9911 0b8b245a2391
child 9913 e79cd19772dd
--- a/src/tunnelbridge_cmd.cpp	Wed Jun 13 11:45:14 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp	Wed Jun 13 12:05:56 2007 +0000
@@ -304,6 +304,9 @@
 		cost = (bridge_len + 1) * _eco->GetPrice(CEconomy::CLEAR_BRIDGE); // The cost of clearing the current bridge.
 		replace_bridge = true;
 		replaced_bridge_type = GetBridgeType(tile_start);
+
+		/* Do not remove road types when upgrading a bridge */
+		roadtypes |= GetRoadTypes(tile_start);
 	} else {
 		/* Build a new bridge. */
 
@@ -859,6 +862,39 @@
 }
 
 /**
+ * Draws the trambits over an already drawn (lower end) of a bridge.
+ * @param x       the x of the bridge
+ * @param y       the y of the bridge
+ * @param z       the z of the bridge
+ * @param offset  number representing whether to level or sloped and the direction
+ * @param overlay do we want to still see the road?
+ */
+static void DrawBridgeTramBits(int x, int y, byte z, int offset, bool overlay)
+{
+	static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
+	static const SpriteID back_offsets[6]    =   {  95,  95,  99, 102, 100, 101 };
+	static const SpriteID front_offsets[6]   =   {  97,  98, 103, 106, 104, 105 };
+
+	static const uint size_x[6] = { 11, 16, 16, 16, 16, 16 };
+	static const uint size_y[6] = { 16, 11, 16, 16, 16, 16 };
+
+	AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], offset >= 2 ? 1 : 0, z);
+
+	SpriteID front = SPR_TRAMWAY_BASE + front_offsets[offset];
+	SpriteID back  = SPR_TRAMWAY_BASE + back_offsets[offset];
+	SpriteID pal   = PAL_NONE;
+	if (HASBIT(_transparent_opt, TO_BUILDINGS)) {
+		SETBIT(front, PALETTE_MODIFIER_TRANSPARENT);
+		SETBIT(back,  PALETTE_MODIFIER_TRANSPARENT);
+		pal = PALETTE_TO_TRANSPARENT;
+	}
+
+	AddSortableSpriteToDraw(back,  pal, x, y, size_x[offset], size_y[offset], 0, z);
+	/* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */
+	AddSortableSpriteToDraw(front, pal, x, y, size_x[offset], size_y[offset], offset >= 2 ? 0x30 : 0x10, z);
+}
+
+/**
  * Draws a tunnel of bridge tile.
  * For tunnels, this is rather simple, as you only needa draw the entrance.
  * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
@@ -887,7 +923,17 @@
 
 		image += GetTunnelDirection(ti->tile) * 2;
 		DrawGroundSprite(image, PAL_NONE);
-		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL && GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
+		if (GetTunnelTransportType(ti->tile) == TRANSPORT_ROAD) {
+			DiagDirection dir = GetTunnelDirection(ti->tile);
+			RoadTypes rts = GetRoadTypes(ti->tile);
+
+			if (HASBIT(rts, ROADTYPE_TRAM)) {
+				static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, {  5, 76, 77,  4 } };
+
+				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][dir], PAL_NONE);
+				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + dir, PAL_NONE, ti->x, ti->y, 16, 16, 16, (byte)ti->z);
+			}
+		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
 			DrawCatenary(ti);
 		}
 
@@ -927,10 +973,6 @@
 			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE);
 		}
 
-		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL && GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
-			DrawCatenary(ti);
-		}
-
 		image = psid->sprite;
 
 		/* draw ramp */
@@ -945,9 +987,27 @@
 		 * it doesn't disappear behind it
 		 */
 		AddSortableSpriteToDraw(
-			image, pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z
+			image, pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z
 		);
 
+		if (GetBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
+			RoadTypes rts = GetRoadTypes(ti->tile);
+
+			if (HASBIT(rts, ROADTYPE_TRAM)) {
+				uint offset = GetBridgeRampDirection(ti->tile);
+				uint z = ti->z;
+				if (ti->tileh != SLOPE_FLAT) {
+					offset = (offset + 1) & 1;
+					z += TILE_HEIGHT;
+				} else {
+					offset += 2;
+				}
+				DrawBridgeTramBits(ti->x, ti->y, z, offset, HASBIT(rts, ROADTYPE_ROAD));
+			}
+		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
+			DrawCatenary(ti);
+		}
+
 		DrawBridgeMiddle(ti);
 	}
 }
@@ -1023,7 +1083,8 @@
 
 	x = ti->x;
 	y = ti->y;
-	z = GetBridgeHeight(rampsouth) - 3;
+	uint bridge_z = GetBridgeHeight(rampsouth);
+	z = bridge_z - 3;
 
 	image = psid->sprite;
 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
@@ -1048,6 +1109,16 @@
 		pal = psid->pal;
 	}
 
+	if (GetBridgeTransportType(rampsouth) == TRANSPORT_ROAD) {
+		RoadTypes rts = GetRoadTypes(rampsouth);
+
+		if (HASBIT(rts, ROADTYPE_TRAM)) {
+			DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HASBIT(rts, ROADTYPE_ROAD));
+		}
+	} else if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) {
+		DrawCatenary(ti);
+	}
+
 	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
 	if (axis == AXIS_X) {
 		y += 12;
@@ -1057,8 +1128,6 @@
 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 1, 16, 0x28, z);
 	}
 
-	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
-
 	psid++;
 	if (ti->z + 5 == z) {
 		/* draw poles below for small bridges */
@@ -1236,13 +1305,15 @@
 }
 
 
-static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
+static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode)
 {
 	if (IsTunnel(tile)) {
 		if (GetTunnelTransportType(tile) != mode) return 0;
+		if (GetTunnelTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 		return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
 	} else {
 		if (GetBridgeTransportType(tile) != mode) return 0;
+		if (GetBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 		return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
 	}
 }
@@ -1254,7 +1325,14 @@
 	if (new_player != PLAYER_SPECTATOR) {
 		SetTileOwner(tile, new_player);
 	} else {
-		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
+			/* When clearing the bridge/tunnel failed there are still vehicles on/in
+			 * the bridge/tunnel. As all *our* vehicles are already removed, they
+			 * must be of another owner. Therefor this must be a road bridge/tunnel.
+			 * In that case we can safely reassign the ownership to OWNER_NONE. */
+			assert((IsTunnel(tile) ? GetTunnelTransportType(tile) : GetBridgeTransportType(tile)) == TRANSPORT_ROAD);
+			SetTileOwner(tile, OWNER_NONE);
+		}
 	}
 }
 
@@ -1349,7 +1427,7 @@
 	} else if (IsBridge(tile)) { // XXX is this necessary?
 		DiagDirection dir;
 
-		if (v->type == VEH_ROAD || (v->type == VEH_TRAIN && IsFrontEngine(v))) {
+		if (v->HasFront() && v->IsPrimaryVehicle()) {
 			/* modify speed of vehicle */
 			uint16 spd = _bridge[GetBridgeType(tile)].speed;