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 ::DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
00027 return _build_tunnel_endtile == 0 ? INVALID_TILE : _build_tunnel_endtile;
00028 }
00029
00030 static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
00031 {
00032 if (!AITunnel::_BuildTunnelRoad2()) {
00033 AIObject::SetLastCommandRes(false);
00034 AIInstance::DoCommandReturn(instance);
00035 return;
00036 }
00037
00038
00039
00040 NOT_REACHED();
00041 }
00042
00043 static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
00044 {
00045 if (!AITunnel::_BuildTunnelRoad1()) {
00046 AIObject::SetLastCommandRes(false);
00047 AIInstance::DoCommandReturn(instance);
00048 return;
00049 }
00050
00051
00052
00053 NOT_REACHED();
00054 }
00055
00056 bool AITunnel::BuildTunnel(AIVehicle::VehicleType vehicle_type, TileIndex start)
00057 {
00058 EnforcePrecondition(false, ::IsValidTile(start));
00059 EnforcePrecondition(false, vehicle_type == AIVehicle::VT_RAIL || vehicle_type == AIVehicle::VT_ROAD);
00060 EnforcePrecondition(false, vehicle_type != AIVehicle::VT_RAIL || AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType()));
00061
00062 uint type = 0;
00063 if (vehicle_type == AIVehicle::VT_ROAD) {
00064 type |= (TRANSPORT_ROAD << 9);
00065 type |= RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
00066 } else {
00067 type |= (TRANSPORT_RAIL << 9);
00068 type |= AIRail::GetCurrentRailType();
00069 }
00070
00071
00072 if (vehicle_type == AIVehicle::VT_RAIL) {
00073 return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL);
00074 }
00075
00076 AIObject::SetCallbackVariable(0, start);
00077 if (!AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1)) return false;
00078
00079
00080 return _BuildTunnelRoad1();
00081 }
00082
00083 bool AITunnel::_BuildTunnelRoad1()
00084 {
00085
00086 TileIndex end = AIObject::GetCallbackVariable(0);
00087 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
00088
00089 DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
00090 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00091
00092 if (!AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildTunnel2)) return false;
00093
00094
00095 return _BuildTunnelRoad2();
00096 }
00097
00098 bool AITunnel::_BuildTunnelRoad2()
00099 {
00100
00101 TileIndex end = AIObject::GetCallbackVariable(0);
00102 TileIndex start = AITunnel::GetOtherTunnelEnd(end);
00103
00104 DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
00105 DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
00106
00107 return AIObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD);
00108 }
00109
00110 bool AITunnel::RemoveTunnel(TileIndex tile)
00111 {
00112 EnforcePrecondition(false, IsTunnelTile(tile));
00113
00114 return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00115 }