(svn r10556) [NoAI] -Add: added AIAirport, which can build an airport noai
authortruelight
Fri, 13 Jul 2007 23:18:12 +0000
branchnoai
changeset 9654 b836eb5c521f
parent 9653 50e2eb4abf46
child 9655 e8e43f333832
(svn r10556) [NoAI] -Add: added AIAirport, which can build an airport
[NoAI] -Add: added FindBestAircraft in AIVehicle
[NoAI] -Add: finished all AIVehicle commands for non-RVs
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
projects/openttd.vcproj
projects/openttd_vs80.vcproj
source.list
src/ai/ai_squirrel.cpp
src/ai/api/ai_airport.cpp
src/ai/api/ai_airport.hpp
src/ai/api/ai_airport.hpp.sq
src/ai/api/ai_vehicle.cpp
src/ai/api/ai_vehicle.hpp
src/ai/api/ai_vehicle.hpp.sq
--- a/bin/ai/regression/regression.nut	Fri Jul 13 19:54:59 2007 +0000
+++ b/bin/ai/regression/regression.nut	Fri Jul 13 23:18:12 2007 +0000
@@ -55,6 +55,38 @@
 	print("  Chance(1, 2): " + base.Chance(1, 2));
 }
 
+function Regression::Airport()
+{
+	local airport = AIAirport();
+	local company = AICompany();
+
+	print("");
+	print("--AIAirport--");
+
+	print("  IsHangarTile():       " + airport.IsHangarTile(32116));
+	print("  IsAirportTile():      " + airport.IsAirportTile(32116));
+	print("  GetHangarOfAirport(): " + airport.GetHangarOfAirport(32116));
+
+	for (local i = -1; i < 10; i++) {
+		print("  AiportAvailable(" + i + "):   " + airport.AiportAvailable(i));
+	}
+
+	print("  GetBankBalance():     " + company.GetBankBalance());
+	print("  BuildAirport():       " + airport.BuildAirport(32116, 0));
+	print("  IsHangarTile():       " + airport.IsHangarTile(32116));
+	print("  IsAirportTile():      " + airport.IsAirportTile(32116));
+	print("  GetHangarOfAirport(): " + airport.GetHangarOfAirport(32116));
+	print("  IsHangarTile():       " + airport.IsHangarTile(32119));
+	print("  IsAirportTile():      " + airport.IsAirportTile(32119));
+	print("  GetBankBalance():     " + company.GetBankBalance());
+
+	print("  RemoveAirport():      " + airport.RemoveAirport(32118));
+	print("  IsHangarTile():       " + airport.IsHangarTile(32119));
+	print("  IsAirportTile():      " + airport.IsAirportTile(32119));
+	print("  GetBankBalance():     " + company.GetBankBalance());
+	print("  BuildAirport():       " + airport.BuildAirport(32116, 0));
+}
+
 function Regression::Cargo()
 {
 	local cargo = AICargo();
@@ -265,7 +297,7 @@
 		print("    " + i + " => " + list.GetValue(i));
 	}
 
-	list = AIStationVehicleList(0);
+	list = AIStationVehicleList(1);
 
 	print("");
 	print("--StationVehicleList--");
@@ -394,7 +426,7 @@
 	print("--Station--");
 	print("  IsValidStation(0):        " + station.IsValidStation(0));
 	print("  IsValidStation(1000):     " + station.IsValidStation(1000));
-	print("  GetLocation(0):           " + station.GetLocation(0));
+	print("  GetLocation(1):           " + station.GetLocation(1));
 	print("  GetLocation(1000):        " + station.GetLocation(1000));
 	print("  GetCargoWaiting(0, 0):    " + station.GetCargoWaiting(0, 0));
 	print("  GetCargoWaiting(1000, 0): " + station.GetCargoWaiting(1000, 0));
@@ -548,6 +580,12 @@
 		print("    Reliability 50:     " + vehicle.FindBestRoadVehicle(i, 50));
 		print("    Reliability 100:    " + vehicle.FindBestRoadVehicle(i, 100));
 	}
