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
00049 static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
00050 {
00051 if (!AITunnel::_BuildTunnelRoad2()) {
00052 AIInstance::DoCommandReturn(instance);
00053 return;
00054 }
00055
00056
00057
00058 NOT_REACHED();
00059 }
00060
00061 static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
00062 {
00063 if (!AITunnel::_BuildTunnelRoad1()) {
00064 AIInstance::DoCommandReturn(instance);
00065 return;
00066 }
00067
00068
00069
00070 NOT_REACHED();
00071 }
00072
00073 bool AITunnel::BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start)
00074 {
00075 EnforcePrecondition(false, ::IsValidTile(start));
00076 EnforcePrecondition(false, vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_ROAD);
00077 EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00078
00079 uint type = 0;
00080 if (vehicle_type == AIVehicle::VT_ROAD) {
00081 type |= (TRANSPORT_ROAD << 8);
00082 type |= ::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
00083 } else {
00084 type |= (TRANSPORT_RAIL << 8);
00085 type |= AIRail::GetCurrentRailType();
00086 }
00087
00088
00089 if (vehicle_type == AIVehicle::VT_RAIL) {
00090 return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL);
00091 }
00092
00093 AIObject::SetCallbackVariable(0, start);
00094 return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1);
00095 }
00096
00097 bool AITunnel::_BuildTunnelRoad1()
00098 {
00099
00100 TileIndex end = AIObject::GetCallbackVariable(0);
00101 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
00102
00103 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00104 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00105
00106 return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildTunnel2);
00107 }
00108
00109 bool AITunnel::_BuildTunnelRoad2()
00110 {
00111
00112 TileIndex end = AIObject::GetCallbackVariable(0);
00113 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
00114
00115 DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
00116 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00117
00118 return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
00119 }
00120
00121 bool AITunnel::RemoveTunnel(TileIndex tile)
00122 {
00123 EnforcePrecondition(false, IsTunnelTile(tile));
00124
00125 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00126 }