changeset 2244:eba7ec7edf28 draft

(svn r2764) -Feature: Clone vehicles -This allows a player to clone an excisting vehicle of his own -[fix]: this uncovered an excisting bug in CmdBuildRailVehicle() where depots could build trains of the wrong track type. This is fixed -Thanks to Celestar for drawing the sprites and _luca_ for including them in openttd.grf
author bjarni <bjarni@openttd.org>
date Sun, 31 Jul 2005 13:08:08 +0000
parents 1b3c000b1dfb
children 865d4c14214d
files aircraft_cmd.c aircraft_gui.c callback_table.c command.c command.h data/openttd.grf lang/english.txt roadveh_gui.c ship_gui.c spritecache.c table/sprites.h train_cmd.c train_gui.c vehicle.c
diffstat 14 files changed, 664 insertions(+), 116 deletions(-) [+]
line wrap: on
line diff
--- a/aircraft_cmd.c
+++ b/aircraft_cmd.c
@@ -332,7 +332,7 @@
 				(_m[tile].m5 == 32 || _m[tile].m5 == 65 || _m[tile].m5 == 86);
 }
 
-static bool CheckStoppedInHangar(Vehicle *v)
+bool CheckStoppedInHangar(Vehicle *v)
 {
 	if (!(v->vehstatus & VS_STOPPED) || !IsAircraftHangarTile(v->tile)) {
 		_error_message = STR_A01B_AIRCRAFT_MUST_BE_STOPPED;
--- a/aircraft_gui.c
+++ b/aircraft_gui.c
@@ -89,6 +89,15 @@
 	}
 }
 
+void CcCloneAircraft(bool success, uint tile, uint32 p1, uint32 p2)
+{
+	Vehicle *v;
+
+	if (success) {
+		v = GetVehicle(_new_aircraft_id);
+		ShowAircraftViewWindow(v);
+	}
+}
 
 static void NewAircraftWndProc(Window *w, WindowEvent *e)
 {
@@ -496,11 +505,14 @@
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  50,  67, 0x2B4,    STR_A03B_REFIT_AIRCRAFT_TO_CARRY },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  68,  85, 0x2B2,    STR_A028_SHOW_AIRCRAFT_S_ORDERS },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  86, 103, 0x2B3,    STR_A02B_SHOW_AIRCRAFT_DETAILS },
+{ WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  32,  49, SPR_CLONE_AIRCRAFT,      STR_CLONE_AIRCRAFT_INFO },
 { WWT_PANEL,      RESIZE_LRB,   14, 232, 249, 104, 103, 0x0,      STR_NULL },
 { WWT_RESIZEBOX,  RESIZE_LRTB,  14, 238, 249, 104, 115, 0x0,      STR_NULL },
 { WIDGETS_END }
 };
 
+bool CheckStoppedInHangar(Vehicle *v);
+
 static void AircraftViewWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -587,6 +599,12 @@
 		case 10: /* show details */
 			ShowAircraftDetailsWindow(v);
 			break;
+		case 11: {
+			/* clone vehicle */
+			Vehicle *v;
+			v = GetVehicle(w->window_number);
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneAircraft, CMD_CLONE_VEHICLE | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
+		} break;
 		}
 	} break;
 
@@ -602,6 +620,19 @@
 		DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
 		DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
 		break;
+		
+		       case WE_MOUSELOOP:
+               {
+                       Vehicle *v;
+                       uint32 h;
+                       v = GetVehicle(w->window_number);
+                       h = CheckStoppedInHangar(v) ? (1<< 7) : (1 << 11);
+                       if (h != w->hidden_state) {
+                               w->hidden_state = h;
+                               SetWindowDirty(w);
+                       }
+               } break;
+
 	}
 }
 
@@ -636,7 +667,7 @@
 
 	/* setup disabled buttons */
 	w->disabled_state =
-		IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 7));
+		IsTileOwner(tile, _local_player) ? 0 : ((1<<4) | (1<<7) | (1<<8));
 
 	/* determine amount of items for scroller */
 	num = 0;
@@ -741,6 +772,42 @@
 	}
 }
 
+/**
+ * Clones an aircraft
+ * @param *v is the original vehicle to clone
+ * @param *w is the window of the hangar where the clone is build
+ */
+static bool HandleCloneVehClick(Vehicle *v, Window *w)
+{
+
+	if (!v){
+		return false;
+	}
+
+	if (v->type != VEH_Aircraft) {
+		// it's not an aircraft, do nothing
+		return false;
+	}
+
+
+    DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0,CcCloneAircraft,CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+
+	ResetObjectToPlace();
+
+	return true;
+}
+
+static void ClonePlaceObj(uint tile, Window *w)
+{
+	Vehicle *v;
+
+
+	v = CheckMouseOverVehicle();
+	if (v && HandleCloneVehClick(v, w))
+		return;
+}
+
+
 static void AircraftDepotWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -754,14 +821,48 @@
 			AircraftDepotClickAircraft(w, e->click.pt.x, e->click.pt.y);
 			break;
 		case 7: /* show build aircraft window */
+			ResetObjectToPlace();
 			ShowBuildAircraftWindow(w->window_number);
 			break;
-		case 8: /* scroll to tile */
+			
+				case 8: /* clone button */
+			InvalidateWidget(w, 8);
+				TOGGLEBIT(w->click_state, 8);
+				
+				if (HASBIT(w->click_state, 8)) {
+					_place_clicked_vehicle = NULL;
+					SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w);
+				} else {
+					ResetObjectToPlace();
+				}
+					break;
+		case 9: /* scroll to tile */
+			ResetObjectToPlace();
 			ScrollMainWindowToTile(w->window_number);
 			break;
 		}
 		break;
 
+
+case WE_PLACE_OBJ: {
+		ClonePlaceObj(e->place.tile, w);
+	} break;
+
+	case WE_ABORT_PLACE_OBJ: {
+		CLRBIT(w->click_state, 8);
+		InvalidateWidget(w, 8);
+	} break;
+	
+	// check if a vehicle in a depot was clicked..
+	case WE_MOUSELOOP: {
+		Vehicle *v = _place_clicked_vehicle;
+		// since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button
+		if (v != NULL && HASBIT(w->click_state, 8)) {
+			_place_clicked_vehicle = NULL;
+			HandleCloneVehClick( v, w);
+		}
+	} break;
+	
 	case WE_DESTROY:
 		DeleteWindowById(WC_BUILD_VEHICLE, w->window_number);
 		break;
