# HG changeset patch # User truebrain # Date 1213574869 0 # Node ID 6c1a6657c7dba18ccb5b61f99452653216c27431 # Parent 5cbf268679aecba864ba93b30fdd6e8168c9d747 (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) diff -r 5cbf268679ae -r 6c1a6657c7db bin/ai/regression/regression.txt --- 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 diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_bridge.cpp --- 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) diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_bridge.hpp --- 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); diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_object.cpp --- 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()); diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_object.hpp --- 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! diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_tunnel.cpp --- 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) diff -r 5cbf268679ae -r 6c1a6657c7db src/ai/api/ai_tunnel.hpp --- 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);