(svn r12589) [NoAI] -Add: GetLastError support for AIBridge. noai
authorrubidium
Sun, 06 Apr 2008 12:26:40 +0000
branchnoai
changeset 9867 b7d9ffe24f81
parent 9866 efc38e1f559a
child 9868 3998f2e73dda
(svn r12589) [NoAI] -Add: GetLastError support for AIBridge.
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
src/ai/api/ai_bridge.cpp
src/ai/api/ai_bridge.hpp
src/ai/api/ai_bridge.hpp.sq
src/ai/api/ai_error.hpp
src/ai/api/ai_error.hpp.sq
--- a/bin/ai/regression/regression.nut	Fri Apr 04 10:43:13 2008 +0000
+++ b/bin/ai/regression/regression.nut	Sun Apr 06 12:26:40 2008 +0000
@@ -102,9 +102,12 @@
 
 	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 	print("  RemoveBridge():       " + AIBridge.RemoveBridge(33155));
+	print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 	print("  BuildBridge():        " + AIBridge.BuildBridge(AIVehicle.VEHICLE_ROAD, 5, 33160, 33155));
 	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33155));
+	print("  BuildBridge():        " + AIBridge.BuildBridge(AIVehicle.VEHICLE_ROAD, 5, 33160, 33155));
+	print("  GetLastErrorString(): " + AIError.GetLastErrorString());
 	print("  RemoveBridge():       " + AIBridge.RemoveBridge(33155));
 	print("  IsBridgeTile():       " + AIBridge.IsBridgeTile(33160));
 }
--- a/bin/ai/regression/regression.txt	Fri Apr 04 10:43:13 2008 +0000
+++ b/bin/ai/regression/regression.txt	Sun Apr 06 12:26:40 2008 +0000
@@ -570,9 +570,12 @@
   Valid Bridges:        13
   IsBridgeTile():       false
   RemoveBridge():       false
+  GetLastErrorString(): ERR_PRECONDITION_FAILED
   BuildBridge():        true
   IsBridgeTile():       true
   IsBridgeTile():       true
+  BuildBridge():        false
+  GetLastErrorString(): ERR_ALREADY_BUILT
   RemoveBridge():       true
   IsBridgeTile():       false
 
