ai_bridge.cpp

Go to the documentation of this file.
00001 /* $Id: ai_bridge.cpp 18330 2009-11-28 20:35:25Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "ai_bridge.hpp"
00013 #include "ai_rail.hpp"
00014 #include "../ai_instance.hpp"
00015 #include "../../bridge_map.h"
00016 #include "../../strings_func.h"
00017 #include "../../economy_func.h"
00018 #include "../../date_func.h"
00019 
00020 /* static */ bool AIBridge::IsValidBridge(BridgeID bridge_id)
00021 {
00022   return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
00023 }
00024 
00025 /* static */ bool AIBridge::IsBridgeTile(TileIndex tile)
00026 {
00027   if (!::IsValidTile(tile)) return false;
00028   return ::IsBridgeTile(tile);
00029 }
00030 
00031 /* static */ BridgeID AIBridge::GetBridgeID(TileIndex tile)
00032 {
00033   if (!IsBridgeTile(tile)) return (BridgeID)-1;
00034   return (BridgeID)::GetBridgeType(tile);
00035 }
00036 
00037 static void _DoCommandReturnBuildBridge2(class AIInstance *instance)
00038 {
00039   if (!AIBridge::_BuildBridgeRoad2()) {
00040     AIInstance::DoCommandReturn(instance);
00041     return;
00042   }
00043 
00044   /* This can never happen, as in test-mode this callback is never executed,
00045    *  and in execute-mode, the other callback is called. */
00046   NOT_REACHED();
00047 }
00048 
00049 static void _DoCommandReturnBuildBridge1(class AIInstance *instance)
00050 {
00051   if (!AIBridge::_BuildBridgeRoad1()) {
00052     AIInstance::DoCommandReturn(instance);
00053     return;
00054   }
00055 
00056   /* This can never happen, as in test-mode this callback is never executed,
00057    *  and in execute-mode, the other callback is called. */
00058   NOT_REACHED();
00059 }
00060 
00061 /* static */ bool AIBridge::BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
00062 {
00063   EnforcePrecondition(false, start != end);
00064   EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
00065   EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
00066   EnforcePrecondition(false, vehicle_type == AIVehicle::VT_ROAD || vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER);
00067   EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00068 
00069   uint type = 0;
00070   switch (vehicle_type) {
00071     case AIVehicle::VT_ROAD:
00072       type |= (TRANSPORT_ROAD << 15);
00073       type |= (::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8);
00074       break;
00075     case AIVehicle::VT_RAIL:
00076       type |= (TRANSPORT_RAIL << 15);
00077       type |= (AIRail::GetCurrentRailType() << 8);
00078       break;
00079     case AIVehicle::VT_WATER:
00080       type |= (TRANSPORT_WATER << 15);
00081       break;
00082     default: NOT_REACHED();
00083   }
00084 
00085   /* For rail and water we do nothing special */
00086   if (vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER) {
00087     return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
00088   }
00089 
00090   AIObject::SetCallbackVariable(0, start);
00091   AIObject::SetCallbackVariable(1, end);
00092   return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &_DoCommandReturnBuildBridge1);
00093 }
00094 
00095 /* static */ bool AIBridge::_BuildBridgeRoad1()
00096 {
00097   /* Build the piece of road on the 'start' side of the bridge */
00098   TileIndex end = AIObject::GetCallbackVariable(0);
00099   TileIndex start = AIObject::GetCallbackVariable(1);
00100 
00101   DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00102   DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00103 
00104   return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildBridge2);
00105 }
00106 
00107 /* static */ bool AIBridge::_BuildBridgeRoad2()
00108 {
00109   /* Build the piece of road on the 'end' side of the bridge */
00110   TileIndex end = AIObject::GetCallbackVariable(0);
00111   TileIndex start = AIObject::GetCallbackVariable(1);
00112 
00113   DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00114   DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00115 
00116   return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
00117 }
00118 
00119 /* static */ bool AIBridge::RemoveBridge(TileIndex tile)
00120 {
00121   EnforcePrecondition(false, IsBridgeTile(tile));
00122   return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00123 }
00124 
00125 /* static */ char *AIBridge::GetName(BridgeID bridge_id)
00126 {
00127   if (!IsValidBridge(bridge_id)) return NULL;
00128 
00129   static const int len = 64;
00130   char *bridge_name = MallocT<char>(len);
00131 
00132   ::GetString(bridge_name, ::GetBridgeSpec(bridge_id)->transport_name[0], &bridge_name[len - 1]);
00133   return bridge_name;
00134 }
00135 
00136 /* static */ int32 AIBridge::GetMaxSpeed(BridgeID bridge_id)
00137 {
00138   if (!IsValidBridge(bridge_id)) return -1;
00139 
00140   return ::GetBridgeSpec(bridge_id)->speed; // km-ish/h
00141 }
00142 
00143 /* static */ Money AIBridge::GetPrice(BridgeID bridge_id, uint length)
00144 {
00145   if (!IsValidBridge(bridge_id)) return -1;
00146 
00147   return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
00148 }
00149 
00150 /* static */ int32 AIBridge::GetMaxLength(BridgeID bridge_id)
00151 {
00152   if (!IsValidBridge(bridge_id)) return -1;
00153 
00154   uint max = ::GetBridgeSpec(bridge_id)->max_length;
00155   if (max >= 16 && _settings_game.construction.longbridges) max = 100;
00156   return max + 2;
00157 }
00158 
00159 /* static */ int32 AIBridge::GetMinLength(BridgeID bridge_id)
00160 {
00161   if (!IsValidBridge(bridge_id)) return -1;
00162 
00163   return ::GetBridgeSpec(bridge_id)->min_length + 2;
00164 }
00165 
00166 /* static */ TileIndex AIBridge::GetOtherBridgeEnd(TileIndex tile)
00167 {
00168   if (!::IsValidTile(tile)) return INVALID_TILE;
00169   if (!IsBridgeTile(tile)) return INVALID_TILE;
00170 
00171   return ::GetOtherBridgeEnd(tile);
00172 }

Generated on Wed Feb 17 23:06:44 2010 for OpenTTD by  doxygen 1.6.1