local A=require(script.Parent:WaitForChild("\066\097\115\101\067\104\097\114\097\099\116\101\114\067\111\110\116\114\111\108\108\101\114"))local O=setmetatable({},A)O.__index=O function O.new()local V=setmetatable(A.new(),O)V.parentUIFrame=nil V.jumpButton=nil V.characterAddedConn=nil V.humanoidStateEnabledChangedConn=nil V.humanoidJumpPowerConn=nil V.humanoidParentConn=nil V.externallyEnabled=false V.jumpPower=0 V.jumpStateEnabled=true V.isJumping=false V.humanoid=nil return V end function O.EnableButton(O,A)if A then if not O.jumpButton then O:Create()end local A=Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if A and O.externallyEnabled then if O.externallyEnabled then if A.JumpPower>0 then O.jumpButton.Visible=true end end end else O.jumpButton.Visible=false O.isJumping=false O.jumpButton.ImageRectOffset=Vector2.new(1,146)end end function O.UpdateEnabled(A)if A.jumpPower>0 and A.jumpStateEnabled then A:EnableButton(true)else A:EnableButton(false)end end function O.HumanoidChanged(O,A)local V=Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if V then if A=="\074\117\109\112\080\111\119\101\114"then O.jumpPower=V.JumpPower O:UpdateEnabled()elseif A=="\080\097\114\101\110\116"then if not V.Parent then O.humanoidChangeConn:Disconnect()end end end end function O.HumanoidStateEnabledChanged(V,A,O)if A==Enum.HumanoidStateType.Jumping then V.jumpStateEnabled=O V:UpdateEnabled()end end function O.CharacterAdded(O,A)if O.humanoidChangeConn then O.humanoidChangeConn:Disconnect()O.humanoidChangeConn=nil end O.humanoid=A:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")while not O.humanoid do A.ChildAdded:wait()O.humanoid=A:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")end O.humanoidJumpPowerConn=(O.humanoid:GetPropertyChangedSignal("\074\117\109\112\080\111\119\101\114")):Connect(function()O.jumpPower=O.humanoid.JumpPower O:UpdateEnabled()end)O.humanoidParentConn=(O.humanoid:GetPropertyChangedSignal("\080\097\114\101\110\116")):Connect(function()if not O.humanoid.Parent then O.humanoidJumpPowerConn:Disconnect()O.humanoidJumpPowerConn=nil O.humanoidParentConn:Disconnect()O.humanoidParentConn=nil end end)O.humanoidStateEnabledChangedConn=O.humanoid.StateEnabledChanged:Connect(function(A,V)O:HumanoidStateEnabledChanged(A,V)end)O.jumpPower=O.humanoid.JumpPower O.jumpStateEnabled=O.humanoid:GetStateEnabled(Enum.HumanoidStateType.Jumping)O:UpdateEnabled()end function O.SetupCharacterAddedFunction(A)A.characterAddedConn=Players.LocalPlayer.CharacterAdded:Connect(function(O)A:CharacterAdded(O)end)if Players.LocalPlayer.Character then A:CharacterAdded(Players.LocalPlayer.Character)end end function O.Enable(V,A,O)if O then V.parentUIFrame=O end V.externallyEnabled=A V:EnableButton(A)end function O.Create(A)if not A.parentUIFrame then return end if A.jumpButton then A.jumpButton:Destroy()A.jumpButton=nil end local O=math.min(A.parentUIFrame.AbsoluteSize.x,A.parentUIFrame.AbsoluteSize.y)local V=O<=500 local p=V and 70 or 120 A.jumpButton=Instance.new("\073\109\097\103\101\066\117\116\116\111\110")A.jumpButton.Name="\074\117\109\112\066\117\116\116\111\110"A.jumpButton.Visible=false A.jumpButton.BackgroundTransparency=1 A.jumpButton.Image=TOUCH_CONTROL_SHEET A.jumpButton.ImageRectOffset=Vector2.new(1,146)A.jumpButton.ImageRectSize=Vector2.new(144,144)A.jumpButton.Size=UDim2.new(0,p,0,p)A.jumpButton.Position=V and UDim2.new(1,-(p*1.5-10),1,-p-20)or UDim2.new(1,-(p*1.5-10),1,-p*1.75)local c=nil A.jumpButton.InputBegan:connect(function(O)if c or O.UserInputType~=Enum.UserInputType.Touch or O.UserInputState~=Enum.UserInputState.Begin then return end c=O A.jumpButton.ImageRectOffset=Vector2.new(146,146)A.isJumping=true end)local Q=function()c=nil A.isJumping=false A.jumpButton.ImageRectOffset=Vector2.new(1,146)end A.jumpButton.InputEnded:connect(function(A)if A==c then Q()end end)GuiService.MenuOpened:connect(function()if c then Q()end end)if not A.characterAddedConn then A:SetupCharacterAddedFunction()end A.jumpButton.Parent=A.parentUIFrame end return O
--[[ The Module ]]
--
local BaseCharacterController = require(script.Parent:WaitForChild("BaseCharacterController"))
local TouchJump = setmetatable({}, BaseCharacterController)
TouchJump.__index = TouchJump

function TouchJump.new()
	local self = setmetatable(BaseCharacterController.new(), TouchJump)

	self.parentUIFrame = nil
	self.jumpButton = nil
	self.characterAddedConn = nil
	self.humanoidStateEnabledChangedConn = nil
	self.humanoidJumpPowerConn = nil
	self.humanoidParentConn = nil
	self.externallyEnabled = false
	self.jumpPower = 0
	self.jumpStateEnabled = true
	self.isJumping = false
	self.humanoid = nil -- saved reference because property change connections are made using it

	return self