--- a/src/ai/api/ai_bridge.cpp	Fri Apr 04 10:43:13 2008 +0000
+++ b/src/ai/api/ai_bridge.cpp	Sun Apr 06 12:26:40 2008 +0000
@@ -24,13 +24,15 @@
 
 /* static */ bool AIBridge::BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
 {
-	if (start == end) return false;
-	if (!::IsValidTile(start)) return false;
-	if (!::IsValidTile(end)) return false;
-	/* Not on one line */
-	if (TileX(start) != TileX(end) &&
-			TileY(start) != TileY(end)) return false;
-	if (vehicle_type != AIVehicle::VEHICLE_ROAD && vehicle_type != AIVehicle::VEHICLE_RAIL) return false;
+	if (start == end ||
+			!::IsValidTile(start) ||
+			!::IsValidTile(end) ||
+			/* Not on one line */
+			(TileX(start) != TileX(end) && TileY(start) != TileY(end)) ||
+			(vehicle_type != AIVehicle::VEHICLE_ROAD && vehicle_type != AIVehicle::VEHICLE_RAIL)) {
+		AIObject::SetLastError(AIError::ERR_PRECONDITION_FAILED);
+		return false;
+	}
 
 	uint type = 0;
 	if (vehicle_type == AIVehicle::VEHICLE_ROAD) {
@@ -46,7 +48,10 @@
 
 /* static */ bool AIBridge::RemoveBridge(TileIndex tile)
 {
-	if (!IsBridgeTile(tile)) return false;
+	if (!IsBridgeTile(tile)) {
+		AIObject::SetLastError(AIError::ERR_PRECONDITION_FAILED);
+		return false;
+	}
 
 	return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
 }
--- a/src/ai/api/ai_bridge.hpp	Fri Apr 04 10:43:13 2008 +0000
+++ b/src/ai/api/ai_bridge.hpp	Sun Apr 06 12:26:40 2008 +0000
@@ -7,6 +7,7 @@
 
 #include "ai_object.hpp"
 #include "ai_vehicle.hpp"
+#include "ai_error.hpp"
 #include "../../bridge.h"
 
 /** In OpenTTD Core 'BridgeID' is called 'BridgeType', so map it to make this API more logic. */
@@ -17,6 +18,26 @@
  */
 class AIBridge : public AIObject {
 public:
+	enum ErrorMessages {
+		/** Base for bridge related errors */
+		ERR_BRIDGE_BASE = AIError::ERR_CAT_BRIDGE << AIError::ERR_CAT_BIT_SIZE,
+
+		/**
+		 * The bridge you want to build is not available yet,
+		 * or it is not available for the requested length.
+		 */
+		ERR_BRIDGE_TYPE_UNAVAILABLE,         // [STR_5015_CAN_T_BUILD_BRIDGE_HERE]
+
+		/** One (or more) of the bridge head(s) ends in water. */
+		ERR_BRIDGE_CANNOT_END_IN_WATER,      // [STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH]
+
+		/** Slope of the land does not allow the required bridge head. */
+		ERR_BRIDGE_SLOPE_WRONG,              // [STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION]
+
+		/** The bride heads need to be on the same height */
+		ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, // [STR_BRIDGEHEADS_NOT_SAME_HEIGHT]
+	};
+
 	static const char *GetClassName() { return "AIBridge"; }
 
 	/**
@@ -96,6 +117,12 @@
 	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
 	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
 	 * @pre 'vehicle_type' is either AIVehicle::VEHICLE_RAIL or AIVEHICLE::VEHICLE_ROAD.
+	 * @exception AIError::ERR_ALREADY_BUILT
+	 * @exception AIError::ERR_AREA_NOT_CLEAR
+	 * @exception AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE
+	 * @exception AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER
+	 * @exception AIBridge::ERR_BRIDGE_SLOPE_WRONG
+	 * @exception AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT
 	 * @return Whether the bridge has been/can be build or not.
 	 */
 	static bool BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end);
--- a/src/ai/api/ai_bridge.hpp.sq	Fri Apr 04 10:43:13 2008 +0000
+++ b/src/ai/api/ai_bridge.hpp.sq	Sun Apr 06 12:26:40 2008 +0000
@@ -1,6 +1,10 @@
 #include "ai_bridge.hpp"
 
 namespace SQConvert {
+	/* Allow enums to be used as Squirrel parameters */
+	template <> AIBridge::ErrorMessages GetParam(ForceType<AIBridge::ErrorMessages>, HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIBridge::ErrorMessages)tmp; }
+	template <> int Return<AIBridge::ErrorMessages>(HSQUIRRELVM vm, AIBridge::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; }
+
 	/* Allow AIBridge to be used as Squirrel parameter */
 	template <> AIBridge *GetParam(ForceType<AIBridge *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIBridge *)instance; }
 	template <> AIBridge &GetParam(ForceType<AIBridge &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIBridge *)instance; }
@@ -14,6 +18,22 @@
 	SQAIBridge.PreRegister(engine);
 	SQAIBridge.AddConstructor<void (AIBridge::*)(), 1>(engine, "x");
 
+	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_BASE,                     "ERR_BRIDGE_BASE");
+	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE,         "ERR_BRIDGE_TYPE_UNAVAILABLE");
+	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER,      "ERR_BRIDGE_CANNOT_END_IN_WATER");
+	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_SLOPE_WRONG,              "ERR_BRIDGE_SLOPE_WRONG");
+	SQAIBridge.DefSQConst(engine, AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, "ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT");
+
+	AIError::RegisterErrorMap(STR_5015_CAN_T_BUILD_BRIDGE_HERE,        AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE);
+	AIError::RegisterErrorMap(STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH,       AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER);
+	AIError::RegisterErrorMap(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION, AIBridge::ERR_BRIDGE_SLOPE_WRONG);
+	AIError::RegisterErrorMap(STR_BRIDGEHEADS_NOT_SAME_HEIGHT,         AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT);
+
+	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE,         "ERR_BRIDGE_TYPE_UNAVAILABLE");
+	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER,      "ERR_BRIDGE_CANNOT_END_IN_WATER");
+	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_SLOPE_WRONG,              "ERR_BRIDGE_SLOPE_WRONG");
+	AIError::RegisterErrorMapString(AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, "ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT");
+
 	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::GetClassName,     "GetClassName",     1, "x");
 	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::IsValidBridge,    "IsValidBridge",    2, "xi");
 	SQAIBridge.DefSQStaticMethod(engine, &AIBridge::IsBridgeTile,     "IsBridgeTile",     2, "xi");
