(svn r14076) -Codechange: Merge the four start/stop commands into a single CMD_START_STOP_VEHICLE.
authorfrosch
Fri, 15 Aug 2008 13:57:43 +0000
changeset 9921 4dfac3c48507
parent 9920 21ce1e2f0e43
child 9922 20699d4320ed
(svn r14076) -Codechange: Merge the four start/stop commands into a single CMD_START_STOP_VEHICLE.
src/ai/default/default.cpp
src/ai/trolly/trolly.cpp
src/aircraft_cmd.cpp
src/command.cpp
src/command_type.h
src/depot_gui.cpp
src/roadveh_cmd.cpp
src/ship_cmd.cpp
src/train_cmd.cpp
src/vehicle.cpp
src/vehicle_gui.cpp
--- a/src/ai/default/default.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/ai/default/default.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -348,7 +348,7 @@
 				CmdSucceeded(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_RAIL_VEHICLE))) {
 			VehicleID veh = _new_vehicle_id;
 			AiRestoreVehicleOrders(GetVehicle(veh), &orderbak);
-			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_TRAIN);
+			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 
 			DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 		}
@@ -378,7 +378,7 @@
 			VehicleID veh = _new_vehicle_id;
 
 			AiRestoreVehicleOrders(GetVehicle(veh), &orderbak);
-			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 			DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 		}
 	}
@@ -406,7 +406,7 @@
 				CmdSucceeded(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_AIRCRAFT))) {
 			VehicleID veh = _new_vehicle_id;
 			AiRestoreVehicleOrders(GetVehicle(veh), &orderbak);
-			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_AIRCRAFT);
+			DoCommand(0, veh, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 
 			DoCommand(0, veh, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 		}
@@ -2563,7 +2563,7 @@
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
 
-	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_TRAIN);
+	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 
 	DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 
@@ -3298,7 +3298,7 @@
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
 
-	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 	DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 
 	if (_players_ai[p->index].num_want_fullload != 0) _players_ai[p->index].num_want_fullload--;
@@ -3596,7 +3596,7 @@
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
 