@@ -824,8 +925,9 @@
 
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   295,    14,    61, 0x204,										STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   319,   330,    14,    61, 0x0,											STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   159,    62,    73, STR_A003_NEW_AIRCRAFT,		STR_A022_BUILD_NEW_AIRCRAFT},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   160,   318,    62,    73, STR_00E4_LOCATION,				STR_A024_CENTER_MAIN_VIEW_ON_HANGAR},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   105,    62,    73, STR_A003_NEW_AIRCRAFT,		STR_A022_BUILD_NEW_AIRCRAFT},
+{WWT_NODISTXTBTN,     RESIZE_TB,    14,   106,   212,    62,    73, STR_CLONE_AIRCRAFT,		STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   213,   318,    62,    73, STR_00E4_LOCATION,				STR_A024_CENTER_MAIN_VIEW_ON_HANGAR},
 {      WWT_PANEL,    RESIZE_RTB,    14,   319,   318,    62,    73, 0x0,													STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   319,   330,    62,    73, 0x0,											STR_RESIZE_BUTTON},
 {   WIDGETS_END},
--- a/callback_table.c
+++ b/callback_table.c
@@ -10,6 +10,7 @@
 
 /* aircraft_gui.c */
 CommandCallback CcBuildAircraft;
+CommandCallback CcCloneAircraft;
 
 /* airport_gui.c */
 CommandCallback CcBuildAirport;
@@ -41,13 +42,16 @@
 
 /* roadveh_gui.c */
 CommandCallback CcBuildRoadVeh;
+CommandCallback CcCloneRoadVeh;
 
 /* ship_gui.c */
 CommandCallback CcBuildShip;
+CommandCallback CcCloneShip;
 
 /* train_gui.c */
 CommandCallback CcBuildWagon;
 CommandCallback CcBuildLoco;
+CommandCallback CcCloneTrain;
 
 CommandCallback *_callback_table[] = {
 	/* 0x00 */ NULL,
@@ -70,7 +74,11 @@
 	/* 0x11 */ CcPlaySound1D,
 	/* 0x12 */ CcPlaySound1E,
 	/* 0x13 */ CcStation,
-	/* 0x14 */ CcTerraform
+	/* 0x14 */ CcTerraform,
+	/* 0x15 */ CcCloneAircraft,
+	/* 0x16 */ CcCloneRoadVeh,
+	/* 0x17 */ CcCloneShip,
+	/* 0x18 */ CcCloneTrain,
 };
 
 const int _callback_table_count = lengthof(_callback_table);
--- a/command.c
+++ b/command.c
@@ -159,6 +159,9 @@
 
 DEF_COMMAND(CmdReplaceVehicle);
 
+DEF_COMMAND(CmdCloneVehicle);
+
+
 /* The master command table */
 static const Command _command_proc_table[] = {
 	{CmdBuildRailroadTrack,                  0}, /*   0 */
@@ -300,6 +303,7 @@
 	{CmdGiveMoney,                           0}, /* 113 */
 	{CmdChangePatchSetting,         CMD_SERVER}, /* 114 */
 	{CmdReplaceVehicle,                      0}, /* 115 */
+	{CmdCloneVehicle,						 0}, /* 116 */
 };
 
 /* This function range-checks a cmd, and checks if the cmd is not NULL */
--- a/command.h
+++ b/command.h
@@ -136,6 +136,9 @@
 	CMD_CHANGE_PATCH_SETTING = 114,
 
 	CMD_REPLACE_VEHICLE = 115,
+
+	CMD_CLONE_VEHICLE = 116,
+
 };
 
 enum {
index d6166f23e22522fddf9bd000bcc0ff162e17ab79..5a784f20e5201f16a27c954d8f0172b990adb843
GIT binary patch
literal 23690
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
--- a/lang/english.txt
+++ b/lang/english.txt
@@ -2404,6 +2404,12 @@
 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
+STR_CLONE_ROAD_VEHICLE                                          :{BLACK}Clone Vehicle
+STR_CLONE_ROAD_VEHICLE_INFO 	                                :{BLACK}This will build a copy of the road vehicle. Control-click will share the orders
+STR_CLONE_ROAD_VEHICLE_DEPOT_INFO	                        :{BLACK}This will build a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Control-click will share the orders
+STR_CLONE_TRAIN                                     		:{BLACK}Clone Train
+STR_CLONE_TRAIN_INFO 	                  			:{BLACK}This will build a copy of the train including all cars. Control-click will share the orders
+STR_CLONE_TRAIN_DEPOT_INFO	                        	:{BLACK}This will build a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Control-click will share the orders
 STR_8820_RENAME                                                 :{BLACK}Rename
 STR_8823_SKIP                                                   :{BLACK}Skip
 STR_8824_DELETE                                                 :{BLACK}Delete
@@ -2560,6 +2566,9 @@
 STR_9807_MUST_BUILD_SHIP_DEPOT_FIRST                            :{WHITE}Must build ship depot first
 STR_9808_NEW_SHIPS                                              :{WHITE}New Ships
 STR_9809_BUILD_SHIP                                             :{BLACK}Build Ship
+STR_CLONE_SHIP                                              	:{BLACK}Clone Ship
+STR_CLONE_SHIP_INFO 	                                        :{BLACK}This will build a copy of the ship. Control-click will share the orders
+STR_CLONE_SHIP_DEPOT_INFO	                          	:{BLACK}This will build a copy of a ship. Click this button and then on a ship inside or outside the depot. Control-click will share the orders
 STR_980B_SHIP_MUST_BE_STOPPED_IN                                :{WHITE}Ship must be stopped in depot
 STR_980C_CAN_T_SELL_SHIP                                        :{WHITE}Can't sell ship...
 STR_980D_CAN_T_BUILD_SHIP                                       :{WHITE}Can't build ship...
@@ -2624,6 +2633,9 @@
 STR_A001_CAN_T_BUILD_AIRPORT_HERE                               :{WHITE}Can't build airport here...
 STR_A002_AIRCRAFT_HANGAR                                        :{WHITE}{STATION} Aircraft Hangar
 STR_A003_NEW_AIRCRAFT                                           :{BLACK}New Aircraft
+STR_CLONE_AIRCRAFT                                           	:{BLACK}Clone Aircraft
+STR_CLONE_AIRCRAFT_INFO                                        	:{BLACK}This will build a copy of the aircraft. Control-click will share the orders
+STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW                          	:{BLACK}This will build a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Control-click will share the orders
 STR_A004_INFORMATION                                            :{BLACK}Information
 STR_A005_NEW_AIRCRAFT                                           :{WHITE}New Aircraft
 STR_A006_BUILD_AIRCRAFT                                         :{BLACK}Build Aircraft
--- a/roadveh_gui.c
+++ b/roadveh_gui.c
@@ -230,6 +230,16 @@
 	w->caption_color = v->owner;
 }
 