+	for (local i = -1; i < 15; i++) {
+		print("  FindBestAircraftVehicle Cargo " + i);
+		print("    Reliability 0:      " + vehicle.FindBestAircraftVehicle(i, 0));
+		print("    Reliability 50:     " + vehicle.FindBestAircraftVehicle(i, 50));
+		print("    Reliability 100:    " + vehicle.FindBestAircraftVehicle(i, 100));
+	}
 
 	local bank = company.GetBankBalance();
 
@@ -595,6 +633,9 @@
 	print("    GetProfitThisYear(): " + vehicle.GetProfitThisYear(1024));
 	print("    GetProfitLastYear(): " + vehicle.GetProfitLastYear(1024));
 
+	print("  BuildVehicle():       " + vehicle.BuildVehicle(32119, 219));
+	print("  IsValidVehicle(1026): " + vehicle.IsValidVehicle(1026));
+
 	local list = AIVehicleList();
 
 	print("");
@@ -648,6 +689,7 @@
 	this.TestInit();
 	this.Std();
 	this.Base();
+	this.Airport();
 	this.Cargo();
 	this.Company();
 	this.Industry();
--- a/bin/ai/regression/regression.txt	Fri Jul 13 19:54:59 2007 +0000
+++ b/bin/ai/regression/regression.txt	Fri Jul 13 23:18:12 2007 +0000
@@ -28,6 +28,35 @@
   Chance(1, 2): true
   Chance(1, 2): false
 
+--AIAirport--
+  IsHangarTile():       false
+  IsAirportTile():      false
+  GetHangarOfAirport(): -1
+  AiportAvailable(-1):   false
+  AiportAvailable(0):   true
+  AiportAvailable(1):   false
+  AiportAvailable(2):   false
+  AiportAvailable(3):   false
+  AiportAvailable(4):   false
+  AiportAvailable(5):   false
+  AiportAvailable(6):   false
+  AiportAvailable(7):   false
+  AiportAvailable(8):   false
+  AiportAvailable(9):   false
+  GetBankBalance():     100000
+  BuildAirport():       true
+  IsHangarTile():       false
+  IsAirportTile():      true
+  GetHangarOfAirport(): 32119
+  IsHangarTile():       true
+  IsAirportTile():      true
+  GetBankBalance():     90100
+  RemoveAirport():      true
+  IsHangarTile():       false
+  IsAirportTile():      false
+  GetBankBalance():     89836
+  BuildAirport():       true
+
 --AICargo--
   Cargo -1
     IsValidCargo():          false
@@ -168,17 +197,17 @@
   SetPresidentName():   true
   GetPresidentName():   Regression AI
   GetCompanyValue():    0
-  GetBankBalance():     100000
+  GetBankBalance():     84436
   GetLoanAmount():      100000
   GetMaxLoanAmount():   300000
   GetLoanInterval():    10000
   SetLoanAmount(1):     false
   SetLoanAmount(100):   false
+  SetLoanAmount(10000): false
+  GetBankBalance():     84436
+  GetLoanAmount():      100000
   SetLoanAmount(10000): true
-  GetBankBalance():     10000
-  GetLoanAmount():      10000
-  SetLoanAmount(10000): true
-  GetBankBalance():     300000
+  GetBankBalance():     284436
   GetLoanAmount():      300000
 
 --Industry--
@@ -792,7 +821,7 @@
 --Station--
   IsValidStation(0):        true
   IsValidStation(1000):     false
-  GetLocation(0):           33411
+  GetLocation(1):           33411
   GetLocation(1000):        -1
   GetCargoWaiting(0, 0):    0
   GetCargoWaiting(1000, 0): -1
@@ -801,14 +830,14 @@
 --StationList--
   Count():             2
   Location ListDump:
-    1 => 33421
-    0 => 33411
+    2 => 33421
+    1 => 33411
   CargoWaiting(0) ListDump:
+    2 => 0
     1 => 0
-    0 => 0
   CargoWaiting(1) ListDump:
+    2 => 0
     1 => 0
-    0 => 0
 
 --TileList--
   Count():             0