-	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_AIRCRAFT);
+	DoCommand(0, loco_id, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 
 	DoCommand(0, loco_id, _ai_service_interval, DC_EXEC, CMD_CHANGE_SERVICE_INT);
 
--- a/src/ai/trolly/trolly.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/ai/trolly/trolly.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -1220,7 +1220,7 @@
 		AI_DoCommand(0, _players_ainew[p->index].veh_id, 1, DC_EXEC, CMD_SKIP_TO_ORDER);
 
 	// 3, 2, 1... go! (give START_STOP command ;))
-	AI_DoCommand(0, _players_ainew[p->index].veh_id, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
+	AI_DoCommand(0, _players_ainew[p->index].veh_id, 0, DC_EXEC, CMD_START_STOP_VEHICLE);
 	// Try to build an other vehicle (that function will stop building when needed)
 	_players_ainew[p->index].idle  = 10;
 	_players_ainew[p->index].state = AI_STATE_BUILD_VEHICLE;
--- a/src/aircraft_cmd.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/aircraft_cmd.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -496,48 +496,6 @@
 	return ret;
 }
 
-/** Start/Stop an aircraft.
- * @param tile unused
- * @param flags for command type
- * @param p1 aircraft ID to start/stop
- * @param p2 unused
- * @return result of operation.  Nothing if everything went well
- */
-CommandCost CmdStartStopAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
-	if (!IsValidVehicleID(p1)) return CMD_ERROR;
-
-	Vehicle *v = GetVehicle(p1);
-
-	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner)) return CMD_ERROR;
-
-	/* cannot stop airplane when in flight, or when taking off / landing */
-	if (v->u.air.state >= STARTTAKEOFF && v->u.air.state < TERM7)
-		return_cmd_error(STR_A017_AIRCRAFT_IS_IN_FLIGHT);
-
-	/* Check if this aircraft can be started/stopped. The callback will fail or
-	 * return 0xFF if it can. */
-	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
-	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
-		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
-		return_cmd_error(error);
-	}
-
-	if (flags & DC_EXEC) {
-		if (v->IsStoppedInDepot()) {
-			DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
-		}
-
-		v->vehstatus ^= VS_STOPPED;
-		v->cur_speed = 0;
-		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
-		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
-		InvalidateWindowClasses(WC_AIRCRAFT_LIST);
-	}
-
-	return CommandCost();
-}
-
 bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
 {
 	const Station *st = GetStation(this->u.air.targetairport);
--- a/src/command.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/command.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -89,8 +89,6 @@
 DEF_COMMAND(CmdBuildRailVehicle);
 DEF_COMMAND(CmdMoveRailVehicle);
 
-DEF_COMMAND(CmdStartStopTrain);
-
 DEF_COMMAND(CmdSellRailWagon);
 
 DEF_COMMAND(CmdSendTrainToDepot);
@@ -124,7 +122,6 @@
 DEF_COMMAND(CmdRenameStation);
 
 DEF_COMMAND(CmdSellAircraft);
-DEF_COMMAND(CmdStartStopAircraft);
 DEF_COMMAND(CmdBuildAircraft);
 DEF_COMMAND(CmdSendAircraftToHangar);
 DEF_COMMAND(CmdRefitAircraft);
@@ -133,7 +130,6 @@
 DEF_COMMAND(CmdRenameSign);
 
 DEF_COMMAND(CmdBuildRoadVeh);
-DEF_COMMAND(CmdStartStopRoadVeh);
 DEF_COMMAND(CmdSellRoadVeh);
 DEF_COMMAND(CmdSendRoadVehToDepot);
 DEF_COMMAND(CmdTurnRoadVeh);
@@ -154,7 +150,6 @@
 
 DEF_COMMAND(CmdChangePatchSetting);
 
-DEF_COMMAND(CmdStartStopShip);
 DEF_COMMAND(CmdSellShip);
 DEF_COMMAND(CmdBuildShip);
 DEF_COMMAND(CmdSendShipToDepot);
@@ -182,6 +177,7 @@
 DEF_COMMAND(CmdSetAutoReplace);
 
 DEF_COMMAND(CmdCloneVehicle);
+DEF_COMMAND(CmdStartStopVehicle);
 DEF_COMMAND(CmdMassStartStopVehicle);
 DEF_COMMAND(CmdDepotSellAllVehicles);
 DEF_COMMAND(CmdDepotMassAutoReplace);
@@ -243,7 +239,6 @@
 	{CmdPlantTree,                    CMD_AUTO}, /* CMD_PLANT_TREE */
 	{CmdBuildRailVehicle,                    0}, /* CMD_BUILD_RAIL_VEHICLE */
 	{CmdMoveRailVehicle,                     0}, /* CMD_MOVE_RAIL_VEHICLE */
-	{CmdStartStopTrain,                      0}, /* CMD_START_STOP_TRAIN */
 
 	{CmdSellRailWagon,                       0}, /* CMD_SELL_RAIL_WAGON */
 	{CmdSendTrainToDepot,                    0}, /* CMD_SEND_TRAIN_TO_DEPOT */
@@ -276,7 +271,6 @@
 	{CmdRenameStation,                       0}, /* CMD_RENAME_STATION */
 
 	{CmdSellAircraft,                        0}, /* CMD_SELL_AIRCRAFT */
-	{CmdStartStopAircraft,                   0}, /* CMD_START_STOP_AIRCRAFT */
 
 	{CmdBuildAircraft,                       0}, /* CMD_BUILD_AIRCRAFT */
 	{CmdSendAircraftToHangar,                0}, /* CMD_SEND_AIRCRAFT_TO_HANGAR */
@@ -286,7 +280,6 @@
 	{CmdRenameSign,                          0}, /* CMD_RENAME_SIGN */
 
 	{CmdBuildRoadVeh,                        0}, /* CMD_BUILD_ROAD_VEH */
-	{CmdStartStopRoadVeh,                    0}, /* CMD_START_STOP_ROADVEH */
 	{CmdSellRoadVeh,                         0}, /* CMD_SELL_ROAD_VEH */
 	{CmdSendRoadVehToDepot,                  0}, /* CMD_SEND_ROADVEH_TO_DEPOT */
 	{CmdTurnRoadVeh,                         0}, /* CMD_TURN_ROADVEH */
@@ -304,7 +297,6 @@
 
 	{CmdSetRoadDriveSide,           CMD_SERVER}, /* CMD_SET_ROAD_DRIVE_SIDE */
 
-	{CmdStartStopShip,                       0}, /* CMD_START_STOP_SHIP */
 	{CmdSellShip,                            0}, /* CMD_SELL_SHIP */
 	{CmdBuildShip,                           0}, /* CMD_BUILD_SHIP */
 	{CmdSendShipToDepot,                     0}, /* CMD_SEND_SHIP_TO_DEPOT */
@@ -332,6 +324,7 @@
 	{CmdChangePatchSetting,         CMD_SERVER}, /* CMD_CHANGE_PATCH_SETTING */
 	{CmdSetAutoReplace,                      0}, /* CMD_SET_AUTOREPLACE */
 	{CmdCloneVehicle,                        0}, /* CMD_CLONE_VEHICLE */
+	{CmdStartStopVehicle,                    0}, /* CMD_START_STOP_VEHICLE */
 	{CmdMassStartStopVehicle,                0}, /* CMD_MASS_START_STOP */
 	{CmdDepotSellAllVehicles,                0}, /* CMD_DEPOT_SELL_ALL_VEHICLES */
 	{CmdDepotMassAutoReplace,                0}, /* CMD_DEPOT_MASS_AUTOREPLACE */
--- a/src/command_type.h	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/command_type.h	Fri Aug 15 13:57:43 2008 +0000
@@ -172,8 +172,6 @@
 	CMD_BUILD_RAIL_VEHICLE,           ///< build a rail vehicle
 	CMD_MOVE_RAIL_VEHICLE,            ///< move a rail vehicle (in the depot)
 
-	CMD_START_STOP_TRAIN,             ///< start or stop a train
-
 	CMD_SELL_RAIL_WAGON,              ///< sell a rail wagon
 
 	CMD_SEND_TRAIN_TO_DEPOT,          ///< send a train to a depot
@@ -205,7 +203,6 @@
 	CMD_RENAME_STATION,               ///< rename a station
 
 	CMD_SELL_AIRCRAFT,                ///< sell an aircraft
-	CMD_START_STOP_AIRCRAFT,          ///< start/stop an aircraft
 	CMD_BUILD_AIRCRAFT,               ///< build an aircraft
 	CMD_SEND_AIRCRAFT_TO_HANGAR,      ///< send an aircraft to a hanger
 	CMD_REFIT_AIRCRAFT,               ///< refit the cargo space of an aircraft
@@ -214,7 +211,6 @@
 	CMD_RENAME_SIGN,                  ///< rename a sign
 
 	CMD_BUILD_ROAD_VEH,               ///< build a road vehicle
-	CMD_START_STOP_ROADVEH,           ///< start/stop a road vehicle
 	CMD_SELL_ROAD_VEH,                ///< sell a road vehicle
 	CMD_SEND_ROADVEH_TO_DEPOT,        ///< send a road vehicle to the depot
 	CMD_TURN_ROADVEH,                 ///< turn a road vehicle around
@@ -233,7 +229,6 @@
 
 	CMD_SET_ROAD_DRIVE_SIDE,          ///< set the side where the road vehicles drive
 
-	CMD_START_STOP_SHIP,              ///< start/stop a ship
 	CMD_SELL_SHIP,                    ///< sell a ship
 	CMD_BUILD_SHIP,                   ///< build a new ship
 	CMD_SEND_SHIP_TO_DEPOT,           ///< send a ship to a depot
@@ -262,6 +257,7 @@
 	CMD_SET_AUTOREPLACE,              ///< set an autoreplace entry
 
 	CMD_CLONE_VEHICLE,                ///< clone a vehicle
+	CMD_START_STOP_VEHICLE,           ///< start or stop a vehicle
 	CMD_MASS_START_STOP,              ///< start/stop all vehicles (in a depot)
 	CMD_DEPOT_SELL_ALL_VEHICLES,      ///< sell all vehicles which are in a given depot
 	CMD_DEPOT_MASS_AUTOREPLACE,       ///< force the autoreplace to take action in a given depot
--- a/src/depot_gui.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/depot_gui.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -539,10 +539,10 @@
 				uint command;
 
 				switch (this->type) {
-					case VEH_TRAIN:    command = CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN);          break;
-					case VEH_ROAD:     command = CMD_START_STOP_ROADVEH | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE); break;
-					case VEH_SHIP:     command = CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP);            break;
-					case VEH_AIRCRAFT: command = CMD_START_STOP_AIRCRAFT | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT);    break;
+					case VEH_TRAIN:    command = CMD_START_STOP_VEHICLE | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN);        break;
+					case VEH_ROAD:     command = CMD_START_STOP_VEHICLE | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE); break;
+					case VEH_SHIP:     command = CMD_START_STOP_VEHICLE | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP);         break;
+					case VEH_AIRCRAFT: command = CMD_START_STOP_VEHICLE | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT);     break;
 					default: NOT_REACHED(); command = 0;
 				}
 				DoCommandP(v->tile, v->index, 0, NULL, command);
