src/vehicle.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6877 889301acc299
--- a/src/vehicle.cpp	Mon Dec 03 23:39:38 2007 +0000
+++ b/src/vehicle.cpp	Tue Jan 22 21:00:30 2008 +0000
@@ -8,27 +8,21 @@
 #include "roadveh.h"
 #include "ship.h"
 #include "spritecache.h"
-#include "table/sprites.h"
-#include "table/strings.h"
-#include "functions.h"
+#include "tile_cmd.h"
 #include "landscape.h"
-#include "map.h"
-#include "tile.h"
-#include "vehicle.h"
 #include "timetable.h"
-#include "gfx.h"
-#include "viewport.h"
+#include "viewport_func.h"
+#include "gfx_func.h"
 #include "news.h"
-#include "command.h"
+#include "command_func.h"
 #include "saveload.h"
-#include "player.h"
+#include "player_func.h"
 #include "engine.h"
-#include "sound.h"
 #include "debug.h"
 #include "vehicle_gui.h"
 #include "depot.h"
 #include "station.h"
-#include "rail.h"
+#include "rail_type.h"
 #include "train.h"
 #include "aircraft.h"
 #include "industry_map.h"
@@ -36,18 +30,36 @@
 #include "water_map.h"
 #include "network/network.h"
 #include "yapf/yapf.h"
-#include "date.h"
 #include "newgrf_callbacks.h"
 #include "newgrf_engine.h"
 #include "newgrf_sound.h"
-#include "helpers.hpp"
 #include "group.h"
-#include "economy.h"
-#include "strings.h"
+#include "order.h"
+#include "strings_func.h"
+#include "zoom_func.h"
+#include "functions.h"
+#include "date_func.h"
+#include "window_func.h"
+#include "vehicle_func.h"
+#include "signal_func.h"
+#include "sound_func.h"
+#include "variables.h"
+#include "autoreplace_func.h"
+#include "autoreplace_gui.h"
+#include "string_func.h"
+#include "settings_type.h"
+
+#include "table/sprites.h"
+#include "table/strings.h"
 
 #define INVALID_COORD (0x7fffffff)
 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
 
+VehicleID _vehicle_id_ctr_day;
+Vehicle *_place_clicked_vehicle;
+VehicleID _new_vehicle_id;
+uint16 _returned_refit_capacity;
+
 
 /* Tables used in vehicle.h to find the right command for a certain vehicle type */
 const uint32 _veh_build_proc_table[] = {
@@ -92,10 +104,10 @@
 bool VehicleNeedsService(const Vehicle *v)
 {
 	if (v->vehstatus & (VS_STOPPED | VS_CRASHED))       return false;
-	if (v->current_order.type != OT_GOTO_DEPOT || !(v->current_order.flags & OF_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list
+	if (v->current_order.type != OT_GOTO_DEPOT || !(v->current_order.flags & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list
 		if (_patches.gotodepot && VehicleHasDepotOrders(v)) return false;
 		if (v->current_order.type == OT_LOADING)            return false;
-		if (v->current_order.type == OT_GOTO_DEPOT && v->current_order.flags & OF_HALT_IN_DEPOT) return false;
+		if (v->current_order.type == OT_GOTO_DEPOT && v->current_order.flags & OFB_HALT_IN_DEPOT) return false;
 	}
 
 	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
@@ -119,33 +131,23 @@
 
 static void *EnsureNoVehicleProcZ(Vehicle *v, void *data)
 {
-	const TileInfo *ti = (const TileInfo*)data;
-
-	if (v->tile != ti->tile || v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return NULL;
-	if (v->z_pos > ti->z) return NULL;
+	byte z = *(byte*)data;
+
+	if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return NULL;
+	if (v->z_pos > z) return NULL;
 
 	_error_message = VehicleInTheWayErrMsg(v);
 	return v;
 }
 
+Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z)
+{
+	return (Vehicle*)VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ);
+}
 
 bool EnsureNoVehicleOnGround(TileIndex tile)
 {
-	TileInfo ti;
-
-	ti.tile = tile;
-	ti.z = GetTileMaxZ(tile);
-	return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ) == NULL;
-}
-
-Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z)
-{
-	TileInfo ti;
-
-	ti.tile = tile;
-	ti.z = z;
-
-	return (Vehicle*)VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ);
+	return FindVehicleOnTileZ(tile, GetTileMaxZ(tile)) == NULL;
 }
 
 Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed)