end

function TouchJump:EnableButton(enable)
	if enable then
		if not self.jumpButton then
			self:Create()
		end
		local humanoid = Players.LocalPlayer.Character
			and Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
		if humanoid and self.externallyEnabled then
			if self.externallyEnabled then
				if humanoid.JumpPower > 0 then
					self.jumpButton.Visible = true
				end
			end
		end
	else
		self.jumpButton.Visible = false
		self.isJumping = false
		self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
	end
end

function TouchJump:UpdateEnabled()
	if self.jumpPower > 0 and self.jumpStateEnabled then
		self:EnableButton(true)
	else
		self:EnableButton(false)
	end
end

function TouchJump:HumanoidChanged(prop)
	local humanoid = Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		if prop == "JumpPower" then
			self.jumpPower = humanoid.JumpPower
			self:UpdateEnabled()
		elseif prop == "Parent" then
			if not humanoid.Parent then
				self.humanoidChangeConn:Disconnect()
			end
		end
	end
end

function TouchJump:HumanoidStateEnabledChanged(state, isEnabled)
	if state == Enum.HumanoidStateType.Jumping then
		self.jumpStateEnabled = isEnabled
		self:UpdateEnabled()
	end
end

function TouchJump:CharacterAdded(char)
	if self.humanoidChangeConn then
		self.humanoidChangeConn:Disconnect()
		self.humanoidChangeConn = nil
	end

	self.humanoid = char:FindFirstChildOfClass("Humanoid")
	while not self.humanoid do
		char.ChildAdded:wait()
		self.humanoid = char:FindFirstChildOfClass("Humanoid")
	end

	self.humanoidJumpPowerConn = self.humanoid:GetPropertyChangedSignal("JumpPower"):Connect(function()
		self.jumpPower = self.humanoid.JumpPower
		self:UpdateEnabled()
	end)

	self.humanoidParentConn = self.humanoid:GetPropertyChangedSignal("Parent"):Connect(function()
		if not self.humanoid.Parent then
			self.humanoidJumpPowerConn:Disconnect()
			self.humanoidJumpPowerConn = nil
			self.humanoidParentConn:Disconnect()
			self.humanoidParentConn = nil
		end
	end)

	self.humanoidStateEnabledChangedConn = self.humanoid.StateEnabledChanged:Connect(function(state, enabled)
		self:HumanoidStateEnabledChanged(state, enabled)
	end)

	self.jumpPower = self.humanoid.JumpPower
	self.jumpStateEnabled = self.humanoid:GetStateEnabled(Enum.HumanoidStateType.Jumping)
	self:UpdateEnabled()
end

function TouchJump:SetupCharacterAddedFunction()
	self.characterAddedConn = Players.LocalPlayer.CharacterAdded:Connect(function(char)
		self:CharacterAdded(char)
	end)
	if Players.LocalPlayer.Character then
		self:CharacterAdded(Players.LocalPlayer.Character)
	end
end

function TouchJump:Enable(enable, parentFrame)
	if parentFrame then
		self.parentUIFrame = parentFrame
	end
	self.externallyEnabled = enable
	self:EnableButton(enable)
end

function TouchJump:Create()
	if not self.parentUIFrame then
		return
	end

	if self.jumpButton then
		self.jumpButton:Destroy()
		self.jumpButton = nil
	end

	local minAxis = math.min(self.parentUIFrame.AbsoluteSize.x, self.parentUIFrame.AbsoluteSize.y)
	local isSmallScreen = minAxis <= 500
	local jumpButtonSize = isSmallScreen and 70 or 120

	self.jumpButton = Instance.new("ImageButton")
	self.jumpButton.Name = "JumpButton"
	self.jumpButton.Visible = false
	self.jumpButton.BackgroundTransparency = 1
	self.jumpButton.Image = TOUCH_CONTROL_SHEET
	self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
	self.jumpButton.ImageRectSize = Vector2.new(144, 144)
	self.jumpButton.Size = UDim2.new(0, jumpButtonSize, 0, jumpButtonSize)

	self.jumpButton.Position = isSmallScreen and UDim2.new(1, -(jumpButtonSize * 1.5 - 10), 1, -jumpButtonSize - 20)
		or UDim2.new(1, -(jumpButtonSize * 1.5 - 10), 1, -jumpButtonSize * 1.75)

	local touchObject = nil
	self.jumpButton.InputBegan:connect(function(inputObject)
		--A touch that starts elsewhere on the screen will be sent to a frame's InputBegan event
		--if it moves over the frame. So we check that this is actually a new touch (inputObject.UserInputState ~= Enum.UserInputState.Begin)
		if
			touchObject
			or inputObject.UserInputType ~= Enum.UserInputType.Touch
			or inputObject.UserInputState ~= Enum.UserInputState.Begin
		then
			return
		end

		touchObject = inputObject
		self.jumpButton.ImageRectOffset = Vector2.new(146, 146)
		self.isJumping = true
	end)

	local OnInputEnded = function()
		touchObject = nil
		self.isJumping = false
		self.jumpButton.ImageRectOffset = Vector2.new(1, 146)
	end

	self.jumpButton.InputEnded:connect(function(inputObject)
		if inputObject == touchObject then
			OnInputEnded()
		end
	end)

	GuiService.MenuOpened:connect(function()
		if touchObject then
			OnInputEnded()
		end
	end)

	if not self.characterAddedConn then
		self:SetupCharacterAddedFunction()
	end

	self.jumpButton.Parent = self.parentUIFrame
end

return TouchJump