+void CcCloneRoadVeh(bool success, uint tile, uint32 p1, uint32 p2)
+{
+	Vehicle *v;
+
+	if (!success) return;
+
+	v = GetVehicle(_new_roadveh_id);
+	ShowRoadVehViewWindow(v);
+}
+
 static void RoadVehViewWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -308,6 +318,12 @@
 		case 10: /* show details */
 			ShowRoadVehDetailsWindow(v);
 			break;
+		case 11: {
+			/* clone vehicle */
+			Vehicle *v;
+			v = GetVehicle(w->window_number);
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneRoadVeh, CMD_CLONE_VEHICLE | CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE));
+			} break;
 		}
 	} break;
 
@@ -322,6 +338,18 @@
 		DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
 		DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
 		break;
+
+	case WE_MOUSELOOP:
+		{
+			Vehicle *v;
+			uint32 h;
+			v = GetVehicle(w->window_number);
+			h = IsTileDepotType(v->tile, TRANSPORT_ROAD) && (v->vehstatus&VS_STOPPED) ? (1<< 7) : (1 << 11);
+			if (h != w->hidden_state) {
+				w->hidden_state = h;
+				SetWindowDirty(w);
+			}
+		}
 	}
 }
 
@@ -337,6 +365,7 @@
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  50,  67, 0x2CB,    STR_9020_FORCE_VEHICLE_TO_TURN_AROUND },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  68,  85, 0x2B2,    STR_901D_SHOW_VEHICLE_S_ORDERS },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  86, 103, 0x2B3,    STR_9021_SHOW_ROAD_VEHICLE_DETAILS },
+{ WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  32,  49, SPR_CLONE_ROADVEH,      STR_CLONE_ROAD_VEHICLE_INFO },
 { WWT_PANEL,      RESIZE_LRB,   14, 232, 249, 104, 103, 0x0,      STR_NULL },
 { WWT_RESIZEBOX,  RESIZE_LRTB,  14, 238, 249, 104, 115, 0x0,      STR_NULL },
 { WIDGETS_END }
@@ -536,7 +565,7 @@
 
 	/* setup disabled buttons */
 	w->disabled_state =
-		IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 7));
+		IsTileOwner(tile, _local_player) ? 0 : ((1<<4) | (1<<7) | (1<<8));
 
 	/* determine amount of items for scroller */
 	num = 0;
@@ -640,6 +669,41 @@
 	}
 }
 
+/**
+ * Clones a road vehicle
+ * @param *v is the original vehicle to clone
+ * @param *w is the window of the depot where the clone is build
+ */
+static bool HandleCloneVehClick(Vehicle *v, Window *w)
+{
+
+	if (!v){
+		return false;
+	}
+
+	if (v->type != VEH_Road) {
+		// it's not a road vehicle, do nothing
+		return false;
+	}
+
+
+    DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0,CcCloneRoadVeh,CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+
+	ResetObjectToPlace();
+
+	return true;
+}
+
+static void ClonePlaceObj(uint tile, Window *w)
+{
+	Vehicle *v;
+
+
+	v = CheckMouseOverVehicle();
+	if (v && HandleCloneVehClick(v, w))
+		return;
+}
+
 static void RoadDepotWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -654,12 +718,45 @@
 			break;
 
 		case 7:
+			ResetObjectToPlace();
 			ShowBuildRoadVehWindow(w->window_number);
 			break;
+			
+		case 8: /* clone button */
+			InvalidateWidget(w, 8);
+				TOGGLEBIT(w->click_state, 8);
+				
+				if (HASBIT(w->click_state, 8)) {
+					_place_clicked_vehicle = NULL;
+					SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w);
+				} else {
+					ResetObjectToPlace();
+				}
+					break;
+				
+			case 9: /* scroll to tile */
+				ResetObjectToPlace();
+				ScrollMainWindowToTile(w->window_number);
+					break;
+		}
+	} break;
+	
+		case WE_PLACE_OBJ: {
+		ClonePlaceObj(e->place.tile, w);
+	} break;
 
-		case 8: /* scroll to tile */
-			ScrollMainWindowToTile(w->window_number);
-			break;
+	case WE_ABORT_PLACE_OBJ: {
+		CLRBIT(w->click_state, 8);
+		InvalidateWidget(w, 8);
+	} break;
+	
+	// check if a vehicle in a depot was clicked..
+	case WE_MOUSELOOP: {
+		Vehicle *v = _place_clicked_vehicle;
+	// since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button
+		if (v != NULL && HASBIT(w->click_state, 8)) {
+			_place_clicked_vehicle = NULL;
+			HandleCloneVehClick( v, w);
 		}
 	} break;
 
