(svn r4150) -Feature: Merged elrails into trunk. Thanks to Tron for lots of code and proofreading, thanks to peter1138 for another lot of code and ideas.
authorcelestar
Wed, 29 Mar 2006 16:30:26 +0000
changeset 3355 e414a0b104a6
parent 3354 245157a5eafe
child 3356 fab7a98c136e
(svn r4150) -Feature: Merged elrails into trunk. Thanks to Tron for lots of code and proofreading, thanks to peter1138 for another lot of code and ideas.
BUGS
Makefile
ai/default/default.c
bridge.h
bridge_map.h
data/elrailsw.grf
docs/elrail.svg
docs/elrail_tile.png
docs/elrail_track.png
docs/landscape.html
elrail.c
engine_gui.c
gfxinit.c
lang/english.txt
misc.c
newgrf.c
npf.c
npf.h
openttd.c
openttd.dsp
openttd.vcproj
pathfind.c
pathfind.h
player.h
rail.h
rail_cmd.c
rail_map.h
railtypes.h
road_cmd.c
saveload.c
station_cmd.c
table/elrail_data.h
table/engines.h
table/landscape_const.h
table/sprites.h
train_cmd.c
train_gui.c
tunnelbridge_cmd.c
variables.h
vehicle.c
vehicle.h
vehicle_gui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BUGS	Wed Mar 29 16:30:26 2006 +0000
@@ -0,0 +1,7 @@
+/* $Id */
+
+KNOWN BUGS / PROBLEMS:
+
+Normal and elrail depots look the same. Use 'X' (transparent buildings)
+   to distinguish between them
+Missing curors / icons for construction (currently using the conventional ones)
--- a/Makefile	Wed Mar 29 16:28:41 2006 +0000
+++ b/Makefile	Wed Mar 29 16:30:26 2006 +0000
@@ -630,6 +630,7 @@
 SRCS += driver.c
 SRCS += dummy_land.c
 SRCS += economy.c
+SRCS += elrail.c
 SRCS += engine.c
 SRCS += engine_gui.c
 SRCS += fileio.c
--- a/ai/default/default.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/ai/default/default.c	Wed Mar 29 16:30:26 2006 +0000
@@ -126,7 +126,7 @@
 	p->ai.state_counter = 0;
 }
 
-static EngineID AiChooseTrainToBuild(byte railtype, int32 money, byte flag, TileIndex tile)
+static EngineID AiChooseTrainToBuild(RailType railtype, int32 money, byte flag, TileIndex tile)
 {
 	EngineID best_veh_index = INVALID_ENGINE;
 	byte best_veh_score = 0;
@@ -137,7 +137,7 @@
 		const RailVehicleInfo *rvi = RailVehInfo(i);
 		const Engine* e = GetEngine(i);
 
-		if (e->railtype != railtype ||
+		if (!IsCompatibleRail(e->railtype, railtype) ||
 				rvi->flags & RVI_WAGON ||
 				(rvi->flags & RVI_MULTIHEAD && flag & 1) ||
 				!HASBIT(e->player_avail, _current_player) ||
@@ -2321,6 +2321,41 @@
 	return GetStationIndex(TILE_ADD(tile, ToTileIndexDiff(p->tileoffs)));
 }
 
+static EngineID AiFindBestWagon(CargoID cargo, RailType railtype)
+{
+	EngineID best_veh_index = INVALID_ENGINE;
+	EngineID i;
+	uint16 best_capacity = 0;
+	uint16 best_speed    = 0;
+	uint speed;
+
+	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
+		const RailVehicleInfo *rvi = RailVehInfo(i);
+		const Engine* e = GetEngine(i);
+
+		if (!IsCompatibleRail(e->railtype, railtype) ||
+				!(rvi->flags & RVI_WAGON) ||
+				!HASBIT(e->player_avail, _current_player)) {
+			continue;
+		}
+
+		if (rvi->cargo_type != cargo) {
+			continue;
+		}
+
+		/* max_speed of 0 indicates no speed limit */
+		speed = rvi->max_speed == 0 ? 0xFFFF : rvi->max_speed;
+
+		if (rvi->capacity >= best_capacity && speed >= best_speed) {
+			best_capacity = rvi->capacity;
+			best_speed    = best_speed;
+			best_veh_index = i;
+		}
+	}
+
+	return best_veh_index;
+}
+
 static void AiStateBuildRailVeh(Player *p)
 {
 	const AiDefaultBlockData *ptr;
@@ -2337,10 +2372,14 @@
 
 	tile = TILE_ADD(p->ai.src.use_tile, ToTileIndexDiff(ptr->tileoffs));
 
+
 	cargo = p->ai.cargo_type;
 	for (i = 0;;) {
 		if (p->ai.wagon_list[i] == INVALID_VEHICLE) {
-			veh = _cargoc.ai_railwagon[p->ai.railtype_to_use][cargo];
+			veh = AiFindBestWagon(cargo, p->ai.railtype_to_use);
+			/* veh will return INVALID_ENGINE if no suitable wagon is available.
+			 * We shall treat this in the same way as having no money */
+			if (veh == INVALID_ENGINE) goto handle_nocash;
 			cost = DoCommandByTile(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE);
 			if (CmdFailed(cost)) goto handle_nocash;
 			p->ai.wagon_list[i] = _new_wagon_id;
--- a/bridge.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/bridge.h	Wed Mar 29 16:30:26 2006 +0000
@@ -22,4 +22,6 @@
 extern const Bridge orig_bridge[MAX_BRIDGES];
 extern Bridge _bridge[MAX_BRIDGES];
 
+uint GetBridgeFoundation(uint tileh, Axis axis);
+
 #endif /* BRIDGE_H */
--- a/bridge_map.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/bridge_map.h	Wed Mar 29 16:30:26 2006 +0000
@@ -127,6 +127,7 @@
  */
 TileIndex GetOtherBridgeEnd(TileIndex);
 
+uint GetBridgeHeight(TileIndex t);
 
 static inline void SetClearUnderBridge(TileIndex t)
 {
Binary file data/elrailsw.grf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/elrail.svg	Wed Mar 29 16:30:26 2006 +0000
@@ -0,0 +1,1091 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.42.2"
+   sodipodi:docbase="/home/vici/openttd/branch/elrail/docs"
+   sodipodi:docname="elrail.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="1.0000000"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.6009318"
+     inkscape:cx="144.00958"
+     inkscape:cy="578.90292"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     showgrid="true"
+     inkscape:window-width="1131"
+     inkscape:window-height="791"
+     inkscape:window-x="1295"
+     inkscape:window-y="46"
+     inkscape:grid-points="false"
+     inkscape:guide-points="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1.0000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0067960;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       id="rect1306"
+       width="159.49321"
+       height="159.49657"
+       x="227.17947"
+       y="-24.569920"
+       transform="matrix(0.707107,0.707107,-0.707107,0.707107,0.000000,0.000000)"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <rect
+       y="272.36218"
+       x="134.28571"
+       height="100.00000"
+       width="100.00000"
+       id="rect2059"
+       style="opacity:1.0000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-opacity:1.0000000;stroke-width:0.0000000;stroke-miterlimit:4.0000000;stroke-dasharray:none"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="177.84283"
+       y="159.25369"
+       id="text6598"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6600"
+         x="177.84283"
+         y="159.25369"
+         style="font-family:Bitstream Vera Sans;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:12.000000;text-anchor:middle;text-align:center;writing-mode:lr;line-height:125%">N</tspan></text>
+    <path
+       transform="translate(-192.0645,-106.5709)"
+       d="M 213.86573 240.06183 A 4.8679605 4.8679605 0 1 1  204.12981,240.06183 A 4.8679605 4.8679605 0 1 1  213.86573 240.06183 z"
+       sodipodi:ry="4.8679605"
+       sodipodi:rx="4.8679605"
+       sodipodi:cy="240.06183"
+       sodipodi:cx="208.99777"
+       id="use6604"
+       style="opacity:1.0000000;fill:#9fb276;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.29899999;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="27.214844"
+       y="135.69812"
+       id="text6606"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6608"
+         x="27.214844"
+         y="135.69812"
+         style="font-size:8.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">Pylon Control Point (PCP)</tspan></text>
+    <g
+       id="g6780"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397">
+      <path
+         transform="translate(-16.64392,10.04300)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6610"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-16.64392,-3.625430)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6612"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-2.975490,-3.625430)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6614"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(10.69294,-3.625430)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6616"
+         style="opacity:1.0000000;fill:#ff0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(10.69294,10.04300)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6620"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(10.69294,23.71143)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6622"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-2.975490,23.71143)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6624"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-16.64392,23.71143)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6626"
+         style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#9fb276;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.29899999;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6732"
+         sodipodi:cx="208.99777"
+         sodipodi:cy="240.06183"
+         sodipodi:rx="4.8679605"
+         sodipodi:ry="4.8679605"
+         d="M 213.86573 240.06183 A 4.8679605 4.8679605 0 1 1  204.12981,240.06183 A 4.8679605 4.8679605 0 1 1  213.86573 240.06183 z"
+         transform="matrix(0.707107,-0.707107,0.707107,0.707107,-82.95220,177.5124)" />
+    </g>
+    <use
+       x="0.0000000"
+       y="0.0000000"
+       xlink:href="#path6616"
+       id="use6742"
+       transform="translate(-222.0702,-28.15283)"
+       width="744.09448"
+       height="1052.3622"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-211.3773,-22.11155)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6744"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-211.3773,-12.44495)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6746"
+       style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-211.3773,-2.778260)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6748"
+       style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="32.279297"
+       y="159.58745"
+       id="text6750"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6752"
+         x="32.279297"
+         y="159.58745"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">not allowed, not owned</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="32.279297"
+       y="188.58745"
+       id="text6754"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6756"
+         x="32.279297"
+         y="188.58745"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">not allowed, owned</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="32.279297"
+       y="178.92078"
+       id="text6758"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6760"
+         x="32.279297"
+         y="178.92078"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">allowed, owned</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="32.279297"
+       y="169.25417"
+       id="text6762"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6764"
+         x="32.279297"
+         y="169.25417"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">allowed, not owned</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="27.214844"
+       y="149.62065"
+       id="text6766"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6768"
+         x="27.214844"
+         y="149.62065"
+         style="font-size:8.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">Pylon Position Point (PPP)</tspan></text>
+    <use
+       x="0.0000000"
+       y="0.0000000"
+       xlink:href="#g6780"
+       id="use6791"
+       transform="matrix(-1.720846e-15,1.000000,-1.000000,-1.720846e-15,433.4807,78.77855)"
+       width="744.09448"
+       height="1052.3622"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <g
+       id="g6793"
+       transform="matrix(1.776357e-15,-1.000000,1.000000,1.776357e-15,-78.04526,434.0590)"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397">
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6795"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,10.04300)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6797"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6799"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-2.975490,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ff0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6801"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6803"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,10.04300)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6805"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,23.71143)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6807"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-2.975490,23.71143)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6809"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,23.71143)" />
+      <path
+         transform="matrix(0.707107,-0.707107,0.707107,0.707107,-82.95220,177.5124)"
+         d="M 213.86573 240.06183 A 4.8679605 4.8679605 0 1 1  204.12981,240.06183 A 4.8679605 4.8679605 0 1 1  213.86573 240.06183 z"
+         sodipodi:ry="4.8679605"
+         sodipodi:rx="4.8679605"
+         sodipodi:cy="240.06183"
+         sodipodi:cx="208.99777"
+         id="path6811"
+         style="opacity:1.0000000;fill:#9fb276;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.29899999;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+    </g>
+    <g
+       id="g6813"
+       transform="matrix(-1.000000,0.000000,0.000000,-1.000000,356.0752,512.3398)"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_tile.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397">
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6815"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,10.04300)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6817"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6819"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-2.975490,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ff0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6821"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,-3.625430)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6823"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,10.04300)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6825"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(10.69294,23.71143)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6827"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-2.975490,23.71143)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6829"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="translate(-16.64392,23.71143)" />
+      <path
+         transform="matrix(0.707107,-0.707107,0.707107,0.707107,-82.95220,177.5124)"
+         d="M 213.86573 240.06183 A 4.8679605 4.8679605 0 1 1  204.12981,240.06183 A 4.8679605 4.8679605 0 1 1  213.86573 240.06183 z"
+         sodipodi:ry="4.8679605"
+         sodipodi:rx="4.8679605"
+         sodipodi:cy="240.06183"
+         sodipodi:cx="208.99777"
+         id="path6831"
+         style="opacity:1.0000000;fill:#9fb276;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.29899999;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+    </g>
+    <use
+       x="0.0000000"
+       y="0.0000000"
+       xlink:href="#path6616"
+       id="use6841"
+       transform="translate(-225.5836,232.1805)"
+       width="744.09448"
+       height="1052.3622"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-214.8907,238.2218)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6843"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-214.8907,247.8884)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6845"
+       style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-214.8907,257.5551)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path6847"
+       style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="28.765947"
+       y="419.92078"
+       id="text6849"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6851"
+         x="28.765947"
+         y="419.92078"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">not allowed, but preferred (end of line marker)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="28.765947"
+       y="448.92078"
+       id="text6853"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6855"
+         x="28.765947"
+         y="448.92078"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">not allowed</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="28.765947"
+       y="439.25409"
+       id="text6857"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6859"
+         x="28.765947"
+         y="439.25409"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">preferred, allowed</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="28.765947"
+       y="429.58746"
+       id="text6861"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         x="28.765947"
+         y="429.58746"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans"
+         id="tspan6933">allowed</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="23.701494"
+       y="409.95398"
+       id="text6865"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan6867"
+         x="23.701494"
+         y="409.95398"
+         style="font-size:8.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">Pylon Position Point (PPP)</tspan></text>
+    <g
+       id="g6989"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397">
+      <path
+         transform="translate(-103.1355,254.9297)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6871"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-103.1355,241.2613)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6873"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-89.46705,241.2613)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6875"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-75.79862,241.2613)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6877"
+         style="opacity:1.0000000;fill:#ff0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-75.79862,254.9297)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6879"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-75.79862,268.5982)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6881"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-89.46705,268.5982)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6883"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         transform="translate(-103.1355,268.5982)"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         sodipodi:ry="2.2717149"
+         sodipodi:rx="2.2717149"
+         sodipodi:cy="189.43504"
+         sodipodi:cx="237.55647"
+         id="path6885"
+         style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6891"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,286.2275,747.1836)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6893"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,286.2275,760.8520)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6895"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,272.5591,760.8520)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ff0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6897"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,258.8907,760.8520)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6899"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,258.8907,747.1836)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#00ffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6901"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,258.8907,733.5153)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6903"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,272.5591,733.5153)" />
+      <path
+         sodipodi:type="arc"
+         style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+         id="path6905"
+         sodipodi:cx="237.55647"
+         sodipodi:cy="189.43504"
+         sodipodi:rx="2.2717149"
+         sodipodi:ry="2.2717149"
+         d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+         transform="matrix(-1.000000,0.000000,0.000000,-1.000000,286.2275,733.5153)" />
+      <path
+         id="path6931"
+         d="M 35.005290,557.75123 L 148.46835,444.19631"
+         style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+    </g>
+    <g
+       id="g7091"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397">
+      <path
+         sodipodi:nodetypes="ccc"
+         id="path6935"
+         d="M 143.36688,574.86732 L 185.00000,533.20050 L 241.50000,533.20050"
+         style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000011px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+      <g
+         id="g7081">
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,436.0591,722.7997)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6973"
+           style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,436.0591,736.4681)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6975"
+           style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,422.3907,736.4681)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6977"
+           style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,408.7223,736.4681)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6979"
+           style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,408.7223,722.7997)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6981"
+           style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,408.7223,709.1314)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6983"
+           style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,422.3907,709.1314)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6985"
+           style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+        <path
+           transform="matrix(-1.000000,0.000000,0.000000,-1.000000,436.0591,709.1314)"
+           d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+           sodipodi:ry="2.2717149"
+           sodipodi:rx="2.2717149"
+           sodipodi:cy="189.43504"
+           sodipodi:cx="237.55647"
+           id="path6987"
+           style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+           sodipodi:type="arc" />
+      </g>
+    </g>
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,608.1528,439.3340)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7037"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,617.8178,448.9990)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7039"
+       style="opacity:1.0000000;fill:#ff00ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,608.1528,458.6640)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7041"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,598.4878,468.3290)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7043"
+       style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,588.8228,458.6640)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7045"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,579.1578,448.9991)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7047"
+       style="opacity:1.0000000;fill:#ff00ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,588.8229,439.3341)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7049"
+       style="opacity:1.0000000;fill:#0000ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="matrix(-0.707107,0.707107,-0.707107,-0.707107,598.4879,429.6690)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7051"
+       style="opacity:1.0000000;fill:#ffff00;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+       d="M 296.56288,570.12631 L 296.49793,409.60031"
+       id="path7053"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <path
+       transform="translate(-214.8907,267.2614)"
+       d="M 239.82819 189.43504 A 2.2717149 2.2717149 0 1 1  235.28476,189.43504 A 2.2717149 2.2717149 0 1 1  239.82819 189.43504 z"
+       sodipodi:ry="2.2717149"
+       sodipodi:rx="2.2717149"
+       sodipodi:cy="189.43504"
+       sodipodi:cx="237.55647"
+       id="path7111"
+       style="opacity:1.0000000;fill:#ff00ff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.12500000;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+       sodipodi:type="arc"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.000000px;font-style:normal;font-weight:normal;line-height:125.00000%;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       x="28.765947"
+       y="458.93326"
+       id="text7113"
+       sodipodi:linespacing="125.00000%"
+       inkscape:export-filename="/home/vici/openttd/branch/elrail/docs/elrail_track.png"
+       inkscape:export-xdpi="299.91397"
+       inkscape:export-ydpi="299.91397"><tspan
+         sodipodi:role="line"
+         id="tspan7115"
+         x="28.765947"
+         y="458.93326"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">preferred, allowed and</tspan><tspan
+         sodipodi:role="line"
+         x="28.765947"
+         y="466.43326"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans"
+         id="tspan7117">can be ignored to create</tspan><tspan
+         sodipodi:role="line"
+         x="28.765947"
+         y="473.93326"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans"
+         id="tspan7119">long wires (which span</tspan><tspan
+         sodipodi:role="line"
+         x="28.765947"
+         y="481.43326"
+         style="font-size:6.0000000px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans"
+         id="tspan7121">2 tiles)</tspan></text>
+  </g>
+</svg>
Binary file docs/elrail_tile.png has changed
Binary file docs/elrail_track.png has changed
--- a/docs/landscape.html	Wed Mar 29 16:28:41 2006 +0000
+++ b/docs/landscape.html	Wed Mar 29 16:30:26 2006 +0000
@@ -129,7 +129,7 @@
 <tr><td nowrap valign=top><tt>B</tt>&nbsp; </td><td align=left>fence on the N side (track in the S corner)</td></tr>
 <tr><td nowrap valign=top><tt>C</tt>&nbsp; </td><td align=left>on snow or desert</td></tr>
 </table></li>
