changeset 18658:227eb97ed2f6 draft

(svn r23506) -Add: [NoAI] Support for dealing with aircraft range.
author michi_cc <michi_cc@openttd.org>
date Tue, 13 Dec 2011 00:43:59 +0000
parents 599d7cf176cf
children c625331ace43
files src/ai/ai_instance.cpp src/aircraft_cmd.cpp src/script/api/ai/ai_engine.hpp.sq src/script/api/ai/ai_event.hpp.sq src/script/api/ai/ai_event_types.hpp.sq src/script/api/ai/ai_order.hpp.sq src/script/api/ai/ai_vehicle.hpp.sq src/script/api/ai_changelog.hpp src/script/api/script_engine.cpp src/script/api/script_engine.hpp src/script/api/script_event.hpp src/script/api/script_event_types.hpp src/script/api/script_order.cpp src/script/api/script_order.hpp src/script/api/script_vehicle.cpp src/script/api/script_vehicle.hpp src/script/api/template/template_event_types.hpp.sq
diffstat 17 files changed, 179 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -122,6 +122,7 @@
 	SQAIEngineList_Register(this->engine);
 	SQAIError_Register(this->engine);
 	SQAIEvent_Register(this->engine);
+	SQAIEventAircraftDestTooFar_Register(this->engine);
 	SQAIEventCompanyAskMerger_Register(this->engine);
 	SQAIEventCompanyBankrupt_Register(this->engine);
 	SQAIEventCompanyInTrouble_Register(this->engine);
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -1855,6 +1855,7 @@
 		if (!HasBit(v->flags, VAF_DEST_TOO_FAR)) {
 			SetBit(v->flags, VAF_DEST_TOO_FAR);
 			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+			AI::NewEvent(v->owner, new ScriptEventAircraftDestTooFar(v->index));
 			if (v->owner == _local_company) {
 				/* Post a news message. */
 				SetDParam(0, v->index);
--- a/src/script/api/ai/ai_engine.hpp.sq
+++ b/src/script/api/ai/ai_engine.hpp.sq
@@ -21,30 +21,31 @@
 	SQAIEngine.PreRegister(engine);
 	SQAIEngine.AddConstructor<void (ScriptEngine::*)(), 1>(engine, "x");
 
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsValidEngine,        "IsValidEngine",        2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsBuildable,          "IsBuildable",          2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetName,              "GetName",              2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetCargoType,         "GetCargoType",         2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRefitCargo,        "CanRefitCargo",        3, ".ii");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanPullCargo,         "CanPullCargo",         3, ".ii");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetCapacity,          "GetCapacity",          2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetReliability,       "GetReliability",       2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxSpeed,          "GetMaxSpeed",          2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPrice,             "GetPrice",             2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxAge,            "GetMaxAge",            2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRunningCost,       "GetRunningCost",       2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPower,             "GetPower",             2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetWeight,            "GetWeight",            2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxTractiveEffort, "GetMaxTractiveEffort", 2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetDesignDate,        "GetDesignDate",        2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetVehicleType,       "GetVehicleType",       2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsWagon,              "IsWagon",              2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRail,         "CanRunOnRail",         3, ".ii");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRail,       "HasPowerOnRail",       3, ".ii");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRoadType,          "GetRoadType",          2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRailType,          "GetRailType",          2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsArticulated,        "IsArticulated",        2, ".i");
-	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPlaneType,         "GetPlaneType",         2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsValidEngine,           "IsValidEngine",           2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsBuildable,             "IsBuildable",             2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetName,                 "GetName",                 2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetCargoType,            "GetCargoType",            2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRefitCargo,           "CanRefitCargo",           3, ".ii");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanPullCargo,            "CanPullCargo",            3, ".ii");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetCapacity,             "GetCapacity",             2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetReliability,          "GetReliability",          2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxSpeed,             "GetMaxSpeed",             2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPrice,                "GetPrice",                2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxAge,               "GetMaxAge",               2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRunningCost,          "GetRunningCost",          2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPower,                "GetPower",                2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetWeight,               "GetWeight",               2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaxTractiveEffort,    "GetMaxTractiveEffort",    2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetDesignDate,           "GetDesignDate",           2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetVehicleType,          "GetVehicleType",          2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsWagon,                 "IsWagon",                 2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRail,            "CanRunOnRail",            3, ".ii");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRail,          "HasPowerOnRail",          3, ".ii");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRoadType,             "GetRoadType",             2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRailType,             "GetRailType",             2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsArticulated,           "IsArticulated",           2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPlaneType,            "GetPlaneType",            2, ".i");
+	SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaximumOrderDistance, "GetMaximumOrderDistance", 2, ".i");
 
 	SQAIEngine.PostRegister(engine);
 }
