(svn r13531) [NoAI] -Add [API CHANGE]: when building a bridge/tunnel for road/tram, the BuildBridge/BuildTunnel function will now also make two half-road/half-tram pieces on both ends of the bridge/tunnel, so it is easier for you to connect them to your network. This give a more consistant behavior for road.
-Note: if the road pieces failed to build, but building the bridge/tunnel succeeded, the function still returns true (for the obvious reasons)
--- a/bin/ai/regression/regression.txt Sun Jun 15 23:35:40 2008 +0000
+++ b/bin/ai/regression/regression.txt Mon Jun 16 00:07:49 2008 +0000
@@ -959,7 +959,7 @@
SetPresidentName(): true
GetPresidentName(): Regression AI
GetCompanyValue(): 0
- GetBankBalance(): 392280
+ GetBankBalance(): 407266
GetCompanyName(): (null : 0x00000000)
GetLoanAmount(): 100000
GetMaxLoanAmount(): 300000
@@ -968,13 +968,13 @@
SetLoanAmount(100): false
SetLoanAmount(10000): true
GetLastErrorString(): ERR_NONE
- GetBankBalance(): 302280
+ GetBankBalance(): 317266
GetLoanAmount(): 10000
SetMinimumLoanAmount(31337): true
- GetBankBalance(): 332280
+ GetBankBalance(): 347266
GetLoanAmount(): 40000
SetLoanAmount(10000): true
- GetBankBalance(): 592280
+ GetBankBalance(): 607266
GetLoanAmount(): 300000
GetCompanyHQ(): -1
BuildCompanyHQ(): true
@@ -5797,7 +5797,7 @@
IsBuoyTile(): false
IsLockTile(): false
IsCanalTile(): false
- GetBankBalance(): 651106
+ GetBankBalance(): 665942
BuildWaterDepot(): true
BuildDock(): true
BuildBuoy(): true
@@ -5810,7 +5810,7 @@
IsBuoyTile(): true
IsLockTile(): true
IsCanalTile(): true
- GetBankBalance(): 686710
+ GetBankBalance(): 701546
RemoveWaterDepot(): true
RemoveDock(): true
RemoveBuoy(): true
@@ -5821,7 +5821,7 @@
IsBuoyTile(): false
IsLockTile(): false
IsCanalTile(): false
- GetBankBalance(): 731710
+ GetBankBalance(): 746546
BuildWaterDepot(): true
BuildDock(): true
@@ -7037,9 +7037,9 @@
GetLocation(): 33417
GetEngineType(): 153
GetUnitNumber(): 1
- GetAge(): 0
+ GetAge(): 1
GetMaxAge(): 5490
- GetAgeLeft(): 5490
+ GetAgeLeft(): 5489
GetCurrentSpeed(): 4
GetRunningCost(): 13
GetProfitThisYear(): 0
@@ -7088,10 +7088,10 @@
13 => 1
11 => 1
Age ListDump:
+ 11 => 1
15 => 0
13 => 0
12 => 0
- 11 => 0
MaxAge ListDump:
15 => 10980
13 => 10980
@@ -7101,7 +7101,7 @@
15 => 10980
13 => 10980
12 => 5490
- 11 => 5490
+ 11 => 5489
CurrentSpeed ListDump:
11 => 7
15 => 0
@@ -7214,14 +7214,11 @@
GetAwardedTo(): -1
GetExpireDate(): 712619
SourceIsTown(): true
- GetSource(): 0
+ GetSource(): 25
DestionationIsTown(): true
- GetDestionation(): 21
+ GetDestionation(): 10
GetCargoType(): 0
GetNextEvent: instance
- GetEventType: 15
- Unknown Event
- GetNextEvent: instance
GetEventType: 3
EventName: SubsidyOffer
--Subsidy (1) --
@@ -7230,22 +7227,9 @@
GetAwardedTo(): -1
GetExpireDate(): 712708
SourceIsTown(): true
- GetSource(): 27
+ GetSource(): 20
DestionationIsTown(): true
- GetDestionation(): 12
+ GetDestionation(): 6
GetCargoType(): 0
- GetNextEvent: instance
- GetEventType: 3
- EventName: SubsidyOffer
- --Subsidy (2) --
- IsValidSubsidy(): true
- IsAwarded(): false
- GetAwardedTo(): -1
- GetExpireDate(): 712769
- SourceIsTown(): false
- GetSource(): 69
- DestionationIsTown(): false
- GetDestionation(): 8
- GetCargoType(): 7
IsEventWaiting: false
ERROR: We've got a suicidal AI for player 1
--- a/src/ai/api/ai_bridge.cpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_bridge.cpp Mon Jun 16 00:07:49 2008 +0000
@@ -38,7 +38,17 @@
type |= (RAILTYPES_RAIL << 8);
}
- return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
+ if (!AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE)) return false;
+ if (vehicle_type == AIVehicle::VEHICLE_RAIL) return true;
+
+ /* Build 2 road-pieces at both ends of the bridge */
+ DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
+ DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
+
+ AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
+ AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
+
+ return true;
}
/* static */ bool AIBridge::RemoveBridge(TileIndex tile)
--- a/src/ai/api/ai_bridge.hpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_bridge.hpp Mon Jun 16 00:07:49 2008 +0000
@@ -103,6 +103,9 @@
/**
* Build a bridge from one tile to the other.
+ * As an extra for road, this functions builds two half-pieces of road on
+ * each end of the bridge, making it easier for you to connect it to your
+ * network.
* @param vehicle_type The vehicle-type of bridge to build.
* @param bridge_id The bridge-type to build.
* @param start Where to start the bridge.
@@ -121,6 +124,8 @@
* @exception AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER
* @exception AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT
* @return Whether the bridge has been/can be build or not.
+ * @note No matter if the road pieces were build or not, if building the
+ * bridge succeeded, this function returns true.
*/
static bool BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end);
--- a/src/ai/api/ai_object.cpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_object.cpp Mon Jun 16 00:07:49 2008 +0000
@@ -8,9 +8,11 @@
#include "table/strings.h"
#include "../../openttd.h"
#include "../../command_func.h"
+#include "../../map_func.h"
#include "../../network/network.h"
#include "../../player_func.h"
#include "../../signs_func.h"
+#include "../../tunnelbridge.h"
#include "../../vehicle_func.h"
#include "../ai.h"
#include "../ai_threads.h"
@@ -24,6 +26,7 @@
bool last_command_res;
VehicleID new_vehicle_id;
SignID new_sign_id;
+ TileIndex new_tunnel_endtile;
RoadType road_type;
void *event_data;
void *log_data;
@@ -121,6 +124,16 @@
return GetDoCommandStruct(_current_player)->new_sign_id;
}
+void AIObject::SetNewTunnelEndtile(TileIndex tile)
+{
+ GetDoCommandStruct(_current_player)->new_tunnel_endtile = tile;
+}
+
+TileIndex AIObject::GetNewTunnelEndtile()
+{
+ return GetDoCommandStruct(_current_player)->new_tunnel_endtile;
+}
+
void *&AIObject::GetEventPointer()
{
return GetDoCommandStruct(_current_player)->event_data;
@@ -218,6 +231,7 @@
/* Store some values inside the AIObject static memory */
SetNewVehicleID(_new_vehicle_id);
SetNewSignID(_new_sign_id);
+ SetNewTunnelEndtile(_build_tunnel_endtile);
/* Suspend the AI player for 1 tick, so it simulates MultiPlayer */
::AI_SuspendPlayer(_current_player, GetDoCommandDelay());
--- a/src/ai/api/ai_object.hpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_object.hpp Mon Jun 16 00:07:49 2008 +0000
@@ -113,6 +113,11 @@
static SignID GetNewSignID();
/**
+ * Get the latest stored new_tunnel_endtile.
+ */
+ static TileIndex GetNewTunnelEndtile();
+
+ /**
* Get the pointer to store event data in.
*/
static void *&GetEventPointer();
@@ -140,6 +145,13 @@
static void SetNewSignID(SignID sign_id);
/**
+ * Store a new_tunnel_endtile per player.
+ * @note NEVER use this yourself in your AI!
+ * @param tile The new TileIndex.
+ */
+ static void SetNewTunnelEndtile(TileIndex tile);
+
+ /**
* If an AI starts, some internals needs to be resetted. This function
* takes care of that.
* @note NEVER use this yourself in your AI!
--- a/src/ai/api/ai_tunnel.cpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_tunnel.cpp Mon Jun 16 00:07:49 2008 +0000
@@ -42,7 +42,18 @@
type |= RAILTYPES_RAIL;
}
- return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL);
+ if (!AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL)) return false;
+ if (vehicle_type == AIVehicle::VEHICLE_RAIL) return true;
+
+ /* Build 2 road-pieces at both ends of the tunnel */
+ TileIndex end = AIObject::GetNewTunnelEndtile();
+ DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
+ DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
+
+ AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
+ AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
+
+ return true;
}
/* static */ bool AITunnel::RemoveTunnel(TileIndex tile)
--- a/src/ai/api/ai_tunnel.hpp Sun Jun 15 23:35:40 2008 +0000
+++ b/src/ai/api/ai_tunnel.hpp Mon Jun 16 00:07:49 2008 +0000
@@ -58,6 +58,9 @@
* Builds a tunnel starting at start. The direction of the tunnel depends
* on the slope of the start tile. Tunnels can be created for either
* rails or roads; use the appropriate AIVehicle::VehicleType.
+ * As an extra for road, this functions builds two half-pieces of road on
+ * each end of the tunnel, making it easier for you to connect it to your
+ * network.
* @param start Where to start the tunnel.
* @param vehicle_type The vehicle-type of tunnel to build.
* @pre AIMap::IsValidTile(start).
@@ -69,6 +72,8 @@
* @exception AITunnel::ERR_TUNNEL_END_SITE_UNSUITABLE
* @return Whether the tunnel has been/can be build or not.
* @note The slope of a tile can be determined by AITile::GetSlope(TileIndex).
+ * @note No matter if the road pieces were build or not, if building the
+ * tunnel succeeded, this function returns true.
*/
static bool BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start);