-- https://discord.gg/ZpyYzvCh9v local Players = game:GetService('Players') local ReplicatedStorage = game:GetService('ReplicatedStorage') local UserInputService = game:GetService('UserInputService') local Debris = game:GetService('Debris') local RunService = game:GetService('RunService') local player = Players.LocalPlayer local PlayerGui = player:WaitForChild('PlayerGui') local SAPLING_NAME = 'sapling' local PLANT_COUNT = 75 local PLANT_DISTANCE = 44 local SHOW_BLUEPRINT = true local BETWEEN_PLANT_WAIT = 0.06 local MARKER_LIFETIME = 6 local START_CFRAME = CFrame.new( -1.29994965, 1.99994278, -1.50001144, -0.249999881, 0.432982802, 0.866040468, 0.865997314, 0.500048637, -1.5437603e-05, -0.43306911, 0.74998486, -0.499974132 ) local function findPlantRemote() if ReplicatedStorage:FindFirstChild('RemoteEvents') then local r = ReplicatedStorage.RemoteEvents:FindFirstChild('RequestPlantItem') if r then return r end end local r = ReplicatedStorage:FindFirstChild('RequestPlantItem') if r then return r end for _, obj in ipairs(ReplicatedStorage:GetDescendants()) do if obj.Name:lower() == 'requestplantitem' then return obj end end return nil end local PlantRemote = findPlantRemote() local function findSaplingInstance() local items = workspace:FindFirstChild('Items') if items then for _, c in ipairs(items:GetChildren()) do if c.Name:lower():find(SAPLING_NAME:lower()) then return c end end end for _, c in ipairs(ReplicatedStorage:GetDescendants()) do if c:IsA('Model') or c:IsA('Tool') then if c.Name:lower():find(SAPLING_NAME:lower()) then return c end end end local backpack = player:FindFirstChild('Backpack') local inv = player:FindFirstChild('Inventory') local containers = { backpack, inv } for _, cont in ipairs(containers) do if cont then for _, c in ipairs(cont:GetChildren()) do if c.Name:lower():find(SAPLING_NAME:lower()) then return c end end end end return nil end local function getGroundY(xzPos, defaultY) local origin = Vector3.new(xzPos.X, (defaultY or xzPos.Y) + 50, xzPos.Z) local rayDir = Vector3.new(0, -200, 0) local rp = RaycastParams.new() rp.FilterDescendantsInstances = { player.Character or player } rp.FilterType = Enum.RaycastFilterType.Blacklist local res = workspace:Raycast(origin, rayDir, rp) if res and res.Position then return res.Position.Y end return defaultY or xzPos.Y end local function createMarker(pos) if not SHOW_BLUEPRINT then return end local p = Instance.new('Part') p.Size = Vector3.new(1, 1, 1) p.Anchored = true p.CanCollide = false p.Transparency = 0.45 p.Color = Color3.fromRGB(45, 200, 45) p.Name = 'SaplingMarker' p.CFrame = CFrame.new(pos + Vector3.new(0, 0.5, 0)) p.Parent = workspace Debris:AddItem(p, MARKER_LIFETIME) return p end local function tryCallRemote(remote, argTable) if not remote then return false end if remote.ClassName == 'RemoteFunction' or remote.InvokeServer then local ok = pcall(function() remote:InvokeServer(unpack(argTable)) end) return ok end if remote.ClassName == 'RemoteEvent' or remote.FireServer then local ok = pcall(function() remote:FireServer(unpack(argTable)) end) return ok end return false end local function robustPlantCall(remote, saplingArg, position) if not remote then return false end local attempts = { { saplingArg, position }, { position, saplingArg }, { tostring(saplingArg), position }, { position, tostring(saplingArg) }, } for _, args in ipairs(attempts) do if tryCallRemote(remote, args) then return true end task.wait(0.03) end return false end local function plantCircle(centerPos, count, distance) local sapInst = findSaplingInstance() local firstArg = sapInst or SAPLING_NAME for i = 1, math.max(1, count) do local angle = (2 * math.pi / count) * (i - 1) local x = centerPos.X + math.cos(angle) * distance local z = centerPos.Z + math.sin(angle) * distance local groundY = getGroundY(Vector3.new(x, centerPos.Y, z), centerPos.Y) local finalPos = Vector3.new(x, groundY, z) createMarker(finalPos) robustPlantCall(PlantRemote, firstArg, finalPos) task.wait(BETWEEN_PLANT_WAIT) end end local function plantSquare(centerPos, totalCount, distance) local side = math.max(1, math.floor(math.sqrt(totalCount))) local startOffset = (side - 1) / 2 local index = 0 local sapInst = findSaplingInstance() local firstArg = sapInst or SAPLING_NAME for x = 0, side - 1 do for z = 0, side - 1 do if index >= totalCount then break end local xx = centerPos.X + (x - startOffset) * distance local zz = centerPos.Z + (z - startOffset) * distance local groundY = getGroundY(Vector3.new(xx, centerPos.Y, zz), centerPos.Y) local finalPos = Vector3.new(xx, groundY, zz) createMarker(finalPos) robustPlantCall(PlantRemote, firstArg, finalPos) index = index + 1 task.wait(BETWEEN_PLANT_WAIT) end if index >= totalCount then break end end end local function plantFromStart(mode) local originPos = START_CFRAME.Position if mode == 'Circle' then plantCircle(originPos, PLANT_COUNT, PLANT_DISTANCE) else plantSquare(originPos, PLANT_COUNT, PLANT_DISTANCE) end end -- TOGGLE SYSTEM local autoPlant = false local planting = false local function togglePlanting() autoPlant = not autoPlant if autoPlant and not planting then planting = true task.spawn(function() while autoPlant do plantFromStart('Circle') task.wait(0.5) end planting = false end) end end -- PC: press Q UserInputService.InputBegan:Connect(function(input, gpe) if gpe then return end if input.KeyCode == Enum.KeyCode.Q then togglePlanting() end end) -- Mobile local screenGui = Instance.new('ScreenGui') screenGui.Name = 'AutoPlantGui' screenGui.Parent = PlayerGui local button = Instance.new('TextButton') button.Size = UDim2.new(0, 120, 0, 50) button.Position = UDim2.new(0.05, 0, 0.8, 0) button.Text = 'Toggle Plant' button.BackgroundColor3 = Color3.fromRGB(50, 200, 50) button.TextColor3 = Color3.new(1, 1, 1) button.Parent = screenGui button.MouseButton1Click:Connect(togglePlanting)