--- a/src/script/api/ai/ai_event.hpp.sq
+++ b/src/script/api/ai/ai_event.hpp.sq
@@ -44,6 +44,7 @@
 	SQAIEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CRASHED, "ET_DISASTER_ZEPPELINER_CRASHED");
 	SQAIEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
 	SQAIEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED,                "ET_TOWN_FOUNDED");
+	SQAIEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR,       "ET_AIRCRAFT_DEST_TOO_FAR");
 
 	SQAIEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
 
--- a/src/script/api/ai/ai_event_types.hpp.sq
+++ b/src/script/api/ai/ai_event_types.hpp.sq
@@ -346,3 +346,18 @@
 
 	SQAIEventTownFounded.PostRegister(engine);
 }
+
+
+template <> const char *GetClassName<ScriptEventAircraftDestTooFar, ST_AI>() { return "AIEventAircraftDestTooFar"; }
+
+void SQAIEventAircraftDestTooFar_Register(Squirrel *engine)
+{
+	DefSQClass<ScriptEventAircraftDestTooFar, ST_AI> SQAIEventAircraftDestTooFar("AIEventAircraftDestTooFar");
+	SQAIEventAircraftDestTooFar.PreRegister(engine, "AIEvent");
+
+	SQAIEventAircraftDestTooFar.DefSQStaticMethod(engine, &ScriptEventAircraftDestTooFar::Convert, "Convert", 2, ".x");
+
+	SQAIEventAircraftDestTooFar.DefSQMethod(engine, &ScriptEventAircraftDestTooFar::GetVehicleID, "GetVehicleID", 1, "x");
+
+	SQAIEventAircraftDestTooFar.PostRegister(engine);
+}
--- a/src/script/api/ai/ai_order.hpp.sq
+++ b/src/script/api/ai/ai_order.hpp.sq
@@ -24,6 +24,7 @@
 	SQAIOrder.DefSQConst(engine, ScriptOrder::ERR_ORDER_BASE,                                   "ERR_ORDER_BASE");
 	SQAIOrder.DefSQConst(engine, ScriptOrder::ERR_ORDER_TOO_MANY,                               "ERR_ORDER_TOO_MANY");
 	SQAIOrder.DefSQConst(engine, ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, "ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION");
+	SQAIOrder.DefSQConst(engine, ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE,              "ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE");
 	SQAIOrder.DefSQConst(engine, ScriptOrder::AIOF_NONE,                                        "AIOF_NONE");
 	SQAIOrder.DefSQConst(engine, ScriptOrder::AIOF_NON_STOP_INTERMEDIATE,                       "AIOF_NON_STOP_INTERMEDIATE");
 	SQAIOrder.DefSQConst(engine, ScriptOrder::AIOF_NON_STOP_DESTINATION,                        "AIOF_NON_STOP_DESTINATION");
@@ -67,9 +68,11 @@
 
 	ScriptError::RegisterErrorMap(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS,          ScriptOrder::ERR_ORDER_TOO_MANY);
 	ScriptError::RegisterErrorMap(STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION, ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION);
+	ScriptError::RegisterErrorMap(STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE,         ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE);
 
 	ScriptError::RegisterErrorMapString(ScriptOrder::ERR_ORDER_TOO_MANY,                               "ERR_ORDER_TOO_MANY");
 	ScriptError::RegisterErrorMapString(ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, "ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION");
+	ScriptError::RegisterErrorMapString(ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE,              "ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE");
 
 	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::IsValidVehicleOrder,           "IsValidVehicleOrder",           3, ".ii");
 	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::IsGotoStationOrder,            "IsGotoStationOrder",            3, ".ii");