@@ -729,8 +826,9 @@
 
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   279,    14,    55, 0x305,												STR_9022_VEHICLES_CLICK_ON_VEHICLE},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   303,   314,    14,    55, 0x0,													STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   150,    56,    67, STR_9004_NEW_VEHICLES,				STR_9023_BUILD_NEW_ROAD_VEHICLE},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   151,   302,    56,    67, STR_00E4_LOCATION,						STR_9025_CENTER_MAIN_VIEW_ON_ROAD},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   100,    56,    67, STR_9004_NEW_VEHICLES,				STR_9023_BUILD_NEW_ROAD_VEHICLE},
+{WWT_NODISTXTBTN,     RESIZE_TB,    14,   101,   200,    56,    67, STR_CLONE_ROAD_VEHICLE,		STR_CLONE_ROAD_VEHICLE_DEPOT_INFO},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   201,   302,    56,    67, STR_00E4_LOCATION,						STR_9025_CENTER_MAIN_VIEW_ON_ROAD},
 {      WWT_PANEL,    RESIZE_RTB,    14,   303,   302,    56,    67, 0x0,													STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   303,   314,    56,    67, 0x0,													STR_RESIZE_BUTTON},
 {   WIDGETS_END},
--- a/ship_gui.c
+++ b/ship_gui.c
@@ -320,6 +320,15 @@
 	ShowShipViewWindow(v);
 }
 
+void CcCloneShip(bool success, uint tile, uint32 p1, uint32 p2)
+{
+	Vehicle *v;
+	if (!success) return;
+
+	v = GetVehicle(_new_ship_id);
+	ShowShipViewWindow(v);
+}
+
 static void NewShipWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -465,60 +474,60 @@
 
 static void ShipViewWndProc(Window *w, WindowEvent *e) {
 	switch(e->event) {
-	case WE_PAINT: {
-		Vehicle *v = GetVehicle(w->window_number);
-		uint32 disabled = 1<<8;
-		StringID str;
+		case WE_PAINT: {
+			Vehicle *v = GetVehicle(w->window_number);
+			uint32 disabled = 1<<8;
+			StringID str;
 
-		// Possible to refit?
-		if (ShipVehInfo(v->engine_type)->refittable &&
+			// Possible to refit?
+			if (ShipVehInfo(v->engine_type)->refittable &&
 				v->vehstatus&VS_STOPPED &&
 				v->u.ship.state == 0x80 &&
 				IsTileDepotType(v->tile, TRANSPORT_WATER))
-			disabled = 0;
+				disabled = 0;
 
-		if (v->owner != _local_player)
-			disabled |= 1<<8 | 1<<7;
-		w->disabled_state = disabled;
+			if (v->owner != _local_player)
+				disabled |= 1<<8 | 1<<7;
+			w->disabled_state = disabled;
 
-		/* draw widgets & caption */
-		SetDParam(0, v->string_id);
-		SetDParam(1, v->unitnumber);
-		DrawWindowWidgets(w);
+			/* draw widgets & caption */
+			SetDParam(0, v->string_id);
+			SetDParam(1, v->unitnumber);
+			DrawWindowWidgets(w);
 
-		if (v->breakdown_ctr == 1) {
-			str = STR_885C_BROKEN_DOWN;
-		} else if (v->vehstatus & VS_STOPPED) {
-			str = STR_8861_STOPPED;
-		} else {
-			switch (v->current_order.type) {
-			case OT_GOTO_STATION: {
-				SetDParam(0, v->current_order.station);
-				SetDParam(1, v->cur_speed * 10 >> 5);
-				str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
-			} break;
+			if (v->breakdown_ctr == 1) {
+				str = STR_885C_BROKEN_DOWN;
+			} else if (v->vehstatus & VS_STOPPED) {
+				str = STR_8861_STOPPED;
+			} else {
+				switch (v->current_order.type) {
+					case OT_GOTO_STATION: {
+						SetDParam(0, v->current_order.station);
+						SetDParam(1, v->cur_speed * 10 >> 5);
+						str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
+					} break;
 
-			case OT_GOTO_DEPOT: {
-				Depot *depot = GetDepot(v->current_order.station);
-				SetDParam(0, depot->town_index);
-				SetDParam(1, v->cur_speed * 10 >> 5);
-				str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
-			} break;
+					case OT_GOTO_DEPOT: {
+						Depot *depot = GetDepot(v->current_order.station);
+						SetDParam(0, depot->town_index);
+						SetDParam(1, v->cur_speed * 10 >> 5);
+						str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
+					} break;
 
-			case OT_LOADING:
-			case OT_LEAVESTATION:
-				str = STR_882F_LOADING_UNLOADING;
-				break;
-
-			default:
-				if (v->num_orders == 0) {
-					str = STR_NO_ORDERS + _patches.vehicle_speed;
-					SetDParam(0, v->cur_speed * 10 >> 5);
-				} else
-					str = STR_EMPTY;
-				break;
+					case OT_LOADING:
+					case OT_LEAVESTATION:
+						str = STR_882F_LOADING_UNLOADING;
+						break;
+						
+					default:
+						if (v->num_orders == 0) {
+							str = STR_NO_ORDERS + _patches.vehicle_speed;
+							SetDParam(0, v->cur_speed * 10 >> 5);
+						} else
+							str = STR_EMPTY;
+						break;
+				}
 			}
-		}
 
 		/* draw the flag plus orders */
 		DrawSprite(v->vehstatus & VS_STOPPED ? 0xC12 : 0xC13, 2, w->widget[5].top + 1);
@@ -526,43 +535,61 @@
 		DrawWindowViewport(w);
 	} break;
 
-	case WE_CLICK: {
-		Vehicle *v = GetVehicle(w->window_number);
+		case WE_CLICK: {
+			Vehicle *v = GetVehicle(w->window_number);
 
-		switch(e->click.widget) {
-		case 5: /* start stop */
-			DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP));
-			break;
-		case 6: /* center main view */
-			ScrollMainWindowTo(v->x_pos, v->y_pos);
-			break;
-		case 7: /* goto hangar */
-			DoCommandP(v->tile, v->index, 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
-			break;
-		case 8: /* refit */
-			ShowShipRefitWindow(v);
-			break;
-		case 9: /* show orders */
-			ShowOrdersWindow(v);
+			switch(e->click.widget) {
+				case 5: /* start stop */
+					DoCommandP(v->tile, v->index, 0, NULL, CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP));
+					break;
+				case 6: /* center main view */
+					ScrollMainWindowTo(v->x_pos, v->y_pos);
+					break;
+				case 7: /* goto hangar */
+					DoCommandP(v->tile, v->index, 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
+					break;
+				case 8: /* refit */
+					ShowShipRefitWindow(v);
+					break;
+				case 9: /* show orders */
+					ShowOrdersWindow(v);
+					break;
+				case 10: /* show details */
+					ShowShipDetailsWindow(v);
+					break;
+				case 11: {
+					/* clone vehicle */
+					Vehicle *v;
+					v = GetVehicle(w->window_number);
+					DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, CcCloneShip, CMD_CLONE_VEHICLE | CMD_MSG(STR_980D_CAN_T_BUILD_SHIP));
+				} break;
+			}
+		} break;
+
+		case WE_RESIZE:
+			w->viewport->width  += e->sizing.diff.x;
+			w->viewport->height += e->sizing.diff.y;
+			w->viewport->virtual_width  += e->sizing.diff.x;
+			w->viewport->virtual_height += e->sizing.diff.y;
 			break;
-		case 10: /* show details */
-			ShowShipDetailsWindow(v);
+
+		case WE_DESTROY:
+			DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
+			DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
+			DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
 			break;
-		}
-	} break;
 
-	case WE_RESIZE:
-		w->viewport->width  += e->sizing.diff.x;
-		w->viewport->height += e->sizing.diff.y;
-		w->viewport->virtual_width  += e->sizing.diff.x;
-		w->viewport->virtual_height += e->sizing.diff.y;
-		break;
-
-	case WE_DESTROY:
-		DeleteWindowById(WC_VEHICLE_ORDERS, w->window_number);
-		DeleteWindowById(WC_VEHICLE_REFIT, w->window_number);
-		DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
-		break;
+		case WE_MOUSELOOP:
+		{
+			Vehicle *v;
+			uint32 h;
+			v = GetVehicle(w->window_number);
+			h = IsTileDepotType(v->tile, TRANSPORT_WATER) && v->vehstatus & VS_HIDDEN ? (1<< 7) : (1 << 11);
+			if (h != w->hidden_state) {
+				w->hidden_state = h;
+				SetWindowDirty(w);
+			}
+		}
 	}
 }
 
@@ -578,6 +605,7 @@
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  50,  67, 0x2B4,    STR_983A_REFIT_CARGO_SHIP_TO_CARRY},
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  68,  85, 0x2B2,    STR_9828_SHOW_SHIP_S_ORDERS},
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  86, 103, 0x2B3,    STR_982B_SHOW_SHIP_DETAILS},
+{ WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  32,  49, SPR_CLONE_SHIP,      STR_CLONE_SHIP_INFO},
 { WWT_PANEL,      RESIZE_LRB,   14, 232, 249, 104, 103, 0x0,      STR_NULL },
 { WWT_RESIZEBOX,  RESIZE_LRTB,  14, 238, 249, 104, 115, 0x0,      STR_NULL },
 { WIDGETS_END }
