ai_bridge.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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 bool AIBridge::IsValidBridge(BridgeID bridge_id)
00021 {
00022 return bridge_id < MAX_BRIDGES && ::GetBridgeSpec(bridge_id)->avail_year <= _cur_year;
00023 }
00024
00025 bool AIBridge::IsBridgeTile(TileIndex tile)
00026 {
00027 if (!::IsValidTile(tile)) return false;
00028 return ::IsBridgeTile(tile);
00029 }
00030
00031 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
00045
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
00057
00058 NOT_REACHED();
00059 }
00060
00061 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
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 bool AIBridge::_BuildBridgeRoad1()
00096 {
00097
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 bool AIBridge::_BuildBridgeRoad2()
00108 {
00109
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 bool AIBridge::RemoveBridge(TileIndex tile)
00120 {
00121 EnforcePrecondition(false, IsBridgeTile(tile));
00122 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00123 }
00124
00125 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 int32 AIBridge::GetMaxSpeed(BridgeID bridge_id)
00137 {
00138 if (!IsValidBridge(bridge_id)) return -1;
00139
00140 return ::GetBridgeSpec(bridge_id)->speed;
00141 }
00142
00143 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 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 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 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 }