@@ -1696,6 +1725,70 @@
     Reliability 0:      65535
     Reliability 50:     65535
     Reliability 100:    65535
+  FindBestAircraftVehicle Cargo -1
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 0
+    Reliability 0:      219
+    Reliability 50:     219
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 1
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 2
+    Reliability 0:      219
+    Reliability 50:     219
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 3
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 4
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 5
+    Reliability 0:      219
+    Reliability 50:     219
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 6
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 7
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 8
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 9
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 10
+    Reliability 0:      219
+    Reliability 50:     219
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 11
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 12
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 13
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
+  FindBestAircraftVehicle Cargo 14
+    Reliability 0:      65535
+    Reliability 50:     65535
+    Reliability 100:    65535
   BuildVehicle():       0
   IsValidVehicle(1024): false
   --Transaction--
@@ -1723,31 +1816,41 @@
     GetAgeLeft():        5490
     GetProfitThisYear(): 0
     GetProfitLastYear(): 0
+  BuildVehicle():       1026
+  IsValidVehicle(1026): true
 
 --VehicleList--
-  Count():             2
+  Count():             3
   Location ListDump:
     1025 => 33417
     1024 => 33417
+    1026 => 32119
   EngineType ListDump:
+    1026 => 219
     1025 => 153
     1024 => 153
   UnitNumber ListDump:
     1025 => 2
+    1026 => 1
     1024 => 1
   Age ListDump:
+    1026 => 0
     1025 => 0
     1024 => 0
   MaxAge ListDump:
+    1026 => 10980
     1025 => 5490
     1024 => 5490
   AgeLeft ListDump:
+    1026 => 10980
     1025 => 5490
     1024 => 5490
   ProfitThisYear ListDump:
+    1026 => 0
     1025 => 0
     1024 => 0
   ProfitLastYear ListDump:
+    1026 => 0
     1025 => 0
     1024 => 0
 
@@ -1774,17 +1877,17 @@
 --VehicleStationList--
   Count():             2
   Location ListDump:
-    1 => 33421
-    0 => 33411
+    2 => 33421
+    1 => 33411
   CargoWaiting(0) ListDump:
+    2 => 0
     1 => 0
-    0 => 0
   CargoWaiting(1) ListDump:
+    2 => 0
     1 => 0
-    0 => 0
   CargoRating(1) ListDump:
+    2 => 69
     1 => 69
-    0 => 69
 
 --StationVehicleList--
   Count():             1
--- a/projects/openttd.vcproj	Fri Jul 13 19:54:59 2007 +0000
+++ b/projects/openttd.vcproj	Fri Jul 13 23:18:12 2007 +0000
@@ -1081,6 +1081,9 @@
 				RelativePath=".\..\src\ai\api\ai_accounting.hpp">
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_airport.hpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_base.hpp">
 			</File>
 			<File
@@ -1184,6 +1187,9 @@
 				RelativePath=".\..\src\ai\api\ai_accounting.cpp">
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_airport.cpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_base.cpp">
 			</File>
 			<File
--- a/projects/openttd_vs80.vcproj	Fri Jul 13 19:54:59 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Fri Jul 13 23:18:12 2007 +0000
@@ -1660,6 +1660,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_airport.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_base.hpp"
 				>
 			</File>
@@ -1796,6 +1800,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\ai\api\ai_airport.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_base.cpp"
 				>
 			</File>
--- a/source.list	Fri Jul 13 19:54:59 2007 +0000
+++ b/source.list	Fri Jul 13 23:18:12 2007 +0000
@@ -333,6 +333,7 @@
 # AI API
 ai/api/ai_abstractlist.hpp
 ai/api/ai_accounting.hpp
+ai/api/ai_airport.hpp
 ai/api/ai_base.hpp
 ai/api/ai_cargo.hpp
 ai/api/ai_company.hpp
@@ -368,6 +369,7 @@
 # AI API Implementation
 ai/api/ai_abstractlist.cpp
 ai/api/ai_accounting.cpp
+ai/api/ai_airport.cpp
 ai/api/ai_base.cpp
 ai/api/ai_cargo.cpp
 ai/api/ai_company.cpp
