local stupid = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local human = stupid:WaitForChild("Humanoid")
local root = stupid:WaitForChild("HumanoidRootPart")

_G.enabled = 0

local runService = game:GetService("RunService")

local currentNumber = 0

local getNearestTarget = function()
	local t = nil
	local veryHugeDist = math.huge
	for i, v in pairs(workspace:GetDescendants()) do
		if v:IsA("Model") and v ~= stupid then
			local h, r = v:FindFirstChildOfClass("Humanoid"), v:FindFirstChild("HumanoidRootPart")
			if h and r and h.Health > 0 then
				local d = (root.Position - r.Position).Magnitude
				if d < veryHugeDist then
					veryHugeDist = d
					t = v
				end
			end
		end
	end
	return t
end

local number = math.random(20,90)

delay(nil,function()
	while wait(math.random(1,5) / 100) do
		number = math.random(20,90)
	end
end)

delay(nil,function()
	local lastMove=0
	local bg = Instance.new("BodyGyro")
	bg.MaxTorque = Vector3.new(40000000,40000000,40000000)
	bg.P = 10000
	bg.D = 1
	bg.Parent = game.ReplicatedStorage
	runService.RenderStepped:Connect(function()
		local t = getNearestTarget()
		if not t then bg.Parent = game.ReplicatedStorage human.AutoRotate = true return end
		local h = t:FindFirstChildOfClass("Humanoid")
		local r = t:FindFirstChild("HumanoidRootPart")
		local rarm = t:FindFirstChild("Right Arm") or t:FindFirstChild("Right Hand")
		if not h or not r then bg.Parent = game.ReplicatedStorage human.AutoRotate = true return end
		if h.Health == 0 then bg.Parent = game.ReplicatedStorage human.AutoRotate = true return end
		if _G.enabled == 1 then
			if h.Health > 0 then
				bg.Parent = root
				human.AutoRotate = false
				local tool = stupid:FindFirstChildOfClass("Tool")
				local lungpos
				if tool and tool:FindFirstChild("Handle") then
					local handle = tool.Handle
					local swordTipPos = (handle.CFrame * CFrame.new(0, 0, -4)).Position -- tip of sword (assumes -Z is blade)
					local directionToArm = (rarm.Position - swordTipPos).Unit

					local origin = swordTipPos
					local offsets = {
						Vector3.new(0, 0, 0),
						Vector3.new(0.5, 0, 0),
						Vector3.new(-0.5, 0, 0),
					}

					local bestPos, bestDist = nil, math.huge
					for _, offset in ipairs(offsets) do
						local castDir = ((rarm.Position + offset) - origin).Unit * 100
						local result = workspace:Raycast(origin, castDir, RaycastParams.new())
						if result then
							local dist = (result.Position - origin).Magnitude
							if dist < bestDist then
								bestDist = dist
								bestPos = result.Position
								lungpos = bestPos
							end
						end
					end

					if bestPos then
						local direction = (bestPos - swordTipPos).Unit * Vector3.new(1,0,1)
						bg.CFrame = CFrame.new(root.Position, (root.Position + direction))
					else
						local fallbackDir = (rarm.Position - swordTipPos).Unit * Vector3.new(1,0,1)
						bg.CFrame = CFrame.new(root.Position, (root.Position + fallbackDir))
					end
				else
					-- fallback if no tool/handle
					local drtn = ((r.CFrame * (CFrame.new(3, 0, 0)).p - root.Position) * Vector3.new(1,0,1))
					bg.CFrame = CFrame.new(root.Position, root.Position + drtn)
				end
				--bg.CFrame = CFrame.new(root.Position, root.Position + ((r.CFrame * CFrame.new(0,0,0).Position) - root.Position).Unit * Vector3.new(1,0,1))
				local microsecond = tick()
				local d = (r.Position - root.Position).Magnitude
				if d > 19 then
					human:MoveTo(r.Position)
				else
					if r.CFrame.LookVector.Unit:Dot((root.Position - r.Position).Unit) > 0.75 then
						if (r.Position - root.Position).Magnitude < 15 then
							bg.CFrame = CFrame.new(root.Position, root.Position + ((r.CFrame * CFrame.new(4,0,0).Position) - root.Position).Unit * Vector3.new(1,0,1)) * CFrame.Angles(0,math.rad(math.sin(tick() * 35) * 25*((number-(math.random()*5))/35)),0)
						end
					end
					if stupid:FindFirstChildOfClass("Tool") then
						stupid:FindFirstChildOfClass("Tool"):Activate()
					end
					if microsecond-lastMove > math.random() * ((number^2/10) / (380 + math.random())) then
						lastMove = tick()
						local STRAFE_AMOUNT = 1 * (number * math.random() * 2 + (math.random() * 5) / 25)
						--print(STRAFE_AMOUNT)
						local offset = Vector3.new(
							math.random(-STRAFE_AMOUNT, STRAFE_AMOUNT),
							0,
							math.random(-STRAFE_AMOUNT, STRAFE_AMOUNT)
						)
						human:MoveTo((r.Position - (r.Position - root.Position).Unit * 2.5) + offset)
						if STRAFE_AMOUNT < 1 then
							human.Jump = true
						end
						if r.Position.Y - 0.5 > root.Position.Y then
							human.Jump = true
						end
					end
				end
			else
				bg.Parent = game.ReplicatedStorage
				human.AutoRotate = true
			end
		else
			bg.Parent = game.ReplicatedStorage
			human.AutoRotate = true
		end
	end)
end)

