if not game.SinglePlayer() then return end
vrmod_ladders = vrmod_ladders or {}
vrmod_ladders["d1_trainstation_01"] = {
	{
		pos = Vector(-3437.8, 93.8, -24),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-3430, 92, 106), },
	},
}

vrmod_ladders["d1_trainstation_02"] = {
	{
		pos = Vector(-3152, -4600, 72),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(-3187, -4577, 224), },
	},
}

vrmod_ladders["d1_trainstation_05"] = {
	{
		pos = Vector(-6936.3, -1546.3, 8),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-6936, -1559, 138), },
	},
}

vrmod_ladders["d1_trainstation_06"] = {
	{
		pos = Vector(-7997, -2144, 3),
		ang = Angle(0, 15, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-7991, -2144, 128), },
	},
}

vrmod_ladders["d1_canals_01"] = {
	{
		pos = Vector(379.5, -7008, 400.2),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(401, -7009, 512), },
	},
	{
		pos = Vector(519.9, 2612.7, -52.4),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(531, 2612, 74), },
	},
}

vrmod_ladders["d1_canals_01a"] = {
	{
		pos = Vector(2348, 6456, -136),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(2391, 6434, 32), Vector(2300, 6436, 32), Vector(2350, 6397, 32)},
	},
	{
		pos = Vector(-3528, 9336, -92),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 13,
		dismounts = {Vector(-3559, 9314, 68), },
	},
}

vrmod_ladders["d1_canals_02"] = {
	{
		pos = Vector(-52, -1000, -1071),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 23,
		dismounts = {Vector(-84, -980, -848), },
	},
}

vrmod_ladders["d1_canals_03"] = {
	{
		pos = Vector(-879.8, 3145, -814),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-901, 3128, -736), },
	},
	{
		pos = Vector(-1496, 900, -1016),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-1482, 898, -896), },
	},
	{
		pos = Vector(-2144, -248, -1720),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 40,
		dismounts = {Vector(-2187, -227, -1455), Vector(-2184, -227, -1135)},
	},
	--
	{
		pos = Vector(-2691.7, -184, -1625),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {},
	},
	{
		pos = Vector(-2691.7, -184, -1368),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(-2692, -191, -1119)},
	},
	--
	{
		pos = Vector(-2295.7, -984, -1620),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {},
	},
	{
		pos = Vector(-2295.7, -984, -1491),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 32,
		dismounts = {Vector(-2324, -961, -1263), Vector(-2270, -965, -1263), Vector(-2294, -904, -1039)},
	},
	--
	{
		pos = Vector(-472, -896.1, -1194),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 13,
		dismounts = {Vector(-460, -896, -989)},
	},
}

vrmod_ladders["d1_canals_05"] = {
	{
		pos = Vector(3468, 6408, -248),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(3506, 6432, -156), Vector(3468, 6452, -156)},
	},
	{
		pos = Vector(4163, 5281.5, -296),
		ang = Angle(0, -73, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(4130, 5301, -126)},
	},
}

vrmod_ladders["d1_canals_06"] = {
	{
		pos = Vector(7927.7, 9316, -456),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(7909, 9279, -237)},
	},
	{
		pos = Vector(4598, 6424, -424),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(4598, 6433, -303)},
	},
	{
		pos = Vector(4442, 5899, 20),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(4416, 5916, 96.1), Vector(4471, 5917, 96.1)},
	},
}

vrmod_ladders["d1_canals_07"] = {
	{
		pos = Vector(10756, 1439, -405.8),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 13,
		dismounts = {Vector(10777, 1407, -255), Vector(10772, 1473, -255)},
	},
	{
		pos = Vector(8563, 1902, -222.8),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 15.5,
		count = 6,
		dismounts = {Vector(8565, 1899, -131)},
	},
	{
		pos = Vector(7822, 1863, -222.8),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 15.5,
		count = 6,
		dismounts = {Vector(7826, 1864, -131)},
	},
}

