ai_bridge.cpp
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
00038 static void _DoCommandReturnBuildBridge2(class AIInstance *instance)
00039 {
00040 if (!AIBridge::_BuildBridgeRoad2()) {
00041 AIInstance::DoCommandReturn(instance);
00042 return;
00043 }
00044
00045
00046
00047 NOT_REACHED();
00048 }
00049
00050 static void _DoCommandReturnBuildBridge1(class AIInstance *instance)
00051 {
00052 if (!AIBridge::_BuildBridgeRoad1()) {
00053 AIInstance::DoCommandReturn(instance);
00054 return;
00055 }
00056
00057
00058
00059 NOT_REACHED();
00060 }
00061
00062 bool AIBridge::BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
00063 {
00064 EnforcePrecondition(false, start != end);
00065 EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
00066 EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
00067 EnforcePrecondition(false, vehicle_type == AIVehicle::VT_ROAD || vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER);
00068 EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00069
00070 uint type = 0;
00071 switch (vehicle_type) {
00072 case AIVehicle::VT_ROAD:
00073 type |= (TRANSPORT_ROAD << 15);
00074 type |= (::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType()) << 8);
00075 break;
00076 case AIVehicle::VT_RAIL:
00077 type |= (TRANSPORT_RAIL << 15);
00078 type |= (AIRail::GetCurrentRailType() << 8);
00079 break;
00080 case AIVehicle::VT_WATER:
00081 type |= (TRANSPORT_WATER << 15);
00082 break;
00083 default: NOT_REACHED();
00084 }
00085
00086
00087 if (vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_WATER) {
00088 return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE);
00089 }
00090
00091 AIObject::SetCallbackVariable(0, start);
00092 AIObject::SetCallbackVariable(1, end);
00093 return AIObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &_DoCommandReturnBuildBridge1);
00094 }
00095
00096 bool AIBridge::_BuildBridgeRoad1()
00097 {
00098
00099 TileIndex end = AIObject::GetCallbackVariable(0);
00100 TileIndex start = AIObject::GetCallbackVariable(1);
00101
00102 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00103 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00104
00105 return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildBridge2);
00106 }
00107
00108 bool AIBridge::_BuildBridgeRoad2()
00109 {
00110
00111 TileIndex end = AIObject::GetCallbackVariable(0);
00112 TileIndex start = AIObject::GetCallbackVariable(1);
00113
00114 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00115 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00116
00117 return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
00118 }
00119
00120 bool AIBridge::RemoveBridge(TileIndex tile)
00121 {
00122 EnforcePrecondition(false, IsBridgeTile(tile));
00123 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00124 }
00125
00126 char *AIBridge::GetName(BridgeID bridge_id)
00127 {
00128 if (!IsValidBridge(bridge_id)) return NULL;
00129
00130 static const int len = 64;
00131 char *bridge_name = MallocT<char>(len);
00132
00133 ::GetString(bridge_name, ::GetBridgeSpec(bridge_id)->transport_name[0], &bridge_name[len - 1]);
00134 return bridge_name;
00135 }
00136
00137 int32 AIBridge::GetMaxSpeed(BridgeID bridge_id)
00138 {
00139 if (!IsValidBridge(bridge_id)) return -1;
00140
00141 return ::GetBridgeSpec(bridge_id)->speed;
00142 }
00143
00144 Money AIBridge::GetPrice(BridgeID bridge_id, uint length)
00145 {
00146 if (!IsValidBridge(bridge_id)) return -1;
00147
00148 return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8;
00149 }
00150
00151 int32 AIBridge::GetMaxLength(BridgeID bridge_id)
00152 {
00153 if (!IsValidBridge(bridge_id)) return -1;
00154
00155 return min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2;
00156 }
00157
00158 int32 AIBridge::GetMinLength(BridgeID bridge_id)
00159 {
00160 if (!IsValidBridge(bridge_id)) return -1;
00161
00162 return ::GetBridgeSpec(bridge_id)->min_length + 2;
00163 }
00164
00165 TileIndex AIBridge::GetOtherBridgeEnd(TileIndex tile)
00166 {
00167 if (!::IsValidTile(tile)) return INVALID_TILE;
00168 if (!IsBridgeTile(tile)) return INVALID_TILE;
00169
00170 return ::GetOtherBridgeEnd(tile);
00171 }