(svn r12547) -Feature: invisibility options to make objects invisible instead of transparent
authorsmatz
Thu, 03 Apr 2008 19:55:40 +0000
changeset 9302 4aa3c4a44b16
parent 9301 79c7f7dee677
child 9303 54a1ba2d4cc9
(svn r12547) -Feature: invisibility options to make objects invisible instead of transparent
src/elrail.cpp
src/industry_cmd.cpp
src/lang/english.txt
src/main_gui.cpp
src/newgrf_house.cpp
src/newgrf_industrytiles.cpp
src/rail_cmd.cpp
src/road_cmd.cpp
src/settings.cpp
src/settings_gui.cpp
src/settings_type.h
src/station_cmd.cpp
src/table/track_land.h
src/town_cmd.cpp
src/transparency.h
src/transparency_gui.cpp
src/tree_cmd.cpp
src/tunnelbridge_cmd.cpp
src/unmovable_cmd.cpp
src/viewport.cpp
src/water_cmd.cpp
--- a/src/elrail.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/elrail.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -434,6 +434,9 @@
 {
 	if (_patches.disable_elrails) return;
 
+	/* Do not draw catenary if it is invisible */
+	if (IsInvisibilitySet(TO_CATENARY)) return;
+
 	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
 		TileIndex head = GetNorthernBridgeEnd(ti->tile);
 
--- a/src/industry_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/industry_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -303,6 +303,9 @@
 
 	DrawGroundSprite(image, pal);
 
+	/* If industries are transparent and invisible, do not draw the upper part */
+	if (IsInvisibilitySet(TO_INDUSTRIES)) return;
+
 	/* Add industry on top of the ground? */
 	image = dits->building.sprite;
 	if (image != 0) {
--- a/src/lang/english.txt	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/lang/english.txt	Thu Apr 03 19:55:40 2008 +0000
@@ -1068,7 +1068,6 @@
 STR_CONFIG_PATCHES_AUTORENEW_MONEY                              :{LTBLUE}Autorenew minimum needed money for renew: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_ERRMSG_DURATION                              :{LTBLUE}Duration of error message: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_POPULATION_IN_LABEL                          :{LTBLUE}Show town population in the town name label: {ORANGE}{STRING1}
-STR_CONFIG_PATCHES_INVISIBLE_TREES                              :{LTBLUE}Invisible trees: {ORANGE}{STRING1}
 
 STR_CONFIG_PATCHES_LAND_GENERATOR                               :{LTBLUE}Land generator: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL                      :Original
@@ -3373,6 +3372,7 @@
 STR_TRANSPARENT_STRUCTURES_DESC                                 :{BLACK}Toggle transparency for structures like lighthouses and antennas. CTRL+click to lock.
 STR_TRANSPARENT_CATENARY_DESC                                   :{BLACK}Toggle transparency for catenary. CTRL+click to lock.
 STR_TRANSPARENT_LOADING_DESC                                    :{BLACK}Toggle transparency for loading indicators. CTRL+click to lock.
+STR_TRANSPARENT_INVISIBLE_DESC                                  :{BLACK}Set objects invisible instead of transparent
 
 STR_PERCENT_UP_SMALL                                            :{TINYFONT}{WHITE}{NUM}%{UPARROW}
 STR_PERCENT_UP                                                  :{WHITE}{NUM}%{UPARROW}
--- a/src/main_gui.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/main_gui.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -1067,6 +1067,19 @@
 				MarkWholeScreenDirty();
 				break;
 
+			case '1' | WKC_CTRL | WKC_SHIFT:
+			case '2' | WKC_CTRL | WKC_SHIFT:
+			case '3' | WKC_CTRL | WKC_SHIFT:
+			case '4' | WKC_CTRL | WKC_SHIFT:
+			case '5' | WKC_CTRL | WKC_SHIFT:
+			case '6' | WKC_CTRL | WKC_SHIFT:
+			case '7' | WKC_CTRL | WKC_SHIFT:
+			case '8' | WKC_CTRL | WKC_SHIFT:
+				/* Invisibility toggle hot keys */
+				ToggleInvisibilityWithTransparency((TransparencyOption)(e->we.keypress.keycode - ('1' | WKC_CTRL | WKC_SHIFT)));
+				MarkWholeScreenDirty();
+				break;
+
 			case 'X' | WKC_CTRL:
 				ShowTransparencyToolbar();
 				break;
--- a/src/newgrf_house.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/newgrf_house.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -322,6 +322,9 @@
 
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
+	/* End now, if houses are invisible */
+	if (IsInvisibilitySet(TO_HOUSES)) return;
+
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
 
--- a/src/newgrf_industrytiles.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/newgrf_industrytiles.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -185,6 +185,9 @@
 
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
+	/* End now if industries are invisible */
+	if (IsInvisibilitySet(TO_INDUSTRIES)) return;
+
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
 
--- a/src/rail_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/rail_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -1772,7 +1772,12 @@
 		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 		if (IsRailDepot(ti->tile)) {
-			dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
+			if (IsInvisibilitySet(TO_BUILDINGS)) {
+				/* Draw rail instead of depot */
+				dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
+			} else {
+				dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
+			}
 
 			relocation = rti->total_offset;
 
@@ -1836,6 +1841,9 @@
 
 		if (HasCatenary(GetRailType(ti->tile))) DrawCatenary(ti);
 
+		/* End now if buildings are invisible */
+		if (IsInvisibilitySet(TO_BUILDINGS)) return;
+
 		foreach_draw_tile_seq(dtss, dts->seq) {
 			SpriteID image = dtss->image.sprite;
 			SpriteID pal;
--- a/src/road_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/road_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -970,6 +970,9 @@
  */
 void DrawTramCatenary(TileInfo *ti, RoadBits tram)
 {
+	/* Do not draw catenary if it is invisible */
+	if (IsInvisibilitySet(TO_CATENARY)) return;
+
 	/* Don't draw the catenary under a low bridge */
 	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_CATENARY)) {
 		uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
@@ -1154,6 +1157,9 @@
 
 			DrawGroundSprite(dts->ground.sprite, PAL_NONE);
 
+			/* End now if buildings are invisible */
+			if (IsInvisibilitySet(TO_BUILDINGS)) break;
+
 			for (dtss = dts->seq; dtss->image.sprite != 0; dtss++) {
 				SpriteID image = dtss->image.sprite;
 				SpriteID pal;
--- a/src/settings.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/settings.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -1296,6 +1296,7 @@
 	  SDTG_VAR("player_face",    SLE_UINT32, S, 0, _player_face,      0,0,0xFFFFFFFF,0, STR_NULL, NULL),
 	  SDTG_VAR("transparency_options", SLE_UINT, S, 0, _transparency_opt,  0,0,0x1FF,0, STR_NULL, NULL),
 	  SDTG_VAR("transparency_locks", SLE_UINT, S, 0, _transparency_lock,   0,0,0x1FF,0, STR_NULL, NULL),
+	  SDTG_VAR("invisibility_options", SLE_UINT, S, 0, _invisibility_opt,  0,0, 0xFF,0, STR_NULL, NULL),
 	  SDTG_STR("keyboard",         SLE_STRB, S, 0, _keyboard_opt[0],       NULL,    STR_NULL, NULL),
 	  SDTG_STR("keyboard_caps",    SLE_STRB, S, 0, _keyboard_opt[1],       NULL,    STR_NULL, NULL),
 	  SDTG_END()
@@ -1379,7 +1380,6 @@
 	 SDT_VAR(Patches, errmsg_duration,    SLE_UINT8, S, 0,  5, 0, 20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,       NULL),
 	 SDT_VAR(Patches, toolbar_pos,        SLE_UINT8, S,MS,  0, 0,  2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,           v_PositionMainToolbar),
 	 SDT_VAR(Patches, window_snap_radius, SLE_UINT8, S,D0, 10, 1, 32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS,           NULL),
-	SDT_BOOL(Patches, invisible_trees,               S, 0, false,        STR_CONFIG_PATCHES_INVISIBLE_TREES,       RedrawScreen),
 	SDT_BOOL(Patches, population_in_label,           S, 0,  true,        STR_CONFIG_PATCHES_POPULATION_IN_LABEL,   PopulationInLabelActive),
 	 SDT_VAR(Patches, map_x,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_X,                 NULL),
 	 SDT_VAR(Patches, map_y,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_Y,                 NULL),
--- a/src/settings_gui.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/settings_gui.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -712,7 +712,6 @@
 	"toolbar_pos",
 	"measure_tooltip",
 	"window_snap_radius",
-	"invisible_trees",
 	"population_in_label",
 	"link_terraform_toolbar",
 	"liveries",
--- a/src/settings_type.h	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/settings_type.h	Thu Apr 03 19:55:40 2008 +0000
@@ -98,7 +98,6 @@
 	bool realistic_acceleration;        ///< realistic acceleration for trains
 	bool wagon_speed_limits;            ///< enable wagon speed limits
 	bool forbid_90_deg;                 ///< forbid trains to make 90 deg turns
-	bool invisible_trees;               ///< don't show trees when buildings are transparent
 	bool no_servicing_if_no_breakdowns; ///< dont send vehicles to depot when breakdowns are disabled
 	bool link_terraform_toolbar;        ///< display terraform toolbar when displaying rail, road, water and airport toolbars
 	bool reverse_scroll;                ///< Right-Click-Scrolling scrolls in the opposite direction
--- a/src/station_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/station_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -2184,6 +2184,9 @@
 		DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
 	}
 
+	/* End now if buildings are invisible */
+	if (IsInvisibilitySet(TO_BUILDINGS)) return;
+
 	const DrawTileSeqStruct *dtss;
 	foreach_draw_tile_seq(dtss, t->seq) {
 		SpriteID image = dtss->image.sprite;
--- a/src/table/track_land.h	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/table/track_land.h	Thu Apr 03 19:55:40 2008 +0000
@@ -33,6 +33,12 @@
 	{ {SPR_FLAT_GRASS_TILE, PAL_NONE}, _depot_gfx_NW }
 };
 
+static const DrawTileSprites _depot_invisible_gfx_table[] = {
+	{ {SPR_RAIL_TRACK_X, PAL_NONE}, _depot_gfx_NE },
+	{ {SPR_RAIL_TRACK_Y, PAL_NONE}, _depot_gfx_SE },
+	{ {SPR_RAIL_TRACK_X, PAL_NONE}, _depot_gfx_SW },
+	{ {SPR_RAIL_TRACK_Y, PAL_NONE}, _depot_gfx_NW }
+};
 
 static const DrawTileSeqStruct _waypoint_gfx_X[] = {
 	TILE_SEQ_LINE((1 << PALETTE_MODIFIER_COLOR) | SPR_WAYPOINT_X_1,  0,  0,  16,  5)
--- a/src/town_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/town_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -189,6 +189,9 @@
 	pal   = dcts->ground.pal;
 	DrawGroundSprite(image, pal);
 
+	/* If houses are invisible, do not draw the upper part */
+	if (IsInvisibilitySet(TO_HOUSES)) return;
+
 	/* Add a house on top of the ground? */
 	image = dcts->building.sprite;
 	if (image != 0) {
--- a/src/transparency.h	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/transparency.h	Thu Apr 03 19:55:40 2008 +0000
@@ -28,6 +28,7 @@
 typedef uint TransparencyOptionBits; ///< transparency option bits
 extern TransparencyOptionBits _transparency_opt;
 extern TransparencyOptionBits _transparency_lock;
+extern TransparencyOptionBits _invisibility_opt;
 
 /**
  * Check if the transparency option bit is set
@@ -41,6 +42,17 @@
 }
 
 /**
+ * Check if the invisibility option bit is set
+ * and if we aren't in the game menu (there's never transparency)
+ *
+ * @param to the structure which invisibility option is ask for
+ */
+static inline bool IsInvisibilitySet(TransparencyOption to)
+{
+	return (HasBit(_transparency_opt & _invisibility_opt, to) && _game_mode != GM_MENU);
+}
+
+/**
  * Toggle the transparency option bit
  *
  * @param to the transparency option to be toggled
@@ -51,6 +63,34 @@
 }
 
 /**
+ * Toggle the invisibility option bit
+ *
+ * @param to the structure which invisibility option is toggle
+ */
+static inline void ToggleInvisibility(TransparencyOption to)
+{
+	ToggleBit(_invisibility_opt, to);
+}
+
+/**
+ * Toggles between invisible and solid state.
+ * If object is transparent, then it is made invisible.
+ * Used by the keyboard shortcuts.
+ *
+ * @param to the object type which invisibility option to toggle
+ */
+static inline void ToggleInvisibilityWithTransparency(TransparencyOption to)
+{
+	if (IsInvisibilitySet(to)) {
+		ClrBit(_invisibility_opt, to);
+		ClrBit(_transparency_opt, to);
+	} else {
+		SetBit(_invisibility_opt, to);
+		SetBit(_transparency_opt, to);
+	}
+}
+
+/**
  * Toggle the transparency lock bit
  *
  * @param to the transparency option to be locked or unlocked
--- a/src/transparency_gui.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/transparency_gui.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -13,6 +13,7 @@
 
 TransparencyOptionBits _transparency_opt;
 TransparencyOptionBits _transparency_lock;
+TransparencyOptionBits _invisibility_opt;
 
 enum TransparencyToolbarWidgets{
 	TTW_WIDGET_SIGNS = 3,    ///< Make signs background transparent
@@ -25,6 +26,9 @@
 	TTW_WIDGET_CATENARY,     ///< Make catenary transparent
 	TTW_WIDGET_LOADING,      ///< Make loading indicators transparent
 	TTW_WIDGET_END,          ///< End of toggle buttons
+
+	/* Panel with buttons for invisibility */
+	TTW_BUTTONS = 12,        ///< Panel with 'invisibility' buttons
 };
 
 static void TransparencyToolbWndProc(Window *w, WindowEvent *e)
@@ -41,6 +45,18 @@
 			for (uint i = TO_SIGNS; i < TO_END; i++) {
 				if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, w->widget[TTW_WIDGET_SIGNS + i].left + 1, w->widget[TTW_WIDGET_SIGNS + i].top + 1);
 			}
+
+			/* Do not draw button for invisible loading indicators */
+			for (uint i = 0; i < 8; i++) {
+				if (i < TTW_WIDGET_BRIDGES - TTW_WIDGET_SIGNS) {
+					DrawFrameRect(i * 22, 38, i * 22 + 19, 46, true, HasBit(_invisibility_opt, i) ? FR_LOWERED : FR_NONE);
+				} else if (i == TTW_WIDGET_BRIDGES - TTW_WIDGET_SIGNS) {
+					DrawFrameRect(i * 22, 38, i * 22 + 41, 46, true, HasBit(_invisibility_opt, i) ? FR_LOWERED : FR_NONE);
+				} else { // i > TTW_WIDGET_BRIDGES - TTW_WIDGET_SIGNS
+					DrawFrameRect((i + 1) * 22, 38, (i + 1) * 22 + 19, 46, true, HasBit(_invisibility_opt, i) ? FR_LOWERED : FR_NONE);
+				}
+			}
+
 			break;
 
 		case WE_CLICK:
@@ -55,7 +71,23 @@
 					SndPlayFx(SND_15_BEEP);
 					MarkWholeScreenDirty();
 				}
+			} else if (e->we.click.widget == TTW_BUTTONS) {
+				uint x = e->we.click.pt.x / 22;
+
+				if (x > TTW_WIDGET_BRIDGES - TTW_WIDGET_SIGNS) x--;
+				if (x > TTW_WIDGET_CATENARY - TTW_WIDGET_SIGNS) break;
+
+				ToggleInvisibility((TransparencyOption)x);
+				SndPlayFx(SND_15_BEEP);
+
+				/* Redraw whole screen only if transparency is set */
+				if (IsTransparencySet((TransparencyOption)x)) {
+					MarkWholeScreenDirty();
+				} else {
+					w->InvalidateWidget(TTW_BUTTONS);
+				}
 			}
+
 			break;
 	}
 }