vrmod_ladders["d1_canals_08"] = {
	{
		pos = Vector(-130, -3547, -442),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 13,
		dismounts = {Vector(-130, -3551, -239)},
	},
}

vrmod_ladders["d1_canals_10"] = {
	{
		pos = Vector(5024, 9351, -377.7),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(5023, 9343, -127)},
	},
	{
		pos = Vector(3104, 9351, -377.7),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(3104, 9343, -127)},
	},
}

vrmod_ladders["d1_canals_11"] = {
	{
		pos = Vector(10231.6, 7276, -887),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 24,
		dismounts = {Vector(10212, 7296, -527)},
	},
	{
		pos = Vector(6443, 4940, -995),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 5,
		dismounts = {Vector(6445, 4944, -922)},
	},
}

--todo theres a moveable ladder in this map, handle it and add it
vrmod_ladders["d1_canals_12"] = {
	{
		pos = Vector(575, 11064, 426),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 5,
		dismounts = {Vector(571, 11065, 500.1)},
	},
}

vrmod_ladders["d1_canals_13"] = {
	{
		pos = Vector(1021, -3261, -272.5), --todo delayed activation
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 14,
		dismounts = {Vector(1025, -3262, -63.9)},
	},
	{
		pos = Vector(1021, -3357, -240.5),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 12,
		dismounts = {Vector(1025, -3358, -63)},
	},
	{
		pos = Vector(3062, 2585, -440),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(3072, 2584, -189)},
	},
	{
		pos = Vector(4971, 1171.7, -400),
		ang = Angle(0, -30, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(4973, 1169, -165)},
	},
}

vrmod_ladders["d1_eli_01"] = {
	{
		pos = Vector(200.5, 4380.5, -1512),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(191, 4380, -1381)},
	},
	--
	{
		pos = Vector(348, 2022.3, -2719.3), --delayed activation
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 5,
		dismounts = {},
	},
	{
		pos = Vector(351, 2022.3, -2639.4),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {},
	},
}

vrmod_ladders["d1_eli_02"] = {
	{
		pos = Vector(-3483.6, 3792, -2946), --delayed activation
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 81,
		dismounts = {Vector(-3488, 3793, -1663)},
	},
}

vrmod_ladders["d1_town_01"] = {
	{
		pos = Vector(337, -181, -3636), --delayed activation
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(337, -178, -3542)},
	},
	{
		pos = Vector(295, -10, -3639.5),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(310, -41, -3455)},
	},
	{
		pos = Vector(291, -152, -3423.5),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(314, -128, -3323)},
	},
}

vrmod_ladders["d1_town_01a"] = {
	{
		pos = Vector(-8.8, 1264, -3592),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 24,
		dismounts = {Vector(-28, 1282, -3263)},
	},
}

vrmod_ladders["d1_town_02"] = {
	{
		pos = Vector(-2434.3, 727.8, -3372),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-2433, 735, -3243)},
	},
	{
		pos = Vector(-2534, 823, -3240),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-2568, 803, -3139)},
	},
	{
		pos = Vector(-3678.3, 317, -3448),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-3677, 320, -3327)},
	},
	{
		pos = Vector(-4908, 680, -3248),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 5,
		dismounts = {Vector(-4911, 676, -3175)},
	},
	{
		pos = Vector(-4351.7, 1476, -3128), --todo handle this
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-4352, 1455, -3007)},
	},
}

vrmod_ladders["d1_town_02a"] = {
	{
		pos = Vector(-4908, 680, -3260),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(-4912, 676, -3171)},
	},
}

vrmod_ladders["d1_town_05"] = {
	{
		pos = Vector(-3940, 7671, 911.6),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-3932, 7669, 1038)},
	},
}

vrmod_ladders["d2_coast_01"] = {
	{
		pos = Vector(-8035.2, -8459.4, 548),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 24,
		dismounts = {Vector(-8028, -8460, 934.1)},
	},
}

vrmod_ladders["d2_coast_03"] = {
	{
		pos = Vector(7000, 5068.5, 271.5),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 28,
		dismounts = {Vector(6998, 5064, 708.1)},
	},
}