@@ -174,6 +176,30 @@
 }
 
 
+/** Procedure called for every vehicle found in tunnel/bridge in the hash map */
+static void *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
+{
+	if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return NULL;
+
+	_error_message = VehicleInTheWayErrMsg(v);
+	return v;
+}
+
+/**
+ * Finds vehicle in tunnel / bridge
+ * @param tile first end
+ * @param endtile second end
+ * @return pointer to vehicle found
+ */
+Vehicle *GetVehicleTunnelBridge(TileIndex tile, TileIndex endtile)
+{
+	Vehicle *v = (Vehicle*)VehicleFromPos(tile, NULL, &GetVehicleTunnelBridgeProc);
+	if (v != NULL) return v;
+
+	return (Vehicle*)VehicleFromPos(endtile, NULL, &GetVehicleTunnelBridgeProc);
+}
+
+
 static void UpdateVehiclePosHash(Vehicle* v, int x, int y);
 
 void VehiclePositionChanged(Vehicle *v)
@@ -194,7 +220,7 @@
 }
 
 /** Called after load to update coordinates */
-void AfterLoadVehicles()
+void AfterLoadVehicles(bool clear_te_id)
 {
 	Vehicle *v;
 
@@ -204,7 +230,7 @@
 
 		v->UpdateDeltaXY(v->direction);
 
-		v->fill_percent_te_id = INVALID_TE_ID;
+		if (clear_te_id) v->fill_percent_te_id = INVALID_TE_ID;
 		v->first = NULL;
 		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
 		if (v->type == VEH_ROAD)  v->u.road.first_engine = INVALID_ENGINE;
@@ -537,16 +563,16 @@
 		delete this->Next();
 	}
 
-	Window *w = FindWindowById(WC_VEHICLE_VIEW, this->index);
-	if (w != NULL && WP(w, vp_d).follow_vehicle == this->index) {
-		ScrollMainWindowTo(this->x_pos, this->y_pos); // lock the main view on the vehicle's last position
+	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+	if (WP(w, vp_d).follow_vehicle == this->index) {
+		ScrollMainWindowTo(this->x_pos, this->y_pos, true); // lock the main view on the vehicle's last position
 		WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
 	}
 }
 
 Vehicle::~Vehicle()
 {
-	DeleteName(this->string_id);
+	free(this->name);
 
 	if (CleaningPool()) return;
 
@@ -570,6 +596,9 @@
 
 	do {
 		Vehicle *u = v;
+		/* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
+		 * it may happen that vehicle chain is deleted when visible */
+		if (!(v->vehstatus & VS_HIDDEN)) MarkSingleVehicleDirty(v);
 		v = v->Next();
 		delete u;
 	} while (v != NULL);
@@ -584,7 +613,7 @@
 void VehicleEnteredDepotThisTick(Vehicle *v)
 {
 	/* we need to set v->leave_depot_instantly as we have no control of it's contents at this time */
-	if (HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OFB_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) {
+	if (HasBit(v->current_order.flags, OF_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OF_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) {
 		/* we keep the vehicle in the depot since the user ordered it to stay */
 		v->leave_depot_instantly = false;
 	} else {
@@ -678,19 +707,33 @@
 */
 CommandCost GetRefitCost(EngineID engine_type)
 {
-	CommandCost base_cost;
-
+	Money base_cost;
+	ExpensesType expense_type;
 	switch (GetEngine(engine_type)->type) {
-		case VEH_SHIP: base_cost.AddCost(_price.ship_base); break;
-		case VEH_ROAD: base_cost.AddCost(_price.roadveh_base); break;
-		case VEH_AIRCRAFT: base_cost.AddCost(_price.aircraft_base); break;
+		case VEH_SHIP:
+			base_cost = _price.ship_base;
+			expense_type = EXPENSES_SHIP_RUN;
+			break;
+
+		case VEH_ROAD:
+			base_cost = _price.roadveh_base;
+			expense_type = EXPENSES_ROADVEH_RUN;
+			break;
+
+		case VEH_AIRCRAFT:
+			base_cost = _price.aircraft_base;
+			expense_type = EXPENSES_AIRCRAFT_RUN;
+			break;
+
 		case VEH_TRAIN:
-			base_cost.AddCost(2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
-							 _price.build_railwagon : _price.build_railvehicle));
+			base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
+							 _price.build_railwagon : _price.build_railvehicle);
+			expense_type = EXPENSES_TRAIN_RUN;
 			break;
-		default: NOT_REACHED(); break;
+
+		default: NOT_REACHED();
 	}
-	return CommandCost((EngInfo(engine_type)->refit_cost * base_cost.GetCost()) >> 10);
+	return CommandCost(expense_type, (EngInfo(engine_type)->refit_cost * base_cost) >> 10);
 }
 
 static void DoDrawVehicle(const Vehicle *v)
@@ -1584,7 +1627,7 @@
 	uint16 wagon_list_length = 0;
 	uint16 wagon_count = 0;
 
-	CommandCost cost;
+	CommandCost cost(EXPENSES_NEW_VEHICLES);
 	uint i, sell_command, total_number_vehicles;
 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
 
@@ -1669,7 +1712,6 @@
 			 * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually
 			 * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money
 			 * we should never reach a condition where the player will end up with negative money from doing this */
-			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 			SubtractMoneyFromPlayer(ret);
 		}
 	}
@@ -1698,7 +1740,7 @@
 {
 	Vehicle *v_front, *v;
 	Vehicle *w_front, *w, *w_rear;
-	CommandCost cost, total_cost;
+	CommandCost cost, total_cost(EXPENSES_NEW_VEHICLES);
 	uint32 build_argument = 2;
 
 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
@@ -1852,9 +1894,6 @@
 		return CMD_ERROR;
 	}
 
-	/* Set the expense type last as refitting will make the cost go towards
-	 * running costs... */
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 	return total_cost;
 }
 