-<li>m3 bits 0..3 = <a name="TrackType">track type</a>: <tt>0</tt> - conventional railway, <tt>1</tt> - monorail, <tt>2</tt> - maglev
+<li>m3 bits 0..3 = <a name="TrackType">track type</a>: <tt>0</tt> - conventional railway, <tt>1</tt> - electrified railway, <tt>2</tt> - monorail, <tt>3</tt> - maglev
 </ul>
 m5 bits 7 and 6 set: railway depot / checkpoints
 <ul>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/elrail.c	Wed Mar 29 16:30:26 2006 +0000
@@ -0,0 +1,352 @@
+/* $Id$ */
+/** @file elrail.c
+  * This file deals with displaying wires and pylons for electric railway systems.
+<h2>Basics</h2>
+
+<h3>Tile Types</h3>
+
+We have two different types of tiles in the drawing code:
+Normal Railway Tiles (NRTs) which can have more than one track on it, and
+Special Railways tiles (SRTs) which have only one track (like crossings, depots
+stations, etc).
+
+<h3>Location Categories</h3>
+
+All tiles are categorized into three location groups (TLG):
+Group 0: Tiles with both an even X coordinate and an even Y coordinate
+Group 1: Tiles with an even X and an odd Y coordinate
+Group 2: Tiles with an odd X and an even Y coordinate
+Group 3: Tiles with both an odd X and Y coordnate.
+
+<h3>Pylon Points</h3>
+<h4>Control Points</h4>
+A Pylon Control Point (PCP) is a position where a wire (or rather two)
+is mounted onto a pylon.
+Each NRT does contain 4 PCPs which are mapped to a byte
+variable and are represented by the DiagDirection enum:
+
+A wire that ends on the PCP has a dark ending, otherwise the end is bright.<p>
+
+Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs are merged
+using an OR matrix (i. e. if one tile needs a PCP at the postion in question, both
+tiles get it).
+
+<h4>Position Points</h4>
+A Pylon Position Point (PPP) is a position where a pylon is located on the ground.
+Each PCP owns 8 in (45 degree steps) PPPs that are located around it. PPPs are numbered
+0 to 7 with 0 starting north and numbering in clockwise direction. Each track bit has PPPs
+that are impossible (because the pylon would be situated on the track), preferred (because
+the pylon would be rectangular to the track). PPPs are represented by the Direction enum.
+
+<img src="../../elrail_tile.png">
+<img src="../../elrail_track.png">
+
+  */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "tile.h"
+#include "viewport.h"
+#include "functions.h" /* We should REALLY get rid of this goddamn file, as it is butt-ugly */
+#include "variables.h" /* ... same here */
+#include "rail.h"
+#include "debug.h"
+#include "tunnel_map.h"
+#include "road_map.h"
+#include "bridge_map.h"
+#include "bridge.h"
+#include "rail_map.h"
+#include "table/sprites.h"
+#include "table/elrail_data.h"
+
+static inline TLG GetTLG(TileIndex t)
+{
+	return (HASBIT(TileX(t), 0) << 1) + HASBIT(TileY(t), 0);
+}
+
+/** Finds which Rail Bits are present on a given tile. For bridge tiles,
+  * returns track bits under the bridge
+  */
+static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
+{
+	switch (GetTileType(t)) {
+		case MP_RAILWAY:
+			if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+			switch (GetRailTileType(t)) {
+				case RAIL_TYPE_NORMAL: case RAIL_TYPE_SIGNALS:
+					return GetTrackBits(t);
+				default:
+					return 0;
+			}
+			break;
+		case MP_TUNNELBRIDGE:
+			if (IsTunnel(t)) {
+				if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+				if (override != NULL) *override = 1 << GetTunnelDirection(t);
+				return (_m[t].m5 & 1) ? TRACK_BIT_Y : TRACK_BIT_X;
+			} else {
+				if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+				if (
+					IsBridgeMiddle(t) &&
+					IsTransportUnderBridge(t) &&
+					GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL) {
+					return GetRailBitsUnderBridge(t);
+				} else {
+					if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) *override = 1 << GetBridgeRampDirection(t);
+
+					return GetBridgeAxis(t) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
+				}
+			}
+		case MP_STREET:
+			if ((_m[t].m4 & 0xF) != RAILTYPE_ELECTRIC) return 0;
+			return GetCrossingRailBits(t);
+		case MP_STATION:
+			if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
+			return _m[t].m5 & 1 ? TRACK_BIT_Y : TRACK_BIT_X;
+		default:
+			return 0;
+	}
+}
+
+/** Draws wires and, if required, pylons on a given tile
+  * @param ti The Tileinfo to draw the tile for
+  * @todo Currently, each pylon is drawn twice (once for each neighbouring tiles use OwnedPPPonPCP for this)
+  */
+static void DrawCatenaryRailway(const TileInfo *ti)
+{
+	/* Pylons are placed on a tile edge, so we need to take into account
+	   the track configuration of 2 adjacent tiles. trackconfig[0] stores the
+	   current tile (home tile) while [1] holds the neighbour */
+	TrackBits trackconfig[TS_END];
+	bool isflat[TS_END];
+	/* Note that ti->tileh has already been adjusted for Foundations */
+	uint tileh[TS_END] = {ti->tileh, 0};
+
+	TLG tlg = GetTLG(ti->tile);
+	byte PCPstatus = 0;
+	byte OverridePCP = 0;
+	byte PPPpreferred[DIAGDIR_END] = {0xFF, 0xFF, 0xFF, 0xFF};
+	byte PPPallowed[DIAGDIR_END] = {AllowedPPPonPCP[0], AllowedPPPonPCP[1], AllowedPPPonPCP[2], AllowedPPPonPCP[3]};
+	byte PPPbuffer[DIAGDIR_END];
+	DiagDirection i;
+	Track t;
+
+	/* Find which rail bits are present, and select the override points.
+	   We don't draw a pylon:
+	   1) INSIDE a tunnel (we wouldn't see it anyway)
+	   2) on the "far" end of a bridge head (the one that connects to bridge middle),
+	      because that one is drawn on the bridge. Exception is for length 0 bridges
+	      which have no middle tiles */
+	trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
+	/* If a track bit is present that is not in the main direction, the track is level */
+	isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
+
+	if (IsTunnelTile(ti->tile)) tileh[TS_HOME] = 0;
+	if (IsBridgeTile(ti->tile) && IsBridgeRamp(ti->tile)) {
+		if (tileh[TS_HOME] != 0) {
+			tileh[TS_HOME] = 0;
+		} else {
+			switch (GetBridgeRampDirection(ti->tile)) {
+				case DIAGDIR_NE: tileh[TS_HOME] = 12; break;
+				case DIAGDIR_SE: tileh[TS_HOME] =  6; break;
+				case DIAGDIR_SW: tileh[TS_HOME] =  3; break;
+				case DIAGDIR_NW: tileh[TS_HOME] =  9; break;
+				default: break;
+			}
+		}
+	}
+
+	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
+		extern const TileIndexDiffC _tileoffs_by_dir[];
+		TileIndex neighbour = ti->tile + TileOffsByDir(i);
+		uint foundation = 0;
+		int k;
+
+		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
+		   existing foundataions, so we do have to do that manually later on.*/
+		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
+		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
+		isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
+
+		/* We cycle through all the existing tracks at a PCP and see what
+		   PPPs we want to have, or may not have at all */
+		for (k = 0; k < TRACKS_AT_PCP; k++) {
+			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
+			if (
+					trackorigin[i][k] == TS_NEIGHBOUR &&
+					IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) &&
+					GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)
+			   ) continue;
+
+			if (HASBIT(trackconfig[trackorigin[i][k]], PPPtracks[i][k])) {
+				DiagDirection PCPpos = (trackorigin[i][k] == 0) ? i : ReverseDiagDir(i);
+				PCPstatus |= 1 << i; /* This PCP is in use */
+				PPPpreferred[i] &= PreferredPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos];
+				PPPallowed[i] &= ~DisallowedPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos];
+			}
+		}
+
+		/* Deactivate all PPPs if PCP is not used */
+		PPPpreferred[i] *= HASBIT(PCPstatus, i);
+		PPPallowed[i] *= HASBIT(PCPstatus, i);
+
+		/* Station on a non-flat tile means foundation. add one height level and adjust tileh */
+		if (IsTileType(neighbour, MP_STATION) && tileh[TS_NEIGHBOUR] != 0) tileh[TS_NEIGHBOUR] = 0;
+
+		/* Read the foundataions if they are present, and adjust the tileh */
+		if (IsTileType(neighbour, MP_RAILWAY)) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]);
+		if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], GetBridgeAxis(neighbour));
+		if (foundation != 0) {
+			if (foundation < 15) {
+				tileh[TS_NEIGHBOUR] = 0;
+			} else {
+				tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
+			}
+		}
+
+		/* Convert the real tileh into a pseudo-tileh for the track */
+		if (IsTunnelTile(neighbour)) tileh[TS_NEIGHBOUR] = 0;
+		if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) {
+			if (tileh[TS_NEIGHBOUR] != 0) {
+				tileh[TS_NEIGHBOUR] = 0;
+			} else {
+				switch (GetBridgeRampDirection(neighbour)) {
+					case DIAGDIR_NE: tileh[TS_NEIGHBOUR] = 12; break;
+					case DIAGDIR_SE: tileh[TS_NEIGHBOUR] =  6; break;
+					case DIAGDIR_SW: tileh[TS_NEIGHBOUR] =  3; break;
+					case DIAGDIR_NW: tileh[TS_NEIGHBOUR] =  9; break;
+					default: break;
+				}
+			}
+		}
+
+		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
+		   Delete the PCP if this is the case. */
+		/* Level means that the slope is the same, or the track is flat */
+		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
+			for (k = 0; k < NUM_IGNORE_GROUPS; k++)
+				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) PCPstatus &= ~(1 << i);
+		}
+
+		/* Now decide where we draw our tiles. First try the preferred PPPs, but they may not exist.
+		   In that case, we try the any of the allowed ones. if they don't exist either, don't draw
+		   anything */
+		if (PPPpreferred[i] != 0) {
+			/* Some of the preferred PPPs (the ones in direct extension of the track bit)
+			   have been used as an "end of line" marker. As these are not ALLOWED, this operation
+			   cancles them out */
+			PPPbuffer[i] = PPPpreferred[i] & PPPallowed[i];
+			/* We haven't any buffer yet, so try something else. Fixes 90° curves */
+			if (PPPbuffer[i] == 0) PPPbuffer[i] = PPPallowed[i];
+		} else {
+			PPPbuffer[i] = PPPallowed[i];
+		}
+
+		if (PPPbuffer[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
+			for (k = 0; k < DIR_END; k++) {
+				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
+				if (HASBIT(PPPbuffer[i], temp)) {
+					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
+					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
+
+					/* Don't build the pylon if it would be outside the tile */
+					if (!HASBIT(OwnedPPPonPCP[i], temp)) {
+						/* We have a neighour that will draw it, bail out */
+						if (trackconfig[TS_NEIGHBOUR] != 0) break;
+						continue; /* No neighbour, go looking for a better position */
+					}
+
+					AddSortableSpriteToDraw(pylons_normal[temp], x, y, 1, 1, 10,
+							GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i]));
+					break; /* We already have drawn a pylon, bail out */
+				}
+			}
+		}
+	}
+
+	/* Drawing of pylons is finished, now draw the wires */
+	for (t = 0; t < TRACK_END; t++) {
+		if (HASBIT(trackconfig[TS_HOME], t)) {
+
+			byte PCPconfig = HASBIT(PCPstatus, PCPpositions[t][0]) +
+				(HASBIT(PCPstatus, PCPpositions[t][1]) << 1);
+
+			const SortableSpriteStruct *sss;
+			int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */
+
+			if ( /* We are not drawing a wire under a low bridge */
+					IsBridgeTile(ti->tile) &&
+					IsBridgeMiddle(ti->tile) &&
+					!(_display_opt & DO_TRANS_BUILDINGS) &&
+					GetBridgeHeight(t) <= TilePixelHeight(t)
+			   ) return;
+
+			assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */
+			assert(!IsSteepTileh(tileh[TS_HOME]));
+			sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]];
+
+			AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+				sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, 15), ti->y + min(sss->y_offset, 15)) + sss->z_offset);
+		}
+	}
+}
+
+static void DrawCatenaryOnBridge(const TileInfo *ti)
+{
+	TileIndex start = GetOtherBridgeEnd(GetSouthernBridgeEnd(ti->tile));
+	uint length = GetBridgeLength(GetSouthernBridgeEnd(ti->tile), GetOtherBridgeEnd(GetSouthernBridgeEnd(ti->tile)));
+	uint num = DistanceMax(ti->tile, start);
+	const SortableSpriteStruct *sss;
+	Axis axis = GetBridgeAxis(ti->tile);
+	TLG tlg = GetTLG(ti->tile);
+
+	CatenarySprite offset = axis == AXIS_X ? 0 : WIRE_Y_FLAT_BOTH - WIRE_X_FLAT_BOTH;
+
+	if ((length % 2) && num == length) {
+		sss = &CatenarySpriteData[WIRE_X_FLAT_BOTH + offset];
+	} else {
+		sss = &CatenarySpriteData[WIRE_X_FLAT_SW + (num % 2) + offset];
+	}
+
+	if (num % 2) {
+		if (axis == AXIS_X) {
+			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + 8);
+		} else {
+			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, GetBridgeHeight(ti->tile) + 8);
+		}
+	}
+
+	if (DistanceMax(ti->tile, start) == length) { /* need a pylon here (the southern end) */
+		if (axis == AXIS_X) {
+			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + 8);
+		} else {
+			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, GetBridgeHeight(ti->tile) + 8);
+		}
+	}
+
+	AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+			sss->x_size, sss->y_size, sss->z_size, GetBridgeHeight(ti->tile) + sss->z_offset + 8);
+}
+
+void DrawCatenary(const TileInfo *ti)
+{
+	switch (GetTileType(ti->tile)) {
+		case MP_RAILWAY:
+			if (GetRailTileType(ti->tile) == RAIL_TYPE_DEPOT_WAYPOINT && GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) {
+				const SortableSpriteStruct *sss = &CatenarySpriteData[WIRE_DEPOT_SW + ReverseDiagDir(GetRailDepotDirection(ti->tile))];
+				AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
+					sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x, ti->y) + sss->z_offset);
+				return;
+			}
+			/* Fall through */
+		case MP_TUNNELBRIDGE:
+			if (IsBridgeTile(ti->tile) && IsBridgeMiddle(ti->tile) && GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenaryOnBridge(ti);
+			/* Fall further */
+		case MP_STREET: case MP_STATION:
+			DrawCatenaryRailway(ti);
+			break;
+		default:
+			break;
+	}
+}
+
--- a/engine_gui.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/engine_gui.c	Wed Mar 29 16:30:26 2006 +0000
@@ -20,9 +20,10 @@
 {
 	if (engine < NUM_TRAIN_ENGINES) {
 		switch (GetEngine(engine)->railtype) {
-			case RAILTYPE_RAIL:   return STR_8102_RAILROAD_LOCOMOTIVE;
-			case RAILTYPE_MONO:   return STR_8106_MONORAIL_LOCOMOTIVE;
-			case RAILTYPE_MAGLEV: return STR_8107_MAGLEV_LOCOMOTIVE;
+			case RAILTYPE_RAIL:     return STR_8102_RAILROAD_LOCOMOTIVE;
+			case RAILTYPE_ELECTRIC: return STR_8102_RAILROAD_LOCOMOTIVE;
+			case RAILTYPE_MONO:     return STR_8106_MONORAIL_LOCOMOTIVE;
+			case RAILTYPE_MAGLEV:   return STR_8107_MAGLEV_LOCOMOTIVE;
 		}
 	}
 
--- a/gfxinit.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/gfxinit.c	Wed Mar 29 16:30:26 2006 +0000
@@ -358,6 +358,9 @@
 	load_index = SPR_AUTORAIL_BASE;
 	load_index += LoadGrfFile("autorail.grf", load_index, i++);
 
+	assert(load_index == SPR_ELRAIL_BASE);
+	load_index += LoadGrfFile("elrailsw.grf", load_index, i++);
+
 	assert(load_index == SPR_2CCMAP_BASE);
 	load_index += LoadGrfFile("2ccmap.grf", load_index, i++);
 
--- a/lang/english.txt	Wed Mar 29 16:28:41 2006 +0000
+++ b/lang/english.txt	Wed Mar 29 16:30:26 2006 +0000
@@ -1443,6 +1443,7 @@
 STR_1007_ALREADY_BUILT                                          :{WHITE}...already built
 STR_1008_MUST_REMOVE_RAILROAD_TRACK                             :{WHITE}Must remove railway track first
 STR_100A_RAILROAD_CONSTRUCTION                                  :{WHITE}Railway Construction
+STR_TITLE_ELRAIL_CONSTRUCTION                                   :{WHITE}Electrified Railway Construction
 STR_100B_MONORAIL_CONSTRUCTION                                  :{WHITE}Monorail Construction
 STR_100C_MAGLEV_CONSTRUCTION                                    :{WHITE}MagLev Construction
 STR_100D_SELECT_RAIL_BRIDGE                                     :{WHITE}Select Rail Bridge
@@ -1454,6 +1455,7 @@
 STR_1013_CAN_T_REMOVE_SIGNALS_FROM                              :{WHITE}Can't remove signals from here...
 STR_1014_TRAIN_DEPOT_ORIENTATION                                :{WHITE}Train Depot Orientation
 STR_1015_RAILROAD_CONSTRUCTION                                  :Railway construction
+STR_TOOLB_ELRAIL_CONSTRUCTION                                   :Electrified Railway construction
 STR_1016_MONORAIL_CONSTRUCTION                                  :Monorail construction
 STR_1017_MAGLEV_CONSTRUCTION                                    :MagLev construction
 STR_1018_BUILD_RAILROAD_TRACK                                   :{BLACK}Build railway track
@@ -2410,6 +2412,7 @@
 STR_881A_TRAINS_CAN_ONLY_BE_ALTERED                             :{WHITE}Trains can only be altered when stopped inside a depot
 STR_881B_TRAINS                                                 :{WHITE}{COMPANY} - {COMMA} Train{P "" s}
 STR_881C_NEW_RAIL_VEHICLES                                      :{WHITE}New Rail Vehicles
+STR_NEW_ELRAIL_VEHICLES                                         :{WHITE}New Electric Rail Vehicles
 STR_881D_NEW_MONORAIL_VEHICLES                                  :{WHITE}New Monorail Vehicles
 STR_881E_NEW_MAGLEV_VEHICLES                                    :{WHITE}New Maglev Vehicles
 STR_881F_BUILD_VEHICLE                                          :{BLACK}Build Vehicle
@@ -2810,6 +2813,7 @@
 ############ Lists rail types
 
 STR_RAIL_VEHICLES                                               :Rail Vehicles
+STR_ELRAIL_VEHICLES                                             :Electrified Rail Vehicles
 STR_MONORAIL_VEHICLES                                           :Monorail Vehicles
 STR_MAGLEV_VEHICLES                                             :Maglev Vehicles
 
--- a/misc.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/misc.c	Wed Mar 29 16:30:26 2006 +0000
@@ -401,8 +401,6 @@
 	byte transit_days_table_1[NUM_CARGO];
 	byte transit_days_table_2[NUM_CARGO];
 
-	byte railwagon_by_cargo[3][NUM_CARGO];
-
 	byte road_veh_by_cargo_start[NUM_CARGO];
 	byte road_veh_by_cargo_count[NUM_CARGO];
 } LandscapePredefVar;