@@ -108,6 +111,7 @@
 	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::CopyOrders,                    "CopyOrders",                    3, ".ii");
 	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::ShareOrders,                   "ShareOrders",                   3, ".ii");
 	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::UnshareOrders,                 "UnshareOrders",                 2, ".i");
+	SQAIOrder.DefSQStaticMethod(engine, &ScriptOrder::GetOrderDistance,              "GetOrderDistance",              4, ".iii");
 
 	SQAIOrder.PostRegister(engine);
 }
--- a/src/script/api/ai/ai_vehicle.hpp.sq
+++ b/src/script/api/ai/ai_vehicle.hpp.sq
@@ -141,6 +141,7 @@
 	SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::IsArticulated,                  "IsArticulated",                  2, ".i");
 	SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::HasSharedOrders,                "HasSharedOrders",                2, ".i");
 	SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::GetReliability,                 "GetReliability",                 2, ".i");
+	SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::GetMaximumOrderDistance,        "GetMaximumOrderDistance",        2, ".i");
 
 	SQAIVehicle.PostRegister(engine);
 }
--- a/src/script/api/ai_changelog.hpp
+++ b/src/script/api/ai_changelog.hpp
@@ -32,8 +32,12 @@
  * \li AICompany::GetQuarterlyPerformanceRating
  * \li AICompany::GetQuarterlyCompanyValue
  * \li AIController::GetOpsTillSuspend
+ * \li AIEngine::GetMaximumOrderDistance
+ * \li AIEventAircraftDestTooFar
  * \li AIInfo::CONFIG_DEVELOPER
  * \li AIInfrastructure
+ * \li AIOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE
+ * \li AIOrder::GetOrderDistance
  * \li AIOrder::GetOrderRefit
  * \li AIOrder::IsRefitOrder
  * \li AIOrder::SetOrderRefit
@@ -45,6 +49,7 @@
  * \li AITown::GetTownAuthority
  * \li AITownEffectList (to walk over all available town effects)
  * \li AIVehicle::ERR_VEHICLE_TOO_LONG in case vehicle length limit is reached
+ * \li AIVehicle::GetMaximumOrderDistance
  *
  * API renames:
  * \li AITown::GetLastMonthTransported to AITown::GetLastMonthSupplied to better
--- a/src/script/api/script_engine.cpp
+++ b/src/script/api/script_engine.cpp
@@ -248,3 +248,19 @@
 
 	return (ScriptAirport::PlaneType)::AircraftVehInfo(engine_id)->subtype;
 }
+
+/* static */ uint ScriptEngine::GetMaximumOrderDistance(EngineID engine_id)
+{
+	if (!IsValidEngine(engine_id)) return 0;
+
+	switch (GetVehicleType(engine_id)) {
+		case ScriptVehicle::VT_WATER:
+			return _settings_game.pf.pathfinder_for_ships != VPF_NPF ? 129 : 0;
+
+		case ScriptVehicle::VT_AIR:
+			return ::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange();
+
+		default:
+			return 0;
+	}
+}
--- a/src/script/api/script_engine.hpp
+++ b/src/script/api/script_engine.hpp
@@ -250,6 +250,16 @@
 	 * @return The PlaneType the engine has.
 	 */
 	static ScriptAirport::PlaneType GetPlaneType(EngineID engine_id);
+
+	/**
+	 * Get the maximum allowed distance between two orders for an engine.
+	 * @param vehicle_id The engine to get the max distance for.
+	 * @pre IsValidEngine(engine_id).
+	 * @return The maximum distance between two orders for the engine
+	 *  or 0 if the distance is unlimited.
+	 * @see ScriptOrder::GetOrderDistance
+	 */
+	static uint GetMaximumOrderDistance(EngineID engine_id);
 };
 
 #endif /* SCRIPT_ENGINE_HPP */
--- a/src/script/api/script_event.hpp
+++ b/src/script/api/script_event.hpp
@@ -49,6 +49,7 @@
 		ET_DISASTER_ZEPPELINER_CRASHED,
 		ET_DISASTER_ZEPPELINER_CLEARED,
 		ET_TOWN_FOUNDED,