@@ -77,11 +109,13 @@
 {   WWT_IMGBTN,   RESIZE_NONE,  7, 175, 196,  14,  35, SPR_BUILD_X_ELRAIL,   STR_TRANSPARENT_CATENARY_DESC},
 {   WWT_IMGBTN,   RESIZE_NONE,  7, 197, 218,  14,  35, SPR_IMG_TRAINLIST,    STR_TRANSPARENT_LOADING_DESC},
 
+{    WWT_PANEL,   RESIZE_NONE,  7,   0, 218,  36,  48, 0x0,                  STR_TRANSPARENT_INVISIBLE_DESC},
+
 {   WIDGETS_END},
 };
 
 static const WindowDesc _transparency_desc = {
-	WDP_ALIGN_TBR, 58+36, 219, 36, 219, 36,
+	WDP_ALIGN_TBR, 58+36, 219, 49, 219, 49,
 	WC_TRANSPARENCY_TOOLBAR, WC_NONE,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
 	_transparency_widgets,
--- a/src/tree_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/tree_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -445,7 +445,7 @@
 	DrawClearLandFence(ti);
 
 	/* Do not draw trees when the invisible trees patch and transparency tree are set */
-	if (IsTransparencySet(TO_TREES) && _patches.invisible_trees) return;
+	if (IsInvisibilitySet(TO_TREES)) return;
 
 	uint16 tmp = ti->x;
 
--- a/src/tunnelbridge_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/tunnelbridge_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -719,7 +719,11 @@
  */
 static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, BridgeType type, int x, int y, int z_bridge)
 {
+	/* Do not draw bridge pillars if they are invisible */
+	if (IsInvisibilitySet(TO_BRIDGES)) return;
+
 	SpriteID image = psid->sprite;
+
 	if (image != 0) {
 		bool drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0);
 
@@ -771,8 +775,9 @@
  * @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?
+ * @param head    are we drawing bridge head?
  */
-static void DrawBridgeTramBits(int x, int y, byte z, int offset, bool overlay)
+static void DrawBridgeTramBits(int x, int y, byte z, int offset, bool overlay, bool head)
 {
 	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,  96,  99, 102, 100, 101 };
@@ -785,7 +790,12 @@
 
 	/* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called
 	 * The bounding boxes here are the same as for bridge front/roof */
-	AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_BRIDGES));
+	if (head || !IsInvisibilitySet(TO_BRIDGES)) {
+		AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, !head && IsTransparencySet(TO_BRIDGES));
+	}
+
+	/* Do not draw catenary if it is set invisible */
+	if (IsInvisibilitySet(TO_CATENARY)) return;
 
 	AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + back_offsets[offset],  PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_CATENARY));
 