@@ -720,6 +748,41 @@
 	}
 }
 
+/**
+ * Clones a ship
+ * @param *v is the original vehicle to clone
+ * @param *w is the window of the depot where the clone is build
+ */
+static bool HandleCloneVehClick(Vehicle *v, Window *w)
+{
+
+	if (!v){
+		return false;
+	}
+
+	if (v->type != VEH_Ship) {
+		// it's not a ship, do nothing
+		return false;
+	}
+
+
+    DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0,CcCloneShip,CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+
+	ResetObjectToPlace();
+
+	return true;
+}
+
+static void ClonePlaceObj(uint tile, Window *w)
+{
+	Vehicle *v;
+
+
+	v = CheckMouseOverVehicle();
+	if (v && HandleCloneVehClick(v, w))
+		return;
+}
+
 static void ShipDepotWndProc(Window *w, WindowEvent *e) {
 	switch(e->event) {
 	case WE_PAINT:
@@ -733,14 +796,49 @@
 			break;
 
 		case 7:
+			ResetObjectToPlace();
 			ShowBuildShipWindow(w->window_number);
 			break;
+			
+			case 8: /* clone button */
+			InvalidateWidget(w, 8);
+				TOGGLEBIT(w->click_state, 8);
+				
+				if (HASBIT(w->click_state, 8)) {
+					_place_clicked_vehicle = NULL;
+					SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w);
+				} else {
+					ResetObjectToPlace();
+				}
+					break;
 
-		case 8: /* scroll to tile */
+		case 9: /* scroll to tile */
+			ResetObjectToPlace();
 			ScrollMainWindowToTile(w->window_number);
 			break;
 		}
 		break;
+		
+	case WE_PLACE_OBJ: {
+		//ClonePlaceObj(e->place.tile, w);
+		ClonePlaceObj(w->window_number, w);
+	} break;
+
+	case WE_ABORT_PLACE_OBJ: {
+		CLRBIT(w->click_state, 8);
+		InvalidateWidget(w, 8);
+	} break;
+	
+	// check if a vehicle in a depot was clicked..
+	case WE_MOUSELOOP: {
+		Vehicle *v = _place_clicked_vehicle;
+
+	// since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button
+		if (v != NULL && HASBIT(w->click_state, 8)) {
+			_place_clicked_vehicle = NULL;
+			HandleCloneVehClick(v, w);
+		}
+	} break;
 
 	case WE_DESTROY:
 		DeleteWindowById(WC_BUILD_VEHICLE, w->window_number);
@@ -804,8 +902,9 @@
 
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   269,    14,    61, 0x203,									STR_981F_SHIPS_CLICK_ON_SHIP_FOR},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   293,   304,    14,    61, 0x0,										STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   146,    62,    73, STR_9804_NEW_SHIPS,			STR_9820_BUILD_NEW_SHIP},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   147,   292,    62,    73, STR_00E4_LOCATION,			STR_9822_CENTER_MAIN_VIEW_ON_SHIP},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,    96,    62,    73, STR_9804_NEW_SHIPS,			STR_9820_BUILD_NEW_SHIP},
+{WWT_NODISTXTBTN,     RESIZE_TB,    14,    97,   194,    62,    73, STR_CLONE_SHIP,		STR_CLONE_SHIP_DEPOT_INFO},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   195,   292,    62,    73, STR_00E4_LOCATION,			STR_9822_CENTER_MAIN_VIEW_ON_SHIP},
 {      WWT_PANEL,    RESIZE_RTB,    14,   293,   292,    62,    73, 0x0,													STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   293,   304,    62,    73, 0x0,										STR_RESIZE_BUTTON},
 {   WIDGETS_END},