--- a/src/ai/ai_squirrel.cpp	Fri Jul 13 19:54:59 2007 +0000
+++ b/src/ai/ai_squirrel.cpp	Fri Jul 13 23:18:12 2007 +0000
@@ -23,6 +23,7 @@
  * Note: this line a marker in squirrel_export.sh. Do not change! */
 #include "api/ai_abstractlist.hpp.sq"
 #include "api/ai_accounting.hpp.sq"
+#include "api/ai_airport.hpp.sq"
 #include "api/ai_base.hpp.sq"
 #include "api/ai_cargo.hpp.sq"
 #include "api/ai_company.hpp.sq"
@@ -207,6 +208,7 @@
 	squirrel_register_std(this->engine);
 	SQAIAbstractListRegister(this->engine);
 	SQAIAccountingRegister(this->engine);
+	SQAIAirportRegister(this->engine);
 	SQAIBaseRegister(this->engine);
 	SQAICargoRegister(this->engine);
 	SQAICompanyRegister(this->engine);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_airport.cpp	Fri Jul 13 23:18:12 2007 +0000
@@ -0,0 +1,59 @@
+/* $Id$ */
+
+#include "ai_airport.hpp"
+#include "../../command.h"
+#include "../../station_map.h"
+
+
+bool AIAirport::IsHangarTile(TileIndex tile)
+{
+	/* Outside of the map */
+	if (tile >= ::MapSize()) return false;
+
+	return ::IsTileType(tile, MP_STATION) && ::IsHangar(tile);
+}
+
+bool AIAirport::IsAirportTile(TileIndex tile)
+{
+	/* Outside of the map */
+	if (tile >= ::MapSize()) return false;
+
+	return ::IsTileType(tile, MP_STATION) && ::IsAirport(tile);
+}
+
+bool AIAirport::AiportAvailable(AirportType type)
+{
+	/* Small airport is always available */
+	if (type == AT_SMALL) return true;
+	/* The rest has to be looked up */
+	return HASBIT(::GetValidAirports(), type);
+}
+
+bool AIAirport::BuildAirport(TileIndex tile, AirportType type)
+{
+	/* Outside of the map */
+	if (tile >= ::MapSize()) return false;
+
+	return this->DoCommand(tile, type, 0, CMD_BUILD_AIRPORT);
+}
+
+bool AIAirport::RemoveAirport(TileIndex tile)
+{
+	/* Outside of the map */
+	if (tile >= ::MapSize()) return false;
+
+	/* Not a airport tile */
+	if (!IsAirportTile(tile) && !IsHangarTile(tile)) return false;
+
+	return this->DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
+}
+
+TileIndex AIAirport::GetHangarOfAirport(TileIndex tile)
+{
+	if (!IsTileType(tile, MP_STATION)) return INVALID_TILE;
+
+	const Station *st = GetStationByTile(tile);
+	if (st->owner != _current_player) return INVALID_TILE;
+
+	return ToTileIndexDiff(st->Airport()->airport_depots[0]) + st->xy;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_airport.hpp	Fri Jul 13 23:18:12 2007 +0000
@@ -0,0 +1,80 @@
+/* $Id$ */
+
+/** @file ai_airport.hpp Everything to query and build airports */
+
+#ifndef AI_AIRPORT_HPP
+#define AI_AIRPORT_HPP
+
+#include "ai_object.hpp"
+
+/**
+ * Class that handles all airport related functions.
+ */
+class AIAirport : public AIObject {
+public:
+	enum AirportType {
+		AT_SMALL         =   0,
+		AT_LARGE         =   1,
+		AT_HELIPORT      =   2,
+		AT_METROPOLITAN  =   3,
+		AT_INTERNATIONAL =   4,
+		AT_COMMUTER      =   5,
+		AT_HELIDEPOT     =   6,
+		AT_INTERCON      =   7,
+		AT_HELISTATION   =   8,
+	};
+
+	/**
+	 * The name of the class, needed by several sub-processes.
+	 */
+	static const char *GetClassName() { return "AIAirport"; }
+
+	/**
+	 * Checks whether the given tile is actually a tile with a hangar.
+	 * @param tile the tile to check.
+	 * @pre tile is always positive and smaller than AIMap::GetMapSize().
+	 * @return true if and only if the tile has a hangar.
+	 */
+	bool IsHangarTile(TileIndex tile);
+
+	/**
+	 * Checks whether the given tile is actually a tile with a airport.
+	 * @param tile the tile to check.
+	 * @pre tile is always positive and smaller than AIMap::GetMapSize().
+	 * @return true if and only if the tile has a airport.
+	 */
+	bool IsAirportTile(TileIndex tile);
+
+	/**
+	 * Check if a certain airport type is already available.
+	 * @param type the type of airport to check.
+	 */
+	bool AiportAvailable(AirportType type);
+
+	/**
+	 * Builds a airport with tile at the topleft corner.
+	 * @param tile the topleft corner of the airport.
+	 * @param type the type of airport to build.
+	 * @pre tile is always positive and smaller than AIMap::GetMapSize().
+	 * @return whether the airport has been/can be build or not.
+	 */
+	bool BuildAirport(TileIndex tile, AirportType type);
+
+	/**
+	 * Removes a airport.
+	 * @param tile any tile of the airport.
+	 * @pre tile is always positive and smaller than AIMap::GetMapSize().
+	 * @return whether the airport has been/can be removed or not.
+	 */
+	bool RemoveAirport(TileIndex tile);
+
+	/**
+	 * Get the first hanger tile of the airport.
+	 * @param tile any tile of the airport.
+	 * @pre tile is always positive and smaller than AIMap::GetMapSize().
+	 * @return the first hanger tile of the airport.
+	 */
+	TileIndex GetHangarOfAirport(TileIndex tile);
+};
+
+#endif /* AI_AIRPORT_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_airport.hpp.sq	Fri Jul 13 23:18:12 2007 +0000
@@ -0,0 +1,40 @@
+#include "ai_airport.hpp"
+
+namespace SQConvert {
+	/* Allow enums to be used as Squirrel parameters */
+	template <> AIAirport::AirportType GetParam(ForceType<AIAirport::AirportType>, HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIAirport::AirportType)tmp; }
+	template <> int Return<AIAirport::AirportType>(HSQUIRRELVM vm, AIAirport::AirportType res) { sq_pushinteger(vm, (int32)res); return 1; }
+
+	/* Allow AIAirport to be used as Squirrel parameter */
+	template <> AIAirport *GetParam(ForceType<AIAirport *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAirport *)instance; }
+	template <> AIAirport &GetParam(ForceType<AIAirport &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAirport *)instance; }
+	template <> const AIAirport *GetParam(ForceType<const AIAirport *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIAirport *)instance; }
+	template <> const AIAirport &GetParam(ForceType<const AIAirport &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAirport *)instance; }
+}; // namespace SQConvert
+
+void SQAIAirportRegister(Squirrel *engine) {
+	DefSQClass <AIAirport> SQAIAirport("AIAirport");
+	SQAIAirport.PreRegister(engine);
+	SQAIAirport.AddConstructor<void (AIAirport::*)(), 1>(engine, "x");
+
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_SMALL,         "AT_SMALL");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_LARGE,         "AT_LARGE");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELIPORT,      "AT_HELIPORT");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_METROPOLITAN,  "AT_METROPOLITAN");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_INTERNATIONAL, "AT_INTERNATIONAL");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_COMMUTER,      "AT_COMMUTER");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELIDEPOT,     "AT_HELIDEPOT");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_INTERCON,      "AT_INTERCON");
+	SQAIAirport.DefSQConst(engine, AIAirport::AT_HELISTATION,   "AT_HELISTATION");
+
+	SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetClassName, "GetClassName", 1, "x");
+
+	SQAIAirport.DefSQMethod(engine, &AIAirport::IsHangarTile,       "IsHangarTile",       2, "xi");
+	SQAIAirport.DefSQMethod(engine, &AIAirport::IsAirportTile,      "IsAirportTile",      2, "xi");
+	SQAIAirport.DefSQMethod(engine, &AIAirport::AiportAvailable,    "AiportAvailable",    2, "xi");
+	SQAIAirport.DefSQMethod(engine, &AIAirport::BuildAirport,       "BuildAirport",       3, "xii");
+	SQAIAirport.DefSQMethod(engine, &AIAirport::RemoveAirport,      "RemoveAirport",      2, "xi");
+	SQAIAirport.DefSQMethod(engine, &AIAirport::GetHangarOfAirport, "GetHangarOfAirport", 2, "xi");
+
+	SQAIAirport.PostRegister(engine);
+}
--- a/src/ai/api/ai_vehicle.cpp	Fri Jul 13 19:54:59 2007 +0000
+++ b/src/ai/api/ai_vehicle.cpp	Fri Jul 13 23:18:12 2007 +0000
@@ -20,18 +20,24 @@
 	return ::IsValidVehicleID(vehicle_id) && ::GetVehicle(vehicle_id)->owner == _current_player;
 }
 
