ai_tunnel.cpp

Go to the documentation of this file.
00001 /* $Id: ai_tunnel.cpp 15299 2009-01-31 20:16:06Z smatz $ */
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 /* static */ bool AITunnel::IsTunnelTile(TileIndex tile)
00014 {
00015   if (!::IsValidTile(tile)) return false;
00016   return ::IsTunnelTile(tile);
00017 }
00018 
00019 /* static */ TileIndex AITunnel::GetOtherTunnelEnd(TileIndex tile)
00020 {
00021   if (!::IsValidTile(tile)) return INVALID_TILE;
00022 
00023   /* If it's a tunnel alread, take the easy way out! */
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   /* This can never happen, as in test-mode this callback is never executed,
00039    *  and in execute-mode, the other callback is called. */
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   /* This can never happen, as in test-mode this callback is never executed,
00052    *  and in execute-mode, the other callback is called. */
00053   NOT_REACHED();
00054 }
00055 
00056 /* static */ 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   /* For rail we do nothing special */
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   /* In case of test-mode, test if we can build both road pieces */
00080   return _BuildTunnelRoad1();
00081 }
00082 
00083 /* static */ bool AITunnel::_BuildTunnelRoad1()
00084 {
00085   /* Build the piece of road on the 'start' side of the tunnel */
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   /* In case of test-mode, test the other road piece too */
00095   return _BuildTunnelRoad2();
00096 }
00097 
00098 /* static */ bool AITunnel::_BuildTunnelRoad2()
00099 {
00100   /* Build the piece of road on the 'end' side of the tunnel */
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 /* static */ bool AITunnel::RemoveTunnel(TileIndex tile)
00111 {
00112   EnforcePrecondition(false, IsTunnelTile(tile));
00113 
00114   return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00115 }

Generated on Mon Mar 9 23:33:45 2009 for openttd by  doxygen 1.5.6