@@ -419,7 +417,6 @@
 
 	lpd = &_landscape_predef_var[_opt.landscape];
 
-	memcpy(_cargoc.ai_railwagon, lpd->railwagon_by_cargo, sizeof(lpd->railwagon_by_cargo));
 	memcpy(_cargoc.ai_roadveh_start, lpd->road_veh_by_cargo_start,sizeof(lpd->road_veh_by_cargo_start));
 	memcpy(_cargoc.ai_roadveh_count, lpd->road_veh_by_cargo_count,sizeof(lpd->road_veh_by_cargo_count));
 
--- a/newgrf.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/newgrf.c	Wed Mar 29 16:30:26 2006 +0000
@@ -355,6 +355,9 @@
 					engclass = 0;
 				} else if (traction <= 0x27) {
 					engclass = 1;
+				} else if (traction <= 0x31) {
+					engclass = 2;
+					ei[i].railtype = RAILTYPE_ELECTRIC;
 				} else if (traction <= 0x41) {
 					engclass = 2;
 				} else {
@@ -2309,12 +2312,8 @@
 	                   | (1 << 0x18)  /* newrvs */
 	                   | (1 << 0x19)  /* newships */
 	                   | (1 << 0x1A)  /* newplanes */
-	                   | (_patches.signal_side ? (1 << 0x1B) : 0);          /* signalsontrafficside */
-	                   /* Uncomment following if you want to fool the GRF file.
-	                    * Some GRF files will refuse to load without this
-	                    * but you can still squeeze something from them even
-	                    * without the support - i.e. USSet. --pasky */
-			               //| (1 << 0x1C); /* electrifiedrailway */
+	                   | (_patches.signal_side ? (1 << 0x1B) : 0)           /* signalsontrafficside */
+	                   | (1 << 0x1C); /* electrifiedrailway */
 
 	_ttdpatch_flags[2] = (_patches.build_on_slopes ? (1 << 0x0D) : 0)       /* buildonslopes */
 	                   | (_patches.build_on_slopes ? (1 << 0x15) : 0)       /* buildoncoasts */
--- a/npf.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/npf.c	Wed Mar 29 16:30:26 2006 +0000
@@ -587,7 +587,7 @@
 	/* check correct rail type (mono, maglev, etc) */
 	if (type == TRANSPORT_RAIL) {
 		RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
-		if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type))
+		if (!HASBIT(aystar->user_data[NPF_RAILTYPES], dst_type))
 			return;
 	}
 