game:GetService("UserInputService").InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.R then
		_G.enabled = _G.enabled == 1 and 0 or 1
		print(_G.enabled == 1 and "enabled" or "disabled")
		game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage", {
			Text = "BOT = " .. _G.enabled,
			Color = Color3.fromRGB(255, 255, 255),
			Font = Enum.Font.SourceSansBold,
			TextSize = 18
		})
		if game.Players.LocalPlayer.PlayerGui:FindFirstChild("sword fighting bot ui") then
			game.Players.LocalPlayer.PlayerGui["sword fighting bot ui"].TextButton.Text = "bot: ".._G.enabled
		end
	end
end)

local function respawn()
	stupid = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
	human = stupid:WaitForChild("Humanoid")
	root = stupid:WaitForChild("HumanoidRootPart")

	human.Died:Connect(function()
		game.Players.LocalPlayer.CharacterAdded:Wait()
		respawn()
	end)
end

game.Players.LocalPlayer.CharacterAdded:Connect(function()
	respawn()
end)

delay(0,function()
	local last = 0
	runService.RenderStepped:Connect(function()
		local t = getNearestTarget()
		if not t then return end
		local h = t:FindFirstChildOfClass("Humanoid")
		local r = t:FindFirstChild("HumanoidRootPart")
		local microsecond = tick()
		if not h and r then return end
		if h.Health == 0 then return end
		if _G.enabled == 1 then
			if microsecond-last > math.random(5,25) / 10 then
				last = microsecond
				local tool = stupid:FindFirstChildOfClass("Tool")
				if tool then
					tool:Activate()
				end
			end
		end
	end)
end)

local UserInputService = game:GetService("UserInputService")

if UserInputService.TouchEnabled then
	local ScreenGui = Instance.new("ScreenGui")
	ScreenGui.Name = "sword fighting bot ui"
	ScreenGui.ResetOnSpawn = false
	ScreenGui.Parent = game.Players.LocalPlayer:WaitForChild("PlayerGui")

	local button = Instance.new("TextButton")
	button.Size = UDim2.new(0, 100, 0, 50)
	button.Position = UDim2.new(0.5, -50, 0, 15)
	button.BackgroundColor3 = Color3.fromRGB(203, 203, 203)
	button.BackgroundTransparency = 0.3
	button.TextColor3 = Color3.new(1, 1, 1)
	button.Text = "bot: ".._G.enabled
	button.Font = Enum.Font.RobotoMono
	button.TextScaled = true
	button.Draggable = true
	button.Parent = ScreenGui
	
	local corner = Instance.new("UICorner")
	corner.Parent = button

	local dragging, dragInput, dragStart, startPos

	button.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.Touch then
			dragging = true
			dragStart = input.Position
			startPos = button.Position

			input.Changed:Connect(function()
				if input.UserInputState == Enum.UserInputState.End then
					dragging = false
				end
			end)
		end
	end)

	button.InputChanged:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.Touch then
			dragInput = input
		end
	end)

	UserInputService.InputChanged:Connect(function(input)
		if input == dragInput and dragging then
			local delta = input.Position - dragStart
			button.Position = UDim2.new(
				startPos.X.Scale,
				startPos.X.Offset + delta.X,
				startPos.Y.Scale,
				startPos.Y.Offset + delta.Y
			)
		end
	end)

	button.MouseButton1Click:Connect(function()
		_G.enabled = _G.enabled == 1 and 0 or 1
		button.Text = "bot: ".._G.enabled
		game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage", {
			Text = "BOT = ".._G.enabled,
			Color = Color3.fromRGB(255, 255, 255),
			Font = Enum.Font.SourceSansBold,
			TextSize = 18
		})
	end)
end