-EngineID AIVehicle::FindBestRoadVehicle(CargoID cargo, uint8 min_reliability)
+EngineID AIVehicle::FindBestVehicle(CargoID cargo, uint8 min_reliability, VehicleType veh_type)
 {
 	if (!AICargo::IsValidCargo(cargo) || min_reliability > 100) return INVALID_ENGINE;
 
 	EngineID best_engine = INVALID_ENGINE;
 	EngineID engine_id;
 
-	FOR_ALL_ENGINEIDS_OF_TYPE(engine_id, VEH_ROAD) {
+	FOR_ALL_ENGINEIDS_OF_TYPE(engine_id, veh_type) {
 		/* Is the vehicle available for this player */
-		if (IsEngineBuildable(engine_id, VEH_ROAD, _current_player) &&
-				GetEngine(engine_id)->reliability * 100 >= min_reliability << 16 &&
-				(RoadVehInfo(engine_id)->cargo_type == cargo || CanRefitTo(engine_id, cargo))) {
+		if (IsEngineBuildable(engine_id, veh_type, _current_player) &&
+				GetEngine(engine_id)->reliability * 100 >= min_reliability << 16) {
+			switch (veh_type) {
+				case VEH_ROAD: if (RoadVehInfo(engine_id)->cargo_type != cargo && !CanRefitTo(engine_id, cargo)) continue; break;
+				case VEH_TRAIN: if (RailVehInfo(engine_id)->cargo_type != cargo && !CanRefitTo(engine_id, cargo)) continue; break;
+				case VEH_SHIP: if (ShipVehInfo(engine_id)->cargo_type != cargo && !CanRefitTo(engine_id, cargo)) continue; break;
+				case VEH_AIRCRAFT: if (cargo != CT_PASSENGERS && !CanRefitTo(engine_id, cargo)) continue; break;
+				default: NOT_REACHED();
+			}
 			best_engine = engine_id;
 		}
 	}
@@ -39,6 +45,16 @@
 	return best_engine;
 }
 
+EngineID AIVehicle::FindBestRoadVehicle(CargoID cargo, uint8 min_reliability)
+{
+	return this->FindBestVehicle(cargo, min_reliability, VEH_ROAD);
+}
+
+EngineID AIVehicle::FindBestAircraftVehicle(CargoID cargo, uint8 min_reliability)
+{
+	return this->FindBestVehicle(cargo, min_reliability, VEH_AIRCRAFT);
+}
+
 VehicleID AIVehicle::BuildVehicle(TileIndex depot, EngineID engine_id)
 {
 	if (!this->IsValidEngine(engine_id)) return false;
@@ -49,7 +65,10 @@
 	bool ret;
 	switch (::GetEngine(engine_id)->type) {
 		case VEH_ROAD: ret = this->DoCommand(depot, engine_id, 0, CMD_BUILD_ROAD_VEH); break;
-		default: NOT_REACHED(); return INVALID_VEHICLE; // TODO: implement trains, ships and aircraft
+		case VEH_TRAIN: ret = this->DoCommand(depot, engine_id, 0, CMD_BUILD_RAIL_VEHICLE); break;
+		case VEH_SHIP: ret = this->DoCommand(depot, engine_id, 0, CMD_BUILD_SHIP); break;
+		case VEH_AIRCRAFT: ret = this->DoCommand(depot, engine_id, 0, CMD_BUILD_AIRCRAFT); break;
+		default: NOT_REACHED(); return INVALID_VEHICLE;
 	}
 
 	return ret ? AIObject::GetNewVehicleID() : INVALID_VEHICLE;
@@ -62,12 +81,7 @@
 	/* Reset the internal NewVehicleID in case we are in TestMode */
 	AIObject::SetNewVehicleID(0);
 
-	bool ret;
-	switch (::GetVehicle(vehicle_id)->type) {
-		case VEH_ROAD: ret = this->DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE); break;
-		default: return INVALID_VEHICLE; // TODO: implement trains, ships and aircraft
-	}
-
+	bool ret = this->DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE);
 	return ret ? AIObject::GetNewVehicleID() : INVALID_VEHICLE;
 }
 
