
Key Required VerifiedUniversal
--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
)No comments yet for this script.