@@ -2115,7 +2154,7 @@
 		max += v->cargo_cap;
 		if (v->cargo_cap != 0) {
 			unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
-			loading |= (u->current_order.flags & OF_UNLOAD) == 0 && st->goods[v->cargo_type].days_since_pickup != 255;
+			loading |= (u->current_order.flags & OFB_UNLOAD) == 0 && st->goods[v->cargo_type].days_since_pickup != 255;
 			cars++;
 		}
 	}
@@ -2137,7 +2176,7 @@
 		case VEH_TRAIN:
 			InvalidateWindowClasses(WC_TRAINS_LIST);
 			if (!IsFrontEngine(v)) v = v->First();
-			UpdateSignalsOnSegment(v->tile, GetRailDepotDirection(v->tile));
+			UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 			v->load_unload_time_rem = 0;
 			break;
 
@@ -2201,11 +2240,11 @@
 			}
 		}
 
-		if (HasBit(t.flags, OFB_PART_OF_ORDERS)) {
+		if (HasBit(t.flags, OF_PART_OF_ORDERS)) {
 			/* Part of orders */
 			UpdateVehicleTimetable(v, true);
 			v->cur_order_index++;
-		} else if (HasBit(t.flags, OFB_HALT_IN_DEPOT)) {
+		} else if (HasBit(t.flags, OF_HALT_IN_DEPOT)) {
 			/* Force depot visit */
 			v->vehstatus |= VS_STOPPED;
 			if (v->owner == _local_player) {
@@ -2269,7 +2308,6 @@
 CommandCost CmdNameVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	StringID str;
 
 	if (!IsValidVehicleID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
 
@@ -2279,17 +2317,11 @@
 
 	if (!IsUniqueVehicleName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
 
-	str = AllocateName(_cmd_text, 2);
-	if (str == 0) return CMD_ERROR;
-
 	if (flags & DC_EXEC) {
-		StringID old_str = v->string_id;
-		v->string_id = str;
-		DeleteName(old_str);
+		free(v->name);
+		v->name = strdup(_cmd_text);
 		ResortVehicleLists();
 		MarkWholeScreenDirty();
-	} else {
-		DeleteName(str);
 	}
 
 	return CommandCost();
@@ -2322,26 +2354,51 @@
 }
 
 
-static Rect _old_vehicle_coords;
-
-void BeginVehicleMove(Vehicle *v)
+static Rect _old_vehicle_coords; ///< coords of vehicle before it has moved
+
+/**
+ * Stores the vehicle image coords for later call to EndVehicleMove()
+ * @param v vehicle which image's coords to store
+ * @see _old_vehicle_coords
+ * @see EndVehicleMove()
+ */
+void BeginVehicleMove(const Vehicle *v)
 {
-	_old_vehicle_coords.left = v->left_coord;
-	_old_vehicle_coords.top = v->top_coord;
-	_old_vehicle_coords.right = v->right_coord;
+	_old_vehicle_coords.left   = v->left_coord;
+	_old_vehicle_coords.top    = v->top_coord;
+	_old_vehicle_coords.right  = v->right_coord;
 	_old_vehicle_coords.bottom = v->bottom_coord;
 }
 
-void EndVehicleMove(Vehicle *v)
+/**
+ * Marks screen dirty after a vehicle has moved
+ * @param v vehicle which is marked dirty
+ * @see _old_vehicle_coords
+ * @see BeginVehicleMove()
+ */
+void EndVehicleMove(const Vehicle *v)
 {
 	MarkAllViewportsDirty(
-		min(_old_vehicle_coords.left,v->left_coord),
-		min(_old_vehicle_coords.top,v->top_coord),
-		max(_old_vehicle_coords.right,v->right_coord)+1,
-		max(_old_vehicle_coords.bottom,v->bottom_coord)+1
+		min(_old_vehicle_coords.left,   v->left_coord),
+		min(_old_vehicle_coords.top,    v->top_coord),
+		max(_old_vehicle_coords.right,  v->right_coord) + 1,
+		max(_old_vehicle_coords.bottom, v->bottom_coord) + 1
 	);
 }
 
+/**
+ * Marks viewports dirty where the vehicle's image is
+ * In fact, it equals
+ *   BeginVehicleMove(v); EndVehicleMove(v);
+ * @param v vehicle to mark dirty
+ * @see BeginVehicleMove()
+ * @see EndVehicleMove()
+ */
+void MarkSingleVehicleDirty(const Vehicle *v)
+{
+	MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
+}
+
 /* returns true if staying in the same tile */
 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
 {
@@ -2547,42 +2604,35 @@
 			case VEH_TRAIN: {
 				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
 
-				switch (rvi->railtype) {
-					default: NOT_REACHED();
-					case RAILTYPE_RAIL:
-					case RAILTYPE_ELECTRIC:
-					{
-						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
-						if (rvi->railveh_type == RAILVEH_WAGON) {
-							if (!GetCargo(cargo_type)->is_freight) {
-								if (parent_engine_type == INVALID_ENGINE) {
-									scheme = LS_PASSENGER_WAGON_STEAM;
-								} else {
-									switch (RailVehInfo(parent_engine_type)->engclass) {
-										default: NOT_REACHED();
-										case EC_STEAM:    scheme = LS_PASSENGER_WAGON_STEAM;    break;
-										case EC_DIESEL:   scheme = LS_PASSENGER_WAGON_DIESEL;   break;
-										case EC_ELECTRIC: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
-									}
-								}
-							} else {
-								scheme = LS_FREIGHT_WAGON;
-							}
+				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
+				if (rvi->railveh_type == RAILVEH_WAGON) {
+					if (!GetCargo(cargo_type)->is_freight) {
+						if (parent_engine_type == INVALID_ENGINE) {
+							scheme = LS_PASSENGER_WAGON_STEAM;
 						} else {
-							bool is_mu = HasBit(EngInfo(engine_type)->misc_flags, EF_RAIL_IS_MU);
-
-							switch (rvi->engclass) {
+							switch (RailVehInfo(parent_engine_type)->engclass) {
 								default: NOT_REACHED();
-								case EC_STEAM:    scheme = LS_STEAM; break;
-								case EC_DIESEL:   scheme = is_mu ? LS_DMU : LS_DIESEL;   break;
-								case EC_ELECTRIC: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
+								case EC_STEAM:    scheme = LS_PASSENGER_WAGON_STEAM;    break;
+								case EC_DIESEL:   scheme = LS_PASSENGER_WAGON_DIESEL;   break;
+								case EC_ELECTRIC: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
+								case EC_MONORAIL: scheme = LS_PASSENGER_WAGON_MONORAIL; break;
+								case EC_MAGLEV:   scheme = LS_PASSENGER_WAGON_MAGLEV;   break;
 							}
 						}
-						break;
+					} else {
+						scheme = LS_FREIGHT_WAGON;
 					}
-
-					case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
-					case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
+				} else {
+					bool is_mu = HasBit(EngInfo(engine_type)->misc_flags, EF_RAIL_IS_MU);
+
+					switch (rvi->engclass) {
+						default: NOT_REACHED();
+						case EC_STEAM:    scheme = LS_STEAM; break;
+						case EC_DIESEL:   scheme = is_mu ? LS_DMU : LS_DIESEL;   break;
+						case EC_ELECTRIC: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
+						case EC_MONORAIL: scheme = LS_MONORAIL; break;
+						case EC_MAGLEV:   scheme = LS_MAGLEV; break;
+					}
 				}
 				break;
 			}
@@ -2702,7 +2752,8 @@
 	    SLE_VAR(Vehicle, subtype,              SLE_UINT8),
 
 	    SLE_REF(Vehicle, next,                 REF_VEHICLE_OLD),
-	    SLE_VAR(Vehicle, string_id,            SLE_STRINGID),
+	SLE_CONDVAR(Vehicle, name,                 SLE_NAME,                    0, 83),
+	SLE_CONDSTR(Vehicle, name,                 SLE_STR, 0,                 84, SL_MAX_VERSION),
 	SLE_CONDVAR(Vehicle, unitnumber,           SLE_FILE_U8  | SLE_VAR_U16,  0, 7),
 	SLE_CONDVAR(Vehicle, unitnumber,           SLE_UINT16,                  8, SL_MAX_VERSION),
 	    SLE_VAR(Vehicle, owner,                SLE_UINT8),
@@ -3062,14 +3113,14 @@
 			this->current_order.dest == this->last_station_visited) {
 		/* Arriving at the ordered station.
 		 * Keep the load/unload flags, as we (obviously) still need them. */
-		this->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
+		this->current_order.flags &= OFB_FULL_LOAD | OFB_UNLOAD | OFB_TRANSFER;
 
 		/* Furthermore add the Non Stop flag to mark that this station
 		 * is the actual destination of the vehicle, which is (for example)
 		 * necessary to be known for HandleTrainLoading to determine
 		 * whether the train is lost or not; not marking a train lost
 		 * that arrives at random stations is bad. */
-		this->current_order.flags |= OF_NON_STOP;
+		this->current_order.flags |= OFB_NON_STOP;
 		UpdateVehicleTimetable(this, true);
 	} else {
 		/* This is just an unordered intermediate stop */
@@ -3079,11 +3130,10 @@
 	current_order.type = OT_LOADING;
 	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
 
-	SET_EXPENSES_TYPE(this->GetExpenseType(true));
 	VehiclePayment(this);
 
 	InvalidateWindow(this->GetVehicleListWindowClass(), this->owner);
-	InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, STATUS_BAR);
+	InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
 	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
 	InvalidateWindow(WC_STATION_VIEW, this->last_station_visited);
 
@@ -3096,7 +3146,7 @@
 	assert(current_order.type == OT_LOADING);
 
 	/* Only update the timetable if the vehicle was supposed to stop here. */
-	if (current_order.flags & OF_NON_STOP) UpdateVehicleTimetable(this, false);
+	if (current_order.flags & OFB_NON_STOP) UpdateVehicleTimetable(this, false);
 
 	current_order.type = OT_LEAVESTATION;
 	current_order.flags = 0;
@@ -3123,7 +3173,7 @@
 			this->LeaveStation();
 
 			/* If this was not the final order, don't remove it from the list. */
-			if (!(b.flags & OF_NON_STOP)) return;
+			if (!(b.flags & OFB_NON_STOP)) return;
 			break;
 		}
 
@@ -3166,3 +3216,15 @@
 	this->sprite_height = 1;
 	this->z_height      = 1;
 }
+
+void StopAllVehicles()
+{
+	Vehicle *v;
+	FOR_ALL_VEHICLES(v) {
+		/* Code ripped from CmdStartStopTrain. Can't call it, because of
+		 * ownership problems, so we'll duplicate some code, for now */
+		v->vehstatus |= VS_STOPPED;
+		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+	}
+}