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