--- a/src/ai/api/ai_error.hpp	Fri Apr 04 10:43:13 2008 +0000
+++ b/src/ai/api/ai_error.hpp	Sun Apr 06 12:26:40 2008 +0000
@@ -23,6 +23,7 @@
 		ERR_CAT_GENERAL,  //!< Error messages related to general things.
 		ERR_CAT_VEHICLE,  //!< Error messages related to building / maintaining vehicles.
 		ERR_CAT_STATION,  //!< Error messages related to building / maintaining stations.
+		ERR_CAT_BRIDGE,   //!< Error messages related to building / removing bridges.
 
 		/**
 		 * DO NOT USE! The error bitsize determines how many errors can be stored in
@@ -52,7 +53,7 @@
 		ERR_LOCAL_AUTHORITY_REFUSES,                  // [STR_2009_LOCAL_AUTHORITY_REFUSES]
 
 		/** The piece of infrastructure you tried to build is already in place */
-		ERR_ALREADY_BUILT,                            // [STR_1007_ALREADY_BUILT]
+		ERR_ALREADY_BUILT,                            // [STR_1007_ALREADY_BUILT, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST]
 
 		/** Area isn't clear, try to demolish the building on it */
 		ERR_AREA_NOT_CLEAR,                           // [STR_2004_BUILDING_MUST_BE_DEMOLISHED, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST, STR_300B_MUST_DEMOLISH_RAILROAD, STR_300E_MUST_DEMOLISH_AIRPORT_FIRST, STR_MUST_DEMOLISH_CARGO_TRAM_STATION, STR_3047_MUST_DEMOLISH_TRUCK_STATION, STR_MUST_DEMOLISH_PASSENGER_TRAM_STATION, STR_3046_MUST_DEMOLISH_BUS_STATION, STR_306A_BUOY_IN_THE_WAY, STR_304D_MUST_DEMOLISH_DOCK_FIRST, STR_4800_IN_THE_WAY, STR_5804_COMPANY_HEADQUARTERS_IN, STR_5800_OBJECT_IN_THE_WAY, STR_1801_MUST_REMOVE_ROAD_FIRST, STR_1008_MUST_REMOVE_RAILROAD_TRACK, STR_5007_MUST_DEMOLISH_BRIDGE_FIRST, STR_5006_MUST_DEMOLISH_TUNNEL_FIRST]
--- a/src/ai/api/ai_error.hpp.sq	Fri Apr 04 10:43:13 2008 +0000
+++ b/src/ai/api/ai_error.hpp.sq	Sun Apr 06 12:26:40 2008 +0000
@@ -23,6 +23,8 @@
 	SQAIError.DefSQConst(engine, AIError::ERR_CAT_NONE,                         "ERR_CAT_NONE");
 	SQAIError.DefSQConst(engine, AIError::ERR_CAT_GENERAL,                      "ERR_CAT_GENERAL");
 	SQAIError.DefSQConst(engine, AIError::ERR_CAT_VEHICLE,                      "ERR_CAT_VEHICLE");
+	SQAIError.DefSQConst(engine, AIError::ERR_CAT_STATION,                      "ERR_CAT_STATION");
+	SQAIError.DefSQConst(engine, AIError::ERR_CAT_BRIDGE,                       "ERR_CAT_BRIDGE");
 	SQAIError.DefSQConst(engine, AIError::ERR_CAT_BIT_SIZE,                     "ERR_CAT_BIT_SIZE");
 	SQAIError.DefSQConst(engine, AIError::ERR_NONE,                             "ERR_NONE");
 	SQAIError.DefSQConst(engine, AIError::ERR_UNKNOWN,                          "ERR_UNKNOWN");
@@ -39,6 +41,7 @@
 	AIError::RegisterErrorMap(STR_0003_NOT_ENOUGH_CASH_REQUIRES,        AIError::ERR_NOT_ENOUGH_CASH);
 	AIError::RegisterErrorMap(STR_2009_LOCAL_AUTHORITY_REFUSES,         AIError::ERR_LOCAL_AUTHORITY_REFUSES);
 	AIError::RegisterErrorMap(STR_1007_ALREADY_BUILT,                   AIError::ERR_ALREADY_BUILT);
+	AIError::RegisterErrorMap(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST,      AIError::ERR_ALREADY_BUILT);
 	AIError::RegisterErrorMap(STR_2004_BUILDING_MUST_BE_DEMOLISHED,     AIError::ERR_AREA_NOT_CLEAR);
 	AIError::RegisterErrorMap(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST,      AIError::ERR_AREA_NOT_CLEAR);
 	AIError::RegisterErrorMap(STR_300B_MUST_DEMOLISH_RAILROAD,          AIError::ERR_AREA_NOT_CLEAR);