@@ -77,7 +91,10 @@
 
 	switch (::GetVehicle(vehicle_id)->type) {
 		case VEH_ROAD: return this->DoCommand(0, vehicle_id, cargo, CMD_REFIT_ROAD_VEH);
-		default: return false; // TODO: implement trains, ships and aircraft
+		case VEH_TRAIN: return this->DoCommand(0, vehicle_id, cargo, CMD_REFIT_RAIL_VEHICLE);
+		case VEH_SHIP: return this->DoCommand(0, vehicle_id, cargo, CMD_REFIT_SHIP);
+		case VEH_AIRCRAFT: return this->DoCommand(0, vehicle_id, cargo, CMD_REFIT_AIRCRAFT);
+		default: return false;
 	}
 }
 
@@ -88,7 +105,10 @@
 
 	switch (::GetVehicle(vehicle_id)->type) {
 		case VEH_ROAD: return this->DoCommand(0, vehicle_id, 0, CMD_SELL_ROAD_VEH);
-		default: return false; // TODO: implement trains, ships and aircraft
+		case VEH_TRAIN: return this->DoCommand(0, vehicle_id, 0, CMD_SELL_RAIL_WAGON);
+		case VEH_SHIP: return this->DoCommand(0, vehicle_id, 0, CMD_SELL_SHIP);
+		case VEH_AIRCRAFT: return this->DoCommand(0, vehicle_id, 0, CMD_SELL_AIRCRAFT);
+		default: return false;
 	}
 }
 