vrmod_ladders["d2_coast_04"] = {
	{
		pos = Vector(2213, -2810, 280),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(2212, -2816, 412.1)},
	},
	{
		pos = Vector(4546.5, -1639, 111.5), --delayed activation
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 10,
		dismounts = {Vector(4542, -1637, 256.1)},
	},
	{
		pos = Vector(4487.5, -1728, 265.5),
		ang = Angle(5.5, -180, 0),
		width = 16,
		spacing = 16,
		count = 30,
		dismounts = {Vector(4469, -1702, 672.1), Vector(4468, -1753, 672.1)},
	},
}

vrmod_ladders["d2_coast_09"] = {
	{
		pos = Vector(272, 5264, -752),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 19,
		dismounts = {Vector(270, 5254, -455)},
	},
}

vrmod_ladders["d2_coast_10"] = {
	{
		pos = Vector(5496, 1050, 944),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(5477, 1026, 1052.1), Vector(5478, 1074, 1052.1)},
	},
}

vrmod_ladders["d2_coast_12"] = {
	{
		pos = Vector(4640.5, -11035, 311.3), --needs tuning
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 15,
		dismounts = {Vector(4639, -11033, 540.1)},
	},
	{
		pos = Vector(4704.6, -8268, 325.3), --needs tuning
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 15,
		dismounts = {Vector(4700, -8266, 554.1)},
	},
	{
		pos = Vector(4512.5, -4236, 337.3), --needs tuning
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 15,
		dismounts = {Vector(4509, -4235, 562.1)},
	},
	{
		pos = Vector(7072, 7770.6, 1423.4),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 32,
		dismounts = {Vector(7038, 7754, 1920.1)},
	},
}

vrmod_ladders["d2_prison_01"] = {
	{
		pos = Vector(1800, -3292, 1032),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(1790, -3291, 1280.1)},
	},
	{
		pos = Vector(1692, -2745, 1569.3),
		ang = Angle(0, -90, 0),
		width = 18,
		spacing = 15.5,
		count = 6,
		dismounts = {Vector(1690, -2745, 1660.2)},
	},
	{
		pos = Vector(3933, -2745.5, 1441),
		ang = Angle(0, -90, 0),
		width = 18,
		spacing = 15.5,
		count = 6,
		dismounts = {Vector(3932, -2745, 1532.2)},
	},
	{
		pos = Vector(3888, -3117.5, 1441),
		ang = Angle(0, -90, 0),
		width = 18,
		spacing = 15.5,
		count = 6,
		dismounts = {Vector(3887, -3116, 1532.2)},
	},
}

vrmod_ladders["d2_prison_02"] = {
	{
		pos = Vector(-2524, 3372, 271.4),
		ang = Angle(0, 0, 0),
		width = 16,
		spacing = 16,
		count = 12,
		dismounts = {Vector(-2505, 3393, 384.1)},
	},
}

vrmod_ladders["d2_prison_03"] = {
	{
		pos = Vector(-2720, 5079.3, 8),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(-2741, 5060, 128.1)},
	},
}

vrmod_ladders["d2_prison_07"] = {
	{
		pos = Vector(1796, -3864, -921),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(1773, -3843, -807)},
	},
	{
		pos = Vector(2456, -3838, -913),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 7,
		dismounts = {Vector(2447, -3837, -807)},
	},
}

vrmod_ladders["d3_c17_01"] = {
	{
		pos = Vector(-6936.4, -1546.3, 8),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 8,
		dismounts = {Vector(-6937, -1561, 138.1)},
	},
}

vrmod_ladders["d3_c17_03"] = {
	{
		pos = Vector(-3152, -4600, 72),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(-3185, -4575, 224.1)},
	},
}

vrmod_ladders["d3_c17_05"] = {
	{
		pos = Vector(1917, -4025, 139.5),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(1916, -4029, 212.2)},
	},
}

