ai_tunnel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "ai_tunnel.hpp"
00013 #include "ai_rail.hpp"
00014 #include "../ai_instance.hpp"
00015 #include "../../tunnel_map.h"
00016 #include "../../command_func.h"
00017
00018 bool AITunnel::IsTunnelTile(TileIndex tile)
00019 {
00020 if (!::IsValidTile(tile)) return false;
00021 return ::IsTunnelTile(tile);
00022 }
00023
00024 TileIndex AITunnel::GetOtherTunnelEnd(TileIndex tile)
00025 {
00026 if (!::IsValidTile(tile)) return INVALID_TILE;
00027
00028
00029 if (IsTunnelTile(tile)) return ::GetOtherTunnelEnd(tile);
00030
00031 uint start_z;
00032 Slope start_tileh = ::GetTileSlope(tile, &start_z);
00033 DiagDirection direction = ::GetInclinedSlopeDirection(start_tileh);
00034 if (direction == INVALID_DIAGDIR) return INVALID_TILE;
00035
00036 TileIndexDiff delta = ::TileOffsByDiagDir(direction);
00037 uint end_z;
00038 do {
00039 tile += delta;
00040 if (!::IsValidTile(tile)) return INVALID_TILE;
00041
00042 ::GetTileSlope(tile, &end_z);
00043 } while (start_z != end_z);
00044
00045 return tile;
00046 }
00047
00048 static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
00049 {
00050 if (!AITunnel::_BuildTunnelRoad2()) {
00051 AIInstance::DoCommandReturn(instance);
00052 return;
00053 }
00054
00055
00056
00057 NOT_REACHED();
00058 }
00059
00060 static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
00061 {
00062 if (!AITunnel::_BuildTunnelRoad1()) {
00063 AIInstance::DoCommandReturn(instance);
00064 return;
00065 }
00066
00067
00068
00069 NOT_REACHED();
00070 }
00071
00072 bool AITunnel::BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start)
00073 {
00074 EnforcePrecondition(false, ::IsValidTile(start));
00075 EnforcePrecondition(false, vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_ROAD);
00076 EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00077
00078 uint type = 0;
00079 if (vehicle_type == AIVehicle::VT_ROAD) {
00080 type |= (TRANSPORT_ROAD << 9);
00081 type |= ::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
00082 } else {
00083 type |= (TRANSPORT_RAIL << 9);
00084 type |= AIRail::GetCurrentRailType();
00085 }
00086
00087
00088 if (vehicle_type == AIVehicle::VT_RAIL) {
00089 return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL);
00090 }
00091
00092 AIObject::SetCallbackVariable(0, start);
00093 return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1);
00094 }
00095
00096 bool AITunnel::_BuildTunnelRoad1()
00097 {
00098
00099 TileIndex end = AIObject::GetCallbackVariable(0);
00100 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
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, &_DoCommandReturnBuildTunnel2);
00106 }
00107
00108 bool AITunnel::_BuildTunnelRoad2()
00109 {
00110
00111 TileIndex end = AIObject::GetCallbackVariable(0);
00112 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
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 AITunnel::RemoveTunnel(TileIndex tile)
00121 {
00122 EnforcePrecondition(false, IsTunnelTile(tile));
00123
00124 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00125 }