+		ET_AIRCRAFT_DEST_TOO_FAR,
 	};
 
 	/**
--- a/src/script/api/script_event_types.hpp
+++ b/src/script/api/script_event_types.hpp
@@ -796,4 +796,37 @@
 	TownID town; ///< The town that got founded.
 };
 
+/**
+ * Event AircraftDestTooFar, indicating the next destination of an aircraft is too far away.
+ * This event can be trigger when the current oder of an aircraft changes, usually either when
+ * loading is done or when switch manually.
+ * @api ai
+ */
+class ScriptEventAircraftDestTooFar : public ScriptEvent {
+public:
+	/**
+	 * @param vehicle_id The aircraft whose destination is too far away.
+	 */
+	ScriptEventAircraftDestTooFar(VehicleID vehicle_id) :
+		ScriptEvent(ET_AIRCRAFT_DEST_TOO_FAR),
+		vehicle_id(vehicle_id)
+	{}
+
+	/**
+	 * Convert an ScriptEvent to the real instance.
+	 * @param instance The instance to convert.
+	 * @return The converted instance.
+	 */
+	static ScriptEventAircraftDestTooFar *Convert(ScriptEvent *instance) { return (ScriptEventAircraftDestTooFar *)instance; }
+
+	/**
+	 * Get the VehicleID of the aircraft whose destination is too far away.
+	 * @return The VehicleID of the aircraft whose destination is too far away.
+	 */
+	VehicleID GetVehicleID() { return this->vehicle_id; }
+
+private:
+	VehicleID vehicle_id; ///< The vehicle aircraft whose destination is too far away.
+};
+
 #endif /* SCRIPT_EVENT_TYPES_HPP */
--- a/src/script/api/script_order.cpp
+++ b/src/script/api/script_order.cpp
@@ -13,6 +13,7 @@
 #include "script_order.hpp"
 #include "script_vehicle.hpp"
 #include "script_cargo.hpp"
+#include "script_map.hpp"
 #include "../script_instance.hpp"
 #include "../../debug.h"
 #include "../../vehicle_base.h"
@@ -655,3 +656,15 @@
 
 	return ScriptObject::DoCommand(0, vehicle_id | CO_UNSHARE << 30, 0, CMD_CLONE_ORDER);
 }
+
+/* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile)
+{
+	if (vehicle_type == ScriptVehicle::VT_AIR) {
+		if (ScriptTile::IsStationTile(origin_tile) && ::Station::Get(origin_tile)->airport.tile != INVALID_TILE) origin_tile = ::Station::Get(origin_tile)->airport.tile;
+		if (ScriptTile::IsStationTile(dest_tile) && ::Station::Get(dest_tile)->airport.tile != INVALID_TILE) dest_tile = ::Station::Get(dest_tile)->airport.tile;
+
+		return ScriptMap::DistanceSquare(origin_tile, dest_tile);
+	} else {
+		return ScriptMap::DistanceManhattan(origin_tile, dest_tile);
+	}
+}
--- a/src/script/api/script_order.hpp
+++ b/src/script/api/script_order.hpp
@@ -13,6 +13,7 @@
 #define SCRIPT_ORDER_HPP
 
 #include "script_error.hpp"
+#include "script_vehicle.hpp"
 
 /**
  * Class that handles all order related functions.
@@ -32,6 +33,9 @@
 
 		/** Destination of new order is to far away from the previous order */
 		ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION,    // [STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION]
+
+		/* Aircraft has not enough range to copy/share orders. */
+		ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE,                 // [STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE]
 	};
 
 	/**
@@ -532,6 +536,7 @@
 	 * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id).
 	 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
 	 * @exception ScriptOrder::ERR_ORDER_TOO_MANY
+	 * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE
 	 * @return True if and only if the copying succeeded.
 	 */
 	static bool CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
@@ -544,6 +549,7 @@
 	 * @pre ScriptVehicle::IsValidVehicle(vehicle_id).
 	 * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id).
 	 * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY
+	 * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE
 	 * @return True if and only if the sharing succeeded.
 	 */
 	static bool ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
@@ -555,6 +561,16 @@
 	 * @return True if and only if the unsharing succeeded.
 	 */
 	static bool UnshareOrders(VehicleID vehicle_id);