vrmod_ladders["d3_c17_08"] = {
	{
		pos = Vector(-1096, -1778, -503),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 24,
		dismounts = {Vector(-1076, -1810, -391), Vector(-1078, -1822, -175)},
	},
	{
		pos = Vector(639.5, -961.6, -471),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 12,
		dismounts = {Vector(640, -953, -279)},
	},
	{
		pos = Vector(967, 528, 403),
		ang = Angle(0, -90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(958, 519, 656.1)},
	},
	{
		pos = Vector(909, -115, 696),
		ang = Angle(0, 90, 0),
		width = 16,
		spacing = 16,
		count = 16,
		dismounts = {Vector(929, -138, 768.1), Vector(909, -109, 944)},
	},
}

vrmod_ladders["d3_c17_10a"] = {
	{
		pos = Vector(-687, 7032, 136),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(-690, 7032, 224.1)},
	},
	{
		pos = Vector(-687, 5512, 136),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(-690, 5512, 224.1)},
	},
}

vrmod_ladders["d3_c17_12"] = {
	{
		pos = Vector(-687, 7032, 136),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(-690, 7032, 224.1)},
	},
	{
		pos = Vector(-687, 5512, 136),
		ang = Angle(0, 180, 0),
		width = 16,
		spacing = 16,
		count = 6,
		dismounts = {Vector(-690, 5512, 224.1)},
	},
}