@@ -661,7 +661,7 @@
  * multiple targets that are spread around, we should perform a breadth first
  * search by specifiying CalcZero as our heuristic.
  */
-static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailType railtype, uint reverse_penalty)
+static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
 {
 	int r;
 	NPFFoundTargetData result;
@@ -703,7 +703,7 @@
 	/* Initialize user_data */
 	_npf_aystar.user_data[NPF_TYPE] = type;
 	_npf_aystar.user_data[NPF_OWNER] = owner;
-	_npf_aystar.user_data[NPF_RAILTYPE] = railtype;
+	_npf_aystar.user_data[NPF_RAILTYPES] = railtypes;
 
 	/* GO! */
 	r = AyStarMain_Main(&_npf_aystar);
@@ -721,7 +721,7 @@
 	return result;
 }
 
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
 {
 	AyStarNode start1;
 	AyStarNode start2;
@@ -735,15 +735,15 @@
 	start2.direction = trackdir2;
 	start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
 
-	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtype, 0);
+	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtypes, 0);
 }
 
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes)
 {
-	return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtype);
+	return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtypes);
 }
 
-NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty)
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
 {
 	AyStarNode start1;
 	AyStarNode start2;
@@ -759,15 +759,15 @@
 
 	/* perform a breadth first search. Target is NULL,
 	 * since we are just looking for any depot...*/
-	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtype, reverse_penalty);
+	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtypes, reverse_penalty);
 }
 
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes)
 {
-	return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtype, 0);
+	return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtypes, 0);
 }
 
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes)
 {
 	/* Okay, what we're gonna do. First, we look at all depots, calculate
 	 * the manhatten distance to get to each depot. We then sort them by
--- a/npf.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/npf.h	Wed Mar 29 16:30:26 2006 +0000
@@ -38,7 +38,7 @@
 enum { /* Indices into AyStar.userdata[] */
 	NPF_TYPE = 0, /* Contains a TransportTypes value */
 	NPF_OWNER, /* Contains an Owner value */
-	NPF_RAILTYPE, /* Contains the RailType value of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */
+	NPF_RAILTYPES, /* Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */
 };
 
 enum { /* Indices into AyStarNode.userdata[] */
@@ -64,28 +64,28 @@
 /* Will search from the given tile and direction, for a route to the given
  * station for the given transport type. See the declaration of
  * NPFFoundTargetData above for the meaning of the result. */
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype);
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes);
 
 /* Will search as above, but with two start nodes, the second being the
  * reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which
  * direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype);
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes);
 
 /* Will search a route to the closest depot. */
 
 /* Search using breadth first. Good for little track choice and inaccurate
  * heuristic, such as railway/road.*/
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype);
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes);
 /* Same as above but with two start nodes, the second being the reverse. Call
  * NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path
  * orginated. All pathfs from the second node will have the given
  * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full
  * tile).
  */
-NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty);
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty);
 /* Search by trying each depot in order of Manhattan Distance. Good for lots
  * of choices and accurate heuristics, such as water. */
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype);
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes);
 
 void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);
 
--- a/openttd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/openttd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -1238,6 +1238,75 @@
 		}
 	}
 
+	/* Elrails got added in rev 24 */
+	if (CheckSavegameVersion(24)) {
+		Vehicle* v;
+		uint i;
+		TileIndex t;
+		bool make_elrail = false;
+
+		for (i = 0; i < lengthof(_engines); i++) {
+			Engine* e = GetEngine(i);
+			if (e->type == VEH_Train &&
+					(e->railtype != RAILTYPE_RAIL || RailVehInfo(i)->engclass == 2)) {
+				e->railtype++;
+			}
+		}
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_Train) {
+				RailType rt = GetEngine(v->engine_type)->railtype;
+
+				v->u.rail.railtype = rt;
+				if (rt == RAILTYPE_ELECTRIC) make_elrail = true;
+			}
+		}
+
+		/* .. so we convert the entire map from normal to elrail (so maintain "fairness") */
+		for (t = 0; t < MapSize(); t++) {
+			switch (GetTileType(t)) {
+				case MP_RAILWAY:
+					if (GetRailType(t) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1);
+					break;
+
+				case MP_STREET:
+					if (IsLevelCrossing(t) && (GetRailTypeCrossing(t) > RAILTYPE_RAIL || make_elrail)) AB(_m[t].m4, 0, 4, 1);
+					break;
+
+				case MP_STATION:
+					if (_m[t].m5 < 8 && (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail)) AB(_m[t].m3, 0, 4, 1);
+					break;
+
+				case MP_TUNNELBRIDGE:
+					if (GB(_m[t].m5, 4, 4) == 0) { // tunnel?
+						if (GB(_m[t].m5, 2, 2) == 0) { // railway tunnel?
+							if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1);
+						}
+					} else {
+						if (GB(_m[t].m5, 1, 2) == 0) { // railway bridge?
+							if (GB(_m[t].m5, 6, 1) == 0) { // bridge ending?
+								if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1);
+							} else {
+								if (GB(_m[t].m3, 4, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 4, 4, 1);
+							}
+						}
+						if ((_m[t].m5 & 0xF8) == 0xE0) { // bridge middle part with rails below?
+							if (GB(_m[t].m3, 0, 4) > RAILTYPE_RAIL || make_elrail) AB(_m[t].m3, 0, 4, 1);
+						}
+					}
+					break;
+
+				default:
+					break;
+			}
+		}
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v);
+		}
+
+	}
+
 	/* In version 16.1 of the savegame a player can decide if trains, which get
 	 * replaced, shall keep their old length. In all prior versions, just default
 	 * to false */
--- a/openttd.dsp	Wed Mar 29 16:28:41 2006 +0000
+++ b/openttd.dsp	Wed Mar 29 16:30:26 2006 +0000
@@ -209,6 +209,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\elrail.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\engine.c
 # End Source File
 # Begin Source File
--- a/openttd.vcproj	Wed Mar 29 16:28:41 2006 +0000
+++ b/openttd.vcproj	Wed Mar 29 16:30:26 2006 +0000
@@ -215,6 +215,9 @@
 				RelativePath=".\economy.c">
 			</File>
 			<File
+				RelativePath=".\elrail.c">
+			</File>
+			<File
 				RelativePath=".\engine.c">
 			</File>
 			<File
--- a/pathfind.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/pathfind.c	Wed Mar 29 16:30:26 2006 +0000
@@ -454,7 +454,8 @@
 	void *userdata;
 	TileIndex dest;
 
-	byte tracktype;
+	TransportType tracktype;
+	RailTypeMask railtypes;
 	uint maxlength;
 
 	HashLink *new_link;
@@ -791,6 +792,11 @@
 			 * bits, not just reachable ones, to prevent infinite loops. */
 			if (bits == 0 || TracksOverlap(allbits)) break;
 
+			if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
+				bits = 0;
+				break;
+			}
+
 			/* If we reach here, the tile has exactly one track, and this
 			 track is reachable => Rail segment continues */
 
@@ -926,14 +932,15 @@
 
 
 // new pathfinder for trains. better and faster.
-void NewTrainPathfind(TileIndex tile, TileIndex dest, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
+void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
 {
 	NewTrackPathFinder tpf;
 
 	tpf.dest = dest;
 	tpf.userdata = data;
 	tpf.enum_proc = enum_proc;
-	tpf.tracktype = 0;
+	tpf.tracktype = TRANSPORT_RAIL;
+	tpf.railtypes = railtypes;
 	tpf.maxlength = min(_patches.pf_maxlength * 3, 10000);
 	tpf.nstack = 0;
 	tpf.new_link = tpf.links;
--- a/pathfind.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/pathfind.h	Wed Mar 29 16:30:26 2006 +0000
@@ -68,6 +68,6 @@
 } FindLengthOfTunnelResult;
 FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection direction);
 
-void NewTrainPathfind(TileIndex tile, TileIndex dest, DiagDirection direction, NTPEnumProc* enum_proc, void* data);
+void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data);
 
 #endif /* PATHFIND_H */
--- a/player.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/player.h	Wed Mar 29 16:30:26 2006 +0000
@@ -248,6 +248,7 @@
 {
 	if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV;
 	if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO;
+	if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC;
 	return RAILTYPE_RAIL;
 }
 
--- a/rail.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/rail.h	Wed Mar 29 16:30:26 2006 +0000
@@ -9,7 +9,6 @@
 #include "rail_map.h"
 #include "tile.h"
 
-
 /** These are a combination of tracks and directions. Values are 0-5 in one
 direction (corresponding to the Track enum) and 8-13 in the other direction. */
 typedef enum Trackdirs {
@@ -110,8 +109,11 @@
 	/** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */
 	SpriteID snow_offset;
 
-	/** bitmask to the OTHER railtypes that can be used by an engine of THIS railtype */
-	byte compatible_railtypes;
+	/** bitmask to the OTHER railtypes on which an engine of THIS railtype generates power */
+	RailTypeMask powered_railtypes;
+
+	/** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */
+	RailTypeMask compatible_railtypes;
 
 	/**
 	 * Offset between the current railtype and normal rail. This means that:<p>
@@ -478,6 +480,11 @@
 	return HASBIT(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype);
 }
 
+static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype)
+{
+	return HASBIT(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype);
+}
+
 /**
  * Checks if the given tracks overlap, ie form a crossing. Basically this
  * means when there is more than one track on the tile, exept when there are
@@ -497,4 +504,13 @@
 
 void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
 void DrawDefaultWaypointSprite(int x, int y, RailType railtype);
+
+/**
+ * Draws overhead wires and pylons for electric railways.
+ * @param ti The TileInfo struct of the tile being drawn
+ * @see DrawCatenaryRailway
+ */
+void DrawCatenary(const TileInfo *ti);
+
+uint GetRailFoundation(uint tileh, uint bits);
 #endif /* RAIL_H */
--- a/rail_cmd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/rail_cmd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -896,11 +896,13 @@
 	return CmdSignalTrackHelper(x, y, flags, p1, SETBIT(p2, 0));
 }
 
-typedef int32 DoConvertRailProc(TileIndex tile, uint totype, bool exec);
+typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
 
-static int32 DoConvertRail(TileIndex tile, uint totype, bool exec)
+static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
 {
-	if (!CheckTileOwnership(tile) || !EnsureNoVehicle(tile)) return CMD_ERROR;
+	if (!CheckTileOwnership(tile)) return CMD_ERROR;
+
+	if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
 
 	// tile is already of requested type?
 	if (GetRailType(tile) == totype) return CMD_ERROR;
@@ -1297,6 +1299,9 @@
 		if (track & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w);
 		if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e);
 	}
