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