if CLIENT then
	g_VR = g_VR or {}
	local convars = vrmod.AddCallbackedConvar("vrmod_climbing", nil, 0)
	concommand.Add("vrmod_ladderdebug", function(ply, cmd, args)
		hook[args[1] == "1" and "Add" or "Remove"]("PostDrawTranslucentRenderables", "vrmod_ladderdebug", function()
			render.SetColorMaterial()
			local ladders = vrmod_ladders[game.GetMap()] or {}
			for k = 1, #ladders do
				local v = ladders[k]
				render.DrawWireframeBox(v.pos, v.ang, Vector(-5, -v.width / 2, -5), Vector(5, v.width / 2, (v.count - 1) * v.spacing + 5), Color(255, 0, 0, 128)) --pos, ang, mins, maxs, color
				render.DrawBox(v.pos, v.ang, Vector(-5, -0.5, -0.5), Vector(0.5, 0.5, 0.5), Color(0, 255, 0, 128))
				for i = 0, v.count - 1 do
					render.DrawBox(v.pos + v.ang:Up() * i * v.spacing, v.ang, Vector(-0.5, -v.width / 2, -0.5), Vector(0.5, v.width / 2, 0.5), Color(0, 255, 0, 128))
				end

				for i = 1, #v.dismounts do
					render.DrawWireframeBox(v.dismounts[i], Angle(), Vector(-16, -16, 0), Vector(16, 16, 36), Color(0, 0, 255, 128)) --player:GetHullDuck()
				end
			end
		end)
	end)

	local function EnableClimbing()
		local ladders = vrmod_ladders[game.GetMap()] or {}
		local ladderCount = #ladders
		if ladderCount == 0 then return end
		local targetPoses = {
			{
				controllerPoseName = "pose_lefthand",
				setHandPoseFunc = vrmod.SetLeftHandPose,
				time = 0
			},
			{
				controllerPoseName = "pose_righthand",
				setHandPoseFunc = vrmod.SetRightHandPose,
				time = 0
			}
		}

		local refHand = nil
		local refPos = nil
		local refOrigin = nil
		local dismounts = nil
		local originLerpStartPos = nil
		local originLerpStartTime = nil
		hook.Add("VRMod_Input", "ladders", function(action, pressed)
			if action == "boolean_left_pickup" or action == "boolean_right_pickup" then
				local hand = action == "boolean_left_pickup" and 1 or 2
				if pressed then
					local handPose = g_VR.tracking[hand == 1 and "pose_lefthand" or "pose_righthand"]
					for k = 1, ladderCount do
						local v = ladders[k]
						if (handPose.pos - v.pos):Length2DSqr() < 1024 then
							local handPosRel = WorldToLocal(handPose.pos, Angle(), v.pos, v.ang)
							if handPosRel.z > -5 and handPosRel.z < (v.count - 1) * v.spacing + 5 and handPosRel.y > -v.width / 2 and handPosRel.y < v.width / 2 and handPosRel.x > -5 and handPosRel.x < 5 then
								handPosRel.x = -3
								handPosRel.z = math.floor((handPosRel.z + v.spacing / 2) / v.spacing) * v.spacing + 1
								local handTargetPos, handTargetAng = LocalToWorld(handPosRel, Angle(0, 0, hand == 1 and 90 or -90), v.pos, v.ang)
								targetPoses[hand].time = SysTime()
								targetPoses[hand].pos = handTargetPos
								targetPoses[hand].ang = handTargetAng
								targetPoses[hand].hold = true
								refHand = hand
								refPos = handPose.pos - g_VR.origin
								refOrigin = g_VR.origin
								vrmod.StopLocomotion()
								dismounts = v.dismounts
								hook.Add("VRMod_PreRender", "ladders", function()
									local curTime = SysTime()
									if refHand then
										local refHandPos = g_VR.tracking[refHand == 1 and "pose_lefthand" or "pose_righthand"].pos - g_VR.origin
										g_VR.origin = refOrigin + refPos - refHandPos
										local tmp = g_VR.tracking.hmd.pos + Angle(0, g_VR.tracking.hmd.ang.yaw, 0):Forward() * -10
										tmp.z = g_VR.origin.z
										LocalPlayer():SetPos(tmp) --this overrides render pos z in the character system, and also affects lighting
									else
										local dt = math.min((curTime - originLerpStartTime) * 10, 1)
										local targetPos = LocalPlayer():GetPos() + Angle(0, g_VR.tracking.hmd.ang.yaw, 0):Forward() * 10
										targetPos = Vector(g_VR.origin.x + targetPos.x - g_VR.tracking.hmd.pos.x, g_VR.origin.y + targetPos.y - g_VR.tracking.hmd.pos.y, targetPos.z)
										g_VR.origin = LerpVector(dt, originLerpStartPos, targetPos)
										if dt == 1 then
											hook.Remove("VRMod_PreRender", "ladders")
											vrmod.StartLocomotion()
										end
									end

									for k = 1, 2 do
										local v = targetPoses[k]
										local dt = math.min((curTime - v.time) * 10, 1)
										if dt < 1 or v.hold then
											local controllerPose = g_VR.tracking[v.controllerPoseName]
											local pos, ang
											if v.hold then
												pos, ang = LerpVector(dt, controllerPose.pos, v.pos), LerpAngle(dt, controllerPose.ang, v.ang)
											else
												pos, ang = LerpVector(dt, v.pos, controllerPose.pos), LerpAngle(dt, v.ang, controllerPose.ang)
											end

											v.setHandPoseFunc(pos, ang)
										end
									end
								end)

								-- input.SelectWeapon(LocalPlayer():GetWeapon("weapon_vrmod_empty"))
								break
							end
						end
					end
				elseif refHand then
					targetPoses[hand].hold = false
					targetPoses[hand].time = targetPoses[hand].pos and SysTime() or 0
					if targetPoses[3 - hand].hold then
						refHand = 3 - hand
						refPos = g_VR.tracking[hand == 2 and "pose_lefthand" or "pose_righthand"].pos - g_VR.origin
						refOrigin = g_VR.origin
					else
						local dismountPos, dismountDot = nil, 0.6
						for k = 1, #dismounts do
							local v = dismounts[k]
							local dot = g_VR.tracking.hmd.ang:Forward():Dot(((v + Vector(0, 0, 18)) - g_VR.tracking.hmd.pos):GetNormalized())
							if math.abs(v.z - g_VR.origin.z) < 60 and dot > dismountDot and util.TraceLine({
								start = g_VR.tracking.hmd.pos,
								endpos = v,
								filter = LocalPlayer()
							}).Fraction > 0.99 then
								dismountPos = v
								dismountDot = dot
							end
						end

						if dismountPos == nil then
							dismountPos = g_VR.tracking.hmd.pos + Angle(0, g_VR.tracking.hmd.ang.yaw, 0):Forward() * -10
							dismountPos.z = g_VR.origin.z
						end

						net.Start("vrmod_ladderteleport")
						net.WriteVector(dismountPos)
						net.SendToServer()
						timer.Simple(0.001, function()
							refHand = nil
							originLerpStartPos = g_VR.origin
							originLerpStartTime = SysTime()
						end)
					end
				end
			end
		end)

		net.Start("vrmod_enableclimbing")
		net.WriteBool(true)
		net.SendToServer()
	end

	local function DisableClimbing()
		vrmod.StartLocomotion()
		hook.Remove("VRMod_Input", "ladders")
		hook.Remove("VRMod_PreRender", "ladders")
		net.Start("vrmod_enableclimbing")
		net.WriteBool(false)
		net.SendToServer()
	end

	cvars.RemoveChangeCallback("vrmod_climbing", "vrmod_climbing")
	cvars.AddChangeCallback("vrmod_climbing", function(convar, oldValue, newValue)
		if not g_VR.active then return end
		if newValue == "1" then
			EnableClimbing()
		else
			DisableClimbing()
		end
	end, "vrmod_climbing")

	hook.Add("VRMod_Start", "climbing", function() if convars.vrmod_climbing:GetBool() then EnableClimbing() end end)
	hook.Add("VRMod_Exit", "climbing", function() if convars.vrmod_climbing:GetBool() then DisableClimbing() end end)