--- a/src/roadveh_cmd.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/roadveh_cmd.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -291,42 +291,6 @@
 	return cost;
 }
 
-/** Start/Stop a road vehicle.
- * @param tile unused
- * @param flags operation to perform
- * @param p1 road vehicle ID to start/stop
- * @param p2 unused
- */
-CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
-	if (!IsValidVehicleID(p1)) return CMD_ERROR;
-
-	Vehicle *v = GetVehicle(p1);
-
-	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
-
-	/* Check if this road veh can be started/stopped. The callback will fail or
-	 * return 0xFF if it can. */
-	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
-	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
-		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
-		return_cmd_error(error);
-	}
-
-	if (flags & DC_EXEC) {
-		if (v->IsStoppedInDepot()) {
-			DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
-		}
-
-		v->vehstatus ^= VS_STOPPED;
-		v->cur_speed = 0;
-		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
-		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
-	}
-
-	return CommandCost();
-}
-
 void ClearSlot(Vehicle *v)
 {
 	RoadStop *rs = v->u.road.slot;
--- a/src/ship_cmd.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/ship_cmd.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -873,43 +873,6 @@
 	return ret;
 }
 
-/** Start/Stop a ship.
- * @param tile unused
- * @param flags type of operation
- * @param p1 ship ID to start/stop
- * @param p2 unused
- */
-CommandCost CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
-	if (!IsValidVehicleID(p1)) return CMD_ERROR;
-
-	Vehicle *v = GetVehicle(p1);
-
-	if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
-
-	/* Check if this ship can be started/stopped. The callback will fail or
-	 * return 0xFF if it can. */
-	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
-	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
-		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
-		return_cmd_error(error);
-	}
-
-	if (flags & DC_EXEC) {
-		if (v->IsStoppedInDepot()) {
-			DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
-		}
-
-		v->vehstatus ^= VS_STOPPED;
-		v->cur_speed = 0;
-		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
-		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
-		InvalidateWindowClasses(WC_SHIPS_LIST);
-	}
-
-	return CommandCost();
-}
-
 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
 {
 	const Depot *depot = FindClosestShipDepot(this);
--- a/src/train_cmd.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/train_cmd.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -1347,42 +1347,6 @@
 	return CommandCost();
 }
 