@@ -856,11 +866,14 @@
 
 				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][tunnelbridge_direction], PAL_NONE);
 
-				catenary = true;
-				StartSpriteCombine();
-				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
+				/* Do not draw wires if they are invisible */
+				if (!IsInvisibilitySet(TO_CATENARY)) {
+					catenary = true;
+					StartSpriteCombine();
+					AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
+				}
 			}
-		} else if (HasCatenary(GetRailType(ti->tile))) {
+		} else if (!IsInvisibilitySet(TO_CATENARY) && HasCatenary(GetRailType(ti->tile))) {
 			DrawCatenary(ti);
 
 			catenary = true;
@@ -916,9 +929,8 @@
 		/* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
 		 * it doesn't disappear behind it
 		 */
-		AddSortableSpriteToDraw(
-			psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z, IsTransparencySet(TO_BRIDGES)
-		);
+		/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
+		AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
 
 		if (transport_type == TRANSPORT_ROAD) {
 			RoadTypes rts = GetRoadTypes(ti->tile);
@@ -933,7 +945,7 @@
 					offset += 2;
 				}
 				/* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
-				DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD));
+				DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD), true);
 			}
 			EndSpriteCombine();
 		} else if (HasCatenary(GetRailType(ti->tile))) {
@@ -1044,10 +1056,12 @@
 	if (transport_type == TRANSPORT_ROAD) StartSpriteCombine();
 
 	/* Draw floor and far part of bridge*/
-	if (axis == AXIS_X) {
-		AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
-	} else {
-		AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
+	if (!IsInvisibilitySet(TO_BRIDGES)) {
+		if (axis == AXIS_X) {
+			AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
+		} else {
+			AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
+		}
 	}
 
 	psid++;
@@ -1057,7 +1071,7 @@
 
 		if (HasBit(rts, ROADTYPE_TRAM)) {
 			/* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
-			DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD));
+			DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD), false);
 		} else {
 			EndSpriteCombine();
 			StartSpriteCombine();
@@ -1067,17 +1081,22 @@
 	}
 
 	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
-	if (axis == AXIS_X) {
-		y += 12;
-		if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 4, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 3, BRIDGE_Z_START);
-	} else {
-		x += 12;
-		if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START);
+	if (!IsInvisibilitySet(TO_BRIDGES)) {
+		if (axis == AXIS_X) {
+			y += 12;
+			if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 4, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 3, BRIDGE_Z_START);
+		} else {
+			x += 12;
+			if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START);
+		}
 	}
 
 	/* Draw TramFront as SpriteCombine */
 	if (transport_type == TRANSPORT_ROAD) EndSpriteCombine();
 
+	/* Do not draw anything more if bridges are invisible */
+	if (IsInvisibilitySet(TO_BRIDGES)) return;
+
 	psid++;
 	if (ti->z + 5 == z) {
 		/* draw poles below for small bridges */
--- a/src/unmovable_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/unmovable_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -171,6 +171,8 @@
 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 			DrawClearLandTile(ti, 2);
 
+			if (IsInvisibilitySet(TO_STRUCTURES)) break;
+
 			AddSortableSpriteToDraw(
 				dtu->image.sprite, PAL_NONE, ti->x | dtu->delta_x, ti->y | dtu->delta_y,
 				dtu->size_x, dtu->size_y, dtu->size_z, ti->z,
@@ -185,6 +187,8 @@
 
 			DrawGroundSprite(SPR_CONCRETE_GROUND, PAL_NONE);
 
+			if (IsInvisibilitySet(TO_STRUCTURES)) break;
+
 			AddSortableSpriteToDraw(SPR_STATUE_COMPANY, PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), ti->x, ti->y, 16, 16, 25, ti->z, IsTransparencySet(TO_STRUCTURES));
 			break;
 
@@ -211,6 +215,8 @@
 			t = &_unmovable_display_datas[GetCompanyHQSection(ti->tile)];
 			DrawGroundSprite(t->ground.sprite, palette);
 
+			if (IsInvisibilitySet(TO_STRUCTURES)) break;
+
 			foreach_draw_tile_seq(dtss, t->seq) {
 				AddSortableSpriteToDraw(
 					dtss->image.sprite, palette,
--- a/src/viewport.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/viewport.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -1230,8 +1230,8 @@
 	const Sign *si;
 	int left, top, right, bottom;
 
-	if (!HasBit(_display_opt, DO_SHOW_SIGNS))
-		return;
+	/* Signs are turned off or are invisible */
+	if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS)) return;
 
 	left = dpi->left;
 	top = dpi->top;
@@ -1495,6 +1495,12 @@
 		uint16 colour;
 
 		if (ss->width != 0) {
+			/* Do not draw signs nor station names if they are set invisible */
+			if (IsInvisibilitySet(TO_SIGNS) && ss->string != STR_2806) {
+				ss = ss->next;
+				continue;
+			}
+
 			int x = UnScaleByZoom(ss->x, zoom) - 1;
 			int y = UnScaleByZoom(ss->y, zoom) - 1;
 			int bottom = y + 11;
@@ -1958,7 +1964,8 @@
 {
 	const Sign *si;
 
-	if (!HasBit(_display_opt, DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false;
+	/* Signs are turned off, or they are transparent and invisibility is ON, or player is a spectator */
+	if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS) || _current_player == PLAYER_SPECTATOR) return false;
 
 	switch (vp->zoom) {
 		case ZOOM_LVL_NORMAL:
--- a/src/water_cmd.cpp	Thu Apr 03 16:16:52 2008 +0000
+++ b/src/water_cmd.cpp	Thu Apr 03 19:55:40 2008 +0000
@@ -597,6 +597,9 @@
 	if (image < 4) image += water_base;
 	if (draw_ground) DrawGroundSprite(image, PAL_NONE);
 
+	/* End now if buildings are invisible */
+	if (IsInvisibilitySet(TO_BUILDINGS)) return;
+
 	for (; wdts->delta_x != 0x80; wdts++) {
 		AddSortableSpriteToDraw(wdts->image + base + ((wdts->image < 24) ? locks_base : 0), palette,
 			ti->x + wdts->delta_x, ti->y + wdts->delta_y,