+
+	if (GB(_m[ti->tile].m3, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 }
 
 static void DrawTile_Track(TileInfo *ti)
@@ -1388,6 +1393,8 @@
 
 				DrawGroundSprite(image);
 
+				if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 				foreach_draw_tile_seq(seq, cust->seq) {
 					DrawSpecialBuilding(
 						seq->image + relocation, 0, ti,
@@ -1420,6 +1427,8 @@
 
 		DrawGroundSprite(image);
 
+		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 		for (; drss->image != 0; drss++) {
 			DrawSpecialBuilding(
 				drss->image, type < 4 ? rti->total_offset : 0, ti,
--- a/rail_map.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/rail_map.h	Wed Mar 29 16:30:26 2006 +0000
@@ -32,13 +32,16 @@
 
 
 typedef enum RailTypes {
-	RAILTYPE_RAIL   = 0,
-	RAILTYPE_MONO   = 1,
-	RAILTYPE_MAGLEV = 2,
+	RAILTYPE_RAIL     = 0,
+	RAILTYPE_ELECTRIC = 1,
+	RAILTYPE_MONO     = 2,
+	RAILTYPE_MAGLEV   = 3,
 	RAILTYPE_END,
 	INVALID_RAILTYPE = 0xFF
 } RailType;
 
+typedef byte RailTypeMask;
+
 static inline RailType GetRailType(TileIndex t)
 {
 	return (RailType)GB(_m[t].m3, 0, 4);
--- a/railtypes.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/railtypes.h	Wed Mar 29 16:30:26 2006 +0000
@@ -40,8 +40,11 @@
 		/* Offset of snow tiles */
 		SPR_RAIL_SNOW_OFFSET,
 
+		/* Powered railtypes */
+		1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC,
+
 		/* Compatible railtypes */
-		(1 << RAILTYPE_RAIL),
+		1 << RAILTYPE_RAIL | 1 << RAILTYPE_ELECTRIC,
 
 		/* main offset */
 		0,
@@ -50,6 +53,56 @@
 		0,
 	},
 
+	/** Electrified railway */
+	{ /* Main Sprites */
+		{ SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X,
+			SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST,
+			SPR_CROSSING_OFF_X_RAIL,
+			SPR_TUNNEL_ENTRY_REAR_RAIL
+		},
+
+		/* GUI sprites */
+		{
+			SPR_BUILD_NS_ELRAIL,
+			SPR_BUILD_X_ELRAIL,
+			SPR_BUILD_EW_ELRAIL,
+			SPR_BUILD_Y_ELRAIL,
+			SPR_OPENTTD_BASE + 0,
+			0x50E,
+			SPR_BUILD_TUNNEL_ELRAIL,
+			SPR_IMG_CONVERT_RAIL
+		},
+
+		{
+			SPR_CURSOR_NS_ELRAIL,
+			SPR_CURSOR_SWNE_ELRAIL,
+			SPR_CURSOR_EW_ELRAIL,
+			SPR_CURSOR_NWSE_ELRAIL,
+			SPR_CURSOR_AUTORAIL,
+			SPR_CURSOR_RAIL_DEPOT,
+			SPR_CURSOR_TUNNEL_ELRAIL,
+			SPR_CURSOR_CONVERT_RAIL
+		},
+
+		/* strings */
+		{ STR_TITLE_ELRAIL_CONSTRUCTION },
+
+		/* Offset of snow tiles */
+		SPR_RAIL_SNOW_OFFSET,
+
+		/* Powered railtypes */
+		1 << RAILTYPE_ELECTRIC,
+
+		/* Compatible railtypes */
+		1 << RAILTYPE_ELECTRIC | 1 << RAILTYPE_RAIL,
+
+		/* main offset */
+		0,
+
+		/* bridge offset */
+		0
+	},
+
 	/** Monorail */
 	{ /* Main Sprites */
 		{ SPR_MONO_TRACK_Y, SPR_MONO_TRACK_N_S, SPR_MONO_TRACK_BASE, SPR_MONO_SINGLE_Y, SPR_MONO_SINGLE_X,
@@ -83,8 +136,11 @@
 		/* Offset of snow tiles */
 		SPR_MONO_SNOW_OFFSET,
 
+		/* Powered railtypes */
+		1 << RAILTYPE_MONO,
+
 		/* Compatible Railtypes */
-		(1 << RAILTYPE_MONO),
+		1 << RAILTYPE_MONO,
 
 		/* main offset */
 		82,
@@ -126,8 +182,11 @@
 		/* Offset of snow tiles */
 		SPR_MGLV_SNOW_OFFSET,
 
+		/* Powered railtypes */
+		1 << RAILTYPE_MAGLEV,
+
 		/* Compatible Railtypes */
-		(1 << RAILTYPE_MAGLEV),
+		1 << RAILTYPE_MAGLEV,
 
 		/* main offset */
 		164,
--- a/road_cmd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/road_cmd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -787,6 +787,7 @@
 			}
 
 			DrawGroundSprite(image);
+			if (GB(_m[ti->tile].m4, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 			break;
 		}
 
--- a/saveload.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/saveload.c	Wed Mar 29 16:30:26 2006 +0000
@@ -30,7 +30,7 @@
 #include "variables.h"
 #include <setjmp.h>
 
-const uint16 SAVEGAME_VERSION = 23;
+const uint16 SAVEGAME_VERSION = 24;
 uint16 _sl_version;       /// the major savegame version identifier
 byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!
 
--- a/station_cmd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/station_cmd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -1959,6 +1959,8 @@
 	// but this is something else. If AI builds station with 114 it looks all weird
 	DrawGroundSprite(image);
 
+	if (GB(_m[ti->tile].m3, 0, 4) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 	foreach_draw_tile_seq(dtss, t->seq) {
 		image = dtss->image + relocation;
 		image += offset;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/table/elrail_data.h	Wed Mar 29 16:30:26 2006 +0000
@@ -0,0 +1,362 @@
+/* $Id */
+/** @file elrail_data.h Stores all the data for overhead wire and pylon drawing. @see elrail.c */
+
+#ifndef ELRAIL_DATA_H
+#define ELRAIL_DATA_H
+
+/** Tile Location group. This defines whether the X and or Y coordinate of a tile is even */
+typedef enum TLG {
+	XEVEN_YEVEN = 0,
+	XEVEN_YODD  = 1,
+	XODD_YEVEN  = 2,
+	XODD_YODD   = 3,
+	TLG_END
+} TLG;
+
+/** When determining the pylon configuration on the edge, two tiles are taken into account:
+  * the tile being drawn itself (the home tile, the one in ti->tile), and the neighbouring tile
+  */
+typedef enum {
+	TS_HOME      = 0,
+	TS_NEIGHBOUR = 1,
+
+	TS_END
+} TileSource;
+
+enum {
+	TRACKS_AT_PCP = 6
+};
+
+/** Which PPPs are possible at all on a given PCP */
+static byte AllowedPPPonPCP[DIAGDIR_END] = {
+	1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW,
+	1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+	1 << DIR_N | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W | 1 << DIR_NW,
+	1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+};
+
+/** Which of the PPPs are inside the tile. For the two PPPs on the tile border the following system is used:
+  if you rotate the PCP so that it is in the north, the eastern PPP belongs to the tile. */
+static byte OwnedPPPonPCP[DIAGDIR_END] = {
+	1 << DIR_SE | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
+	1 << DIR_N | 1 << DIR_SW | 1 << DIR_W | 1 << DIR_NW,
+	1 << DIR_N | 1 << DIR_NE | 1 << DIR_E | 1 << DIR_NW,
+	1 << DIR_NE | 1 << DIR_E | 1 << DIR_SE | 1 << DIR_S
+};
+
+/** Preferred points of each trackbit. Those are the ones perpendicular to the track, plus the point in
+  extension of the track (to mark end-of-track).*/
+static byte PreferredPPPofTrackBitAtPCP[TRACK_END][DIAGDIR_END] = {
+	{1 << DIR_NE | 1 << DIR_SE | 1 << DIR_NW, 0xFF, 1 << DIR_SE | 1 << DIR_SW | 1 << DIR_NW, 0xFF }, /* X */
+	{0xFF, 1 << DIR_NE | 1 << DIR_SE | 1 << DIR_SW, 0xFF, 1 << DIR_SW | 1 << DIR_NW | 1 << DIR_NE }, /* Y */
+	{1 << DIR_E | 1 << DIR_N | 1 << DIR_S, 0xFF, 0xFF, 1 << DIR_W | 1 << DIR_N | 1 << DIR_S},        /* UPPER */
+	{0xFF, 1 << DIR_E | 1 << DIR_N | 1 << DIR_S, 1 << DIR_W | 1 << DIR_N | 1 << DIR_S, 0xFF},        /* LOWER */
+	{0xFF, 0xFF, 1 << DIR_S | 1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_E | 1 << DIR_W},        /* LEFT */
+	{1 << DIR_N | 1 << DIR_E | 1 << DIR_W, 1 << DIR_S | 1 << DIR_E | 1 << DIR_W, 0xFF, 0xFF},        /* RIGHT */
+};
+
+#define NUM_IGNORE_GROUPS 3
+/** In case we have a staight line, we place pylon only every two tiles, so there are certain tiles
+  which we ignore. A straight line is found if we have exactly two preferred points.*/
+static byte IgnoredPCP[NUM_IGNORE_GROUPS][TLG_END][DIAGDIR_END] = {
+	{
+		{1 << DIR_N  | 1 << DIR_S , 1 << DIR_NE | 1 << DIR_SW, 1 << DIR_NW | 1 << DIR_SE, 1 << DIR_W  | 1 << DIR_E},
+		{0xFF , 1 << DIR_E | 1 << DIR_W, 1 << DIR_NW | 1 << DIR_SE, 1 << DIR_NE | 1 << DIR_SW},
+		{1 << DIR_NW | 1 << DIR_SE, 1 << DIR_NE | 1 << DIR_SW, 1 << DIR_N  | 1 << DIR_S , 0xFF},
+		{1 << DIR_NW | 1 << DIR_SE, 0xFF , 0xFF, 1 << DIR_NE | 1 << DIR_SW}
+	},
+	{
+		{1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_S, 0xFF, 1 << DIR_E | 1 << DIR_W},
+		{0xFF, 0xFF, 1 << DIR_N | 1 << DIR_S, 1 << DIR_N | 1 << DIR_S},
+		{0xFF, 1 << DIR_E | 1 << DIR_W, 1 << DIR_E | 1 << DIR_W, 1 << DIR_N | 1 << DIR_S},
+		{1 << DIR_N | 1 << DIR_S, 1 << DIR_N | 1 << DIR_S, 0xFF, 1 << DIR_E | 1 << DIR_W}
+	},
+	{
+		{0xFF, 0xFF, 0xFF, 0xFF},
+		{0xFF, 0xFF, 1 << DIR_E | 1 << DIR_W, 0xFF},
+		{0xFF, 0xFF, 0xFF, 0xFF},
+		{1 << DIR_E | 1 << DIR_W, 0xFF, 0xFF, 0xFF}
+	}
+};
+
+/** Which pylons can definately NOT be built */
+static byte DisallowedPPPofTrackBitAtPCP[TRACK_END][DIAGDIR_END] = {
+	{1 << DIR_SW | 1 << DIR_NE, 0,           1 << DIR_SW | 1 << DIR_NE, 0          }, /* X */
+	{0,           1 << DIR_NW | 1 << DIR_SE, 0,           1 << DIR_NW | 1 << DIR_SE}, /* Y */
+	{1 << DIR_W | 1 << DIR_E,  0,           0,           1 << DIR_W | 1 << DIR_E }, /* UPPER */
+	{0,           1 << DIR_W | 1 << DIR_E,  1 << DIR_W | 1 << DIR_E,  0          }, /* LOWER */
+	{0,           0,           1 << DIR_S | 1 << DIR_N,  1 << DIR_N | 1 << DIR_S }, /* LEFT */
+	{1 << DIR_S | 1 << DIR_N,  1 << DIR_S | 1 << DIR_N,  0,           0,         }, /* RIGHT */
+};
+
+typedef struct {
+	SpriteID image;
+	int8 x_offset;
+	int8 y_offset;
+	int8 x_size;
+	int8 y_size;
+	int8 z_size;
+	int8 z_offset;
+} SortableSpriteStruct;
+
+enum {
+	/** Distance between wire and rail */
+	ELRAIL_ELEVATION = 8,
+	/** Corrects an off-by-one error in some places (tileh 12 and 9) (TODO -- find source of error) */
+	ELRAIL_ELEV_CORR = ELRAIL_ELEVATION + 1,
+	/** Wires that a draw one level higher than the north corner. */
+	ELRAIL_ELEVRAISE = ELRAIL_ELEVATION + TILE_HEIGHT
+};
+
+static const SortableSpriteStruct CatenarySpriteData[] = {
+/* X direction */
+	/* Flat tiles: */
+		/* Wires */
+	{ SPR_WIRE_X_SW,          0,  8, 16,  1,  1, ELRAIL_ELEVATION }, //! 0: Wire in X direction, pylon on the SW end only
+	{ SPR_WIRE_X_NE,          0,  8, 16,  1,  1, ELRAIL_ELEVATION }, //! 1: Wire in X direction, pylon on the NE end
+	{ SPR_WIRE_X_SHORT,       0,  8, 16,  1,  1, ELRAIL_ELEVATION }, //! 2: Wire in X direction, pylon on both ends
+
+	/* "up" tiles */
+		/* Wires */
+	{ SPR_WIRE_X_SW_UP,       0,  8, 16,  8,  1, ELRAIL_ELEVRAISE }, //! 3: Wire in X pitch up, pylon on the SW end only
+	{ SPR_WIRE_X_NE_UP,       0,  8, 16,  8,  1, ELRAIL_ELEVRAISE }, //! 4: Wire in X pitch up, pylon on the NE end
+	{ SPR_WIRE_X_SHORT_UP,    0,  8, 16,  8,  1, ELRAIL_ELEVRAISE }, //! 5: Wire in X pitch up, pylon on both ends
+
+	/* "down" tiles */
+		/* Wires */
+	{ SPR_WIRE_X_SW_DOWN,     0,  8, 16,  8,  1, ELRAIL_ELEV_CORR }, //! 6: Wire in X pitch down, pylon on the SW end
+	{ SPR_WIRE_X_NE_DOWN,     0,  8, 16,  8,  1, ELRAIL_ELEV_CORR }, //! 7: Wire in X pitch down, pylon on the NE end
+	{ SPR_WIRE_X_SHORT_DOWN,  0,  8, 16,  8,  1, ELRAIL_ELEV_CORR }, //! 8: Wire in X pitch down, pylon on both ends
+
+
+/* Y direction */
+	/* Flat tiles: */
+		/* Wires */
+	{ SPR_WIRE_Y_SE,          8,  0,  1, 16,  1, ELRAIL_ELEVATION }, //! 9: Wire in Y direction, pylon on the SE end only
+	{ SPR_WIRE_Y_NW,          8,  0,  1, 16,  1, ELRAIL_ELEVATION }, //!10: Wire in Y direction, pylon on the NW end
+	{ SPR_WIRE_Y_SHORT,       8,  0,  1, 16,  1, ELRAIL_ELEVATION }, //!11: Wire in Y direction, pylon on both ends
+
+	/* "up" tiles */
+		/* Wires */
+	{ SPR_WIRE_Y_SE_UP,       8,  0,  8, 16,  1, ELRAIL_ELEVRAISE }, //!12: Wire in Y pitch up, pylon on the SE end only
+	{ SPR_WIRE_Y_NW_UP,       8,  0,  8, 16,  1, ELRAIL_ELEVRAISE }, //!13: Wire in Y pitch up, pylon on the NW end
+	{ SPR_WIRE_Y_SHORT_UP,    8,  0,  8, 16,  1, ELRAIL_ELEVRAISE }, //!14: Wire in Y pitch up, pylon on both ends
+
+	/* "down" tiles */
+		/* Wires */
+	{ SPR_WIRE_Y_SE_DOWN,     8,  0,  8, 16,  1, ELRAIL_ELEV_CORR }, //!15: Wire in Y pitch down, pylon on the SE end
+	{ SPR_WIRE_Y_NW_DOWN,     8,  0,  8, 16,  1, ELRAIL_ELEV_CORR }, //!16: Wire in Y pitch down, pylon on the NW end
+	{ SPR_WIRE_Y_SHORT_DOWN,  8,  0,  8, 16,  1, ELRAIL_ELEV_CORR }, //!17: Wire in Y pitch down, pylon on both ends
+
+/* NS Direction */
+	{ SPR_WIRE_NS_SHORT,      8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!18: LEFT  trackbit wire, pylon on both ends
+	{ SPR_WIRE_NS_SHORT,      0,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!19: RIGHT trackbit wire, pylon on both ends
+
+	{ SPR_WIRE_NS_N,          8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!20: LEFT  trackbit wire, pylon on N end
+	{ SPR_WIRE_NS_N,          0,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!21: RIGHT trackbit wire, pylon on N end
+
+	{ SPR_WIRE_NS_S,          8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!22: LEFT  trackbit wire, pylon on S end
+	{ SPR_WIRE_NS_S,          0,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!23: RIGHT trackbit wire, pylon on S end
+
+/* EW Direction */
+	{ SPR_WIRE_EW_SHORT,      8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!24: UPPER trackbit wire, pylon on both ends
+	{ SPR_WIRE_EW_SHORT,     16,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!25: LOWER trackbit wire, pylon on both ends
+
+	{ SPR_WIRE_EW_W,          8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!28: UPPER trackbit wire, pylon on both ends
+	{ SPR_WIRE_EW_W,         16,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!29: LOWER trackbit wire, pylon on both ends
+
+	{ SPR_WIRE_EW_E,          8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!32: UPPER trackbit wire, pylon on both ends
+	{ SPR_WIRE_EW_E,         16,  8,  8,  8,  1, ELRAIL_ELEVATION }, //!33: LOWER trackbit wire, pylon on both ends
+
+/* Depots */
+	{ SPR_WIRE_DEPOT_SW,      0,  8,  8,  1,  1, ELRAIL_ELEVATION }, //!36: Wire for SW depot exit
+	{ SPR_WIRE_DEPOT_NW,      8,  0,  1,  8,  1, ELRAIL_ELEVATION }, //!37: Wire for NW depot exit
+	{ SPR_WIRE_DEPOT_NE,      0,  8,  8,  1,  1, ELRAIL_ELEVATION }, //!38: Wire for NE depot exit
+	{ SPR_WIRE_DEPOT_SE,      8,  0,  1,  8,  1, ELRAIL_ELEVATION }, //!39: Wire for SE depot exit
+};
+
+/** Refers to a certain element of the catenary.
+  * Identifiers for Wires:
+  * <ol><li>Direction of the wire</li>
+  * <li>Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces</li>
+  * <li>Place where a pylon shoule be</li></ol>
+  * Identifiers for Pylons:
+  * <ol><li>Direction of the wire</li>
+  * <li>Slope of the tile</li>
+  * <li>Position of the Pylon relative to the track</li>
+  * <li>Position of the Pylon inside the tile</li></ol>
+  */
+typedef enum {
+	WIRE_X_FLAT_SW,
+	WIRE_X_FLAT_NE,
+	WIRE_X_FLAT_BOTH,
+
+	WIRE_X_UP_SW,
+	WIRE_X_UP_NE,
+	WIRE_X_UP_BOTH,
+
+	WIRE_X_DOWN_SW,
+	WIRE_X_DOWN_NE,
+	WIRE_X_DOWN_BOTH,
+
+	WIRE_Y_FLAT_SE,
+	WIRE_Y_FLAT_NW,
+	WIRE_Y_FLAT_BOTH,
+
+	WIRE_Y_UP_SE,
+	WIRE_Y_UP_NW,
+	WIRE_Y_UP_BOTH,
+
+	WIRE_Y_DOWN_SE,
+	WIRE_Y_DOWN_NW,
+	WIRE_Y_DOWN_BOTH,
+
+	WIRE_NS_W_BOTH,
+	WIRE_NS_E_BOTH,
+
+	WIRE_NS_W_N,
+	WIRE_NS_E_N,
+
+	WIRE_NS_W_S,
+	WIRE_NS_E_S,
+
+	WIRE_EW_N_BOTH,
+	WIRE_EW_S_BOTH,
+
+	WIRE_EW_N_W,
+	WIRE_EW_S_W,
+
+	WIRE_EW_N_E,
+	WIRE_EW_S_E,
+
+	WIRE_DEPOT_SW,
+	WIRE_DEPOT_NW,
+	WIRE_DEPOT_NE,
+	WIRE_DEPOT_SE,
+
+	INVALID_CATENARY = 0xFF
+} CatenarySprite;
+
+/* This array stores which track bits can meet at a tile edge */
+static const Track PPPtracks[DIAGDIR_END][TRACKS_AT_PCP] = {
+	{TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+	{TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+	{TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+	{TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
+};
+
+/* takes each of the 8 track bits from the array above and
+   assigns it to the home tile or neighbour tile */
+static const TileSource trackorigin[DIAGDIR_END][TRACKS_AT_PCP] = {
+	{TS_HOME, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     },
+	{TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_HOME     },
+	{TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     , TS_HOME     , TS_NEIGHBOUR},
+	{TS_HOME, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR},
+};
+
+/* Several PPPs maybe exist, here they are sorted in order of preference. */
+static const Direction PPPorder[DIAGDIR_END][TLG_END][DIR_END] = {    /*  X  -  Y  */
+	{   /* PCP 0 */
+		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - evn */
+		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - odd */
+		{DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - evn */
+		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - odd */
+	}, {/* PCP 1 */
+		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - evn */
+		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - odd */
+		{DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - evn */
+		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - odd */
+	}, {/* PCP 2 */
+		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - evn */
+		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - odd */
+		{DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_N, DIR_E, DIR_S, DIR_W}, /* odd - evn */
+		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - odd */
+	}, {/* PCP 3 */
+		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - evn */
+		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - odd */
+		{DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - evn */
+		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - odd */
+	}
+};
+/* Geometric placement of the PCP relative to the tile origin */
+static const char x_pcp_offsets[DIAGDIR_END] = {0,  8, 15, 8};
+static const char y_pcp_offsets[DIAGDIR_END] = {8, 15,  8, 0};
+/* Geometric placement of the PPP relative to the PCP*/
+static const char x_ppp_offsets[DIR_END] = {-3, -4, -3,  0, +3, +4, +3,  0};
+static const char y_ppp_offsets[DIR_END] = {-3,  0, +3, +4, +3,  0, -3, -4};
+/* The type of pylon to draw at each PPP */
+static const SpriteID pylons_normal[] = {
+	SPR_PYLON_EW_N,
+	SPR_PYLON_Y_NE,
+	SPR_PYLON_NS_E,
+	SPR_PYLON_X_SE,
+	SPR_PYLON_EW_S,
+	SPR_PYLON_Y_SW,
+	SPR_PYLON_NS_W,
+	SPR_PYLON_X_NW
+};
+
+static const SpriteID pylons_bridge[] = {
+	SPR_PYLON_X_NW,
+	SPR_PYLON_X_SE,
+	SPR_PYLON_Y_NE,
+	SPR_PYLON_Y_SW
+};
+
+/* Maps a track bit onto two PCP positions */
+static const byte PCPpositions[TRACK_END][2] = {
+	{0, 2}, /* X */
+	{1, 3}, /* Y */
+	{3, 0}, /* UPPER */
+	{1, 2}, /* LOWER */
+	{2, 3}, /* LEFT */
+	{0, 1}, /* RIGHT */
+};
+
+/* Selects a Wire (with white and grey ends) depending on whether:
+   a) none (should never happen)
+   b) the first
+   c) the second
+   d) both
+   PCP exists.*/
+static const CatenarySprite Wires[5][TRACK_END][4] = {
+	{ /* Tileh == 0 */
+		{INVALID_CATENARY, WIRE_X_FLAT_NE, WIRE_X_FLAT_SW, WIRE_X_FLAT_BOTH},
+		{INVALID_CATENARY, WIRE_Y_FLAT_SE, WIRE_Y_FLAT_NW, WIRE_Y_FLAT_BOTH},
+		{INVALID_CATENARY, WIRE_EW_N_W, WIRE_EW_N_E, WIRE_EW_N_BOTH},
+		{INVALID_CATENARY, WIRE_EW_S_E, WIRE_EW_S_W, WIRE_EW_S_BOTH},
+		{INVALID_CATENARY, WIRE_NS_W_S, WIRE_NS_W_N, WIRE_NS_W_BOTH},
+		{INVALID_CATENARY, WIRE_NS_E_N, WIRE_NS_E_S, WIRE_NS_E_BOTH},
+	}, { /* Tileh == 3 */
+		{INVALID_CATENARY, WIRE_X_UP_NE, WIRE_X_UP_SW, WIRE_X_UP_BOTH},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+	}, { /* Tileh == 6 */
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, WIRE_Y_UP_SE, WIRE_Y_UP_NW, WIRE_Y_UP_BOTH},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+	}, { /* Tileh == 9 */
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, WIRE_Y_DOWN_SE, WIRE_Y_DOWN_NW, WIRE_Y_DOWN_BOTH},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+	}, { /* Tileh == 12 */
+		{INVALID_CATENARY, WIRE_X_DOWN_NE, WIRE_X_DOWN_SW, WIRE_X_DOWN_BOTH},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
+	}
+};
+
+#endif /* ELRAIL_DATA_H */
+
--- a/table/engines.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/table/engines.h	Wed Mar 29 16:30:26 2006 +0000
@@ -27,11 +27,13 @@
 
 // Rail types
 // R = Conventional railway
+// E = Electrified railway
 // M = Monorail
 // L = MagLev
 #define R 0
-#define M 1
-#define L 2
+#define E 1
+#define M 2
+#define L 3
 // Climates
 // T = Temperate
 // A = Arctic
@@ -65,10 +67,10 @@
 	MK( 20454,  20,  22,  30, R,   A|S  ), /*  20 Turner Turbo (Diesel) */
 	MK( 16071,  20,  22,  30, R,   A|S  ), /*  21 MJS 1000 (Diesel) */
 	MK( 20820,  20,  20,  25, R, T      ), /*  22 SH '125' (Diesel) */
-	MK( 16437,  20,  23,  30, R, T      ), /*  23 SH '30' (Electric) */
-	MK( 19359,  20,  23,  80, R, T      ), /*  24 SH '40' (Electric) */
-	MK( 23376,  20,  25,  30, R, T      ), /*  25 'T.I.M.' (Electric) */
-	MK( 26298,  20,  25,  50, R, T      ), /*  26 'AsiaStar' (Electric) */
+	MK( 16437,  20,  23,  30, E, T      ), /*  23 SH '30' (Electric) */
+	MK( 19359,  20,  23,  80, E, T      ), /*  24 SH '40' (Electric) */
+	MK( 23376,  20,  25,  30, E, T      ), /*  25 'T.I.M.' (Electric) */
+	MK( 26298,  20,  25,  50, E, T      ), /*  26 'AsiaStar' (Electric) */
 	MW(  1827,  20,  20,  50, R, T|A|S|Y), /*  27 Passenger Carriage */
 	MW(  1827,  20,  20,  50, R, T|A|S|Y), /*  28 Mail Van */
 	MW(  1827,  20,  20,  50, R, T|A    ), /*  29 Coal Truck */
@@ -306,6 +308,7 @@
 #undef L
 #undef M
 #undef R
+#undef E
 
 /** Writes the properties of a rail vehicle into the RailVehicleInfo struct.
  * @see RailVehicleInfo
--- a/table/landscape_const.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/table/landscape_const.h	Wed Mar 29 16:30:26 2006 +0000
@@ -42,13 +42,6 @@
 			24, 255, 90, 255, 18, 28, 40, 255, 255, 255, 32, 30,
 		},
 
-		/* normal railveh by cargo */
-		{
-			{27, 29, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38},
-			{57, 59, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68},
-			{89, 91, 90, 92, 93, 94, 95, 96, 97, 98, 99, 100}
-		},
-
 		/* normal road veh by cargo start & count */
 		{116, 123, 126, 132, 135, 138, 141, 144, 147, 150, 153, 156},
 		{7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3}
@@ -95,14 +88,6 @@
 			24, 255, 90, 255, 18, 28, 40, 255, 255, 60, 40, 30
 		},
 
-		/* hilly railveh by cargo */
-		{
-			{27, 29, 28, 30, 31, 32, 33, 34, 35, 39, 37, 38},
-			{57, 59, 58, 60, 61, 62, 63, 64, 65, 69, 67, 68},
-			{89, 91, 90, 92, 93, 94, 95, 96, 97, 101, 99, 100}
-		},
-
-
 		/* hilly road veh by cargo start & count */
 		{116, 123, 126, 132, 135, 138, 141, 144, 147, 159, 153, 156},
 		{7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3},
@@ -150,13 +135,6 @@
 			24, 20, 90, 255, 15, 28, 40, 255, 255, 80, 255, 30
 		},
 
-		/* desert railveh by cargo */
-		{
-			{27, 43, 28, 30, 42, 32, 33, 34, 40, 41, 37, 38},
-			{57, 73, 58, 60, 72, 62, 63, 64, 70, 71, 67, 68},
-			{89, 105, 90, 92, 104, 94, 95, 96, 102, 103, 99, 100}
-		},
-
 		/* desert road veh by cargo start & count */
 		{116, 171, 126, 132, 168, 138, 141, 144, 162, 165, 153, 156},
 		{7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3}
@@ -203,13 +181,6 @@
 			24, 255, 90, 255, 30, 40, 60, 75, 25, 80, 255, 50
 		},
 
-		/* candy railveh by cargo */
-		{
-			{27, 44, 28, 50, 51, 49, 46, 48, 45, 47, 53, 52},
-			{57, 74, 58, 80, 81, 79, 76, 78, 75, 77, 83, 82},
-			{89, 106, 90, 112, 113, 111, 108, 110, 107, 109, 115, 114}
-		},
-
 		/* candy road veh by cargo start & count */
 		{116, 174, 126, 186, 192, 189, 183, 177, 180, 201, 198, 195},
 		{7, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3}
--- a/table/sprites.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/table/sprites.h	Wed Mar 29 16:30:26 2006 +0000
@@ -51,7 +51,8 @@
 	SPR_CANALS_BASE   = 5382,
 	SPR_SLOPES_BASE   = SPR_CANALS_BASE + 70,
 	SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78,
-	SPR_2CCMAP_BASE   = SPR_AUTORAIL_BASE + 55,
+	SPR_ELRAIL_BASE   = SPR_AUTORAIL_BASE + 55,
+	SPR_2CCMAP_BASE   = SPR_ELRAIL_BASE + 53,
 	SPR_OPENTTD_BASE  = SPR_2CCMAP_BASE + 256,
 
 	SPR_BLOT = SPR_OPENTTD_BASE + 29, // colored circle (mainly used as vehicle profit marker and for sever compatibility)
@@ -206,6 +207,54 @@
 	OFFSET_TILEH_13             = 19,
 	OFFSET_TILEH_14             = 16,
 
+	/* Elrail stuff */
+	/* Wires. First identifier is the direction of the track, second is the required placement of the pylon.
+	   "short" denotes a wire that requires a pylon on each end. Third identifier is the direction of the slope
+	   (in positive coordinate direction) */
+	SPR_WIRE_X_SHORT = SPR_ELRAIL_BASE + 3,
+	SPR_WIRE_Y_SHORT = SPR_ELRAIL_BASE + 4,
+	SPR_WIRE_EW_SHORT = SPR_ELRAIL_BASE + 5,
+	SPR_WIRE_NS_SHORT = SPR_ELRAIL_BASE + 6,
+	SPR_WIRE_X_SHORT_DOWN = SPR_ELRAIL_BASE + 7,
+	SPR_WIRE_Y_SHORT_UP = SPR_ELRAIL_BASE + 8,
+	SPR_WIRE_X_SHORT_UP = SPR_ELRAIL_BASE + 9,
+	SPR_WIRE_Y_SHORT_DOWN = SPR_ELRAIL_BASE + 10,
+
+	SPR_WIRE_X_SW = SPR_ELRAIL_BASE + 11,
+	SPR_WIRE_Y_SE = SPR_ELRAIL_BASE + 12,
+	SPR_WIRE_EW_E = SPR_ELRAIL_BASE + 13,
+	SPR_WIRE_NS_S = SPR_ELRAIL_BASE + 14,
+	SPR_WIRE_X_SW_DOWN = SPR_ELRAIL_BASE + 15,
+	SPR_WIRE_Y_SE_UP = SPR_ELRAIL_BASE + 16,
+	SPR_WIRE_X_SW_UP = SPR_ELRAIL_BASE + 17,
+	SPR_WIRE_Y_SE_DOWN = SPR_ELRAIL_BASE + 18,
+
+	SPR_WIRE_X_NE = SPR_ELRAIL_BASE + 19,
+	SPR_WIRE_Y_NW = SPR_ELRAIL_BASE + 20,
+	SPR_WIRE_EW_W = SPR_ELRAIL_BASE + 21,
+	SPR_WIRE_NS_N = SPR_ELRAIL_BASE + 22,
+	SPR_WIRE_X_NE_DOWN = SPR_ELRAIL_BASE + 23,
+	SPR_WIRE_Y_NW_UP = SPR_ELRAIL_BASE + 24,
+	SPR_WIRE_X_NE_UP = SPR_ELRAIL_BASE + 25,
+	SPR_WIRE_Y_NW_DOWN = SPR_ELRAIL_BASE + 26,
+
+	/* Tunnel entries */
+	SPR_WIRE_DEPOT_SW = SPR_ELRAIL_BASE + 27,
+	SPR_WIRE_DEPOT_NW = SPR_ELRAIL_BASE + 28,
+	SPR_WIRE_DEPOT_NE = SPR_ELRAIL_BASE + 29,
+	SPR_WIRE_DEPOT_SE = SPR_ELRAIL_BASE + 30,
+
+
+	/* Pylons, first identifier is the direction of the track, second the placement relative to the track */
+	SPR_PYLON_Y_NE = SPR_ELRAIL_BASE + 31,
+	SPR_PYLON_Y_SW = SPR_ELRAIL_BASE + 32,
+	SPR_PYLON_X_NW = SPR_ELRAIL_BASE + 33,
+	SPR_PYLON_X_SE = SPR_ELRAIL_BASE + 34,
+	SPR_PYLON_EW_N = SPR_ELRAIL_BASE + 35,
+	SPR_PYLON_EW_S = SPR_ELRAIL_BASE + 36,
+	SPR_PYLON_NS_W = SPR_ELRAIL_BASE + 37,
+	SPR_PYLON_NS_E = SPR_ELRAIL_BASE + 38,
+
 	/* sprites for airports and airfields*/
 	/* Small airports are AIRFIELD, everything else is AIRPORT */
 	SPR_HELIPORT                    = 2633,
@@ -955,6 +1004,13 @@
 	SPR_BUBBLE_ABSORB_3 = 4761,
 	SPR_BUBBLE_ABSORB_4 = 4762,
 
+	/* Electrified rail build menu */
+	SPR_BUILD_NS_ELRAIL = SPR_ELRAIL_BASE + 39,
+	SPR_BUILD_X_ELRAIL  = SPR_ELRAIL_BASE + 40,
+	SPR_BUILD_EW_ELRAIL = SPR_ELRAIL_BASE + 41,
+	SPR_BUILD_Y_ELRAIL  = SPR_ELRAIL_BASE + 42,
+	SPR_BUILD_TUNNEL_ELRAIL = SPR_ELRAIL_BASE + 47,
+
 	/* road_gui.c */
 	SPR_IMG_ROAD_NW       = 1309,
 	SPR_IMG_ROAD_NE       = 1310,
@@ -1034,9 +1090,15 @@
 	SPR_CURSOR_EW_MAGLEV      = 1273,
 	SPR_CURSOR_NWSE_MAGLEV    = 1274,
 
+	SPR_CURSOR_NS_ELRAIL      = SPR_ELRAIL_BASE + 43,
+	SPR_CURSOR_SWNE_ELRAIL    = SPR_ELRAIL_BASE + 44,
+	SPR_CURSOR_EW_ELRAIL      = SPR_ELRAIL_BASE + 45,
+	SPR_CURSOR_NWSE_ELRAIL    = SPR_ELRAIL_BASE + 46,
+
 	SPR_CURSOR_RAIL_STATION   = 1300,
 
 	SPR_CURSOR_TUNNEL_RAIL    = 2434,
+	SPR_CURSOR_TUNNEL_ELRAIL  = SPR_ELRAIL_BASE + 48,
 	SPR_CURSOR_TUNNEL_MONO    = 2435,
 	SPR_CURSOR_TUNNEL_MAGLEV  = 2436,
 
--- a/train_cmd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/train_cmd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -72,6 +72,46 @@
 }
 
 /**
+ * Recalculates the cached total power of a train. Should be called when the consist is changed
+ * @param v First vehicle of the consist.
+ */
+void TrainPowerChanged(Vehicle* v)
+{
+	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
+	Vehicle* u;
+	uint32 power = 0;
+
+	for (u = v; u != NULL; u = u->next) {
+		const RailVehicleInfo *rvi_u;
+		bool engine_has_power = true;
+		bool wagon_has_power = true;
+
+		/* Power is not added for articulated parts */
+		if (IsArticulatedPart(u)) continue;
+
+		if (IsBridgeTile(u->tile) && IsBridgeMiddle(u->tile) && DiagDirToAxis(DirToDiagDir(u->direction)) == GetBridgeAxis(u->tile)) {
+			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeOnBridge(u->tile))) engine_has_power = false;
+			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeOnBridge(u->tile))) wagon_has_power = false;
+		} else {
+			if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false;
+			if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false;
+		}
+
+		rvi_u = RailVehInfo(u->engine_type);
+
+		if (engine_has_power) power += rvi_u->power;
+		if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
+			power += rvi_v->pow_wag_power;
+		}
+	}
+
+	if (v->u.rail.cached_power != power) {
+		v->u.rail.cached_power = power;
+		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
+	}
+}
+
+/**
  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
  * to/removed from the chain, and when the game is loaded.
  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
@@ -82,7 +122,6 @@
 	const RailVehicleInfo *rvi_v;
 	Vehicle *u;
 	uint16 max_speed = 0xFFFF;
-	uint32 power = 0;
 	EngineID first_engine;
 
 	assert(v->type == VEH_Train);
@@ -92,6 +131,7 @@
 	rvi_v = RailVehInfo(v->engine_type);
 	first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
 	v->u.rail.cached_total_length = 0;
+	v->u.rail.compatible_railtypes = 0;
 
 	for (u = v; u != NULL; u = u->next) {
 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
@@ -102,6 +142,7 @@
 
 		// update the 'first engine'
 		u->u.rail.first_engine = (v == u) ? INVALID_ENGINE : first_engine;
+		u->u.rail.railtype = GetEngine(u->engine_type)->railtype;
 
 		if (rvi_u->visual_effect != 0) {
 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
@@ -119,9 +160,6 @@
 		}
 
 		if (!IsArticulatedPart(u)) {
-			// power is the sum of the powers of all engines and powered wagons in the consist
-			power += rvi_u->power;
-
 			// check if its a powered wagon
 			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
 			if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) {
@@ -135,10 +173,15 @@
 				if (u->u.rail.cached_vis_effect < 0x40) {
 					/* wagon is powered */
 					SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
-					power += rvi_v->pow_wag_power;
 				}
 			}
 
+			/* Do not count powered wagons for the compatible railtypes, as wagons always
+			   have railtype normal */
+			if (rvi_u->power > 0) {
+				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
+			}
+
 			// max speed is the minimum of the speed limits of all vehicles in the consist
 			if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits)
 				if (rvi_u->max_speed != 0 && !UsesWagonOverride(u))
@@ -159,7 +202,8 @@
 
 	// store consist weight/max speed in cache
 	v->u.rail.cached_max_speed = max_speed;
-	v->u.rail.cached_power = power;
+
+	TrainPowerChanged(v);
 
 	// recalculate cached weights too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
 	TrainCargoChanged(v);
@@ -333,6 +377,7 @@
 	if (speed > 0) {
 		switch (v->u.rail.railtype) {
 			case RAILTYPE_RAIL:
+			case RAILTYPE_ELECTRIC:
 			case RAILTYPE_MONO:
 				force = power / speed; //[N]
 				force *= 22;
@@ -1468,6 +1513,9 @@
 
 		VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 	}
+
+	/* Update train's power incase tiles were different rail type */
+	TrainPowerChanged(v);
 }
 
 /* Check if the vehicle is a train and is on the tile we are testing */
@@ -1786,7 +1834,7 @@
 		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
 
 		assert (trackdir != INVALID_TRACKDIR);
-		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, NPF_INFINITE_PENALTY);
+		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
 		if (ftd.best_bird_dist == 0) {
 			/* Found target */
 			tfdd.tile = ftd.node.tile;
@@ -1805,7 +1853,7 @@
 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
 			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
 		}
-		NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 		if (tfdd.best_length == (uint)-1){
 			tfdd.reverse = true;
 			// search in backwards direction
@@ -1813,7 +1861,7 @@
 			if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
 				i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
 			}
-			NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+			NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 		}
 	}
 
@@ -1899,7 +1947,7 @@
 		// no smoke?
 		if ((RailVehInfo(engtype)->flags & RVI_WAGON && effect_type == 0) ||
 				disable_effect ||
-				GetEngine(engtype)->railtype > RAILTYPE_RAIL ||
+				GetEngine(engtype)->railtype > RAILTYPE_ELECTRIC ||
 				v->vehstatus & VS_HIDDEN ||
 				v->u.rail.track & 0xC0) {
 			continue;
@@ -1961,6 +2009,7 @@
 
 	switch (GetEngine(engtype)->railtype) {
 		case RAILTYPE_RAIL:
+		case RAILTYPE_ELECTRIC:
 			SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
 			break;
 
@@ -2112,7 +2161,7 @@
 		trackdir = GetVehicleTrackdir(v);
 		assert(trackdir != 0xff);
 
-		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
+		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
 
 		if (ftd.best_trackdir == 0xff) {
 			/* We are already at our target. Just do something */
@@ -2136,7 +2185,7 @@
 		fd.best_track = 0xFF;
 
 		NewTrainPathfind(tile - TileOffsByDir(enterdir), v->dest_tile,
-			enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+			v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
 
 		if (fd.best_track == 0xff) {
 			// blaha
@@ -2190,7 +2239,7 @@
 		assert(trackdir != 0xff);
 		assert(trackdir_rev != 0xff);
 
-		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
+		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
 		if (ftd.best_bird_dist != 0) {
 			/* We didn't find anything, just keep on going straight ahead */
 			reverse_best = false;
@@ -2206,7 +2255,7 @@
 			fd.best_bird_dist = (uint)-1;
 			fd.best_track_dist = (uint)-1;
 
-			NewTrainPathfind(v->tile, v->dest_tile, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
+			NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
 
 			if (best_track != -1) {
 				if (best_bird_dist != 0) {
@@ -2575,7 +2624,7 @@
 	return
 		IsTileOwner(tile, v->owner) && (
 			!IsFrontEngine(v) ||
-			IsCompatibleRail(v->u.rail.railtype, GetRailType(tile))
+			HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile))
 		);
 }
 
@@ -2585,9 +2634,10 @@
 	byte z_down; // fraction to remove when moving down
 } RailtypeSlowdownParams;
 
-static const RailtypeSlowdownParams _railtype_slowdown[3] = {
+static const RailtypeSlowdownParams _railtype_slowdown[] = {
 	// normal accel
 	{256/4, 256/2, 256/4, 2}, // normal
+	{256/4, 256/2, 256/4, 2}, // electrified
 	{256/4, 256/2, 256/4, 2}, // monorail
 	{0,     256/2, 256/4, 2}, // maglev
 };
@@ -2873,6 +2923,11 @@
 
 				if (!(r&0x4)) {
 					v->tile = gp.new_tile;
+
+					if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) {
+						TrainPowerChanged(GetFirstVehicleInChain(v));
+					}
+
 					v->u.rail.track = chosen_track;
 					assert(v->u.rail.track);
 				}
--- a/train_gui.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/train_gui.c	Wed Mar 29 16:30:26 2006 +0000
@@ -177,7 +177,7 @@
 		const Engine *e = GetEngine(i);
 		const RailVehicleInfo *rvi = RailVehInfo(i);
 
-		if (!IsCompatibleRail(e->railtype, railtype) || !(rvi->flags & RVI_WAGON) != is_engine ||
+		if (!HasPowerOnRail(e->railtype, railtype) || !(rvi->flags & RVI_WAGON) != is_engine ||
 				!HASBIT(e->player_avail, _local_player))
 			continue;
 
@@ -208,7 +208,7 @@
 
 			for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
 				const Engine *e = GetEngine(i);
-				if (IsCompatibleRail(e->railtype, railtype)
+				if (HasPowerOnRail(e->railtype, railtype)
 				    && HASBIT(e->player_avail, _local_player))
 					count++;
 			}
--- a/tunnelbridge_cmd.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/tunnelbridge_cmd.c	Wed Mar 29 16:30:26 2006 +0000
@@ -799,9 +799,9 @@
 
 
 // fast routine for getting the height of a middle bridge tile. 'tile' MUST be a middle bridge tile.
-static uint GetBridgeHeight(const TileInfo *ti)
+uint GetBridgeHeight(TileIndex t)
 {
-	TileIndex tile = GetSouthernBridgeEnd(ti->tile);
+	TileIndex tile = GetSouthernBridgeEnd(t);
 
 	/* Return the height there (the height of the NORTH CORNER)
 	 * If the end of the bridge is on a tileh 7 (all raised, except north corner),
@@ -930,6 +930,7 @@
 
 		image += GetTunnelDirection(ti->tile) * 2;
 		DrawGroundSprite(image);
+		if (GB(_m[ti->tile].m3, 0, 3) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 
 		AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
@@ -973,6 +974,8 @@
 				DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
 			}
 
+			if (GB(_m[ti->tile].m3, 0, 3) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 			// draw ramp
 			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 			AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
@@ -1029,7 +1032,7 @@
 			// get bridge sprites
 			b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + base_offset;
 
-			z = GetBridgeHeight(ti) + 5;
+			z = GetBridgeHeight(ti->tile) + 5;
 
 			// draw rail or road component
 			image = b[0];
@@ -1054,6 +1057,8 @@
 				if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
 			}
 
+			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC || GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 			if (ti->z + 5 == z) {
 				// draw poles below for small bridges
 				image = b[2];
@@ -1107,7 +1112,7 @@
 				if (_get_z_hint >= z + 8) return _get_z_hint;
 
 				// actually on the bridge, but not yet in the shared area.
-				if (!IS_INT_INSIDE(x, 5, 10 + 1)) return GetBridgeHeight(ti) + 8;
+				if (!IS_INT_INSIDE(x, 5, 10 + 1)) return GetBridgeHeight(ti->tile) + 8;
 
 				// in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it.
 				// if rail or road below then it means it's possibly build on slope below the bridge.
--- a/variables.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/variables.h	Wed Mar 29 16:30:26 2006 +0000
@@ -345,7 +345,6 @@
 	SpriteID sprites[NUM_CARGO];
 	byte transit_days_1[NUM_CARGO];
 	byte transit_days_2[NUM_CARGO];
-	byte ai_railwagon[3][NUM_CARGO];
 	byte ai_roadveh_start[NUM_CARGO];
 	byte ai_roadveh_count[NUM_CARGO];
 } CargoConst;
--- a/vehicle.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/vehicle.c	Wed Mar 29 16:30:26 2006 +0000
@@ -218,6 +218,10 @@
 
 	FOR_ALL_VEHICLES(v) {
 		v->first = NULL;
+		if (v->type == VEH_Train) v->u.rail.first_engine = INVALID_ENGINE;
+	}
+
+	FOR_ALL_VEHICLES(v) {
 		if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
 			TrainConsistChanged(v);
 	}
--- a/vehicle.h	Wed Mar 29 16:28:41 2006 +0000
+++ b/vehicle.h	Wed Mar 29 16:30:26 2006 +0000
@@ -72,6 +72,7 @@
 	byte track;
 	byte force_proceed;
 	byte railtype;
+	RailTypeMask compatible_railtypes;
 
 	byte flags;
 
@@ -307,6 +308,7 @@
 int LoadUnloadVehicle(Vehicle *v);
 
 void TrainConsistChanged(Vehicle *v);
+void TrainPowerChanged(Vehicle *v);
 int32 GetTrainRunningCost(const Vehicle *v);
 
 int CheckTrainStoppedInDepot(const Vehicle *v);
--- a/vehicle_gui.c	Wed Mar 29 16:28:41 2006 +0000
+++ b/vehicle_gui.c	Wed Mar 29 16:30:26 2006 +0000
@@ -76,6 +76,7 @@
 
 static const StringID _rail_types_list[] = {
 	STR_RAIL_VEHICLES,
+	STR_ELRAIL_VEHICLES,
 	STR_MONORAIL_VEHICLES,
 	STR_MAGLEV_VEHICLES,
 	INVALID_STRING_ID
@@ -450,7 +451,7 @@
  *	if used compined with show_cars set to false, it will work as intended. Replace window do it like that
  *  this was a big hack even before show_outdated was added. Stupid newgrf :p										*/
 static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, EngineID *selected_id, RailType railtype,
-	uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated)
+	uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated, bool show_compatible)
 {
 	EngineID j;
 	byte colour;
@@ -472,7 +473,9 @@
 
 		colour = *sel == 0 ? 0xC : 0x10;
 		if (!(ENGINE_AVAILABLE && show_outdated && RailVehInfo(i)->power && e->railtype == railtype)) {
-			if (e->railtype != railtype || !(rvi->flags & RVI_WAGON) != is_engine ||
+			if ((!HasPowerOnRail(e->railtype, railtype) && show_compatible)
+				|| (e->railtype != railtype && !show_compatible)
+				|| !(rvi->flags & RVI_WAGON) != is_engine ||
 				!HASBIT(e->player_avail, _local_player))
 				continue;
 		} /*else {
@@ -522,16 +525,15 @@
 				const Engine* e = GetEngine(eid);
 				const EngineInfo* info = &_engine_info[eid];
 
+				// left window contains compatible engines while right window only contains engines of the selected type
 				if (ENGINE_AVAILABLE && (
 							(RailVehInfo(eid)->power != 0 && WP(w, replaceveh_d).wagon_btnstate) ||
-							(RailVehInfo(eid)->power == 0 && !WP(w, replaceveh_d).wagon_btnstate)
-						) &&
-						e->railtype == railtype) {
-					if (_player_num_engines[eid] > 0 || EngineHasReplacementForPlayer(p, eid)) {
+							(RailVehInfo(eid)->power == 0 && !WP(w, replaceveh_d).wagon_btnstate))) {
+					if (HasPowerOnRail(e->railtype, railtype) && (_player_num_engines[eid] > 0 || EngineHasReplacementForPlayer(p, eid))) {
 						if (sel[0] == count) selected_id[0] = eid;
 						count++;
 					}
-					if (HASBIT(e->player_avail, _local_player)) {
+					if (e->railtype == railtype && HASBIT(e->player_avail, _local_player)) {
 						if (sel[1] == count2) selected_id[1] = eid;
 						count2++;
 					}
@@ -647,12 +649,12 @@
 			* engines to get more types.. Stays here until we have our own format
 			* then it is exit!!! */
 			if (WP(w,replaceveh_d).wagon_btnstate) {
-				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true); // True engines
-				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false); // True engines
-				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false); // Feeble wagons
+				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true, true); // True engines
+				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false, false); // True engines
+				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false, false); // Feeble wagons
 			} else {
-				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true);
-				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false);
+				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true, true);
+				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false, true);
 			}
 			break;
 		}