@@ -98,7 +118,10 @@
 
 	switch (::GetVehicle(vehicle_id)->type) {
 		case VEH_ROAD: return this->DoCommand(0, vehicle_id, 0, CMD_SEND_ROADVEH_TO_DEPOT);
-		default: return false; // TODO: implement trains, ships and aircraft
+		case VEH_TRAIN: return this->DoCommand(0, vehicle_id, 0, CMD_SEND_TRAIN_TO_DEPOT);
+		case VEH_SHIP: return this->DoCommand(0, vehicle_id, 0, CMD_SEND_SHIP_TO_DEPOT);
+		case VEH_AIRCRAFT: return this->DoCommand(0, vehicle_id, 0, CMD_SEND_AIRCRAFT_TO_HANGAR);
+		default: return false;
 	}
 }
 
@@ -108,7 +131,10 @@
 
 	switch (::GetVehicle(vehicle_id)->type) {
 		case VEH_ROAD: return this->DoCommand(0, vehicle_id, 0, CMD_START_STOP_ROADVEH);
-		default: return false; // TODO: implement trains, ships and aircraft
+		case VEH_TRAIN: return this->DoCommand(0, vehicle_id, 0, CMD_START_STOP_TRAIN);
+		case VEH_SHIP: return this->DoCommand(0, vehicle_id, 0, CMD_START_STOP_SHIP);
+		case VEH_AIRCRAFT: return this->DoCommand(0, vehicle_id, 0, CMD_START_STOP_AIRCRAFT);
+		default: return false;
 	}
 }
 