--- a/spritecache.c
+++ b/spritecache.c
@@ -732,7 +732,7 @@
 	"cached_sprites.xx3",
 };
 
-#define OPENTTD_SPRITES_COUNT 98
+#define OPENTTD_SPRITES_COUNT 100
 static const SpriteID _openttd_grf_indexes[] = {
 	SPR_OPENTTD_BASE + 0, SPR_OPENTTD_BASE + 7, // icons etc
 	134, 134,  // euro symbol medium size
--- a/table/sprites.h
+++ b/table/sprites.h
@@ -64,6 +64,11 @@
 	SPR_ARROW_LEFT    = SPR_OPENTTD_BASE + 97,
 	SPR_ARROW_RIGHT   = SPR_OPENTTD_BASE + 98,
 
+	/* Clone vehicles stuff */
+	SPR_CLONE_AIRCRAFT = SPR_OPENTTD_BASE + 99,
+	SPR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 99,
+	SPR_CLONE_TRAIN = SPR_OPENTTD_BASE + 99,
+	SPR_CLONE_SHIP = SPR_OPENTTD_BASE + 99,
 
 	/* Network GUI sprites */
 	SPR_SQUARE = SPR_OPENTTD_BASE + 23,     // colored square (used for newgrf compatibility)
@@ -942,6 +947,8 @@
 	SPR_CURSOR_BUS_STATION    = 2725,
 	SPR_CURSOR_TRUCK_STATION  = 2726,
 	SPR_CURSOR_ROAD_TUNNEL    = 2433,
+
+	SPR_CURSOR_CLONE = SPR_OPENTTD_BASE + 100,
 } CursorSprite;
 
 /// Animation macro in table/animcursors.h (_animcursors[])
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -568,7 +568,7 @@
 /** Build a railroad vehicle.
  * @param x,y tile coordinates (depot) where rail-vehicle is built
  * @param p1 engine type id
- * @param p2 unused
+ * @param p2 build only one engine, even if it is a dualheaded engine. It also prevents any free cars from being added to the train
  */
 int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -594,10 +594,19 @@
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
 	rvi = RailVehInfo(p1);
+	e = GetEngine(p1);
+
+	/* Check if depot and new engine uses the same kind of tracks */
+	if (!IsCompatibleRail(e->railtype, GetRailType(tile))) return CMD_ERROR;
 
 	if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags);
 
 	value = EstimateTrainCost(rvi);
+		
+	//make sure we only pay for half a dualheaded engine if we only requested half of it
+	if (rvi->flags&RVI_MULTIHEAD && HASBIT(p2,0))
+		value /= 2;
+	
 
 	if (!(flags & DC_QUERY_COST)) {
 		v = AllocateVehicle();
@@ -633,7 +642,6 @@
 			v->dest_tile = 0;
 
 			v->engine_type = (byte)p1;
-			e = GetEngine(p1);
 
 			v->reliability = e->reliability;
 			v->reliability_spd_dec = e->reliability_spd_dec;
@@ -651,12 +659,16 @@
 
 			VehiclePositionChanged(v);
 
-			if (rvi->flags&RVI_MULTIHEAD && (u = AllocateVehicle()) != NULL)
-				AddRearEngineToMultiheadedTrain(v, u, true);
+			if (rvi->flags&RVI_MULTIHEAD && (u = AllocateVehicle()) != NULL && !HASBIT(p2,0)) {
+					AddRearEngineToMultiheadedTrain(v, u, true);
+			}
 
 			TrainConsistChanged(v);
 			UpdateTrainAcceleration(v);
-			NormalizeTrainVehInDepot(v);
+
+			if (!HASBIT(p2,0)) {	// do not move the cars if HASBIT(p2,0) is set
+				NormalizeTrainVehInDepot(v);
+			}
 
 			InvalidateWindow(WC_VEHICLE_DEPOT, tile);
 			RebuildVehicleLists();
@@ -1472,10 +1484,7 @@
 /** Refits a train to the specified cargo type.
  * @param x,y unused
  * @param p1 vehicle ID of the train to refit
- * @param p2 various bitstuffed elements
- * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF)
- * - p2 = (bit 8)   - skip check for stopped in depot, used by autoreplace (p2 & 0x100)
- * @todo p2 bit8 check <b>NEEDS TO GO</b>
+ * @param p2 the new cargo type to refit to (p2 & 0xFF)
  */
 int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -1483,14 +1492,13 @@
 	int32 cost;
 	uint num;
 	CargoID new_cid = p2 & 0xFF; //gets the cargo number
-	bool SkipStoppedInDepotCheck = !!HASBIT(p2, 8); // XXX - needs to go, yes?
 
 	if (!IsVehicleIndex(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
-	if (!SkipStoppedInDepotCheck && CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
+	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
 
 	/* Check cargo */
 	if (new_cid > NUM_CARGO) return CMD_ERROR;
@@ -1537,10 +1545,7 @@
 					cost += (_price.build_railvehicle >> 8);
 				num += amount;
 				if (flags & DC_EXEC) {
-					//autorefitted train cars wants to keep the cargo
-					//it will be checked if the cargo is valid in CmdReplaceVehicle
-					if (!(SkipStoppedInDepotCheck))
-						v->cargo_count = 0;
+					v->cargo_count = 0;
 					v->cargo_type = new_cid;
 					v->cargo_cap = amount;
 					InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
@@ -1548,8 +1553,7 @@
 				}
 			}
 		}
-	// SkipStoppedInDepotCheck is called by CmdReplace and it should only apply to the single car it is called for
-	} while ( (v=v->next) != NULL || SkipStoppedInDepotCheck );
+	} while ( (v=v->next) != NULL );
 
 	_returned_refit_amount = num;
 