elseif SERVER then
	util.AddNetworkString("vrmod_ladderteleport")
	util.AddNetworkString("vrmod_enableclimbing")
	local climbingEnabled = false
	hook.Add("AcceptInput", "vrmod_ladders", function(ent, input, activator, caller, value)
		if value ~= "vrmod" and ent:GetClass() == "func_useableladder" and (input == "Enable" or input == "Disable") then
			for k, v in pairs(vrmod_ladders[game.GetMap()]) do
				if (ent:LocalToWorld(ent:GetKeyValues().point1) - v.pos):Length2DSqr() < 1024 then
					ent.vrmod_shouldenable = input == "Enable"
					if ent.vrmod_shouldenable and climbingEnabled then return true end
				end
			end
		end
	end)

	net.Receive("vrmod_enableclimbing", function(len, ply)
		climbingEnabled = net.ReadBool()
		if climbingEnabled then
			for k, v in pairs(ents.FindByClass("func_useableladder")) do
				for k2, v2 in pairs(vrmod_ladders[game.GetMap()]) do
					if (v:LocalToWorld(v:GetKeyValues().point1) - v2.pos):Length2DSqr() < 1024 then
						v.vrmod_shouldenable = v.vrmod_shouldenable or v:GetKeyValues().StartDisabled ~= 1
						v:Fire("Disable", "vrmod")
						break
					end
				end
			end
		else
			for k, v in pairs(ents.FindByClass("func_useableladder")) do
				if v.vrmod_shouldenable then v:Fire("Enable", "vrmod") end
			end
		end
	end)

	net.Receive("vrmod_ladderteleport", function(len, ply)
		local pos = net.ReadVector()
		ply:SetPos(pos)
	end)

	concommand.Add("vrmod_ladderdebugdismounts", function(ply, cmd, args)
		local dismounts = {}
		local index = 1
		for k, v in pairs(vrmod_ladders[game.GetMap()] or {}) do
			for i = 1, #v.dismounts do
				dismounts[#dismounts + 1] = {
					ladderindex = k,
					dismountindex = i,
					pos = v.dismounts[i]
				}
			end
		end

		hook.Add("KeyPress", "ladderdebug", function(ply, key)
			if key == IN_RELOAD then
				local tmp = dismounts[index]
				if tmp then
					ply:ChatPrint("ladder: " .. tmp.ladderindex .. ", dismount: " .. tmp.dismountindex)
					index = dismounts[index + 1] and index + 1 or 1
					ply:SetPos(tmp.pos)
				end
			end
		end)
	end)
end