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