rework and enhance 3x this script, and remove all comments
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local head = character:WaitForChild("Head")

local TweenService = game:GetService("TweenService")
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local currentMode = 1
local modeChangeCooldown = 5 -- seconds
local soundPlayChance = 0.2 -- 20% chance to play a sound each iteration
local lifespanDuration = 10 -- seconds
local spawnTime = tick()

local function getRandomPosition()
	local randomAngle = math.random() * math.pi * 2
	local randomDistance = math.random(10, 30)
	local newX = rootPart.Position.X + math.cos(randomAngle) * randomDistance
	local newZ = rootPart.Position.Z + math.sin(randomAngle) * randomDistance
	return Vector3.new(newX, rootPart.Position.Y, newZ)
end

local function getNearbyPlayers(maxDistance)
	local nearbyPlayers = {}
	for _, player in pairs(game.Players:GetPlayers()) do
		if player.Character and player.Character ~= character then
			local distance = (player.Character.HumanoidRootPart.Position - rootPart.Position).Magnitude
			if distance <= maxDistance then
				table.insert(nearbyPlayers, player.Character)
			end
		end
	end
	return nearbyPlayers
end

local function getNearestPlayer()
	local nearestPlayer = nil
	local nearestDistance = math.huge

	for _, player in pairs(game.Players:GetPlayers()) do
		if player.Character and player.Character ~= character then
			local distance = (player.Character.HumanoidRootPart.Position - rootPart.Position).Magnitude
			if distance < nearestDistance then
				nearestDistance = distance
				nearestPlayer = player.Character
			end
		end
	end

	return nearestPlayer
end

local function moveToPosition(targetPosition)
	local path = PathfindingService:CreatePath()
	path:ComputeAsync(rootPart.Position, targetPosition)

	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()

		for i, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				humanoid.Jump = true
			end
			humanoid:MoveTo(waypoint.Position)
			humanoid.MoveToFinished:Wait()
		end
	end
end

local function tweenLookAt(targetPosition, duration)
	local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local startCFrame = rootPart.CFrame
	local endCFrame = CFrame.new(rootPart.Position, Vector3.new(targetPosition.X, rootPart.Position.Y, targetPosition.Z))

	local tween = TweenService:Create(rootPart, tweenInfo, {CFrame = endCFrame})
	tween:Play()
	tween.Completed:Wait()
end

local function lookAtRandomNearbyPlayer()
	local nearbyPlayers = getNearbyPlayers(50) -- Adjust the max distance as needed
	if #nearbyPlayers > 0 then
		local randomPlayer = nearbyPlayers[math.random(1, #nearbyPlayers)]
		tweenLookAt(randomPlayer.HumanoidRootPart.Position, 0.5)
	end
end

local function playRandomSound()
	if math.random() < soundPlayChance then
		local soundNumber = math.random(1, 4)
		local soundName = "Talk" .. soundNumber
		local sound = head:FindFirstChild(soundName)
		if sound and sound:IsA("Sound") then
			sound:Play()
		end
	end
end

local function stand()
	lookAtRandomNearbyPlayer()
	playRandomSound()
	wait(1)
end

local function followNearestPlayer()
	local nearestPlayer = getNearestPlayer()
	if nearestPlayer then
		local targetPosition = nearestPlayer.HumanoidRootPart.Position
		local randomOffset = Vector3.new(math.random(-5, 5), 0, math.random(-5, 5))
		moveToPosition(targetPosition + randomOffset)
	end
	playRandomSound()
	wait(1)
end

local function randomMovement()
	local targetPosition = getRandomPosition()
	local midPoint1 = rootPart.Position:Lerp(targetPosition, 0.33) + Vector3.new(math.random(-5, 5), 0, math.random(-5, 5))
	local midPoint2 = rootPart.Position:Lerp(targetPosition, 0.66) + Vector3.new(math.random(-5, 5), 0, math.random(-5, 5))

	moveToPosition(midPoint1)
	playRandomSound()
	wait(0.5)

	moveToPosition(midPoint2)
	playRandomSound()
	wait(0.5)

	moveToPosition(targetPosition)
	playRandomSound()
	wait(0.5)

	lookAtRandomNearbyPlayer()
	playRandomSound()

	wait(1 + math.random())
end

local function isPlayerNearMushroom(mushroom)
	local nearbyPlayers = game.Players:GetPlayers()
	for _, player in ipairs(nearbyPlayers) do
		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
			local distance = (player.Character.HumanoidRootPart.Position - mushroom.PrimaryPart.Position).Magnitude
			if distance <= 10 then -- Adjust this distance as needed
				return true
			end
		end
	end
	return false
end

local function transformIntoMushroom()
	local mushroomModel = ReplicatedStorage:FindFirstChild("Mushroom")
	if mushroomModel then
		local mushroom = mushroomModel:Clone()
		mushroom.Parent = workspace
		mushroom:SetPrimaryPartCFrame(rootPart.Parent["Left Leg"].CFrame)

		character.Parent = ReplicatedStorage

		while true do
			if isPlayerNearMushroom(mushroom) then
				mushroom:Destroy()
				character.Parent = workspace
				spawnTime = tick() -- Reset the spawn time
				print("Character respawned. 10 seconds until next transformation.")
				return
			end
			wait(1)
		end
	else
		warn("Mushroom model not found in ReplicatedStorage")
	end
end

-- Play death sound when the character dies
humanoid.Died:Connect(function()
	local deathSound = head:FindFirstChild("Death")
	if deathSound and deathSound:IsA("Sound") then
		deathSound:Play()
	end
end)

local lastPrintTime = 0
local printInterval = 30 -- Print time left every 30 seconds

while true do
	local currentTime = tick()
	local timeElapsed = currentTime - spawnTime
	local timeLeft = lifespanDuration - timeElapsed

	if timeLeft <= 0 then
		print("Transforming into mushroom...")
		transformIntoMushroom()
	else
		if currentTime - lastPrintTime >= printInterval then
			print(string.format("Time left before mushrooming: %.0f seconds", timeLeft))
			lastPrintTime = currentTime
		end

		if currentMode == 1 then
			stand()
		elseif currentMode == 2 then
			followNearestPlayer()
		elseif currentMode == 3 then
			randomMovement()
		end

		if math.random() < 0.2 then
			currentMode = math.random(1, 3)
			wait(modeChangeCooldown)
		end
	end

	wait(0.1) -- Small wait to prevent excessive looping
end