+
+	/**
+	 * Get the distance between two points for a vehicle type.
+	 * @param vehicle_type The vehicle type to get the distance for.
+	 * @param origin_tile Origin, can be any tile or a tile of a specific station.
+	 * @param dest_tile Destination, ca be any tile or a tile of a specific station.
+	 * @return The distance between the origin and the destination for a vehicle of the given vehicle type.
+	 * @see ScriptEngine::GetMaximumOrderDistance and ScriptVehicle::GetMaximumOrderDistance
+	 */
+	static uint GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile);
 };
 DECLARE_ENUM_AS_BIT_SET(ScriptOrder::ScriptOrderFlags)
 
--- a/src/script/api/script_vehicle.cpp
+++ b/src/script/api/script_vehicle.cpp
@@ -22,6 +22,7 @@
 #include "../../roadveh.h"
 #include "../../train.h"
 #include "../../vehicle_func.h"
+#include "../../aircraft.h"
 #include "table/strings.h"
 
 /* static */ bool ScriptVehicle::IsValidVehicle(VehicleID vehicle_id)
@@ -421,3 +422,20 @@
 	const Vehicle *v = ::Vehicle::Get(vehicle_id);
 	return ::ToPercent16(v->reliability);
 }
+
+/* static */ uint ScriptVehicle::GetMaximumOrderDistance(VehicleID vehicle_id)
+{
+	if (!IsValidVehicle(vehicle_id)) return 0;
+
+	const ::Vehicle *v = ::Vehicle::Get(vehicle_id);
+	switch (v->type) {
+		case VEH_SHIP:
+			return _settings_game.pf.pathfinder_for_ships != VPF_NPF ? 129 : 0;
+
+		case VEH_AIRCRAFT:
+			return ::Aircraft::From(v)->acache.cached_max_range_sqr;
+
+		default:
+			return 0;
+	}
+}
--- a/src/script/api/script_vehicle.hpp
+++ b/src/script/api/script_vehicle.hpp
@@ -527,6 +527,16 @@
 	 */
 	static int GetReliability(VehicleID vehicle_id);
 
+	/**
+	 * Get the maximum allowed distance between two orders for a vehicle.
+	 * @param vehicle_id The vehicle to get the distance for.
+	 * @pre IsValidVehicle(vehicle_id).
+	 * @return The maximum distance between two orders for this vehicle
+	 *  or 0 if the distance is unlimited.
+	 * @see ScriptOrder::GetOrderDistance
+	 */
+	static uint GetMaximumOrderDistance(VehicleID vehicle_id);
+
 private:
 	/**
 	 * Internal function used by SellWagon(Chain).
--- a/src/script/api/template/template_event_types.hpp.sq
+++ b/src/script/api/template/template_event_types.hpp.sq
@@ -203,3 +203,12 @@
 	template <> inline const ScriptEventTownFounded &GetParam(ForceType<const ScriptEventTownFounded &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventTownFounded *)instance; }
 	template <> inline int Return<ScriptEventTownFounded *>(HSQUIRRELVM vm, ScriptEventTownFounded *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventTownFounded", res, NULL, DefSQDestructorCallback<ScriptEventTownFounded>, true); return 1; }
 } // namespace SQConvert
+
+namespace SQConvert {
+	/* Allow ScriptEventAircraftDestTooFar to be used as Squirrel parameter */
+	template <> inline ScriptEventAircraftDestTooFar *GetParam(ForceType<ScriptEventAircraftDestTooFar *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptEventAircraftDestTooFar *)instance; }
+	template <> inline ScriptEventAircraftDestTooFar &GetParam(ForceType<ScriptEventAircraftDestTooFar &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; }
+	template <> inline const ScriptEventAircraftDestTooFar *GetParam(ForceType<const ScriptEventAircraftDestTooFar *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptEventAircraftDestTooFar *)instance; }
+	template <> inline const ScriptEventAircraftDestTooFar &GetParam(ForceType<const ScriptEventAircraftDestTooFar &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; }
+	template <> inline int Return<ScriptEventAircraftDestTooFar *>(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, NULL, DefSQDestructorCallback<ScriptEventAircraftDestTooFar>, true); return 1; }
+} // namespace SQConvert