Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../../stdafx.h"
00013 #include "ai_bridge.hpp"
00014 #include "ai_rail.hpp"
00015 #include "../ai_instance.hpp"
00016 #include "../../bridge_map.h"
00017 #include "../../strings_func.h"
00018 #include "../../economy_func.h"
00019 #include "../../date_func.h"
00020
00021 bool AIBridge::IsValidBridge(BridgeID bridge_id)
00022 {
00023 return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
00024 }
00025
00026 bool AIBridge::IsBridgeTile(TileIndex tile)
00027 {
00028 if (!::IsValidTile(tile)) return false;
00029 return ::IsBridgeTile(tile);
00030 }
00031
00032 BridgeID AIBridge::GetBridgeID(TileIndex tile)
00033 {
00034 if (!IsBridgeTile(tile)) return (BridgeID)-1;
00035 return (BridgeID)::GetBridgeType(tile);
00036 }
00037
00042 static void _DoCommandReturnBuildBridge2(class AIInstance *instance)
00043 {
00044 if (!AIBridge::_BuildBridgeRoad2()) {
00045 AIInstance::DoCommandReturn(instance);
00046 return;
00047 }
00048
00049
00050
00051 NOT_REACHED();
00052 }
00053
00058 static void _DoCommandReturnBuildBridge1(class AIInstance *instance)
00059 {
00060 if (!AIBridge::_BuildBridgeRoad1()) {
00061 AIInstance::DoCommandReturn(instance);
00062 return;
00063 }
00064
00065
00066
00067 NOT_REACHED();
00068 }
00069
00070 bool AIBridge::BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
00071 {
00072 EnforcePrecondition(false, start != end);
00073 EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
00074 EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
00075 EnforcePrecondition(false, vehicle_type == AIVehicle::VT_ROAD || vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER);
00076 EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00077
00078 uint type = 0;
00079 switch (vehicle_type) {
00080 case AIVehicle::VT_ROAD:
00081 type |= (TRANSPORT_ROAD << 15);
00082 type |= (::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8);
00083 break;
00084 case AIVehicle::VT_RAIL:
00085 type |= (TRANSPORT_RAIL << 15);
00086 type |= (AIRail::GetCurrentRailType() << 8);
00087 break;
00088 case AIVehicle::VT_WATER:
00089 type |= (TRANSPORT_WATER << 15);
00090 break;
00091 default: NOT_REACHED();
00092 }
00093
00094
00095 if (vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER) {
00096 return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
00097 }
00098
00099 AIObject::SetCallbackVariable(0, start);
00100 AIObject::SetCallbackVariable(1, end);
00101 return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &::_DoCommandReturnBuildBridge1);
00102 }
00103
00104 bool AIBridge::_BuildBridgeRoad1()
00105 {
00106
00107 TileIndex end = AIObject::GetCallbackVariable(0);
00108 TileIndex start = AIObject::GetCallbackVariable(1);
00109
00110 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00111 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00112
00113 return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &::_DoCommandReturnBuildBridge2);
00114 }
00115
00116 bool AIBridge::_BuildBridgeRoad2()
00117 {
00118
00119 TileIndex end = AIObject::GetCallbackVariable(0);
00120 TileIndex start = AIObject::GetCallbackVariable(1);
00121
00122 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00123 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00124
00125 return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
00126 }
00127
00128 bool AIBridge::RemoveBridge(TileIndex tile)
00129 {
00130 EnforcePrecondition(false, IsBridgeTile(tile));
00131 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00132 }
00133
00134 char *AIBridge::GetName(BridgeID bridge_id)
00135 {
00136 if (!IsValidBridge(bridge_id)) return NULL;
00137
00138 static const int len = 64;
00139 char *bridge_name = MallocT<char>(len);
00140
00141 ::GetString(bridge_name, ::GetBridgeSpec(bridge_id)->transport_name[0], &bridge_name[len - 1]);
00142 return bridge_name;
00143 }
00144
00145 int32 AIBridge::GetMaxSpeed(BridgeID bridge_id)
00146 {
00147 if (!IsValidBridge(bridge_id)) return -1;
00148
00149 return ::GetBridgeSpec(bridge_id)->speed;
00150 }
00151
00152 Money AIBridge::GetPrice(BridgeID bridge_id, uint length)
00153 {
00154 if (!IsValidBridge(bridge_id)) return -1;
00155
00156 return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
00157 }
00158
00159 int32 AIBridge::GetMaxLength(BridgeID bridge_id)
00160 {
00161 if (!IsValidBridge(bridge_id)) return -1;
00162
00163 return min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
00164 }
00165
00166 int32 AIBridge::GetMinLength(BridgeID bridge_id)
00167 {
00168 if (!IsValidBridge(bridge_id)) return -1;
00169
00170 return ::GetBridgeSpec(bridge_id)->min_length + 2;
00171 }
00172
00173 TileIndex AIBridge::GetOtherBridgeEnd(TileIndex tile)
00174 {
00175 if (!::IsValidTile(tile)) return INVALID_TILE;
00176 if (!IsBridgeTile(tile)) return INVALID_TILE;
00177
00178 return ::GetOtherBridgeEnd(tile);
00179 }