--By YAREK --Switch to First person and tap Y to start/stop farm local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local player = Players.LocalPlayer if getgenv then local old = getgenv().LemonTreeScript if old then old.Running = false old.AutoCollecting = false if old.InputConnection then old.InputConnection:Disconnect() end if old.DescendantConnection then old.DescendantConnection:Disconnect() end if old.DescendantRemovingConnection then old.DescendantRemovingConnection:Disconnect() end if old.FlightConnection then old.FlightConnection:Disconnect() end if old.RescanConnection then old.RescanConnection:Disconnect() end if old.CameraTween then old.CameraTween:Cancel() end if old.FlightForce then old.FlightForce:Destroy() end if old.FlightAttachment then old.FlightAttachment:Destroy() end end getgenv().LemonTreeScript = { Running = true, AutoCollecting = false, InputConnection = nil, DescendantConnection = nil, DescendantRemovingConnection = nil, FlightConnection = nil, RescanConnection = nil, FlightForce = nil, FlightAttachment = nil, CameraTween = nil } end local ScriptState if getgenv then ScriptState = getgenv().LemonTreeScript else ScriptState = { Running = true, AutoCollecting = false } end local FIXED_Y = 3.7 local TELEPORT_OFFSET = 5 local CAMERA_TWEEN_TIME = 0.05 local FLIGHT_FORCE_MULTIPLIER = 1 local FRUIT_DELAY = 0.05 local SEARCH_DELAY = 0.03 local FRUIT_REACTION_TIME = 0.2 local CLICK_DELAY = 0.02 local VISIBILITY_ATTEMPTS = 16 local RESCAN_INTERVAL = 60 local ZONE_MIN_X = -302.91552734375 local ZONE_MAX_X = 302.94000244140625 local ZONE_MIN_Z = -457.056884765625 local ZONE_MAX_Z = 457.1495056152344 local ZONE_MARGIN = 2 local TELEPORT_MIN_X = ZONE_MIN_X + ZONE_MARGIN local TELEPORT_MAX_X = ZONE_MAX_X - ZONE_MARGIN local TELEPORT_MIN_Z = ZONE_MIN_Z + ZONE_MARGIN local TELEPORT_MAX_Z = ZONE_MAX_Z - ZONE_MARGIN local trees = {} local fruitCache = {} local fruitStates = {} local previousFruitPresence = {} local lastRescan = 0 local VirtualInputManager pcall(function() VirtualInputManager = game:GetService("VirtualInputManager") end) local function isRunning() return ScriptState.Running == true end local function getVisualFruit(clickPart) if not clickPart then return nil end local fruit = clickPart.Parent if not fruit then return nil end if fruit.Name ~= "Fruit" then return nil end if not fruit:IsA("BasePart") then return nil end return fruit end local function isClickFruitPart(object) if not object then return false end if object.Name ~= "ClickFruitPart" then return false end if not object:IsA("BasePart") then return false end local fruit = object.Parent if not fruit then return false end if fruit.Name ~= "Fruit" then return false end if not fruit:IsA("BasePart") then return false end local detector = object:FindFirstChildOfClass("ClickDetector") if not detector then return false end return true end local function addTree(tree) if not isRunning() then return end if not tree then return end if tree.Name ~= "LemonTree" then return end if not tree:IsA("Model") then return end if not table.find(trees, tree) then trees[#trees + 1] = tree end end local function addFruitToCache(object) if not isRunning() then return end if not isClickFruitPart(object) then return end local fruit = object.Parent if not fruit then return end local lemonTree = fruit:FindFirstAncestor("LemonTree") if not lemonTree then return end if not lemonTree:IsA("Model") then return end if not lemonTree:IsDescendantOf(workspace) then return end fruitCache[object] = true end local function removeFruitFromCache(object) if object then fruitCache[object] = nil end end local function scanContainer(container) if not isRunning() then return end if not container then return end if container.Name == "LemonTree" and container:IsA("Model") then addTree(container) for _, object in ipairs( container:GetDescendants() ) do if not isRunning() then return end if isClickFruitPart(object) then addFruitToCache(object) end end return end for _, child in ipairs( container:GetChildren() ) do if not isRunning() then return end if child.Name == "LemonTree" and child:IsA("Model") then scanContainer(child) elseif child:IsA("Folder") or child:IsA("Model") then scanContainer(child) end end end local function rebuildTreeList() if not isRunning() then return end local newTrees = {} local newTreeSet = {} for i = 1, 9 do if not isRunning() then return end local tycoon = workspace:FindFirstChild( "Tycoon" .. i ) if tycoon then for _, object in ipairs( tycoon:GetDescendants() ) do if object.Name == "LemonTree" and object:IsA("Model") then if not newTreeSet[object] then newTreeSet[object] = true newTrees[#newTrees + 1] = object end end end end end local directTree = workspace:FindFirstChild( "LemonTree" ) if directTree and directTree:IsA("Model") then if not newTreeSet[directTree] then newTreeSet[directTree] = true newTrees[#newTrees + 1] = directTree end end trees = newTrees end local function rebuildFruitCache() if not isRunning() then return end local oldPresence = previousFruitPresence local newCache = {} local newPresence = {} for _, tree in ipairs(trees) do if tree and tree.Parent and tree:IsDescendantOf(workspace) then for _, object in ipairs( tree:GetDescendants() ) do if not isRunning() then return end if isClickFruitPart(object) then newCache[object] = true newPresence[object] = true if not oldPresence[object] then fruitStates[object] = nil end end end end end for fruit in pairs(fruitStates) do if not newPresence[fruit] then fruitStates[fruit] = nil end end fruitCache = newCache previousFruitPresence = newPresence end local function fullRescan() if not isRunning() then return end rebuildTreeList() rebuildFruitCache() lastRescan = os.clock() end fullRescan() ScriptState.DescendantConnection = workspace.DescendantAdded:Connect( function(object) if not isRunning() then return end if object.Name == "LemonTree" and object:IsA("Model") then addTree(object) for _, child in ipairs( object:GetDescendants() ) do if isClickFruitPart(child) then addFruitToCache(child) end end return end if isClickFruitPart(object) then addFruitToCache(object) end end ) ScriptState.DescendantRemovingConnection = workspace.DescendantRemoving:Connect( function(object) removeFruitFromCache(object) end ) ScriptState.RescanConnection = RunService.Heartbeat:Connect( function() if not isRunning() then return end if not ScriptState.AutoCollecting then return end if os.clock() - lastRescan >= RESCAN_INTERVAL then fullRescan() end end ) local function isFruitValid(clickPart) if not clickPart then return false end if not clickPart.Parent then return false end if not clickPart:IsDescendantOf(workspace) then return false end local detector = clickPart:FindFirstChildOfClass( "ClickDetector" ) if not detector then return false end local fruit = getVisualFruit(clickPart) if not fruit then return false end if not fruit:IsDescendantOf(workspace) then return false end return true end local function isFruitActuallyVisible(clickPart) if not isFruitValid(clickPart) then return false end local fruit = getVisualFruit(clickPart) if not fruit then return false end if fruit.Transparency >= 0.95 then return false end if fruit.Size.Magnitude < 0.05 then return false end return true end local function isPositionInsideZone(position) return position.X >= TELEPORT_MIN_X and position.X <= TELEPORT_MAX_X and position.Z >= TELEPORT_MIN_Z and position.Z <= TELEPORT_MAX_Z end local function getCandidatePosition( fruit, angle ) local radians = math.rad(angle) local direction = Vector3.new( math.cos(radians), 0, math.sin(radians) ) local position = fruit.Position + direction * TELEPORT_OFFSET return Vector3.new( position.X, FIXED_Y, position.Z ) end local function canReachFruit(fruit) if not isFruitValid(fruit) then return false end for attempt = 0, VISIBILITY_ATTEMPTS - 1 do local angle = attempt * ( 360 / VISIBILITY_ATTEMPTS ) local candidate = getCandidatePosition( fruit, angle ) if isPositionInsideZone(candidate) then return true end end return false end local function getFruitState(fruit) local state = fruitStates[fruit] if not state then return nil end if state.Position then local distance = ( fruit.Position - state.Position ).Magnitude if distance > 1 then fruitStates[fruit] = nil return nil end end return state end local function skipFruit(fruit) if not fruit then return end fruitStates[fruit] = { Skipped = true, Position = fruit.Position } end local function canUseFruit(fruit) if not isFruitValid(fruit) then return false end local state = getFruitState(fruit) if state and state.Skipped then return false end if not isFruitActuallyVisible(fruit) then skipFruit(fruit) return false end if not canReachFruit(fruit) then skipFruit(fruit) return false end return true end local function getNearestFruit() if not isRunning() then return nil end local character = player.Character if not character then return nil end local root = character:FindFirstChild( "HumanoidRootPart" ) if not root then return nil end local nearest = nil local nearestDistance = math.huge for fruit in pairs(fruitCache) do if not isFruitValid(fruit) then fruitCache[fruit] = nil elseif canUseFruit(fruit) then local visualFruit = getVisualFruit(fruit) if visualFruit then local distance = ( root.Position - visualFruit.Position ).Magnitude if distance < nearestDistance then nearestDistance = distance nearest = fruit end end end end return nearest end local function findBestPosition(fruit) if not isFruitValid(fruit) then return nil end local character = player.Character if not character then return nil end local root = character:FindFirstChild( "HumanoidRootPart" ) if not root then return nil end local offset = root.Position - fruit.Position local horizontal = Vector3.new( offset.X, 0, offset.Z ) local startAngle = 0 if horizontal.Magnitude > 0.1 then startAngle = math.deg( math.atan2( horizontal.Z, horizontal.X ) ) end for attempt = 0, VISIBILITY_ATTEMPTS - 1 do local angle = startAngle + ( attempt * ( 360 / VISIBILITY_ATTEMPTS ) ) local candidate = getCandidatePosition( fruit, angle ) if isPositionInsideZone(candidate) then return candidate end end return nil end local function teleportToFruit(fruit) if not isRunning() then return false end if not isFruitValid(fruit) then return false end local targetPosition = findBestPosition(fruit) if not targetPosition then skipFruit(fruit) return false end local character = player.Character if not character then return false end local root = character:FindFirstChild( "HumanoidRootPart" ) if not root then return false end root.CFrame = CFrame.new( targetPosition ) RunService.Heartbeat:Wait() if not isFruitActuallyVisible(fruit) then skipFruit(fruit) return false end return true end local function turnCameraToFruit(fruit) if not isRunning() then return false end if not isFruitValid(fruit) then return false end local camera = workspace.CurrentCamera if not camera then return false end local visualFruit = getVisualFruit(fruit) if not visualFruit then return false end if ScriptState.CameraTween then ScriptState.CameraTween:Cancel() ScriptState.CameraTween = nil end local cameraPosition = camera.CFrame.Position local direction = visualFruit.Position - cameraPosition if direction.Magnitude < 0.01 then return false end direction = direction.Unit local targetCFrame = CFrame.lookAt( cameraPosition, cameraPosition + direction, Vector3.yAxis ) local tween = TweenService:Create( camera, TweenInfo.new( CAMERA_TWEEN_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.Out ), { CFrame = targetCFrame } ) ScriptState.CameraTween = tween tween.Completed:Connect( function() if ScriptState.CameraTween == tween then if isFruitValid(fruit) then local currentCamera = workspace.CurrentCamera local currentFruit = getVisualFruit(fruit) if currentCamera and currentFruit then local position = currentCamera.CFrame.Position local finalDirection = currentFruit.Position - position if finalDirection.Magnitude > 0.01 then currentCamera.CFrame = CFrame.lookAt( position, position + finalDirection.Unit, Vector3.yAxis ) end end end ScriptState.CameraTween = nil end end ) tween:Play() return true end local function isCameraLookingAtFruit(fruit) if not isFruitActuallyVisible(fruit) then return false end local camera = workspace.CurrentCamera if not camera then return false end local visualFruit = getVisualFruit(fruit) if not visualFruit then return false end local params = RaycastParams.new() params.FilterType = Enum.RaycastFilterType.Exclude params.IgnoreWater = true local filter = {} if player.Character then filter[#filter + 1] = player.Character end params.FilterDescendantsInstances = filter local origin = camera.CFrame.Position local direction = visualFruit.Position - origin if direction.Magnitude < 0.01 then return true end local result = workspace:Raycast( origin, direction, params ) if not result then return true end if result.Instance == visualFruit then return true end if result.Instance == fruit then return true end return false end local function simulateMouseClick(fruit) if not isRunning() then return false end if not isFruitValid(fruit) then return false end local camera = workspace.CurrentCamera if not camera then return false end local visualFruit = getVisualFruit(fruit) if not visualFruit then return false end local screenPosition, onScreen = camera:WorldToScreenPoint( visualFruit.Position ) if not onScreen then return false end local x = math.floor( screenPosition.X ) local y = math.floor( screenPosition.Y ) if x < 0 or y < 0 or x > camera.ViewportSize.X or y > camera.ViewportSize.Y then return false end if VirtualInputManager then local moveOk = pcall( function() VirtualInputManager: SendMouseMoveEvent( x, y, game ) end ) if not moveOk then return false end task.wait(CLICK_DELAY) local downOk = pcall( function() VirtualInputManager: SendMouseButtonEvent( x, y, 0, true, game, 0 ) end ) if not downOk then return false end task.wait(CLICK_DELAY) local upOk = pcall( function() VirtualInputManager: SendMouseButtonEvent( x, y, 0, false, game, 0 ) end ) if not upOk then return false end return true end if mouse1click then local ok = pcall( function() mouse1click() end ) if ok then return true end end return false end local function waitForFruitReaction(fruit) local startTime = os.clock() local initialPosition = fruit.Position while isRunning() and ScriptState.AutoCollecting and os.clock() - startTime < FRUIT_REACTION_TIME do if not isFruitValid(fruit) then return true end if not isFruitActuallyVisible(fruit) then return true end if ( fruit.Position - initialPosition ).Magnitude > 0.05 then return true end RunService.Heartbeat:Wait() end return false end local function processFruit(fruit) if not isRunning() then return false end if not ScriptState.AutoCollecting then return false end if not isFruitValid(fruit) then return false end local state = getFruitState(fruit) if state and state.Skipped then return false end fruitStates[fruit] = { Skipped = true, Position = fruit.Position } if not teleportToFruit(fruit) then return false end RunService.RenderStepped:Wait() if not turnCameraToFruit(fruit) then return false end task.wait( CAMERA_TWEEN_TIME ) if not isCameraLookingAtFruit(fruit) then return false end task.wait(FRUIT_DELAY) if not simulateMouseClick(fruit) then return false end return waitForFruitReaction(fruit) end local function enableFlight() if not isRunning() then return end local character = player.Character if not character then return end local root = character:FindFirstChild( "HumanoidRootPart" ) if not root then return end if ScriptState.FlightForce then ScriptState.FlightForce:Destroy() ScriptState.FlightForce = nil end if ScriptState.FlightAttachment then ScriptState.FlightAttachment:Destroy() ScriptState.FlightAttachment = nil end local attachment = Instance.new( "Attachment" ) attachment.Name = "LemonFlightAttachment" attachment.Parent = root ScriptState.FlightAttachment = attachment local force = Instance.new( "VectorForce" ) force.Name = "LemonFlightForce" force.Attachment0 = attachment force.RelativeTo = Enum.ActuatorRelativeTo.World force.ApplyAtCenterOfMass = true force.Force = Vector3.new( 0, root.AssemblyMass * workspace.Gravity * FLIGHT_FORCE_MULTIPLIER, 0 ) force.Parent = root ScriptState.FlightForce = force end local function disableFlight() if ScriptState.FlightForce then ScriptState.FlightForce:Destroy() ScriptState.FlightForce = nil end if ScriptState.FlightAttachment then ScriptState.FlightAttachment:Destroy() ScriptState.FlightAttachment = nil end end ScriptState.FlightConnection = RunService.Heartbeat:Connect( function() if not isRunning() then return end local character = player.Character if not character then return end local root = character:FindFirstChild( "HumanoidRootPart" ) if not root then return end if ScriptState.FlightForce then ScriptState.FlightForce.Force = Vector3.new( 0, root.AssemblyMass * workspace.Gravity * FLIGHT_FORCE_MULTIPLIER, 0 ) end end ) local function autoCollectLoop() enableFlight() while isRunning() and ScriptState.AutoCollecting do local ok = pcall( function() if os.clock() - lastRescan >= RESCAN_INTERVAL then fullRescan() end local fruit = getNearestFruit() if not fruit then fullRescan() fruit = getNearestFruit() end if fruit then processFruit(fruit) end end ) task.wait(SEARCH_DELAY) end end ScriptState.InputConnection = UserInputService.InputBegan:Connect( function( input, gameProcessed ) if not isRunning() then return end if gameProcessed then return end if input.KeyCode ~= Enum.KeyCode.Y then return end if ScriptState.AutoCollecting then ScriptState.AutoCollecting = false if ScriptState.CameraTween then ScriptState.CameraTween:Cancel() ScriptState.CameraTween = nil end disableFlight() return end ScriptState.AutoCollecting = true lastRescan = 0 task.spawn( autoCollectLoop ) end ) player.CharacterAdded:Connect( function() if not isRunning() then return end fruitStates = {} previousFruitPresence = {} task.wait(1) fullRescan() if ScriptState.AutoCollecting then enableFlight() end end )