--- a/train_gui.c
+++ b/train_gui.c
@@ -154,6 +154,17 @@
 	ShowTrainViewWindow(v);
 }
 
+void CcCloneTrain(bool success, uint tile, uint32 p1, uint32 p2)
+{
+	Vehicle *v;
+
+	if (!success)
+		return;
+
+	v = GetVehicle(_new_train_id);
+	ShowTrainViewWindow(v);
+}
+
 static void engine_drawing_loop(int *x, int *y, int *pos, int *sel,
 	int *selected_id, byte railtype, byte show_max, bool is_engine)
 {
@@ -366,7 +377,7 @@
 
 	/* setup disabled buttons */
 	w->disabled_state =
-		IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 5) | (1 << 8));
+		IsTileOwner(tile, _local_player) ? 0 : ((1 << 4) | (1 << 5) | (1 << 8) | (1<<9));
 
 	/* determine amount of items for scroller */
 	num = 0;
@@ -580,6 +591,47 @@
 	}
 }
 
+/**
+ * Clones a train
+ * @param *v is the original vehicle to clone
+ * @param *w is the window of the depot where the clone is build
+ */
+static bool HandleCloneVehClick(Vehicle *v, Window *w)
+{
+
+	if (!v){
+		return false;
+	}
+
+	// for train vehicles: subtype 0 for locs and not zero for others
+	if (v->type == VEH_Train && v->subtype != 0) {
+		v = GetFirstVehicleInChain(v);
+		if (v->subtype != 0) // This happens when clicking on a train in depot with no loc attached
+			return false;
+	}else{
+		if (v->type != VEH_Train) {
+			// it's not a train, Do Nothing
+			return false;
+		}
+	}
+
+    DoCommandP(w->window_number, v->index, _ctrl_pressed ? 1 : 0, CcCloneTrain, CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+
+	ResetObjectToPlace();
+
+	return true;
+}
+
+static void ClonePlaceObj(uint tile, Window *w)
+{
+	Vehicle *v;
+
+
+	v = CheckMouseOverVehicle();
+	if (v && HandleCloneVehClick(v, w))
+		return;
+}
+
 static void TrainDepotWndProc(Window *w, WindowEvent *e)
 {
 	switch(e->event) {
@@ -590,17 +642,51 @@
 	case WE_CLICK: {
 		switch(e->click.widget) {
 		case 8:
+			ResetObjectToPlace();
 			ShowBuildTrainWindow(w->window_number);
 			break;
-		case 9:
+		case 10:
+			ResetObjectToPlace();
 			ScrollMainWindowToTile(w->window_number);
 			break;
 		case 6:
 			TrainDepotClickTrain(w, e->click.pt.x, e->click.pt.y);
 			break;
+		case 9: /* clone button */
+			InvalidateWidget(w, 9);
+			TOGGLEBIT(w->click_state, 9);
+
+			if (HASBIT(w->click_state, 9)) {
+				_place_clicked_vehicle = NULL;
+				SetObjectToPlaceWnd(SPR_CURSOR_CLONE, VHM_RECT, w);
+			} else {
+				ResetObjectToPlace();
+			}
+			break;
+
+ 		}
+ 	} break;
+ 
+	case WE_PLACE_OBJ: {
+		ClonePlaceObj(e->place.tile, w);
+	} break;
+
+	case WE_ABORT_PLACE_OBJ: {
+		CLRBIT(w->click_state, 9);
+		InvalidateWidget(w, 9);
+	} break;
+	
+	// check if a vehicle in a depot was clicked..
+	case WE_MOUSELOOP: {
+		Vehicle *v = _place_clicked_vehicle;
+	// since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button
+		if (v != NULL && HASBIT(w->click_state, 9)) {
+			_place_clicked_vehicle = NULL;
+			HandleCloneVehClick( v, w);
 		}
 	} break;
 
+
 	case WE_DESTROY:
 		DeleteWindowById(WC_BUILD_VEHICLE, w->window_number);
 		break;
@@ -680,10 +766,14 @@
 
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   325,    14,    97, 0x601,									STR_883F_TRAINS_CLICK_ON_TRAIN_FOR},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   349,   360,    14,   109, 0x0,										STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   167,   110,   121, STR_8815_NEW_VEHICLES,	STR_8840_BUILD_NEW_TRAIN_VEHICLE},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   168,   348,   110,   121, STR_00E4_LOCATION,			STR_8842_CENTER_MAIN_VIEW_ON_TRAIN},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   116,   110,   121, STR_8815_NEW_VEHICLES,	STR_8840_BUILD_NEW_TRAIN_VEHICLE},
+{WWT_NODISTXTBTN,     RESIZE_TB,    14,   117,   232,   110,   121, STR_CLONE_TRAIN,		STR_CLONE_TRAIN_DEPOT_INFO},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   233,   348,   110,   121, STR_00E4_LOCATION,			STR_8842_CENTER_MAIN_VIEW_ON_TRAIN},
+
+
 { WWT_HSCROLLBAR,    RESIZE_RTB,    14,     0,   325,    98,   109, 0x0,										STR_HSCROLL_BAR_SCROLLS_LIST},
 {      WWT_PANEL,    RESIZE_RTB,    14,   349,   348,   110,   121, 0x0,										STR_NULL},
+
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   349,   360,   110,   121, 0x0,										STR_RESIZE_BUTTON},
 {   WIDGETS_END},
 };
@@ -803,6 +893,7 @@
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  86, 103, 0x2B2,    STR_8847_SHOW_TRAIN_S_ORDERS },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249, 104, 121, 0x2B3,    STR_884C_SHOW_TRAIN_DETAILS },
 { WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  68,  85, 0x2B4,    STR_RAIL_REFIT_VEHICLE_TO_CARRY },
+{ WWT_PUSHIMGBTN, RESIZE_LR,    14, 232, 249,  32,  49, SPR_CLONE_TRAIN,      STR_CLONE_TRAIN_INFO },
 { WWT_PANEL,      RESIZE_LRB,   14, 232, 249, 122, 121, 0x0,      STR_NULL },
 { WWT_RESIZEBOX,  RESIZE_LRTB,  14, 238, 249, 122, 133, 0x0,      STR_NULL },
 { WIDGETS_END }
