(svn r12589) [NoAI] -Add: GetLastError support for AIBridge.
--- 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);