-/** Start/Stop a train.
- * @param tile unused
- * @param flags type of operation
- * @param p1 train to start/stop
- * @param p2 unused
- */
-CommandCost CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
-{
-	if (!IsValidVehicleID(p1)) return CMD_ERROR;
-
-	Vehicle *v = GetVehicle(p1);
-
-	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
-
-	/* Check if this train can be started/stopped. The callback will fail or
-	 * return 0xFF if it can. */
-	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
-	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
-		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
-		return_cmd_error(error);
-	}
-
-	if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY);
-
-	if (flags & DC_EXEC) {
-		if (v->vehstatus & VS_STOPPED && v->u.rail.track == TRACK_BIT_DEPOT) {
-			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
-		}
-
-		v->vehstatus ^= VS_STOPPED;
-		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
-		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
-	}
-	return CommandCost();
-}
-
 /** Sell a (single) train wagon/engine.
  * @param tile unused
  * @param flags type of operation
--- a/src/vehicle.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/vehicle.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -30,6 +30,7 @@
 #include "newgrf_engine.h"
 #include "newgrf_sound.h"
 #include "newgrf_station.h"
+#include "newgrf_text.h"
 #include "group.h"
 #include "order_func.h"
 #include "strings_func.h"
@@ -977,6 +978,72 @@
 	}
 }
 
+/** Start/Stop a vehicle
+ * @param tile unused
+ * @param flags type of operation
+ * @param p1 vehicle to start/stop
+ * @param p2 unused
+ * @return result of operation.  Nothing if everything went well
+ */
+CommandCost CmdStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+	if (!IsValidVehicleID(p1)) return CMD_ERROR;
+
+	Vehicle *v = GetVehicle(p1);
+
+	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+
+	switch (v->type) {
+		case VEH_TRAIN:
+			if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY);
+			break;
+
+		case VEH_SHIP:
+		case VEH_ROAD:
+			break;
+
+		case VEH_AIRCRAFT:
+			/* cannot stop airplane when in flight, or when taking off / landing */
+			if (v->u.air.state >= STARTTAKEOFF && v->u.air.state < TERM7) return_cmd_error(STR_A017_AIRCRAFT_IS_IN_FLIGHT);
+			break;
+
+		default: return CMD_ERROR;
+	}
+
+	/* Check if this vehicle can be started/stopped. The callback will fail or
+	 * return 0xFF if it can. */
+	uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+	if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
+		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+		return_cmd_error(error);
+	}
+
+	if (flags & DC_EXEC) {
+		static const StringID vehicle_waiting_in_depot[] = {
+			STR_8814_TRAIN_IS_WAITING_IN_DEPOT,
+			STR_9016_ROAD_VEHICLE_IS_WAITING,
+			STR_981C_SHIP_IS_WAITING_IN_DEPOT,
+			STR_A014_AIRCRAFT_IS_WAITING_IN,
+		};
+
+		static const WindowClass vehicle_list[] = {
+			WC_TRAINS_LIST,
+			WC_ROADVEH_LIST,
+			WC_SHIPS_LIST,
+			WC_AIRCRAFT_LIST,
+		};
+
+		if (v->IsStoppedInDepot()) DeleteVehicleNews(p1, vehicle_waiting_in_depot[v->type]);
+
+		v->vehstatus ^= VS_STOPPED;
+		v->cur_speed = 0;
+		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
+		InvalidateWindowClasses(vehicle_list[v->type]);
+	}
+	return CommandCost();
+}
+
 /** Starts or stops a lot of vehicles
  * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
  * @param flags type of operation
@@ -991,19 +1058,10 @@
 {
 	VehicleList list;
 	CommandCost return_value = CMD_ERROR;
-	uint stop_command;
 	VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5);
 	bool start_stop = HasBit(p2, 5);
 	bool vehicle_list_window = HasBit(p2, 6);
 
-	switch (vehicle_type) {
-		case VEH_TRAIN:    stop_command = CMD_START_STOP_TRAIN;    break;
-		case VEH_ROAD:     stop_command = CMD_START_STOP_ROADVEH;  break;
-		case VEH_SHIP:     stop_command = CMD_START_STOP_SHIP;     break;
-		case VEH_AIRCRAFT: stop_command = CMD_START_STOP_AIRCRAFT; break;
-		default: return CMD_ERROR;
-	}
-
 	if (vehicle_list_window) {
 		uint32 id = p1;
 		uint16 window_type = p2 & VLW_MASK;
@@ -1027,7 +1085,7 @@
 			}
 		}
 
-		CommandCost ret = DoCommand(tile, v->index, 0, flags, stop_command);
+		CommandCost ret = DoCommand(tile, v->index, 0, flags, CMD_START_STOP_VEHICLE);
 
 		if (CmdSucceeded(ret)) {
 			return_value = CommandCost();
--- a/src/vehicle_gui.cpp	Fri Aug 15 12:47:20 2008 +0000
+++ b/src/vehicle_gui.cpp	Fri Aug 15 13:57:43 2008 +0000
@@ -1627,10 +1627,10 @@
 /** Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type. */
 static const uint32 _vehicle_command_translation_table[][4] = {
 	{ // VCT_CMD_START_STOP
-		CMD_START_STOP_TRAIN | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN),
-		CMD_START_STOP_ROADVEH | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE),
-		CMD_START_STOP_SHIP | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP),
-		CMD_START_STOP_AIRCRAFT | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT)
+		CMD_START_STOP_VEHICLE | CMD_MSG(STR_883B_CAN_T_STOP_START_TRAIN),
+		CMD_START_STOP_VEHICLE | CMD_MSG(STR_9015_CAN_T_STOP_START_ROAD_VEHICLE),
+		CMD_START_STOP_VEHICLE | CMD_MSG(STR_9818_CAN_T_STOP_START_SHIP),
+		CMD_START_STOP_VEHICLE | CMD_MSG(STR_A016_CAN_T_STOP_START_AIRCRAFT)
 	},
 	{ // VCT_CMD_GOTO_DEPOT
 		/* TrainGotoDepot has a nice randomizer in the pathfinder, which causes desyncs... */