--- a/src/ai/api/ai_vehicle.hpp	Fri Jul 13 19:54:59 2007 +0000
+++ b/src/ai/api/ai_vehicle.hpp	Fri Jul 13 23:18:12 2007 +0000
@@ -6,6 +6,7 @@
 #define AI_VEHICLE_HPP
 
 #include "ai_object.hpp"
+#include "../../vehicle.h"
 
 /**
  * Class that handles all vehicle related functions.
@@ -36,8 +37,6 @@
 	 * @param cargo           the cargo the vehicle has to transport.
 	 * @param min_reliability the minimum reliability of the vehicle,
 	 *   between 0 and 100.
-	 * @pre the tile at depot has a depot that can build the engine and
-	 *   is owned by you.
 	 * @pre AICargo::IsValidCargo(cargo).
 	 * @pre min_reliability is between 0 and 100.
 	 * @return the engine with the best characteristics, or an invalid engine
@@ -47,6 +46,19 @@
 	EngineID FindBestRoadVehicle(CargoID cargo, uint8 min_reliability);
 
 	/**
+	 * Find the best aircraft for this job, given a minimum reliability.
+	 * @param cargo           the cargo the vehicle has to transport.
+	 * @param min_reliability the minimum reliability of the vehicle,
+	 *   between 0 and 100.
+	 * @pre AICargo::IsValidCargo(cargo).
+	 * @pre min_reliability is between 0 and 100.
+	 * @return the engine with the best characteristics, or an invalid engine
+	 *   when no engine was found given the cargo and reliability. Check the
+	 *   return value using IsValidEngine.
+	 */
+	EngineID FindBestAircraftVehicle(CargoID cargo, uint8 min_reliability);
+
+	/**
 	 * Builds a vehicle with the given engine at the given depot.
 	 * @param depot     the depot where the vehicle will be build.
 	 * @param engine_id the engine to use for this vehicle.
@@ -188,6 +200,9 @@
 	 * @return the profit the vehicle had last year.
 	 */
 	static int32 GetProfitLastYear(VehicleID vehicle_id);
+
+private:
+	EngineID FindBestVehicle(CargoID cargo, uint8 min_reliability, VehicleType veh_type);
 };
 
 #endif /* AI_VEHICLE_HPP */
--- a/src/ai/api/ai_vehicle.hpp.sq	Fri Jul 13 19:54:59 2007 +0000
+++ b/src/ai/api/ai_vehicle.hpp.sq	Fri Jul 13 23:18:12 2007 +0000
@@ -25,14 +25,15 @@
 	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetProfitThisYear, "GetProfitThisYear", 2, "xi");
 	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetProfitLastYear, "GetProfitLastYear", 2, "xi");
 
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::FindBestRoadVehicle, "FindBestRoadVehicle", 3, "xii");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::BuildVehicle,        "BuildVehicle",        3, "xii");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::CloneVehicle,        "CloneVehicle",        4, "xiib");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::RefitVehicle,        "RefitVehicle",        3, "xii");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SellVehicle,         "SellVehicle",         2, "xi");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SendVehicleToDepot,  "SendVehicleToDepot",  2, "xi");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::StartStopVehicle,    "StartStopVehicle",    2, "xi");
-	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SkipVehicleOrder,    "SkipVehicleOrder",    2, "xi");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::FindBestRoadVehicle,     "FindBestRoadVehicle",     3, "xii");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::FindBestAircraftVehicle, "FindBestAircraftVehicle", 3, "xii");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::BuildVehicle,            "BuildVehicle",            3, "xii");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::CloneVehicle,            "CloneVehicle",            4, "xiib");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::RefitVehicle,            "RefitVehicle",            3, "xii");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SellVehicle,             "SellVehicle",             2, "xi");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SendVehicleToDepot,      "SendVehicleToDepot",      2, "xi");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::StartStopVehicle,        "StartStopVehicle",        2, "xi");
+	SQAIVehicle.DefSQMethod(engine, &AIVehicle::SkipVehicleOrder,        "SkipVehicleOrder",        2, "xi");
 
 	SQAIVehicle.PostRegister(engine);
 }