@@ -833,7 +924,7 @@
 
 		/* draw widgets & caption */
 		SetDParam(0, v->string_id);
-		SetDParam(1, v->unitnumber);
+		SetDParam(1, v->unitnumber); 
 		DrawWindowWidgets(w);
 
 		if (v->u.rail.crash_anim_pos != 0) {
@@ -920,6 +1011,9 @@
 		case 12:
 			ShowRailVehicleRefitWindow(v);
 			break;
+		case 13:
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_CLONE_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
+			break;
 		}
 	} break;
 
@@ -942,7 +1036,7 @@
 
 		v = GetVehicle(w->window_number);
 		assert(v->type == VEH_Train);
-		h = CheckTrainStoppedInDepot(v) >= 0 ? (1 << 9) : (1 << 12);
+		h = CheckTrainStoppedInDepot(v) >= 0 ? (1 << 9)| (1 << 7) : (1 << 12) | (1 << 13);
 		if (h != w->hidden_state) {
 			w->hidden_state = h;
 			SetWindowDirty(w);
--- a/vehicle.c
+++ b/vehicle.c
@@ -21,6 +21,7 @@
 #include "vehicle_gui.h"
 #include "depot.h"
 #include "station.h"
+#include "gui.h"
 #include "rail.h"
 
 #define INVALID_COORD (-0x8000)
@@ -1669,6 +1670,122 @@
 	_current_player = OWNER_NONE;
 }
 
+int32 CmdCloneOrder(int x, int y, uint32 flags, uint32 veh1_veh2, uint32 mode);
+int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+int32 CmdBuildShip(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+int32 CmdBuildAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+ 
+
+typedef int32 VehBuildProc(int x, int y, uint32 flags, uint32 p1, uint32 p2);
+
+static VehBuildProc * const _veh_build_proc_table[] = {
+	CmdBuildRailVehicle,
+	CmdBuildRoadVeh,
+	CmdBuildShip,
+	CmdBuildAircraft,
+};
+
+static VehicleID * _new_vehicle_id_proc_table[] = {
+	&_new_train_id,
+	&_new_roadveh_id,
+	&_new_ship_id,
+	&_new_aircraft_id,	
+};
+
+/** Clone a vehicle. If it is a train, it will clone all the cars too
+  * @param x,y unused
+  * @param p1 the original vehicle's index
+  * @param p2 1 = shared orders, else copied orders
+  */
+int32 CmdCloneVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
+{
+	Vehicle *vfront, *v;
+	Vehicle *wfront, *w1, *w2;
+	int cost, total_cost;
+	VehBuildProc *proc;
+	VehicleID *new_id;
+	uint refit_command = 0;
+	byte needs_refitting = 255;
+
+	if (!IsVehicleIndex(p1))
+		return CMD_ERROR;
+	v = GetVehicle(p1);
+	wfront = v; 
+	w1 = v;
+	vfront = v;
+
+	if (!CheckOwnership(v->owner))
+		return CMD_ERROR;
+
+	if (v->type == VEH_Train && v->subtype != TS_Front_Engine) return CMD_ERROR;
+
+	//no need to check if it is a depot since the build command do that
+	switch (v->type) {
+		case VEH_Train:		refit_command = CMD_REFIT_RAIL_VEHICLE; break;
+		case VEH_Road:		break;
+		case VEH_Ship:		refit_command = CMD_REFIT_SHIP; break;
+		case VEH_Aircraft:	refit_command = CMD_REFIT_AIRCRAFT; break;
+		default: return CMD_ERROR;
+	}
+
+	proc = _veh_build_proc_table[v->type - VEH_Train];
+	new_id = _new_vehicle_id_proc_table[v->type - VEH_Train];
+	total_cost = proc(x, y, flags, v->engine_type, 1);
+	if (total_cost == CMD_ERROR)
+		return CMD_ERROR;
+
+	if (flags & DC_EXEC) {
+		wfront = GetVehicle(*new_id);
+		w1 = wfront;
+		CmdCloneOrder(x, y, flags, (v->index << 16) | w1->index, p2 & 1 ? CO_SHARE : CO_COPY);
+
+		if (wfront->cargo_type != v->cargo_type) {
+			//a refit is needed
+			needs_refitting = v->cargo_type;
+		}
+	}
+	if (v->type == VEH_Train) {
+		// now we handle the cars
+		v = v->next;
+		while (v != NULL) {
+			cost = proc(x, y, flags, v->engine_type, 1);
+			if (cost == CMD_ERROR)
+				return CMD_ERROR;
+			total_cost += cost;
+
+			if (flags & DC_EXEC) {
+				// add this unit to the end of the train
+				w2 = GetVehicle(RailVehInfo(v->engine_type)->flags & RVI_WAGON ? _new_wagon_id : _new_train_id);
+				CmdMoveRailVehicle(x, y, flags, (w1->index << 16) | w2->index, 0);
+				w1 = w2;
+			}
+			v = v->next;
+		}
+
+		if (flags & DC_EXEC) {
+			_new_train_id = wfront->index;
+			v = vfront;
+			w1 = wfront;
+			while (w1 != NULL && v != NULL) {
+				w1->spritenum = v->spritenum; // makes sure that multiheaded engines are facing the correct way
+				if (w1->cargo_type != v->cargo_type)	// checks if a refit is needed
+					needs_refitting = v->cargo_type;
+				w1 = w1->next;
+				v = v->next;
+			}
+			
+		}
+	}
+	if (flags && DC_EXEC && needs_refitting != 255 && v->type != VEH_Road) {	// right now we do not refit road vehicles
+		if (DoCommandByTile(wfront->tile, wfront->index, needs_refitting, 0, refit_command) != CMD_ERROR)
+			DoCommandByTile(wfront->tile, wfront->index, needs_refitting, DC_EXEC, refit_command);
+	}
+	return total_cost;
+}
+
+
 /** Give a custom name to your vehicle
  * @param x,y unused
  * @param p1 vehicle ID to name